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