Имя: Пароль:
1C
 
v8: 1c и c#
0 Sali_64
 
12.11.09
16:12
Добрый день уважаемые!
Появилась необходимость работы с c#. Но наш программер на с# никак не может продвинуться дальше коннекта с базой. Т.е. к базе подключаемся, можем выбрать справочник или документ и создать запрос, но просмотреть реквизиты документа(справочника) или установить реквизит Запрос.Текст уже никак. Все примеры с сайта не помогли (((.
Может дадите рабочий фрагмент кода от начала, т.е. коннекта к базе и выборки из запроса непосредственно данных.
Буду очень благодарен.
1 Rie
 
12.11.09
16:14
(0) А оно сильно надо именно на C#?
2 Господин ПЖ
 
12.11.09
16:15
>>Но наш программер на с# никак не может продвинуться дальше коннекта с базой

предлагаю заменить...
3 Ненавижу 1С
 
гуру
12.11.09
16:15
4 Sali_64
 
12.11.09
16:18
(3) Спасибо. Этот пример уже 2 дня пытались использовать (
5 Ненавижу 1С
 
гуру
12.11.09
16:21
(4) значит (2)
6 Господин ПЖ
 
12.11.09
16:23
достаточно вбить 1С + C# в гугле - на любом ресурсе все есть.
7 Serginio1
 
12.11.09
16:23
(3) Проще бейсик выучить, чем заниматься рефлексией.
8 Ненавижу 1С
 
гуру
12.11.09
16:24
(7) может и проще
9 Sali_64
 
12.11.09
16:55
(7) Да. на VB это всего лишь...
(8) Желают C#

Dim V8 As Object
Set V8 = CreateObject("V81.COMConnector")
Set Con = V8.Connect("Srvr=""server022"";Ref=""upp_test"";Usr=""WEB"";Pwd=""15619""")
Set q1 = Con.newObject("Запрос")
q1.Text = "ВЫБРАТЬ Валюты.Код, Валюты.Наименование ИЗ Справочник.Валюты КАК Валюты"
Set Result = q1.Выполнить().Выбрать()
For I = 1 To Result.Количество()
Result.Next
Cells(I, 1).Value = Result.Код
Cells(I, 2).Value = Result.Наименование
Next
11 1c_asp
 
12.11.09
17:01
Если Вы используете C# то Вам проще всего работать с web расширением.
12 Sali_64
 
12.11.09
17:08
(11) так его нужно купить и настроить, а времени нет. Да вроде бы задача тривиальная.
14 1c_asp
 
12.11.09
17:10
(12) ну если только выборка данных, то да, не стоит
15 Rie
 
12.11.09
17:11
(10) Так а на C# у вас - какой код это пытается сделать?
16 Rie
 
12.11.09
17:12
(15)->(9)
17 Sali_64
 
12.11.09
17:14
(16) для примера именно (9)
а рабочем виде запрос по заявкам на расход ДС.
18 1c_asp
 
12.11.09
17:16
На шарпе выглядит примерно так (с использованием Вэб расширения)

       V8DbSelectCommand select = new V8DbSelectCommand();
       select.Connection = Connection;
       select.CommandType = CommandType.TableDirect;
       select.CommandText = "Справочник.Пользователи";
       select.Fields = "Ссылка,Наименование";
       select.WhereClause = @"НЕ ПометкаУдаления";

       V8DataReader reader = (V8DataReader)select.ExecuteReader();
       while (reader.Read())
       {
           ObjectRef refr = (ObjectRef)reader.GetValue(0);
           string str_ref = ((_1C.V8.Data.ObjectRef)(refr)).UUID.ToString();
           string Name = reader.GetString(1);

           ListChoiceItem lci = new ListChoiceItem();
           lci.Value = refr;
           lci.Text = Name;

           Ответственный.ListChoice.Add(lci);
       }
       reader.Close();
19 1c_asp
 
12.11.09
17:18
А вот например получение переменной по си шарповски (опять же через вэб расширение):

 object Usr = V8.Call(Connection, Connection.Connection, "глЗначениеПеременной", new object[1] { "глТекущийПользователь" });
 string Presentation = ((ObjectRef)Usr).Presentation(Connection);

Думаю что если все так сложно через вэб расширение, то напрямую будет как минимум не проще
20 1c_asp
 
12.11.09
17:19
А вот создание отчета :

       GetConnect gc = new GetConnect();
       V8DbConnection Connection = gc.GetNewConnect(Session, Response);
       if (!gc.isTestConnectionOk)
       {

           return;
       }

       Connection.Open();


       object Reports = V8.Get(Connection, Connection.Connection, "Отчеты");
       object manager_rep = V8.Get(Connection, (ComObject)Reports, "_ОтчетРабочееВремя");
       object rep = V8.Call(Connection, (ComObject)manager_rep, "Create", new object[] { 0 });

       object[] param = new object[] { НачПериода.Value, КонПериода.Value, Ответственный.Value };
       string HTML = (string)V8.Call(Connection, (ComObject)rep, "GetHTML", param);
       ReportPlace.InnerHtml = HTML;

       ((ComObject)rep).Dispose();
       ((ComObject)manager_rep).Dispose();
       ((ComObject)Reports).Dispose();

       Connection.Close();
21 Rie
 
12.11.09
17:22
(17) В чём именно проблемы с C#?
Если вы создали объект, скажем, СправочникМенеджер конкретного вида, то что мешает тем же способом двинуться дальше?
22 Sali_64
 
12.11.09
17:30
Все делали по примерам указанным выше. К сожалению программист уже ушел и код показать не могу. Но было А-ля:
object v8_deb = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "СправочникМенеджер.Контрагенты" });

