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