Как программно восстановить последовательность документов в 1С

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Управленческий учет IT и автоматизация бизнеса
← На главную

Вопрос восстановления последовательности документов — одна из классических задач в 1С:Предприятии, особенно когда речь идет о складском учете или расчетах с контрагентами в конфигурациях вроде «Бухгалтерия предприятия» или «ERP». Часто начинающие разработчики пытаются реализовать этот механизм через обычный перебор документов в цикле, что приводит к ошибкам или неоптимальной работе системы. В этой статье мы подробно разберем, как правильно подойти к этой задаче, проанализируем типичные ошибки и рассмотрим программные методы управления последовательностями.

Понятие последовательности и типичные ошибки реализации

Прежде чем переходить к коду, давайте выясним причину, по которой ручное перепроведение документов в произвольном порядке не является «восстановлением последовательности». Суть последовательности заключается в строгом хронологическом порядке. Если мы сначала проведем Реализацию от 14:00, а затем Поступление от 10:00 того же дня, остатки могут рассчитаться некорректно, и граница последовательности (точка, до которой учет считается верным) не сдвинется вперед.

Рассмотрим распространенную ошибку, которую часто совершают разработчики. Попытка вызвать метод Восстановить() внутри цикла по выборке документов является методологически неверной:


// ОШИБОЧНЫЙ ПОДХОД
Пока Выборка.Следующий() Цикл
    Момент = Новый МоментВремени(Выборка.Дата, Выборка.Ссылка);
    Последовательности.ДокументыОрганизаций.Восстановить(Момент);
    ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
КонецЦикла;

В чем здесь ошибка? Метод Восстановить() сам по себе является итератором. При его вызове платформа автоматически находит самый старый документ, нарушивший последовательность, перепроводит его и сдвигает «Границу». Если мы вызываем его в своем цикле, мы фактически заставляем систему выполнять двойную работу и нарушаем логику работы встроенных механизмов 1С.

Метод 1: Использование стандартного механизма восстановления

Самый простой и правильный способ программного восстановления — позволить платформе самой управлять процессом. Рассмотрим, как это сделать. Для этого нам не нужно делать запрос к документам, нам нужно лишь указать «конечную точку», до которой мы хотим актуализировать данные.

Проанализируем пример кода для восстановления последовательности до текущего момента времени:


Процедура ВосстановитьПоследовательностьПрограммно(ОрганизацияСсылка)
    
    // Создаем отбор, если последовательность разделена по измерениям (например, по Организации)
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Организация", ОрганизацияСсылка);
    
    // Получаем текущую границу, чтобы понимать масштаб проблемы (необязательно)
    ТекущаяГраница = Последовательности.ДокументыОрганизаций.ПолучитьГраницу(СтруктураОтбора);
    
    // Восстанавливаем до текущего момента. 
    // Если передать Неопределено, будет восстановлено всё до самого последнего документа.
    Последовательности.ДокументыОрганизаций.Восстановить(Неопределено, СтруктураОтбора);
    
    Сообщить("Восстановление завершено");
    
КонецПроцедуры

При таком подходе платформа сама найдет все документы, входящие в последовательность ДокументыОрганизаций, и будет проводить их по одному, пока граница не достигнет актуального состояния. Это гарантирует, что каждый последующий документ «видит» корректные движения предыдущего.

Метод 2: Ручное восстановление через запрос и МоментВремени

Иногда требуется более тонкий контроль (например, если нужно перепроводить только определенные типы документов или добавлять специфическую логику). В этом случае мы пишем запрос вручную. Разберем по шагам, на что обратить внимание.

Важнейшее правило: Сортировка в запросе должна быть строго по Дата и Ссылка. В 1С МоментВремени — это комбинация времени и уникального идентификатора. Если несколько документов созданы в одну и ту же секунду, только сортировка по ссылке обеспечит стабильный и правильный порядок проведения.


ТекстЗапроса = 
"ВЫБРАТЬ
|   Док.Ссылка КАК Ссылка,
|   Док.Дата КАК Дата
|ИЗ
|   Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
|   Док.Проведен И Док.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   Док.Ссылка,
|   Док.Дата
|ИЗ
|   Документ.ПоступлениеТоваровУслуг КАК Док
|ГДЕ
|   Док.Проведен И Док.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
|
|УПОРЯДОЧИТЬ ПО
|   Дата,
|   Ссылка"; // Критически важная сортировка

После получения такой выборки мы проводим документы в цикле. Однако помните: при ручном проведении платформа может автоматически НЕ двигать границу последовательности, если в свойствах документа отключено «Заполнение последовательностей» или стоит режим «Не заполнять автоматически».

Работа с границей (Boundary) последовательности

Выясним, как управлять «флажком» актуальности без перепроведения самих документов. Для этого используются методы ПолучитьГраницу и УстановитьГраницу.

  1. ПолучитьГраницу(Отбор) — возвращает объект МоментВремени, указывающий на первый документ, после которого последовательность нарушена.
  2. УстановитьГраницу(МоментВремени, Отбор) — позволяет принудительно установить отметку. Это полезно, если вы уверены в корректности данных и не хотите тратить часы на перепроведение старых периодов.

Рассмотрим пример «перепрыгивания» периода:


// Установим границу на начало текущего года, считая, что прошлый год закрыт верно
НужныйМомент = Новый МоментВремени(НачалоГода(ТекущаяДата()));
Отбор = Новый Структура("Организация", ВыбраннаяОрганизация);
Последовательности.ДокументыОрганизаций.УстановитьГраницу(НужныйМомент, Отбор);

Особенности в современных конфигурациях (БП 3.0)

Проанализируем ситуацию, упомянутую в обсуждении: почему в «Бухгалтерии предприятия 3.0» у последовательности часто не указаны регистры в метаданных?

В современных конфигурациях используется механизм «входящих документов». Это означает, что последовательность контролирует сам факт записи документа, входящего в её состав, независимо от того, по каким регистрам он делает движения. Кроме того, в БП 3.0 часто используются программные интерфейсы (общие модули), которые управляют состоянием учета через задания закрытия месяца. Если вы работаете с БП 3.0, рекомендуется изучить возможности общего модуля ОбщегоНазначенияБП, который содержит процедуры для проверки актуальности учета.

Блокировки и производительность

Восстановление последовательности — тяжелая операция. Проанализируем основные риски:

В завершение отметим, что для глубокого понимания работы этого механизма полезно изучить видеоуроки (например, курсы Павла Чистова), где наглядно показывается, как перемещение границы влияет на итоги в регистрах накопления. Правильное использование МоментВремени и штатных методов Последовательности избавит вас от множества проблем с актуальностью данных в 1С.

← На главную