а вот здесь выдает ошибку
           object v8_deb_select = v8_deb.GetType().InvokeMember("НайтиПоКоду", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v8_deb, new object[] { "V00000665" });

и не видно свойств у v8_deb
23 Sali_64
 
16.11.09
10:07
Вот наш код:
           Работает:
v8_connect = new COMConnector();
           MainObj = v8_connect.Connect(@"Srvr=server022;Ref=upp_test;usr=test;pwd=00000");

object query = MainObj.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, MainObj, new object[] { "Запрос" });
           
                              Падает:
MainObj.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, query,
new object[] { "ВЫБРАТЬ Валюты.Код, Валюты.Наименование ИЗ Справочник.Валюты КАК Валюты" });
24 Rie
 
16.11.09
10:11
(23) Что-то я не понял, что этот падающий код должен проделать по задумке пишущего.
Точнее, понял, что хочется создать запрос и задать его текст. Ну так и задавай значение свойству Текст объекта типа Запрос.
25 Sali_64
 
16.11.09
10:18
(24) Как задавать значение? query.Текст= ? Пробовали. Не получается.
Я не прогр. С# поэтому и прошу пример работающего кода.
26 Rie
 
16.11.09
10:21
(25) SetProperty в BindingFlags и "Текст" в качестве имени свойства.
27 Rie
 
16.11.09
10:23
+(26) Если нужен полностью пример работающего кода - тогда погоди чуток, пока доберусь до VS и набросаю пример.
28 Rie
 
16.11.09
10:24
В (26) я имел в виду именно параметры InvokeMember.
29 Sali_64
 
16.11.09
10:28
(27) Буду очень благодарен! А то прогр.C# говорит что ничего не получиться, а если и получиться, емеет в виду выполнить запрос, то типа потом прочитать результат, чтобы вывести на экран, будет еще сложнее...
30 Sali_64
 
16.11.09
10:31
+(29) если бы получить аналог того что в (9) то было бы супер!
31 hhhh
 
16.11.09
10:53
(30) вроде в (9) надо не Result.Next, а Result.Next()
32 Rie
 
16.11.09
11:11
(31) Для VB - в самый раз.
33 1c_asp
 
16.11.09
12:33
(29) Подумайте, может имеет смысл не экономить, а взять за 15 тыров web расширение ? Возможно это обойдется дешевле, чем оплата рабочего времени
34 Rie
 
16.11.09
13:10
Возвращаясь к нашим баранам.
Пусть определен класс

   public class Connection
   {
       private static BindingFlags INVOKE_METHOD = BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static;
       private static BindingFlags GET_PROPERTY = BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Static;
       private static BindingFlags SET_PROPERTY = BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Static;

       private object connector;
       private object connection;

       public Connection(string ParamStr)
       {
           connector = System.Activator.CreateInstance(Type.GetTypeFromProgID("V81.COMConnector"));
           connection = connector.GetType().InvokeMember("Connect", INVOKE_METHOD, null, connector, new object[] { ParamStr });
       }

       public object NewObject(string ObjectType)
       {
           return connection.GetType().InvokeMember("NewObject", INVOKE_METHOD, null, connection, new object[] { ObjectType });
       }

       public static Object CallMethod(object Object, string Name, object[] Args)
       {
           return Object.GetType().InvokeMember(Name, INVOKE_METHOD, null, Object, Args);
       }

       public static object GetProperty(object Object, string Name)
       {
           return Object.GetType().InvokeMember(Name, GET_PROPERTY, null, Object, null);
       }

       public static void SetProperty(object Object, string Name, object Value)
       {
           Object.GetType().InvokeMember(Name, SET_PROPERTY, null, Object, new object[] { Value });
       }

}
35 Rie
 
16.11.09
13:11
Тогда в форме

   public partial class Form1 : Form
   {
       private V8.Connection link1C;

       public Form1()
       {
           InitializeComponent();
       }

       private void button1_Click(object sender, EventArgs e)
       {
           link1C = new V8.Connection("File=\"R:\\Projects\\Патюков\\УПП\"");
       }

       private void button2_Click(object sender, EventArgs e)
       {
           object q1 = link1C.NewObject("Запрос");
           V8.Connection.SetProperty(q1,"Text","ВЫБРАТЬ Валюты.Код, Валюты.Наименование ИЗ Справочник.Валюты КАК Валюты");
           object Result = V8.Connection.CallMethod(q1,"Выполнить", null);
           object Selection = V8.Connection.CallMethod(Result,"Выбрать",null);
           V8.Connection.CallMethod(Selection, "Следующий", null);
           MessageBox.Show((string)V8.Connection.GetProperty(Selection,"Наименование"));
       }
   }
36 Rie
 
16.11.09
13:11
Я не стал крутить цикл по выборке, полагаю, что суть понятна из приведенного.
37 Rie
 
16.11.09
13:13
(29) Насчёт программиста - см. (2).
38 Sali_64
 
16.11.09
16:05
(34-36) Огромное спасибо, добрый человек! Все получилось.
39 Sali_64
 
16.11.09
17:01
(35) Уважаемый  Rie появилась еще одна проблемка. Запрос не выполняется если в его тексте появляется символ "_" нижнее подчеркивание.
40 Rie
 
16.11.09
17:06
(39) "Не выполняется" - что при этом говорит и какой именно запрос?
41 Sali_64
 
16.11.09
17:09
Как говорит прогр.С# запрос "заваливатеся".
А запрос:
....ПРЕДСТАВЛЕНИЕ(ЗаявкиНаРасходованиеСредствОбороты.ЗаявкаНаРасходование.ГЛ_ДатаСчета) КАК ДатаСчета,
...
ИЗ
   РегистрНакопления.ЗаявкиНаРасходованиеСредств.Обороты(ДАТАВРЕМЯ(2009, 1, 1), , , ) КАК ЗаявкиНаРасходованиеСредствОбороты

Если удаляем строки содержащие "ГЛ_" то запрос выполняется.
42 Rie
 
16.11.09
17:14
(41) ГЛ_ДатаСчета - это что (с точки зрения 1С)? _Этот же_ запрос в 1С - выполняется?
"Если удаляем строки, содержащие" - то это ведь будет уже несколько другой запрос?

Ну и слово "заваливается" - мне не совсем понятно. Вернее, совсем не понятно.
43 Rie
 
16.11.09
17:14
+(42) И на всякий случай скажите, с какой конфигурацией вы работаете.
44 Sali_64
 
16.11.09
17:21
(42) конечно же запрос в 1С выпоняется. Просто искали ошибку удалением строки из запроса при выполнении кода на С#.
Заваливается - выдает ошибку. Цитрировать ее не могу т.к. прогр. уже ушел ).
УПП (1.2.16.1) далее доработанная
1С:Предприятие 8.1 (8.1.14.72)
45 Rie
 
16.11.09
17:27
(44) Всё же нужна более подробная информация - текст запроса и сообщение об ошибке. IMHO, вряд ли проблема именно в символе подчеркивания.

Попробуйте тот же запрос вызвать из VBA. Выполнится ли он?
Если ли у запроса параметры - и что передаётся в качестве параметров?
И т.д.
46 Sali_64
 
16.11.09
17:54
(44) да. Выполнил запрос на VBA и смог прочитать ошибку(в c# одни краякозябры)! Действительно "...нет поля". Заморочился и слал "рабочий" запрос к "тестовой" базе. Извините великодушно! Еще раз большое спасибо, спасли от кучи бестолковой работы т.к. прогр.C# уже настаивал на переносе данных через промежуточные таблицы на MSSQL.
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.