Почему при пакетном создании счетов-фактур создается и проводится только последний документ?

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

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

Анализ причины: создание объекта вне цикла

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

  1. Перед началом цикла создается один-единственный объект документа СчетФактураВыданныйОбъект.
  2. На первой итерации цикла реквизиты этого объекта заполняются данными первой реализации, после чего вызывается метод Записать(). Документ физически сохраняется в базе данных и получает ссылку.
  3. На второй итерации цикл продолжает работать с тем же самым объектом в памяти. Код перезаписывает его реквизиты данными второй реализации и снова вызывает Записать(). Платформа не создает новый документ, а обновляет ранее сохраненный.
  4. В результате всех итераций в базе остается только один документ, содержащий реквизиты последней строки выборки.

Ошибочный и правильный шаблоны кода

Посмотрим на пример ошибочного кода, приводящего к перезаписи одного документа:


// ОШИБКА: создание объекта вынесено за пределы цикла
НовыйСчетФактура = Документы.СчетФактураВыданный.СоздатьДокумент();

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

Теперь разберем, как исправить эту ошибку. Создание нового экземпляра объекта Документы.СчетФактураВыданный.СоздатьДокумент() обязательно должно выполняться внутри тела цикла на каждой итерации:


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

Рекомендации по надежному пакетному формированию счетов-фактур

Рассмотрим дополнительные правила, которые необходимо соблюдать при программной генерации счетов-фактур выданных:

  1. Инициализация через метод Заполнить(): Прямое присвоение отдельных реквизитов (организация, контрагент, сумма) часто приводит к пропуску скрытых служебных реквизитов (вид счета-фактуры, код вида операции, признак выставления, табличная часть документов-оснований). Вызов НовыйСчетФактура.Заполнить(ДокументОснование) автоматически выполняет типовой алгоритм ввода на основании.
  2. Проверка на существование дубликатов: Перед формированием нового документа обязательно выполним запрос к информационной базе на проверку наличия уже выписанного счета-фактуры к данному документу реализации. Это защитит учет от повторного ввода и задвоения записей в книге продаж.
  3. Проверка статуса документа-основания: Счет-фактура выданный опирается на движения по НДС, формируемые реализацией. Документ-основание обязательно должен быть проведен.
  4. Изоляция транзакций: Не оборачиваем весь цикл пакетной обработки в единую транзакцию (НачатьТранзакцию() ... ЗафиксироватьТранзакцию()). Длительная транзакция заблокирует таблицы нумерации и регистров учета НДС для других пользователей. Каждый документ следует записывать в отдельной транзакции с перехватом возможных ошибок через конструкцию Попытка ... Исключение.
  5. Использование типовых инструментов: Перед разработкой собственной обработки проверим наличие стандартного механизма. В большинстве конфигураций 1С (включая 1С:Бухгалтерию, 1С:ERP и 1С:Комплексную автоматизацию) присутствует встроенное рабочее место «Регистрация счетов-фактур на реализацию», которое уже решает задачу пакетного ввода с учетом всех проверок и отборов по организациям и контрагентам.
← На главную