Как привести значение из Внешнего Источника Данных к локальному ссылочному типу 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с Внешними источниками данных (ВИД) разработчики часто сталкиваются с ситуацией, когда необходимо сопоставить данные из внешней базы данных (например, SQL Server или PostgreSQL) с объектами текущей базы 1С. Типичный сценарий: внешний запрос возвращает идентификатор объекта в формате binary(16), который по сути является _IDRRef (внутренним уникальным идентификатором) объекта 1С. Однако платформа 1С по умолчанию воспринимает такие данные как «Двоичные данные», а не как ссылку на справочник или документ.

В этой статье мы разберем несколько эффективных способов «объяснить» системе, что набор байтов из внешнего источника — это готовая ссылка на Справочник.Номенклатура или любой другой объект.

Метод 1. Преобразование на стороне СУБД через VIEW

Один из самых производительных способов заключается в подготовке данных еще до того, как они попадут в 1С. Если мы не можем изменить структуру внешней таблицы, мы можем создать Представление (VIEW) на стороне сервера SQL.

Основная сложность здесь заключается в порядке байтов. 1С хранит GUID в базе данных в инвертированном виде. Чтобы 1С корректно распознала строку как УникальныйИдентификатор, ее нужно правильно сконкатенировать на стороне SQL. Проанализируем пример функции для SQL Server, которая превращает binary(16) в строковое представление, понятное для 1С:


SELECT 
    -- Преобразуем бинарные данные в строку нужного формата
    LOWER(CONVERT(NVARCHAR(36), CAST(BinaryField AS UNIQUEIDENTIFIER))) as GUIDString
FROM ExternalTable

Однако помните: стандартный NEWID() в SQL и 1С-овский _IDRRef имеют разную последовательность групп байтов. При создании VIEW убедитесь, что вы получаете строку именно в том порядке, который ожидает конструктор Новый УникальныйИдентификатор(). После того как во внешнем источнике появится поле типа «Строка» с ГУИДом, мы сможем легко преобразовать его в ссылку в коде 1С.

Метод 2. Использование метода ПолучитьСсылку()

Существует заблуждение, что создание ссылок из уникальных идентификаторов в цикле — это медленная операция, нагружающая базу данных. Это не так. Рассмотрим, почему этот метод эффективен.

Метод Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаГП)) является «чистой» математической операцией. В этот момент 1С не обращается к SQL-серверу. Она просто создает объект ссылки в оперативной памяти на основе переданного идентификатора. Обращение к базе произойдет только тогда, когда вы попытаетесь получить реквизит этой ссылки (например, Ссылка.Наименование).

Разберем алгоритм быстрой обработки данных:

  1. Выполняем запрос к Внешнему источнику данных, получая идентификаторы в виде строк или двоичных данных.
  2. Выгружаем результат в ТаблицаЗначений.
  3. Добавляем в таблицу колонку с типом нужной нам ссылки.
  4. В цикле заполняем эту колонку, используя ПолучитьСсылку().

Пример кода для обработки тысяч записей:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВнешняяТаблица.Идентификатор КАК ИдСтрока
    |ИЗ
    |	ВнешнийИсточникДанных.ВнешняяБД.Таблица КАК ВнешняяТаблица";

ТЗ = Запрос.Выполнить().Выгрузить();
ТЗ.Колонки.Добавить("НоменклатураСсылка", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

Для Каждого Стр Из ТЗ Цикл
    // Предполагаем, что ИдСтрока — это строковый GUID из SQL
    Попытка
        УИД = Новый УникальныйИдентификатор(Стр.ИдСтрока);
        Стр.НоменклатураСсылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);
    Исключение
        // Обработка некорректных данных
    КонецПопытки;
КонецЦикла;

Метод 3. Смешанные запросы (Соединение ВИД и локальных таблиц)

Начиная с версии платформы 8.3.5, 1С поддерживает запросы, в которых одновременно участвуют таблицы из Внешних источников данных и таблицы самой информационной базы. Это позволяет нам делегировать сопоставление типов самой платформе.

Проанализируем ситуацию: если во внешней таблице есть поле, по которому можно однозначно идентифицировать номенклатуру (например, Код, Артикул или тот же ГУИД в виде строки), мы можем написать прямой запрос.


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    ВнешнийИсточникДанных.МояВнешняяБД.ТаблицаЗапроса КАК ВнешниеДанные
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
    ПО ВнешниеДанные.Код = Номенклатура.Код

Важный нюанс: при выполнении таких запросов 1С может сначала выгрузить данные из внешнего источника во временную таблицу в основной базе данных, а затем выполнить соединение. Если внешняя таблица содержит миллионы записей, это может вызвать задержку. Рекомендуется максимально фильтровать данные на стороне внешнего источника (используя параметры запроса) перед соединением.

Метод 4. Работа с Binary(16) и ADODB

Если данные получаются не через стандартный механизм ВИД, а через ADODB.Connection, то значение binary(16) возвращается в 1С как COMSafeArray (массив байтов). Для его преобразования в ссылку удобно использовать промежуточную функцию конвертации байтов в шестнадцатеричную строку, которую затем принимает конструктор УникальныйИдентификатор.

Рассмотрим логику: 1С ожидает строку ГУИД в формате "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX". Ваша задача — прочитать массив из 16 байт и собрать из них эту строку. Помните о специфике 1С: группы байтов в _IDRRef часто записаны в обратном порядке относительно стандартного GUID.

Метод 5. Использование индексированных дополнительных реквизитов

Если задача сопоставления стоит остро и выполняется часто, рассмотрим вариант оптимизации архитектуры. Мы можем добавить в справочник Номенклатура дополнительный реквизит ВнешнийИдентификатор (тип Строка, длина 36, Индексировать).

При записи новой номенклатуры в 1С мы записываем в это поле строковое представление ее ГУИДа или идентификатор из внешней системы. Тогда работа с внешним источником сводится к простому и очень быстрому соединению в запросе по индексированному полю, что избавляет нас от любых манипуляций с типами binary.

Итоги и рекомендации

Выбор метода зависит от ваших ограничений:

Важное предостережение: Избегайте "алхимии" с подменой таблиц 1С на уровне СУБД (через создание вьюх с именами таблиц 1С). Это может привести к фатальным ошибкам при реструктуризации базы данных или при выполнении тестирования и исправления (ТиИ).

← На главную