Работа с внешними базами данных через COM-соединение — это стандартная задача для разработчика 1С. Часто возникает необходимость выполнить сложный запрос во внешней базе и получить результат в виде ТаблицыЗначений для дальнейшей обработки. Однако при прямом обращении к COM-объекту мы получаем не саму таблицу, а ссылку на объект внешней базы. Разберем, как эффективно передать данные на «нашу» сторону.
В начале пути многие разработчики пробуют перебирать результат запроса через цикл Пока Выборка.Следующий() Цикл. Рассмотрим пример такого подхода, который мы анализировали:
// Пример итерационного перебора через COM
Пока Выборка.Следующий Цикл
Стр = ИзРарус.Добавить;
стр.КодРарус = Выборка.КодРарус;
стр.НоменклатураРарус = Выборка.НаименованиеРарус;
// ... и так далее
КонецЦикла;
Хотя этот метод рабочий, он крайне неэффективен при больших объемах данных. Каждое обращение к полю Выборка.НаименованиеРарус через COM-интерфейс — это отдельный сетевой вызов. Если в таблице тысячи строк, процесс будет идти очень долго. Поэтому мы рекомендуем использовать методы сериализации.
Самый быстрый и надежный способ «вытянуть» таблицу целиком — это преобразовать её в строку во внешней базе и восстановить локально. Этот метод превращает таблицу в строковое представление, передает через COM-канал как единый пакет и восстанавливает объект в памяти локальной базы.
Разберем этот процесс по шагам:
Выгрузить() преобразуем результат в ТаблицуЗначений.ValueToStringInternal(), чтобы сериализовать таблицу во внешнюю строку.ТаблицуЗначений функцией ЗначениеИзСтрокиВнутр().Пример реализации:
// Код для выполнения на стороне локальной базы
// ВнешняяБД - это установленное COM-соединение
// Запрос - объект, созданный через ВнешняяБД.NewObject("Запрос")
СтрокаРезультат = ВнешняяБД.ValueToStringInternal(Запрос.Выполнить().Выгрузить());
ТабВнешняя = ЗначениеИзСтрокиВнутр(СтрокаРезультат);
При использовании этого «хака» важно помнить о некоторых ограничениях:
ValueToStringInternal не передает «живые» ссылки на объекты внешней базы. Если в колонке таблицы хранятся ссылки, после десериализации они станут невалидными. Рекомендация: выбирайте в запросе примитивные данные (строки, числа) или строковое представление ссылок, например, УникальныйИдентификатор или Код.ТаблицуЗначений в качестве параметра запроса (в блоке ПОМЕСТИТЬ), обязательно принудительно установите типы колонок через Таблица.Колонки.ИмяКолонки.ТипЗначения = Новый ОписаниеТипов("Строка").Если объем передаваемой информации исчисляется сотнями тысяч строк, сериализация в строку может вызвать переполнение оперативной памяти. В таких случаях мы рекомендуем автоматизировать регулярный обмен данными по расписанию или:
ЗаписьJSON на стороне источника. Это стандарт, который позволяет более гибко работать с типами данных.XML или ТабличныйДокумент во внешней базе, сохраняйте во временный файл на диске, а затем читайте его локально. Это значительно снижает нагрузку на оперативную память COM-процесса.Используя предложенные методы, вы значительно ускорите взаимодействие между базами данных и сделаете свой код чище и профессиональнее. Не забывайте всегда закрывать соединение, присваивая переменной Соединение = Неопределено после завершения всех манипуляций.