При организации обмена данными между базами 1С:Предприятия 7.7 через OLE Automation часто возникает задача точной идентификации объектов. Стандартного метода УникальныйИдентификатор(), привычного по версии 8.х, в платформе 7.7 нет. Для сопоставления записей используется внутренний идентификатор базы данных (ID), закодированный в 36-ричной системе счисления.
Разберем типичные ошибки при получении ID объектов через OLE и рассмотрим рабочие способы решения задачи.
Проанализируем распространенную ошибку. Попытка передать локальный OLE-объект в функцию EvalExpr базы-источника приводит к ошибке «Переменная не определена»:
// Ошибочный вариант:
ИД = ПУБ.EvalExpr("ЗначениеВСтрокуВнутр(Обж)");
// Ошибка: Переменная не определена (Обж)
Выясним причину такого поведения: метод EvalExpr выполняется строго в глобальном контексте удаленного OLE-приложения. Локальные переменные вашего модуля или функции в этот контекст не попадают. Для базы-источника имя Обж является несуществующей переменной.
Если база-источник является типовой и вносить изменения в ее конфигурацию нельзя, вызовем встроенную функцию ЗначениеВСтрокуВнутр напрямую у самого OLE-объекта базы.
Посмотрим на рабочий пример функции получения строкового ID для элемента справочника:
Функция ПолучитьID_OLE(БазаОЛЕ, ОбъектОЛЕ)
Перем СтрВнутр, СтрБезСпецСимволов, ИД_Base36;
// Получаем внутреннее строковое представление объекта
СтрВнутр = БазаОЛЕ.ЗначениеВСтрокуВнутр(ОбъектОЛЕ.ТекущийЭлемент());
// Очищаем полученную строку от фигурных скобок и кавычек
СтрБезСпецСимволов = СтрЗаменить(СтрВнутр, "{", "");
СтрБезСпецСимволов = СтрЗаменить(СтрБезСпецСимволов, "}", "");
СтрБезСпецСимволов = СтрЗаменить(СтрБезСпецСимволов, Симв(34), "");
// Преобразуем параметры через запятую в многострочный текст
СтрБезСпецСимволов = СтрЗаменить(СтрБезСпецСимволов, ",", РазделительСтрок);
// Извлекаем 7-й параметр (идентификатор объекта в Base36)
ИД_Base36 = СтрПолучитьСтроку(СтрБезСпецСимволов, 7);
// Преобразуем внутренний номер в нормализованную строку
Возврат _IdToStr(ИД_Base36);
КонецФункции
Обратите внимание на важные особенности этого метода:
ТекущийЭлемент() применяется для объектов типа «Справочник». Для документов необходимо использовать ТекущийДокумент(), а для счетов плана счетов — ТекущийСчет()._IdToStr() выполняет преобразование числового значения или Base36-номера в строковый идентификатор требуемого формата.Если база-источник доступна для редактирования, наиболее надежный и быстрый способ — объявить специализированные экспортные функции в ее Глобальном модуле:
// В Глобальный модуль OLE-базы:
Функция глЗначениеВСтрокуВнутр(Объект) Экспорт
Возврат ЗначениеВСтрокуВнутр(Объект);
КонецФункции
Функция глЗначениеИзСтрокиВнутр(СтрВнутр) Экспорт
Возврат ЗначениеИзСтрокиВнутр(СтрВнутр);
КонецФункции
Теперь на стороне вызывающей базы достаточно обратиться к созданным функциям напрямую:
// В вызывающей базе:
ВнутрСтрока = БазаОЛЕ.глЗначениеВСтрокуВнутр(ОбъектОЛЕ);
// Обратное получение объекта по строковому идентификатору:
ОбъектОЛЕ = БазаОЛЕ.глЗначениеИзСтрокиВнутр(ВнутрСтрока);
Когда редактирование метаданных источника запрещено, но необходимо выполнить сложную сериализацию или пакетную обработку, используем запуск внешней обработки (.ert) через OLE:
ОткрытьФорму с передачей контекста:
БазаОЛЕ.ОткрытьФорму("Отчет", КонтекстПередачи, "C:\ExtForms\GetOLEData.ert");
Через параметр КонтекстПередачи (например, список значений или таблицу значений) внешняя обработка выполнит все нужные преобразования на стороне сервера и вернет результат без накладных расходов на поштучные OLE-вызовы.
При наличии подключенной внешней компоненты 1С++ задача получения ID решается без ручного строкового парсинга с помощью класса MetaDataWork:
МДВ = СоздатьОбъект("MetaDataWork");
ИДОбъекта = МДВ.ИДОбъекта(Объект);
Данный подход исключает ошибки при разборе внутренних строк и работает единообразно для всех типов ссылочных метаданных платформы 1С 7.7.