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