Перепроведение документов за определенный интервал времени — одна из типовых задач при администрировании и доработке конфигураций 1С. Необходимость в массовом перепроведении возникает при исправлении учетных ошибок задним числом, изменении алгоритмов проведения или восстановлении правильной последовательности движений по регистрам. Разберем типичные ошибки при реализации этой задачи, рассмотрим правильный программный код и изучим стандартные платформенные инструменты.
Рассмотрим частую ошибку начинающих разработчиков при попытке выбрать документы нескольких видов в одном запросе. Если перечислить таблицы документов через запятую в секции ИЗ без явного указания условий соединения, СУБД выполнит полное декартово произведение таблиц:
// ОШИБОЧНЫЙ ЗАПРОС
ВЫБРАТЬ
ПриходныйКассовыйОрдер.Ссылка,
РасходныйКассовыйОрдер.Ссылка
ИЗ
Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер,
Документ.РасходныйКассовыйОрдер КАК РасходныйКассовыйОрдер
ГДЕ
ПриходныйКассовыйОрдер.Дата МЕЖДУ &НачДата И &КонДата
И РасходныйКассовыйОрдер.Дата МЕЖДУ &НачДата И &КонДата
Проанализируем последствия такого запроса: если в базе за выбранный интервал находится 100 документов ПриходныйКассовыйОрдер и 100 документов РасходныйКассовыйОрдер, в результате выполнения сформируется 10 000 строк (100 * 100). При циклической обработке такой выборки каждый документ будет перепроводиться многократно, что приведет к колоссальной бессмысленной нагрузке на систему и искажению данных.
Для корректной выборки документов разных типов необходимо использовать конструкцию ОБЪЕДИНИТЬ ВСЕ, которая объединяет строки результатов независимых запросов в единый список. Разберем по шагам создание правильной процедуры:
Ссылка из каждого необходимого вида документа, накладываем фильтр по периоду и обязательное условие Проведен.Запрос.Выбрать() без избыточной выгрузки в оперативную память.ПолучитьОбъект() и вызываем метод Записать с указанием неоперативного режима.Попытка ... Исключение, чтобы ошибка в одном документе не прервала выполнение всего пакета.Посмотрим на готовый программный пример:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Док.Ссылка КАК Ссылка,
| Док.Дата КАК Дата
|ИЗ
| Документ.ПриходныйКассовыйОрдер КАК Док
|ГДЕ
| Док.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
| И Док.Проведен
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| Док.Ссылка,
| Док.Дата
|ИЗ
| Документ.РасходныйКассовыйОрдер КАК Док
|ГДЕ
| Док.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
| И Док.Проведен
|
|УПОРЯДОЧИТЬ ПО
| Дата,
| Ссылка";
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаКонца", КонецДня(ДатаКонца));
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Попытка
ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
Исключение
Сообщить("Ошибка проведения документа " + Строка(Выборка.Ссылка) + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Рассмотрим ключевые параметры и правила, которые необходимо учитывать при пакетной обработке документов:
Записать всегда следует явно указывать второй параметр — РежимПроведенияДокумента.Неоперативный. Если параметр опущен, платформа для документов с текущей датой может применить оперативный режим, что вызовет проверки точки актуальности и избыточные блокировки.ДокументОбъект.ОбменДанными.Загрузка = Истина устанавливать нельзя. Если включить этот режим, обработчик ОбработкаПроведения будет пропущен платформой, и движения по регистрам не обновятся.УПОРЯДОЧИТЬ ПО Дата, Ссылка, чтобы однозначно упорядочить даже те документы, которые имеют одинаковую секунду записи.Если нет жесткого требования писать собственный программный код в рамках специальной доработки, для решения задачи можно применить стандартные типовые инструменты платформы 1С: