Имя: Пароль:
1C
1С v8
Вызов функции общего модуля серверной 1С (8.3) по COM
,
0 alexeyomg
 
31.05.16
12:20
Я цепляюсь из программы (на c#) через COM к 1с (серверная, не файловая). Подключение проходит успешно, но я не могу обратиться к функции общего модуля.
Пишет следующее:
"2016-05-30 16:19:13.1634 ERROR Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: "System.__ComObject" не содержит определения для "ОбщийМодуль"
   в CallSite.Target(Closure , CallSite , ComObject )
   в CallSite.Target(Closure , CallSite , Object )..."

на c# код следующий:

string connectionString = "srvr='" + mainConfig.base1cServer +
                            "';ref='" + mainConfig.base1cName +
                            "';Usr='" + mainConfig.base1cUser +
                            "';Pwd='" + mainConfig.base1cPassword + "';";
V83.COMConnector com1c83 = new V83.COMConnector();
com1c83.PoolCapacity = 10;
com1c83.PoolTimeout = 60;
com1c83.MaxConnections = 2;
connection1C = com1c83.Connect(connectionString);
dynamic result1c = connection1C.ОбщийМодуль.Тест(new object[] {});

в 1С код следующий:

Функция Тест() Экспорт
    Возврат "тест";
КонецФункции

Всё это находится в модуле "ОбщийМодуль" (созданный мной) в разделе "Общие модули". У этого модуля активированы следующие параметры:
-Сервер
-Внешнее соединение
-Вызов сервера

В случае с файловой базой - всё работает!!!
В случае с серверной базой пишет ошибку, указанную в начале поста.

Я пробовал делать общий модуль Глобальным, и тогда в c# команда выглядит так:
dynamic result1c = connection1C.Тест(new object[] {});
С файловой это работает, с серверной нет.

Я также пытался написать тот же метод в "Модуль внешнего соединения" в 1с-ке. И опять, с файловой это работает, а с серверной - нет.

Подскажите, в чём прикол серверной версии 1с? И как мне обратиться к методу модуля?
1 alexeyomg
 
31.05.16
12:35
Через Com результат запроса на северную 1с приходит отлично!!! А вот с вызовом метода - проблемы :(
2 Philix
 
31.05.16
12:40
3 Рэйв
 
31.05.16
12:41
поставить модулю  галку "Внешнее соединение" или скопировать функцию в модуль внешнего соединения и постаивть Экспорт
4 MrStomak
 
31.05.16
12:41
1. Галочка "Внешнее соединение" точно-точно-точно стоит?
5 arsik
 
гуру
31.05.16
12:41
(3) Так у него стоит "внешнее соединение"
6 HardBall
 
31.05.16
12:42
Нажать F7 не предлагали?
7 Рэйв
 
31.05.16
12:43
(5)Каюсь,прочитал сабж по диагонали:-)
8 alexeyomg
 
31.05.16
12:45
я видел где-то про f7, но что это?
я нажимал, у меня ничего не происходило
9 alexeyomg
 
31.05.16
12:45
(6) выше
10 Philix
 
31.05.16
12:46
И есть у меня какие-то сомнения на счет использования кириллицы в именах общих модулей и функций при обращении из Си Шарп. Попробуй старую добрую латынь
11 Рэйв
 
31.05.16
12:48
(10)Нормально должно быть вроде.Я даже процедуры по русски называл.Съедало
12 Тролль главный
 
31.05.16
12:49
а зачем там пустой массив?

dynamic result1c = connection1C.ОбщийМодуль.Тест();
13 MrStomak
 
31.05.16
12:49
(0) А вызов метода без параметров обязательно с этим new object[] {} выполняется?
14 alexeyomg
 
31.05.16
12:50
(12) (13) ну в файловой работало нормально.
сейчас попробую без пустого массива
15 Serginio1
 
31.05.16
12:51
16 Serginio1
 
31.05.16
12:53
17 alexeyomg
 
31.05.16
13:07
Так, убрал new object[] {} - заработало.
Но есть метод с параметрами. Как его вызывать?
18 Тролль главный
 
31.05.16
13:15
(17) вот так:

dynamic result1c = connection1C.ОбщийМодуль.Тест(ПервыйПараметр,ВторойПараметр);
19 Philix
 
31.05.16
13:17
Через ком-соединения проходят только простые типы данных.
Или сложные, но уже определенные на той стороне ком-соединения. Т.е. или строку туда (дату, число, буелво), или результат выражения типа connection1C.Справочники.Контрагенты.найтипокоду("12345678")
20 hhhh
 
31.05.16
13:17
(17) параметры передавать
21 Serginio1
 
31.05.16
13:22
(19) Чере COM соединения проходят любые COM совместимые типы в том числе и IDispatch
22 alexeyomg
 
31.05.16
13:24
мне обязательно нужно вызвать метод через InvokeMethod

я делаю на самом деле так:

result1c = module.GetType().InvokeMember(methodSplit[i], BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static,
                            null, module, new object[] { valiuesDict });


valiuesDict- это Dictionary в c#. По сути оно сконвертируется в Соответствие в 1с-ке. Или нет?

Вроде как если инвоук с параметрами, то надо писать последним атрибутом массив new object[] { valiuesDict }, чьи члены - это параметры.


но у меня не работает. Даже если строку передаю
23 Serginio1
 
31.05.16
13:28
Dictionary в c#. По сути оно сконвертируется в Соответствие в 1с-ке. Или нет? Не сконвертируется. Нужна com обертка
Например по ссылке из 15
Использование классов .Net в 1С для новичков
24 alexeyomg
 
31.05.16
13:30
(21) (20) (19) (18)
А если через массив? (23)
25 hhhh
 
31.05.16
13:36
(24) ты должен определить массив на той стороне

connection1C.ntwObject("Массив");
connection1C.ntwObject("Структура");

и так далее. Даже если из 1с вызывать 1с, всё равно у них массивы свои у каждой.
26 hhhh
 
31.05.16
13:37
newObject
27 alexeyomg
 
31.05.16
14:36
Всё работает. НО!!!
Не работает, если внутри функции вызывается метод с дерективой "&НаСервере". Пишет:
System.Runtime.InteropServices.COMException (0x80020006): Неизвестное имя. (Исключение из HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))
28 Serginio1
 
31.05.16
22:44
(27) Если массив простых типов то будет передаваться SafeArray
29 alexeyomg
 
01.06.16
11:03
Спасибо, ребят, заработало.
Создаю в c# объект
dynamic object1c = connection1C.newObject("Соответствие");

потом добавляю данные в Соответствие
object1c.Вставить(...);

а потом передаю
result1c = connection1C.GetType().InvokeMember("Тест", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static,
                            null, module, new object[] { object1c });
Закон Брукера: Даже маленькая практика стоит большой теории.