При работе со стандартными механизмами обмена данными в решениях на платформе 1С:Предприятие 8.3 (таких как «1С:Розница», «1С:Управление торговлей», «1С:ERP» и других конфигурациях на базе Библиотеки стандартных подсистем) специалисты часто сталкиваются с необходимостью ручной регистрации объектов на узлах планов обмена. Стандартная обработка «Регистрация изменений для обмена данными» предоставляет мощный функционал, но встроенный механизм регистрации по результатам запроса по умолчанию может быть отключен. В этой статье мы подробно разберем, как активировать консоль запросов в этой обработке, как правильно передавать параметры и как при необходимости зарегистрировать список объектов программно.
При попытке выполнить регистрацию по запросу через меню «Зарегистрировать» -> «Результат запроса» система может перенаправлять пользователя в окно настроек, где по умолчанию установлен переключатель «Не использовать консоль запросов». Это штатное поведение БСП. Разработчики конфигурации не внедряют тяжелую внешнюю консоль запросов непосредственно в состав метаданных основной базы, чтобы не загромождать систему. Вместо этого они оставляют гибкую возможность подключить внешнюю обработку (файл с расширением .epf), которую администратор или программист может скачать с диска ИТС или использовать из собственных наработок.
Давайте пошагово разберем, как связать обработку регистрации изменений с вашей консолью запросов.
Для того чтобы включить использование консоли запросов в обработке регистрации изменений, выполним следующие действия:
КонсольЗапросов.epf, предварительно скачанной с портала ИТС или из состава инструментов разработчика БСП).После выполнения этих простых шагов при выборе команды «Зарегистрировать» -> «Результат запроса» система автоматически инициализирует и откроет указанный вами файл внешней консоли запросов.
Важно понимать, что далеко не каждая скачанная из интернета консоль запросов сможет корректно взаимодействовать с обработкой регистрации изменений. Для успешной интеграции должны соблюдаться два важнейших технических нюанса:
Во-первых, внешняя консоль должна уметь принимать параметры запуска и возвращать результат выбора. При вызове консоли из формы регистрации ей передается структура параметров. Совместимая консоль (например, поставляемая в составе дистрибутива БСП) считывает эти параметры и выводит на форму специальную кнопку — «Выбрать результат» (или «Выполнить выбор»). Если вы используете слишком старую консоль, разработанную исключительно для обычных форм или без поддержки API интеграции, этой кнопки просто не будет, и вы не сможете передать данные обратно.
Во-вторых, существует строгое требование к самому тексту SQL-подобного запроса 1С. Поле, содержащее регистрируемый объект, обязательно должно иметь псевдоним Ссылка. Рассмотрим правильный пример написания запроса:
ВЫБРАТЬ
ДокументПродажи.Ссылка КАК Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК ДокументПродажи
ГДЕ
ДокументПродажи.Дата МЕЖДУ &НачалоПериода И &КонецПериода
Если вы напишете просто ВЫБРАТЬ ДокументПродажи.Ссылка ИЗ ... или назовете колонку иначе (например, ДокументПродажи.Ссылка КАК ДокументРеализации), обработка регистрации не сможет сопоставить возвращаемую таблицу данных и выдаст ошибку.
Рассмотрим частую проблему пользователей: как передать в параметр запроса конкретный список документов, когда у них нет общего реквизита для отбора (например, определенный перечень счетов-фактур за разные даты)? Вводить их вручную по одному значению в параметры консоли крайне неэффективно.
Для решения этой задачи в консоли запросов можно использовать параметры с типом данных Список значений:
ГДЕ Ссылка В (&СписокДокументов).СписокДокументов и дважды кликнем по колонке «Тип».Список значений.Если документов очень много и они известны заранее (например, у вас есть текстовый список номеров), можно прописать условие отбора по номерам непосредственно в тексте запроса:
ГДЕ Номер В ("0000-000001", "0000-000015", "0000-000124")
Иногда использование консоли запросов избыточно или неудобно, например, когда список ссылок на объекты уже получен вами в другой обработке, отчете или внешней таблице. В этом случае гораздо быстрее и надежнее зарегистрировать изменения программно, используя встроенный язык 1С.
Давайте разберем, как выглядит универсальный программный метод для регистрации списка документов на конкретном узле плана обмена. Нам понадобятся объект ПланыОбмена и его метод ЗарегистрироватьИзменения().
Посмотрим на пример процедуры, выполняемой на сервере:
&НаСервере
Процедура ЗарегистрироватьСписокОбъектов(ИмяПланаОбмена, КодУзлаОбмена, СписокСсылок)
// Выполняем поиск узла плана обмена по его уникальному коду
УзелСсылка = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзлаОбмена);
Если УзелСсылка.Пустая() Тогда
ВызватьИсключение "Узел обмена с кодом '" + КодУзлаОбмена + "' не найден в плане обмена " + ИмяПланаОбмена;
КонецЕсли;
// Обходим переданный список ссылок (массив или список значений)
Для Каждого ЭлементСписка Из СписокСсылок Цикл
СсылкаНаОбъект = Неопределено;
// Проверяем тип переданной коллекции для корректного получения ссылки
Если ТипЗнч(СписокСсылок) = Тип("СписокЗначений") Тогда
СсылкаНаОбъект = ЭлементСписка.Значение;
Иначе // Если передан обычный Массив
СсылкаНаОбъект = ЭлементСписка;
КонецЕсли;
// Регистрируем изменение для конкретного узла без фактического изменения реквизитов объекта
Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзелСсылка, СсылкаНаОбъект);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот код хорош тем, что он не перезаписывает сам документ в базе данных. Он не вызывает обработчики событий ПередЗаписью или ПриЗаписи, не меняет версию данных, автора или дату изменения документа, а лишь делает запись в служебную таблицу регистрации изменений для указанного узла плана обмена. Это гарантирует высокую скорость работы и отсутствие коллизий в учете.
Если вам необходимо зарегистрировать очень большое количество объектов (десятки или сотни тысяч), выполнение метода ПланыОбмена.ЗарегистрироватьИзменения() в цикле для каждого отдельного элемента может вызвать существенные задержки из-за частых обращений к базе данных.
Для оптимизации процесса мы можем передавать в метод ЗарегистрироватьИзменения не одиночную ссылку, а массив ссылок одного типа метаданных. Платформа 1С оптимизирует такой запрос и выполнит регистрацию пакетом. Рассмотрим улучшенный вариант кода:
&НаСервере
Процедура ОптимизированнаяРегистрацияСписка(УзелСсылка, МассивСсылокОдногоТипа)
// Проверяем, что массив не пустой
Если МассивСсылокОдногоТипа.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Передаем весь массив за один вызов метода
ПланыОбмена.ЗарегистрироватьИзменения(УзелСсылка, МассивСсылокОдногоТипа);
КонецПроцедуры
Использование этого подхода позволяет сократить время регистрации сотен тысяч документов с нескольких минут до нескольких секунд. Помните, что в передаваемом массиве все элементы должны относиться к одному и тому же типу данных (например, только ДокументСсылка.РеализацияТоваровУслуг). Если у вас в списке присутствуют разные типы документов, предварительно сгруппируйте их по типам метаданных перед вызовом процедуры регистрации.