Как обновить данные в регистре сведений на основе внешней таблицы значений?

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

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

Алгоритм решения задачи

Для того чтобы понять, какие именно данные требуют обновления, нам необходимо выполнить следующие шаги:

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

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

Лучшим способом реализации является использование пакетных запросов с применением временных таблиц. Это позволяет свести все операции сравнения к выполнению одного запроса к СУБД, что значительно повышает производительность системы.

Рассмотрим структуру запроса, который позволяет выявить записи для обновления:


ВЫБРАТЬ 
    ВнешняяТаблица.Наименование КАК Наименование, 
    ВнешняяТаблица.Цена КАК Цена, 
    ВнешняяТаблица.ТипЦены КАК ТипЦены 
ПОМЕСТИТЬ ВнешняяТаблица 
ИЗ &ВнешняяТаблица КАК ВнешняяТаблица 
ИНДЕКСИРОВАТЬ ПО Наименование;

ВЫБРАТЬ 
    ЦеныНоменклатуры.Наименование КАК Наименование, 
    ЦеныНоменклатуры.Цена КАК Цена, 
    ЦеныНоменклатуры.ТипЦены КАК ТипЦены 
ПОМЕСТИТЬ ЦеныНоменклатуры 
ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры 
ГДЕ ЦеныНоменклатуры.Наименование В (ВЫБРАТЬ Наименование ИЗ ВнешняяТаблица);

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

ВЫБРАТЬ 
    ВнешняяТаблица.Наименование КАК Наименование, 
    ВнешняяТаблица.Цена КАК Цена, 
    ВнешняяТаблица.ТипЦены КАК ТипЦены 
ИЗ ВнешняяТаблица КАК ВнешняяТаблица 
ГДЕ НЕ ВнешняяТаблица.Наименование В (ВЫБРАТЬ Наименование ИЗ ОдинаковыеЦены);

Разбор нюансов реализации

При реализации данного подхода важно учитывать несколько технических моментов:

Почему запрос может возвращать пустой результат?

Частая проблема новичков заключается в том, что условие связи ВНУТРЕННЕЕ СОЕДИНЕНИЕ слишком жесткое. Если в одном из полей (например, ТипЦены) есть несоответствие типов, запись не попадет в выборку. Также внимательно проверяйте условие ГДЕ НЕ ... В (...): оно исключает все записи, которые система посчитала «идентичными». Если вы случайно добавите в условия сравнения лишнее поле, которое всегда будет различаться (например, Период), то «одинаковых» записей не будет, и запрос вернет все строки таблицы.

Рекомендация по записи данных

После того как запрос вернул список записей для обновления, не торопитесь записывать их в цикле по одной записи. Это создает высокую нагрузку на базу данных и вызывает лишние блокировки. Используйте объект РегистрСведенийНаборЗаписей. Вы можете установить отбор по Наименованию или ТипуЦены, прочитать набор и обновить нужные значения ресурсов в памяти, после чего выполнить метод Записать(). Это позволит выполнить операцию транзакционно и максимально быстро.

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

← На главную