Home News

1с - IDispatch GetIDsOfNames в Delphi - Stack Overflow на русском

01.09.2018

Имеется код для подключения к базе 1С-предприятие 8.3 и выполнения в ней функции Тест1(5, 2).

var pDisp : IDispatch; sMethodName : Widestring; iDispId : TDispId; dpPutArgs : TDispParams; ei : TExcepInfo; iError : uint; vSet : olevariant; vParams : array [1..63] of olevariant; VarResult : OleVariant; function_1c : AnsiString; begin pDisp := CreateOleObject('V83.Application'); sMethodName := 'Connect'; OleCheck (pDisp.GetIDsOfNames (GUID_NULL, @sMethodName, 1, LOCALE_SYSTEM_DEFAULT, @iDispId)); vSet := 'File=C:\Users\Admin\Documents\InfoBase'; FillChar (dpPutArgs, sizeof (dpPutArgs), 0); dpPutArgs.rgvarg := @vSet; dpPutArgs.cArgs := 1; dpPutArgs.cNamedArgs := 0; dpPutArgs.rgdispidNamedArgs := nil; OleCheck (pDisp.Invoke (iDispId, GUID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, dpPutArgs, @VarResult, @ei, @iError)); function_1c := 'Тест1'; sMethodName := function_1c; OleCheck (pDisp.GetIDsOfNames (GUID_NULL, @sMethodName, 1, GetThreadLocale, @iDispId)); vParams[1] := 2; vParams[2] := 5; FillChar (dpPutArgs, sizeof (dpPutArgs), 0); dpPutArgs.rgvarg := @vParams; dpPutArgs.cArgs := 2; dpPutArgs.cNamedArgs := 0; dpPutArgs.rgdispidNamedArgs := nil; OleCheck (pDisp.Invoke (iDispId, GUID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, dpPutArgs, @VarResult, @ei, @iError)); pDisp := UnAssigned; end;

Проблема заключается в том, что необходимо вместо V83.Application использовать V83.COMConnector . Если просто изменить одну строчку кода, то, при попытке получить идентификатор функции на втором GetIdsOfNames, программа сообщает об ошибке "Неизвестное имя" . Пробовал вводить английское имя функции (Test), ошибка оставалась.

Склоняюсь думать, что GetidsOfNames не понимает кодировку строки "Тест1". Даже при V83.Application приходиться использовать костыль в виде преобразования AnsiString в WideString перед получением идентификатора (SMethodName := function_1c).

Также я пробовал, вместо позднего связывания, чётко прописать в коде функцию на выполнение, а потом смотрел какие системные интерфейсы дёргаются при таком варианте. Всё сходится, как и в коде выше: сначала GetidsOfNames, а потом Invoke.

OLE_obj := CreateOleObject('V83.COMConnector'); OLE_obj := OLE_obj.Connect('File=C:\Users\Admin\Documents\InfoBase'); ansver := OLE_obj.Тест1(2, 5);

P.S. Использую Delphi-XE3, 1С-Предприятие 8.3. В базе данная функция находиться в глобальном общем модуле, выставлены все галочки для клиент-серверного взаимодействия, сама функция Тест1 является экспортируемой.

rss