Использование русских символов при работе с 1С из Delphi

01.04.14

Разработка - Разработка внешних компонент

Решение проблемы "Method 'НазваниеМетода' not supported by automation object" при работе с 1C: Предприятие для некоторых версий Delphi.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Исходный код и пример
.zip 234,30Kb
7 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Проблема

При подключении к системе 1С: Предприятие 8 из программ, разработанных в среде программирования Delphi, возникает ошибка с неверными обращениями к объекту автоматизации сервера. Например, подобная строка кода:

1CEnterprise.Справочники.Номенклатура.Выбрать();

, где  1CEnterprise  – переменная типа Variant  с указателем на интерфейс IDispatch COM-объекта 1С: Предприятие, приведет к появлению сообщения об ошибке: Method 'Справочники ' not supported by automation object.

Данная проблема возникает из-за того что идентификаторы содержат русские буквы, а передача их интерфейсу IDispatch происходит в кодировке Юникод. Но из-за ошибок в среде Delphi происходит искажение имён. Проблема нивелируется, пока можно использовать английские синонимы, но они определены только для встроенных объектов и функций платформы! Множество прикладных функций не имеет их…

Решение

Вначале рассмотрим типичный сценарий подключения к системе 1С:Предприятие:

Var 1CEnterprise: Variant;

begin

