Почему при установке реквизита Проведен в значение Ложь через групповое изменение реквизитов остаются движения документов?

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

При выполнении массовых операций над документами в 1С специалисты нередко сталкиваются с ситуацией, когда после изменения реквизита Проведен на значение Ложь с помощью стандартной обработки Групповое изменение реквизитов документ визуально отображается как непроведенный, но его движения по регистрам остаются активными. Разберем механику платформы 1С, выясним причины такого поведения и рассмотрим корректные способы групповой отмены проведения документов.

Причина поведения платформы: почему движения не очищаются

Проанализируем, как платформа 1С управляет записями регистров. В метаданных документа свойство Проведен является системным реквизитом, хранящимся в таблице самого документа. Однако очистка движений в регистрах накопления, бухгалтерии или сведений привязана не к факту изменения значения булева реквизита, а к вызову метода записи документа в определенном режиме.

Когда обработка Групповое изменение реквизитов меняет реквизит Проведен, платформа выполняет обычную запись объекта с флагом РежимЗаписиДокумента.Запись. При этом:

  1. В строке таблицы документа значение поля Проведен устанавливается в Ложь.
  2. События отмены проведения не инициализируются, и алгоритмы очистки наборов записей не вызываются.
  3. Записи в таблицах движений по-прежнему сохраняют флаг Активность = Истина.

Даже если в конфигураторе для документа задана настройка Удалять движения: Удалять автоматически при отмене проведения, данное правило срабатывает исключительно при явной отмене проведения через вызов соответствующего режима записи.

Способ 1. Использование встроенного произвольного алгоритма в обработке

В расширенных версиях обработки Групповое изменение реквизитов (включая версии с диска ИТС) предусмотрена возможность выполнения произвольного кода для каждого выбранного объекта. Чтобы корректно снять проведение и очистить движения, перейдем на вкладку выполнения произвольного алгоритма и применим следующий код:

Объект.Записать(РежимЗаписиДокумента.ОтменаПроведения);

При таком вызове платформа запустит штатные механизмы распроведения, очистит все связанные наборы записей и корректно пересчитает итоги.

Способ 2. Штатная обработка «Проведение документов»

Если требуется массово отменить проведение без доработки конфигурации и запуска стороннего кода, воспользуемся стандартным платформенным инструментом:

  1. Откроем меню Функции для технического специалиста (или Все функции).
  2. Перейдем в раздел Стандартные и выберем пункт Проведение документов.
  3. В открывшемся окне перейдем на вкладку Отмена проведения, зададим необходимый период, выберем нужные типы документов и нажмем кнопку выполнения.

Способ 3. Массовая отмена проведения из динамического списка

Рассмотрим вариант быстрого снятия с проведения группы документов непосредственно из журнала или формы списка:

  1. Откроем список нужных документов (например, Реализация товаров и услуг).
  2. Выделим необходимые строки, используя сочетания клавиш Ctrl + A (для выделения всех документов) или удерживая клавишу Shift/Ctrl.
  3. Нажмем правую кнопку мыши и выберем команду Отменить проведение.

В этом случае платформа автоматически инициирует транзакцию отмены проведения для каждого выбранного объекта с полным удалением всех движений.

Способ 4. Программная обработка для выборки и отмены проведения

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


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

Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(ДатаОкончания));

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    Попытка
        ДокументОбъект = Выборка.ДокументСсылка.ПолучитьОбъект();
        Если ДокументОбъект.Проведен Тогда
            ДокументОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
        КонецЕсли;
    Исключение
        Сообщить("Ошибка при отмене проведения документа " + Выборка.ДокументСсылка + ": " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

Как исправить «зависшие» движения, если реквизит уже сброшен

Если реквизит Проведен уже был изменен на Ложь, а движения остались в базе, восстановить корректное состояние регистров можно двумя путями:

  1. Цикл перепроведения: Выделим ошибочные документы, выполним для них команду Провести (движения перезапишутся), а затем вызовем команду Отменить проведение.
  2. Программная очистка движений по регистратору: Запишем пустой набор записей по каждому регистру, где остались «хвосты»:

НаборЗаписей = РегистрыНакопления.ПартииТоваровНаСкладах.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
НаборЗаписей.Записать(Истина);

Нюансы совместимости при использовании внешних обработок

При использовании внешних версий обработки группового изменения с диска ИТС на конфигурациях с пониженным режимом совместимости может возникнуть ошибка Метод не найден (СтрРазделить).

Функции СтрРазделить, СтрСоединить и СтрНайти поддерживаются платформой на уровне встроенного языка только в том случае, если режим совместимости конфигурации установлен на версию 8.3.6 или выше. Если режим совместимости конфигурации ниже (например, 8.3.4), даже при работе на платформе 8.3.10 вызов этих методов приведет к ошибке.

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

← На главную