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

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

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

Анализ типичной ошибки при проведении документов

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


Процедура КнопкаВыполнитьНажатие(Кнопка)
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ.ПриходнаяНакладная";
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
        ДокОбъект.Проведен = Истина; // ОШИБКА: Это просто меняет значение реквизита, но не делает движений!
    КонецЦикла;
КонецПроцедуры

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

Корректный способ проведения через метод Записать

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

  1. Создаем запрос для получения ссылок на документы.
  2. В цикле получаем объект документа через метод ПолучитьОбъект().
  3. Вызываем метод Записать() с параметром проведения.

Проанализируем исправленный код:


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

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

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

Разберем параметры метода Записать():

Оптимизация запроса и фильтрация данных

Посмотрим на структуру запроса. При массовом проведении важно не выбирать лишние данные. В исходном примере кода в запрос были включены реквизиты Склад, Контрагент и СуммаДокумента. Если ваша цель — только проведение, эти данные в запросе избыточны. Они лишь замедляют выполнение кода и увеличивают потребление памяти.

Также необходимо учитывать состояние документов. Проанализируем дополнительные условия:

Обработка ошибок при массовом проведении

В реальной базе данных процесс может прерваться из-за нехватки остатков на складе, незаполненных обязательных реквизитов или блокировок другими пользователями. Если не предусмотреть обработку ошибок, вся процедура "вылетит" на первом же проблемном документе.

Рассмотрим, как обезопасить наш код с помощью блока Попытка — Исключение:


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

Использование ОписаниеОшибки() позволит вам после завершения работы алгоритма увидеть список всех проблемных документов и причин, по которым система отказала в их проведении.

Универсальное проведение всех типов документов

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


Для Каждого МетаДокумент Из Метаданные.Документы Цикл
    ИмяДокумента = МетаДокумент.Имя;
    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ." + ИмяДокумента + " ГДЕ Проведен = Ложь И ПометкаУдаления = Ложь";
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
        Попытка
            ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
        Исключение
            // Логируем ошибку
        КонецПопытки;
    КонецЦикла;
КонецЦикла;

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

Использование встроенных инструментов системы

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

  1. Групповое изменение реквизитов: В дополнительных параметрах этой обработки часто доступна опция перепроведения документов.
  2. Групповое проведение документов: Специализированный инструмент (обычно находится в разделе "Администрирование" или "Сервис"), который позволяет выбрать типы документов, период и автоматически выстроить их в нужной последовательности.

Если же типовые средства не подходят (например, нужна сложная логика отбора), то программный метод с использованием Записать(РежимЗаписиДокумента.Проведение) является единственно верным и надежным способом решения задачи.

← На главную