Почему документ 1С помечается как проведенный, но не создает движений в регистрах?

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

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

Анализ исходной ситуации и программного кода

Рассмотрим типовой сценарий. Разработчик пытается программно провести массив неопубликованных документов. Код выглядит стандартно и на первый взгляд не содержит изъянов:


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

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

Выяснение причины: контекст выполнения и гибридный режим

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

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

  1. Управляемая форма всегда инициирует серверный контекст для записи объекта.
  2. Платформа ищет процедуру ОбработкаПроведения в модуле объекта.
  3. Если эта процедура обернута в директиву препроцессора #Если Клиент Тогда, сервер ее «не видит».

Разберем подробнее работу препроцессора. В толстом клиенте (обычное приложение) понятие Клиент охватывает и выполнение кода модуля объекта. Но как только управление передается на сервер (что неизбежно для управляемых форм или фоновых заданий), препроцессор отсекает всё, что помечено как клиентское.

Важный момент: Если тело процедуры ОбработкаПроведения оказывается «пустым» для текущего контекста (сервера), 1С считает, что разработчик просто не описал алгоритм проведения. С точки зрения платформы это не является ошибкой. Транзакция завершается успешно, документу устанавливается признак Проведен = Истина, но фактической записи в регистры не происходит, так как код, отвечающий за это, был скрыт директивой.

Пошаговое решение проблемы

Чтобы исправить «неадекватное» поведение системы, выполним следующие шаги:

  1. Откроем модуль объекта проблемного документа.
  2. Найдем процедуру ОбработкаПроведения.
  3. Проверим наличие инструкций препроцессора в начале модуля или непосредственно перед процедурой.
  4. Если вы видите конструкцию типа #Если Клиент Тогда, ее необходимо изменить или удалить.

Правильное оформление процедур модуля объекта, которые должны работать в любом режиме, должно выглядеть так (без ограничивающих директив клиента):


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Здесь располагается код формирования движений
    Движения.ОстаткиТоваров.Записывать = Истина;
    // ... логика проведения ...
КонецПроцедуры

Если же вам критично оставить разделение кода, используйте более широкие условия, например, #Если Сервер Или ТолстыйКлиентОбычноеПриложение Тогда, однако для модуля объекта лучшей практикой является отсутствие клиентских директив вокруг стандартных обработчиков событий.

Дополнительные факторы и методы диагностики

Если проверка препроцессора не помогла, проанализируем другие возможные причины отсутствия движений:

1. Режим записи движений

Проверим свойство документа Запись движений при проведении. Если установлено значение Записывать выбранные, то в коде ОбработкаПроведения обязательно должна присутствовать явная установка флага записи для каждого набора:

Движения.ИмяРегистра.Записывать = Истина;

Если установлено Записывать модифицированные, 1С сама запишет те наборы, в которых были изменения, но только если процедура проведения была физически выполнена.

2. Подписки на события

Выясним, нет ли подписок на событие ОбработкаПроведения, которые могут влиять на результат. Иногда сторонний код в подписке может очищать коллекции движений или устанавливать Отказ = Истина в определенных условиях. Однако в нашем случае Отказ привел бы к отмене проведения, а мы видим документ «проведенным».

3. Права доступа и фоновые задания

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

4. Использование синтаксического контроля

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

Это позволит сразу увидеть, какие части модуля объекта становятся недоступными при вызове с сервера.

Рекомендация по написанию надежного кода

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


Попытка 
    Док.Записать(РежимЗаписиДокумента.Проведение); 
Исключение
    ЗаписьЖурналаРегистрации("ПрограммноеПроведение", УровеньЖурналаРегистрации.Ошибка, , , 
        "Ошибка при проведении документа " + Док.Ссылка + ": " + ОписаниеОшибки());
КонецПопытки;

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

← На главную