В практике администратора или программиста 1С нередко возникают ситуации, когда требуется массово отменить проведение документов. Это может быть связано с необходимостью пересчета итогов, исправлением глобальных ошибок в учетной политике, подготовкой базы к свертке или полным переделом учета за определенный период. В данной статье мы подробно разберем, как реализовать такую задачу, используя как встроенные возможности системы, так и написание собственной внешней обработки.
Прежде чем приступать к реализации, проанализируем ситуацию. Отмена проведения — это действие, которое удаляет записи документа из всех регистров (бухгалтерии, накопления, сведений), при этом сам документ остается в базе, но перестает влиять на остатки и обороты. Мы рассмотрим три основных способа решения этой задачи:
Если вы работаете в современной конфигурации (например, Бухгалтерия предприятия 3.0, ERP или УТ 11), разберем самый безопасный путь, не требующий программирования. В составе Библиотеки стандартных подсистем (БСП) есть мощный инструмент.
Рассмотрим пошагово, как им воспользоваться:
Система самостоятельно обойдет все документы и корректно снимет их с проведения, соблюдая установленные в коде правила.
Проанализируем ситуацию, когда нам нужно обработать документы только одного вида за короткий промежуток времени. В этом случае создавать отдельный код нецелесообразно. Рассмотрим простой алгоритм:
Ctrl + A.Этот способ хорош своей наглядностью, однако он может быть медленным при работе с очень большими объемами данных (десятки тысяч строк).
Теперь разберем, как написать собственную обработку. Это полезно, если нам нужна специфическая логика или мы работаем в конфигурации, где стандартные инструменты ограничены. Выясним причину, по которой лучше использовать обход через метаданные: это делает код универсальным для любой базы.
Для начала создадим новую внешнюю обработку через меню Файл — Новый. В модуле обработки создадим процедуру, которая будет перебирать все виды документов.
Посмотрим на пример универсального кода:
Процедура ОтменитьПроведениеВсехДокументов() Экспорт
// Проанализируем все метаданные документов в системе
Для Каждого МетаДокумент Из Метаданные.Документы Цикл
// Создаем выборку для конкретного типа документа
Выборка = Документы[МетаДокумент.Имя].Выбрать();
Пока Выборка.Следующий() Цикл
// Проверяем, проведен ли документ в данный момент
Если Выборка.Проведен Тогда
Попытка
ОбъектДокумента = Выборка.ПолучитьОбъект();
// Устанавливаем режим загрузки, чтобы пропустить лишние проверки модулей
ОбъектДокумента.ОбменДанными.Загрузка = Истина;
// Выполняем отмену проведения
ОбъектДокумента.Записать(РежимЗаписиДокумента.ОтменаПроведения);
Сообщить("Отменено проведение: " + ОбъектДокумента.Ссылка);
Исключение
Сообщить("Ошибка при обработке " + Выборка.Ссылка + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Проанализируем важные детали представленного выше кода, которые обеспечивают его надежность:
ОбменДанными.Загрузка. Это критически важно при массовых операциях. Данный флаг сообщает системе, что документ записывается «как есть», отключая сложные проверки в модуле объекта. Это предотвращает остановку процесса, если в старых документах не заполнены новые обязательные реквизиты.Записать в блок обработки ошибок. Если какой-то конкретный документ заблокирован другим пользователем или вызывает критический сбой, наша обработка не прервется, а просто пропустит его и перейдет к следующему.Метаданные.Документы позволяет нам не перечислять РеализацияТоваровУслуг, ПоступлениеТоваровУслуг и прочие типы вручную. Код сам определит, какие документы существуют в конфигурации.Если в вашей базе миллионы документов, выполнение кода в одной транзакции может привести к переполнению лога транзакций SQL-сервера. Разберем, как оптимизировать этот процесс. Вместо одного глобального цикла, рекомендуется фиксировать транзакции порциями.
Рассмотрим пример логики с фиксацией порций:
// Пример порционной обработки (фрагмент)
Счетчик = 0;
Пока Выборка.Следующий() Цикл
// ... логика получения объекта ...
ОбъектДокумента.Записать(РежимЗаписиДокумента.ОтменаПроведения);
Счетчик = Счетчик + 1;
// Каждые 1000 документов принудительно фиксируем изменения
Если Счетчик % 1000 = 0 Тогда
// В некоторых случаях здесь можно делать паузу или фиксировать транзакцию
КонецЕсли;
КонецЦикла;
Прежде чем запускать любые массовые обработки по отмене проведения, необходимо выполнить следующие действия:
Помните, что после массовой отмены проведения вам, скорее всего, потребуется восстановить последовательность документов, выполнив их перепроведение в хронологическом порядке, чтобы восстановить корректные остатки и себестоимость товаров.