При переносе документов между базами конфигурации 1С:Управление торговлей 11 с помощью инструмента Конвертация данных 2.1 разработчики часто сталкиваются с ситуацией, когда перенесенные документы (например, «Заказ клиента» или «Реализация товаров и услуг») отказываются проводиться. При ручном открытии формы и интерактивном перевыборе номенклатуры документ проводится без ошибок. Разберем причины такого поведения и рассмотрим, как автоматизировать этот процесс на этапе загрузки данных.
Проанализируем механику работы типовых конфигураций на платформе 1С:Предприятие 8.3 при обмене данными:
ОбменДанными.Загрузка = Истина. В этом режиме стандартные события модуля объекта (ПередЗаписью, ОбработкаЗаполнения) и клиентские обработчики форм не отрабатывают. Это сделано для максимального ускорения загрузки и исключения проверок бизнес-логики.Товары содержит множество скрытых или зависимых колонок. Для корректного проведения требуются корректно заполненные поля: Склад (если включено указание складов в строках), ВариантОбеспечения, ЗаказКлиента, КодСтроки и другие.ОбработкаТабличнойЧастиКлиент. При программной загрузке клиентский контекст и элементы формы полностью отсутствуют.Выясним самый быстрый и надежный способ решить проблему: если для проведения не хватает конкретных реквизитов табличной части, их следует явно прописать в обработчике события «После загрузки» соответствующего Правила конвертации объектов (ПКО).
Посмотрим на пример кода для ПКО документа «Заказ клиента», где необходимо задать склад для каждой строки и установить вариант обеспечения:
Для Каждого Стр Из Объект.Товары Цикл
Стр.Склад = Справочники.Склады.НайтиПоНаименованию("Основной склад");
Стр.ВариантОбеспечения = Перечисления.ВариантыОбеспечения.Отгрузить;
КонецЦикла;
Разберем пример для документа «Реализация товаров и услуг», создаваемого на основании или в связке с заказом. Здесь каждой строке необходимо явно передать ссылку на заказ и соответствующий склад:
Для Каждого Стр Из Объект.Товары Цикл
Стр.ЗаказКлиента = Объект.ЗаказКлиента;
Стр.Склад = Справочники.Склады.НайтиПоНаименованию("Основной склад");
КонецЦикла;
Важное замечание по производительности: Поиск по наименованию через метод Справочники.Склады.НайтиПоНаименованию(...) внутри цикла выполняет отдельный запрос к базе данных на каждую строчку документа. Чтобы оптимизировать скорость загрузки, вынесите получение ссылки на склад перед началом цикла:
СсылкаНаСклад = Справочники.Склады.НайтиПоНаименованию("Основной склад");
Для Каждого Стр Из Объект.Товары Цикл
Стр.ЗаказКлиента = Объект.ЗаказКлиента;
Стр.Склад = СсылкаНаСклад;
КонецЦикла;
Рассмотрим случай, когда табличная часть требует расчета целого набора служебных параметров (ставки НДС, упаковки, признаки типа номенклатуры), а ручное перечисление всех колонок в цикле нецелесообразно.
В типовых конфигурациях нельзя вызывать клиентские процедуры (такие как ОбработкаТабличнойЧастиКлиент.ОбработатьСтрокуТЧ), однако доступны серверные механизмы. В модулях менеджеров или общих модулях серверного контекста присутствуют функции заполнения служебных колонок.
Для обновления служебных связей и кодов строк в модуле объекта документа можно вызывать типовые процедуры заполнения:
Объект.ЗаполнитьКодыСтрок() (если процедура экспортная в модуле объекта конкретной версии конфигурации).ОбработкаТабличнойЧастиСервер, передавая туда ссылку на объект или саму строку табличной части.Часто попытка вызвать Объект.Записать(РежимЗаписиДокумента.Проведение) прямо в обработчике «После загрузки» завершается ошибкой блокировок или нехватки данных, если связанные документы (например, Заказ клиента) еще не загрузились в базу-приемник.
Разберем по шагам правильный алгоритм пакетного проведения:
Параметры.Вставить("СписокДокументовДляПроведения", Новый Массив);
Параметры.СписокДокументовДляПроведения.Добавить(Объект.Ссылка);
Для Каждого СсылкаДок Из Параметры.СписокДокументовДляПроведения Цикл
Попытка
ДокОбъект = СсылкаДок.ПолучитьОбъект();
Если ДокОбъект <> Неопределено Тогда
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("ОшибкаПроведенияПриОбмене",
УровеньЖурналаРегистрации.Ошибка,,,
"Ошибка проведения документа: " + СсылкаДок + " | " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Такой подход гарантирует, что к моменту проведения отгрузок все заказы и справочники уже будут записаны в информационную базу со всеми необходимыми табличными реквизитами.