1CEnterprise := CreateOleObject(‘V82.COMConnector’). Connect(‘File="С:\1CBase\"; Usr="Администратор"; Pwd="Пароль";’);

…

Далее при обращении к свойству Справочники происходит неявное обращение к интерфейсу IDispatch (что-то вроде вызова Invoke(‘Справочники’) если упрощено). Осуществляется же это благодаря функциональности типа Variant. 

Для трансляции обращения к интерфейсу вызывается функция, назначенная в глобальную переменную VarDispProc. По умолчанию в неё назначена процедура из модуля ComObj. Но ничего не мешает заместить её на свою собственную и работать с интерфейсом IDispatch напрямую.

procedure MyVarDispInvoke(Result: PVariant; const Instance: Variant;
  CallDesc: PCallDesc; Params: Pointer); cdecl;

  procedure RaiseException;
  begin
    raise EOleError.CreateRes(@SVarNotObject);
  end;

var
  Dispatch: Pointer;
  DispIDs: array[0..MaxDispArgs - 1] of Integer;
begin
  if (CallDesc^.ArgCount) > MaxDispArgs then raise EOleError.CreateRes(@STooManyParams);
  if TVarData(Instance).VType = varDispatch then
    Dispatch := TVarData(Instance).VDispatch
  else if TVarData(Instance).VType = (varDispatch or varByRef) then
    Dispatch := Pointer(TVarData(Instance).VPointer^)
  else RaiseException;
  GetIDsOfNames(IDispatch(Dispatch), @CallDesc^.ArgTypes[CallDesc^.ArgCount],
    CallDesc^.NamedArgCount + 1, @DispIDs);
  if Result <> nil then VarClear(Result^);
  DispatchInvoke(IDispatch(Dispatch), CallDesc, @DispIDs, Params, Result);
end;

Естественно лучше использовать некое подобие первоначальной функции, рассматривая которую можно заметить участок кода который и отвечает за передачу имен:

GetIDsOfNames(IDispatch(Dispatch), @CallDesc^.ArgTypes[CallDesc^.ArgCount], CallDesc^.NamedArgCount + 1, @DispIDs);

Процедура GetIDsOfNames преобразует строковое имя в целочисленный идентификатор для вызова Invoke. Второй параметр содержит строку с именем вызываемого метода, но что важно - в каком формате? Выяснить это можно с помощью отладчика. Так вот в разных версиях Delphi формат разный и именно поэтому возникает ошибка, но только при работе с системой 1С: Предриятие 8 - подавляющее число интерфейсов у систем имеет идентификаторы только на английском языке! Здесь следует проникнуться гордостью за отечественных разработчиков и осыпать проклятьями их зарубежных коллег... Само же решение проблемы сильно зависит от формата параметра и содержимого процедуры GetIDsOfNames. В Delphi 2006 параметр передается уже в формате Юникод, а метод преобразует его в Юникод повторно, что и вызывает ошибку

Ошибка 

Достаточно просто сконвертировать строку из Юникода, например так:

procedure GetIDsOfNames(const Dispatch: IDispatch; Names: PChar;
  NameCount: Integer; DispIDs: PDispIDList);

  procedure RaiseNameException;
  begin
    raise EOleError.CreateResFmt(@SNoMethod, [Names]);
  end;

type
  PNamesArray = ^TNamesArray;
  TNamesArray = array[0..0] of PWideChar;
var
  N, SrcLen, DestLen: Integer;
  Src: PChar;
  Dest: PWideChar;
  NameRefs: PNamesArray;
  StackTop: Pointer;
  Temp: Integer;
begin
  //Src := Names; ---------------------------------------- БЫЛО
Src := PChar(Utf8ToAnsi(Names)); // ------------------- СТАЛО
N := 0;
asm
MOV StackTop, ESP
MOV EAX, NameCount
INC EAX
...

 

Всё - этого достаточно. Советы из разряда "установи старую Delphi" теперь можете смело игнорировать.

 Исправление

Не забудьте только перед использованием подменить адрес процедуры в глобальной переменной  VarDispProc.

VarDispProc := MyVarDispInvoke;

В архиве содержится исходный код и пример (пытается выполнить ShowMessage(obj.Метаданные.Справочники.Банки.Комментарий); ). Удачного внешнего управления системой 1С Предприятие!

PS. Если вы думаете что IDispatch что-то специфичное и нужное только в Delphi, то задумайтесь - как 1С работает со значениями через точку? Когда вы работаете в конфигураторе с переменной содержимое которой не определяете самостоятельно (например параметр), то после точки может быть любой идентификатор - ошибки при проверке не будет (тип переменной неизвестен), а ошибка может произойти только при исполнении, когда в работу вступит интерфейс... да-да  IDispatch объекта 1С !!! 

Вступайте в нашу телеграмм-группу Инфостарт

Delphi IDispatch OLE COM Ошибка

См. также

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Программист Пользователь 1С:Предприятие 8 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Медиадисплей покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Экран можно использовать в качестве графического меню-борда в кафе и видеовывески. В качестве устройства отображения можно использовать Android-планшеты, смарт-телевизоры с Android, мониторы или проекторы под управлением Windows или Linux-компьютера. Linux-версия успешно запускается на одноплатных компьютерах Raspberri Pi и Orange Pi. Настраивается ЛЮБОЙ ДИЗАЙН экрана при помощи встроенного графического редактора! Решение можно масштабировать от одного экрана до тысяч экранов с централизованным управлением.

18300 руб.

30.05.2017    57404    11    71    

48

Разработка внешних компонент Программист 1С:Предприятие 8 1C:Бухгалтерия 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

5084 руб.

12.05.2020    34181    145    100    

101

Разработка внешних компонент Программист 1С:Предприятие 8 Бесплатно (free)

Нативная внешняя компонента для 1С 8 для чтения файлов Excel без установленного Excel и делает это быстро, файл 68МБ загружается в таблицу значений ~1 секунду. Компонента поддерживает чтение двух форматов: Excel 2007+ и Excel 97-2003 Формат файла определяется автоматически по сигнатуре (первые 8 байт файла), а не по расширению. Позволяет открывать XLS и XLSX файлы и получать содержимое листов в виде ТаблицыЗначений или JSON-массива.

03.07.2026    983    skyadmin    31    

21

Разработка внешних компонент Программист 1С 8.3 Бесплатно (free)

В современных корпоративных решениях на платформе 1С:Предприятие 8.3 всё чаще возникает потребность в визуальном моделировании и автоматизации бизнес-процессов с использованием нотации BPMN 2.0. Стандартные средства платформы не предоставляют полноценного редактора BPMN, однако интеграция открытой библиотеки bpmn-js позволяет реализовать интерактивное моделирование бизнес-процессов непосредственно в 1С. В статье рассмотрены архитектура решения, пошаговая инструкция по сборке библиотеки из исходников для WebKit, а также примеры программного взаимодействия между 1С и JavaScript.

03.04.2026    3073    SultanovStas    8    

23

Разработка внешних компонент Системный администратор Программист Стажер Бесплатно (free)

Библиотека для работы с базами SQLite из 1С на основе внешней компоненты. Для Linux и Windows, бесплатно и с открытым исходным кодом!

14.01.2025    7271    bayselonarrend    17    

54

Разработка внешних компонент Программист 1С:Предприятие 8 Россия Бесплатно (free)

В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.

04.12.2024    12582    kovalevdmv    29    

83
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. anig99 2865 01.04.14 14:07 Сейчас в теме
Однозначно +!!!!! В пору начала освоения 1с пытался подружить 1с и delphi - уперся именно в русские буквы.
2. EmpireSer 15.04.14 13:00 Сейчас в теме
Это применимо к какой версии Delphi? Ведь версии Delphi XE и выше изначально считают всё юникодом.
3. Rik30 9 07.05.14 09:25 Сейчас в теме
+
А есть у кого пример для работой с 7ой?
Никак не могу брать значения справочников, которые в 7ке берутся из "Перечислений"
4. ogursoft 22.08.17 13:21 Сейчас в теме
Теме уже 3 года, но тем не менее понадобилось написать внешнее приложение на Дельфи через Ole
Используется Delphi последней версии (Embarcadero® RAD Studio 10.1 Berlin)
Почему отдельные русские свойства и процедуры нормально отрабатываются, а отдельные нет. Была рабочая программа, добавили свойство в документ, дельфи спотыкается на нем, старые свойства обрабатывает нормально.
5. capitan 2591 05.08.18 09:06 Сейчас в теме
Все не так однозначно.
Наоборот, в моей практике Delphi нормально вызов передает, это сообщение об ошибке возвращается кракозябрами.
Его надо раскодировать примерно так AnsiToUtf8(Utf8ToAnsi(E.Message))
(4) Курить надо в сторону не кривизны Delphi, а учить матчасть - V83.Application и V83.COMConnector разные наборы методов поддерживают
Простейший пример - oCOMConnector.ИмяКомпьютера();
6. Junior1C_37 18.12.21 12:06 Сейчас в теме
Вот наткнулся: Делфи 10.3, 1с 8.3 не вызывалась процедура пока в свойствах модуля не поставил галочку Сервер и Внешнее соединение. Понятно что и Экспорт должно присутствовать.
И с русскими буквами заработало.
7. tormozit 7380 16.05.26 22:28 Сейчас в теме
Решил похожую проблему в библиотеке JACOB для JAVA https://github.com/tormozit/jacob-project/commit/1a98dc0555e5b9c4307c0c75a86bf97f7854edc2
В стандартной сборке этой DLL вызов COM метода портил кириллическое имя метода и COM 1С возвращал ошибку "Can't map name to dispid".
Для отправки сообщения требуется регистрация/авторизация