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

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

При разработке или администрировании систем на платформе 1С:Предприятие часто возникает задача массовой корректировки данных. Одной из самых востребованных операций является выборочная отмена проведения документов. Это может потребоваться для исправления ошибок в учете, перепроведения документов в правильной последовательности или очистки движений перед удалением объектов.

В этой статье мы подробно разберем, как создать обработку для выполнения этой задачи, проанализируем базовый код, обсудим риски и рассмотрим способы оптимизации процесса для работы с большими объемами данных.

Шаг 1: Подготовка и безопасность (Бэкап)

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

Как справедливо заметили участники обсуждения, начинать нужно не с кода, а с обеспечения возможности «отката» системы к исходному состоянию.

Шаг 2: Реализация базового алгоритма через запрос

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


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

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

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

Разберем этот код по шагам:

  1. Создание запроса: Мы используем объект Запрос, чтобы выбрать ссылки на документы. В тексте запроса мы указываем конкретный вид документа (в примере это РеализацияТоваровУслуг) и устанавливаем фильтр Проведен = ИСТИНА. Это важно, так как нет смысла пытаться отменить проведение у документов, которые и так не проведены.
  2. Обход выборки: С помощью цикла Пока Выборка.Следующий() мы перебираем все найденные документы.
  3. Получение объекта: Поскольку ссылка (Ссылка) предназначена только для чтения, для изменения состояния документа нам необходимо вызвать метод ПолучитьОбъект().
  4. Метод записи: Ключевым моментом здесь является использование метода Записать с параметром РежимЗаписиДокумента.ОтменаПроведения. Именно этот режим инициирует удаление движений документа из всех регистров.
  5. Обработка исключений: Мы добавили конструкцию Попытка...Исключение. Это критически важно, так как документ может быть заблокирован другим пользователем или его отмена проведения может быть запрещена программными проверками в модуле документа.

Шаг 3: Оптимизация и расширение логики

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

Использование фильтров по периоду и организации

В реальных задачах редко требуется отменить проведение абсолютно всех документов за всю историю ведения базы. Обычно мы ограничиваем выборку. Проанализируем, как добавить параметры в запрос:


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

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

Режим загрузки данных

Если ваша задача — чисто техническая очистка и вы уверены в своих действиях, можно использовать свойство ОбменДанными.Загрузка. Установка этого свойства в значение Истина позволяет пропустить большинство прикладных проверок в модуле документа (например, проверку прав или остатков на складах), что значительно ускоряет процесс:


ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);

Однако помните: использование этого флага требует осторожности, так как вы обходите бизнес-логику, заложенную разработчиками конфигурации.

Шаг 4: Альтернативные способы решения

Проанализируем ситуацию: стоит ли всегда писать код? Если вы работаете в современной типовой конфигурации (например, 1С:ERP, 1С:УТ 11 или 1С:Бухгалтерия 3.0), в них встроены стандартные инструменты.

Рассмотрим инструмент «Групповое изменение реквизитов». Он позволяет:

Это безопаснее и быстрее, так как механизм уже отлажен и учитывает многие нюансы платформы.

Советы для начинающих разработчиков

Если вы только начинаете изучать программирование в 1С, как советовали участники форума, обратите внимание на фундаментальную литературу. Понимание работы запросов и объектной модели — это база, без которой написание подобных обработок превращается в опасное занятие.

Рекомендуется изучить работы следующих авторов:

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

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

← На главную