В практике разработки на платформе 1С:Предприятие 8.3 часто возникает необходимость обработать данные, полученные из внешних источников (SQL, Excel или API), и сопоставить их с объектами внутренней базы данных (справочниками, документами или регистрами). Оптимальным способом решения этой задачи является выгрузка данных в ТаблицуЗначений и последующая передача этой таблицы в запрос в качестве параметра. Однако начинающие разработчики часто сталкиваются с тем, что запрос к такой таблице возвращает пустой результат или выдает ошибки типов. Рассмотрим подробно, как правильно организовать этот процесс.
Разберем типичную ситуацию: вы выполняете запрос к Внешнему Источнику Данных, выгружаете результат в ТаблицуЗначений методом Результат.Выгрузить() и пытаетесь прочитать её в следующем запросе. Основная причина неудач здесь кроется в типизации. Когда мы используем ТаблицаЗначений как источник для временной таблицы в запросе, 1С требует, чтобы каждая колонка имела строго определенный тип. Если колонки не типизированы (имеют составной тип или тип Неопределено), механизм временных таблиц не сможет корректно создать структуру в базе данных (в tempdb), и соединение не сработает.
Проанализируем также поле Ссылка во внешних источниках. Оно существенно отличается от привычных нам ссылок 1С. Внешняя ссылка — это объектный идентификатор, который нельзя напрямую сравнивать со ссылкой на справочник 1С. Для связи таблиц лучше использовать примитивные типы данных: строки (артикулы, ИНН, коды) или числа (идентификаторы ID).
Для того чтобы запрос «увидел» данные в вашей таблице, мы не можем просто выгрузить результат первого запроса. Нам необходимо создать новую таблицу с четко описанной структурой. Рассмотрим, как это сделать программно:
ТЗ = Новый ТаблицаЗначений;
// Указываем конкретные типы для каждой колонки
ТЗ.Колонки.Добавить("Id", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
ТЗ.Колонки.Добавить("Name", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)));
ТЗ.Колонки.Добавить("Login", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)));
После создания структуры нам нужно наполнить её данными из первого запроса. Рекомендуется использовать обход выборки, чтобы иметь возможность нормализовать данные, например, обрезать лишние пробелы функцией СокрЛП, что критично при работе с внешними SQL-базами (типы CHAR).
// Предположим, ЗапросКВнешнемуИсточнику уже выполнен
Выборка = ЗапросКВнешнемуИсточнику.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Id = СокрЛП(Выборка.Id);
НоваяСтрока.Name = СокрЛП(Выборка.Name);
НоваяСтрока.Login = СокрЛП(Выборка.Login);
КонецЦикла;
Для объединения данных нескольких запросов нам понадобится объект МенеджерВременныхТаблиц. Он позволяет сохранять промежуточные результаты (в нашем случае — содержимое ТаблицыЗначений) и обращаться к ним в последующих инструкциях пакета запросов.
Рассмотрим пошагово процесс помещения таблицы в запрос:
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
// Первый запрос пакета: помещаем ТЗ во временную таблицу
Запрос.Текст =
"ВЫБРАТЬ
| ВходящаяТЗ.Id КАК Id,
| ВходящаяТЗ.Name КАК Name,
| ВходящаяТЗ.Login КАК Login
|ПОМЕСТИТЬ ВРТаблица
|ИЗ
| &ПараметрТЗ КАК ВходящаяТЗ;
|
|////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВРТаблица.Name КАК ИмяИзВнешнегоИсточника,
| Контрагенты.Ссылка КАК Ссылка1С,
| Контрагенты.Код КАК Код1С
|ИЗ
| ВРТаблица КАК ВРТаблица
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
| ПО ВРТаблица.Name = Контрагенты.Наименование";
Запрос.УстановитьПараметр("ПараметрТЗ", ТЗ);
РезультатЗапроса = Запрос.Выполнить();
Выясним причину, по которой ЛЕВОЕ СОЕДИНЕНИЕ может возвращать пустые поля из справочников 1С, даже если визуально данные совпадают. Посмотрим на наиболее частые ошибки:
Строка и колонку с типом Ссылка. Всегда соединяйте строку со строкой (например, Наименование или ИНН).Fixed String, оно дополняется пробелами. Перед помещением в ТЗ всегда используйте СокрЛП.ТаблицеЗначений меньше, чем длина поля в справочнике 1С, данные могут обрезаться, что сделает сопоставление невозможным.Проанализируем ситуацию, когда необходимо найти дубли или задвоенные записи. Для этого можно использовать соединение таблицы самой с собой или соединение с условием ГДЕ Контрагенты.Ссылка ЕСТЬ NULL, если мы ищем записи из внешнего источника, которых еще нет в нашей базе 1С.
Если ваша ТаблицаЗначений содержит большое количество строк (более тысячи), работа запроса может замедлиться. В этом случае рекомендуется индексировать временную таблицу по полям связи сразу при её создании. Это делается с помощью инструкции ИНДЕКСИРОВАТЬ ПО в тексте запроса:
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.Id,
| ТЗ.Name
|ПОМЕСТИТЬ ВРТаблица
|ИЗ
| &ПараметрТЗ КАК ТЗ
|ИНДЕКСИРОВАТЬ ПО
| Name";
Также важно помнить, что после завершения работы с запросом МенеджерВременныхТаблиц желательно очищать или закрывать, чтобы освободить ресурсы сервера, особенно если обработка выполняется в цикле или регламентном задании. Хотя 1С делает это автоматически при уничтожении объекта, явное управление ресурсами является признаком хорошего тона в разработке.
Таким образом, правильный алгоритм работы включает: строгую типизацию ТЗ, нормализацию строковых данных, использование Менеджера временных таблиц и контроль типов полей в условии соединения. Следуя этим шагам, вы сможете эффективно объединять данные из любых внешних систем с вашей информационной базой 1С.