Давайте вместе разберемся в распространенной задаче: у нас есть данные в Регистре сведений и есть внешний источник данных, например, файл, который мы загрузили в Таблицу значений (ТЗ). Наша цель — синхронизировать регистр с данными из файла. Для этого нужно в одном запросе эффективно сравнить две таблицы и выявить, какие записи являются новыми, какие были изменены, а какие, возможно, нужно удалить из регистра.
Проанализируем ситуацию. Простое соединение таблиц не даст полной картины, так как оно, как правило, отсекает данные, которых нет в одном из источников. Нам же нужно получить полную картину расхождений. Для этого в языке запросов 1С существуют специальные виды соединений. Рассмотрим два основных подхода к решению этой задачи.
Это наиболее мощный и правильный способ для задачи полной синхронизации. ПОЛНОЕ СОЕДИНЕНИЕ (FULL OUTER JOIN) позволяет объединить данные из обеих таблиц, не теряя ни одной записи. Если для записи из одной таблицы не нашлось соответствия в другой, поля второй таблицы будут заполнены значением NULL.
Рассмотрим подробнее, как это работает. Такой подход позволяет нам за один запрос получить всю необходимую информацию для анализа:
ТаблицеЗначений, но отсутствуют в РегистреСведений. В результате запроса у таких строк поля со стороны регистра будут иметь значение NULL.РегистреСведений, но их уже нет в ТаблицеЗначений. У таких строк, наоборот, поля со стороны ТЗ будут NULL.Посмотрим на пример. Допустим, у нас есть ключевое поле Номенклатура и ресурс Цена.
ВЫБРАТЬ
ВЫБОР
КОГДА Источник.Номенклатура ЕСТЬ NULL
ТОГДА Регистр.Номенклатура
ИНАЧЕ Источник.Номенклатура
КОНЕЦ КАК Номенклатура,
Источник.Цена КАК НоваяЦена,
Регистр.Цена КАК СтараяЦена,
ВЫБОР
КОГДА Регистр.Номенклатура ЕСТЬ NULL
ТОГДА "Новая"
КОГДА Источник.Номенклатура ЕСТЬ NULL
ТОГДА "Удалить"
КОГДА Источник.Цена <> Регистр.Цена
ТОГДА "Изменена"
ИНАЧЕ "Не изменилась"
КОНЕЦ КАК СтатусЗаписи
ИЗ
ТаблицаЗначений КАК Источник
ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Регистр
ПО Источник.Номенклатура = Регистр.Номенклатура
В результате этого запроса мы получим таблицу, которую очень легко обработать. Пройдясь по ней в цикле, мы сможем в зависимости от значения поля СтатусЗаписи выполнить нужное действие: добавить, обновить или удалить запись в регистре.
ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN) также можно использовать, но этот подход имеет свои нюансы и ограничения. Ключевой момент — какая таблица является основной (левой). От этого зависит, какую часть задачи мы решим.
Вариант А: Основная таблица — Таблица Значений (данные из файла)
Разберем по шагам. Мы берем все записи из нашей ТЗ и "присоединяем" к ним данные из регистра по совпадающему ключу. Если в регистре соответствия нет, поля из него будут NULL.
ВЫБРАТЬ
Источник.Номенклатура,
Источник.Цена,
Регистр.Цена КАК ЦенаВРегистре
ИЗ
ТаблицаЗначений КАК Источник
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Регистр
ПО Источник.Номенклатура = Регистр.Номенклатура
Проанализируем результат этого запроса:
Регистр.Номенклатура (или любое другое ключевое поле из регистра) равно NULL — это новая запись, ее нужно добавить в регистр.Регистр.Номенклатура заполнено, но Источник.Цена <> Регистр.Цена — это измененная запись, ее нужно обновить.Важный недостаток этого подхода: мы не сможем выявить записи, которые нужно удалить. Запрос вернет только те данные, которые есть в исходном файле (ТЗ), и полностью проигнорирует записи регистра, которых в этом файле нет.
Вариант Б: Как найти записи для удаления с помощью ЛЕВОГО СОЕДИНЕНИЯ?
Чтобы найти записи, которые есть в регистре, но отсутствуют в файле, нам потребуется выполнить второй, "обратный" запрос. В нем основной (левой) таблицей будет уже РегистрСведений.
ВЫБРАТЬ
Регистр.Номенклатура
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Регистр
ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаЗначений КАК Источник
ПО Регистр.Номенклатура = Источник.Номенклатура
ГДЕ
Источник.Номенклатура ЕСТЬ NULL
Этот запрос вернет нам список номенклатуры, которую следует удалить из регистра, так как для нее не нашлось соответствия в ТаблицеЗначений.
Давайте подведем итог и выберем оптимальный путь.
ПОЛНОЕ СОЕДИНЕНИЕ — это наиболее комплексное и эффективное решение для задачи полной синхронизации данных. Оно позволяет в одном запросе получить всю информацию для добавления, изменения и удаления записей. Рекомендуем использовать именно его, если вам нужно привести регистр в полное соответствие с файлом.ЛЕВОЕ СОЕДИНЕНИЕ — хороший инструмент, если ваша задача проще. Например, если вам нужно только добавить новые и обновить существующие записи, не трогая те, что отсутствуют в файле. Для полной синхронизации этот метод потребует выполнения двух отдельных запросов, что менее оптимально.Таким образом, выбор метода зависит от конечной цели. Для полной и надежной синхронизации ваш выбор — ПОЛНОЕ СОЕДИНЕНИЕ.