Как организовать сверку данных между справочником 1С и внешним источником данных

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

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

Метод 1. Использование таблиц значений и пакетных запросов

Проанализируем самый популярный и надежный способ — получение данных из двух источников по отдельности с их последующим сопоставлением. Поскольку прямое соединение запрещено, мы будем использовать промежуточное хранилище в оперативной памяти — Таблицу Значений.

Рассмотрим алгоритм действий:

  1. Сначала мы выбираем все необходимые идентификаторы из справочника Контрагенты.
  2. Затем получаем список идентификаторов из внешнего источника данных.
  3. Загружаем одну из таблиц в запрос как параметр и выполняем сопоставление.

Пример кода для реализации этого подхода:


// 1. Получаем данные из справочника 1С
Запрос1С = Новый Запрос;
Запрос1С.Текст = 
"ВЫБРАТЬ
|	Контрагенты.Ссылка КАК Ссылка,
|	Контрагенты.Id_SD КАК Id_SD
|ИЗ
|	Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|	НЕ Контрагенты.ПометкаУдаления";

Таблица1С = Запрос1С.Выполнить().Выгрузить();

// 2. Получаем данные из внешнего источника
ЗапросВИД = Новый Запрос;
ЗапросВИД.Текст = 
"ВЫБРАТЬ
|	ВнешняяТаблица.Id КАК Id
|ИЗ
|	ВнешнийИсточникДанных.SD.Таблица.dbo_BlaBla КАК ВнешняяТаблица";

ТаблицаВИД = ЗапросВИД.Выполнить().Выгрузить();

После получения двух таблиц мы можем использовать метод Левого соединения в новом запросе, чтобы найти записи, которые есть в 1С, но отсутствуют в SD, или наоборот. Чтобы это работало быстро, важно передать одну из таблиц как параметр запроса.

Метод 2. Поиск расхождений через параметр «В СПИСКЕ»

Если задача стоит только в том, чтобы найти объекты, которых нет во внешней базе, мы можем использовать условие НЕ В ИЕРАРХИИ или НЕ В СПИСКЕ. Выясним, как это реализовать оптимально.

Выберем все ID из внешнего источника в массив и передадим этот массив в запрос к справочнику 1С. Это позволит сразу получить список «проблемных» контрагентов, у которых Id_SD не находит соответствия в таблице Id.


// Получаем массив всех ID из внешнего источника
СписокID_SD = ТаблицаВИД.ВыгрузитьКолонку("Id");

ЗапросСверки = Новый Запрос;
ЗапросСверки.Текст = 
"ВЫБРАТЬ
|	Контрагенты.Ссылка,
|	Контрагенты.Id_SD
|ИЗ
|	Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|	НЕ Контрагенты.Id_SD В (&СписокID_SD)";

ЗапросСверки.УстановитьПараметр("СписокID_SD", СписокID_SD);
РезультатСверки = ЗапросСверки.Выполнить().Выбрать();

Важный момент: Если количество записей во внешнем источнике превышает десятки тысяч, передача огромного массива в параметр В (&СписокID_SD) может негативно сказаться на производительности SQL-сервера. В этом случае лучше использовать временные таблицы.

Метод 3. Алгоритм свертки таблицы (метод «Счетчика»)

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

  1. Создаем одну общую ТаблицуЗначений с колонками: ID, Источник, Счетчик.
  2. Заполняем её данными из 1С (в поле Источник пишем "1С", в поле Счетчик ставим 1).
  3. Добавляем в эту же таблицу данные из внешнего источника (в поле Источник пишем "SD", в поле Счетчик ставим 1).
  4. Выполняем метод Свернуть("ID", "Счетчик").

Проанализируем результат: если после свертки Счетчик равен 2, значит ID присутствует в обеих системах. Если Счетчик равен 1, то запись уникальна для одной из систем и требует внимания.

Оптимизация: Использование Системы компоновки данных (СКД)

Выясним, как обойти ограничение на соединение таблиц наиболее элегантным способом. Платформа 1С позволяет связывать разные наборы данных в СКД. Мы можем создать два набора данных типа «Запрос»:

На закладке Связи наборов данных мы указываем условие связи: НаборДанных1.Id_SD = НаборДанных2.Id. СКД сама выполнит необходимые итерации и соединения на уровне программного кода, предоставив вам готовый отчет с сопоставленными данными. Это избавит вас от необходимости вручную писать алгоритмы перебора строк.

Технические нюансы: типы данных и индексы

При сопоставлении полей Id_SD и Id часто возникают ошибки, связанные с типами данных. Разберем основные причины, по которым визуально одинаковые ID могут не совпадать:

  1. Пробелы в строках: В SQL-базах часто используются поля типа CHAR с фиксированной длиной, которые дополняются пробелами справа. В 1С Id_SD может быть типом String (Varchar). Перед сравнением обязательно используйте функцию СОКРЛП().
  2. Регистр символов: Если идентификаторы содержат буквы (например, GUID), убедитесь, что в обеих системах они имеют одинаковый регистр.
  3. Индексация: Если вы используете временные таблицы для сравнения больших объемов данных, обязательно создавайте Индекс по полю Id_SD. Это ускорит операцию соединения в разы.

Пример создания индекса во временной таблице:


МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

// Загружаем ТЗ во временную таблицу с индексацией
Запрос.Текст = 
"ВЫБРАТЬ
|	ТЗ_Данные.Id_SD КАК Id_SD
|ПОМЕСТИТЬ ВТ_Данные1С
|ИЗ
|	&ТЗ_Данные КАК ТЗ_Данные
|ИНДЕКСИРОВАТЬ ПО
|	Id_SD";
Запрос.УстановитьПараметр("ТЗ_Данные", Таблица1С);
Запрос.Выполнить();

Подводя итог, выбор метода зависит от объема данных. Для небольших таблиц достаточно метода В СПИСКЕ или свертки ТЗ. Для высоконагруженных систем с миллионами записей лучшим решением станет использование СКД или предварительная индексация временных таблиц в пакетном запросе.

← На главную