Как программно установить номер платежного поручения в 1С, чтобы он не менялся при записи?

Программист 1C:Бухгалтерия Бухгалтерский учет
← На главную

При автоматизации импорта данных из систем клиент-банка программисты часто сталкиваются с ситуацией, когда при программном создании документа ПлатежноеПоручениеИсходящее реквизит НомерПоручения (или другие поля, такие как Комментарий и флаги учета) сбрасывается или заменяется стандартным нумератором системы сразу после вызова метода Записать(). Рассмотрим подробно, почему это происходит и как правильно обойти это ограничение, сохранив при этом целостность данных.

Анализ причины: почему 1С затирает программно введенные данные?

В типовых конфигурациях 1С, таких как «Бухгалтерия для Украины 1.2», «Управление торговым предприятием» или «Бухгалтерия предприятия 2.0», логика управления номером платежного поручения вынесена в модуль объекта документа. Разберем механизм работы события ПередЗаписью. Проанализируем стандартный код, который часто встречается в этих конфигурациях:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    // ... логика проверки сумм ...
    
    Если НЕ ЗначениеЗаполнено(НомерПоручения) ИЛИ ЭтоНовый() Тогда
        Попытка
            // Здесь система вычисляет следующий номер на основе существующих документов
            НомерПоручения = ПолучитьСледующийНомерПоручения(); 
        Исключение
            НомерПоручения = 1;
        КонецПопытки;
    КонецЕсли;
    
    // ... остальная логика ...
КонецПроцедуры

Обратим внимание на условие ИЛИ ЭтоНовый(). Даже если вы в своей обработке присвоили значение ДокППИ.НомерПоручения = "123", при вызове метода Записать() система проверяет, является ли объект новым в базе данных. Если документ создается впервые, условие выполняется, и ваш номер перезаписывается результатом работы функции автонумерации. Аналогичная ситуация происходит с реквизитами ОтражатьВБухгалтерскомУчете или Комментарий, если в модуле прописаны процедуры инициализации параметров по умолчанию.

Решение №1: Использование флага «ОбменДанными.Загрузка»

Это самый правильный и эффективный способ «заставить» систему принять ваши данные без изменений. Свойство ОбменДанными.Загрузка сообщает платформе и логике конфигурации, что документ создается внешним механизмом (обработкой, обменом), и стандартные проверки или автоматические заполнения в модуле объекта выполнять не нужно.

Рассмотрим пример правильного программного создания документа:


ДокППИ = Документы.ПлатежноеПоручениеИсходящее.СоздатьДокумент();
ДокППИ.Дата = ДатаДок;
ДокППИ.Организация = Фирма;
ДокППИ.Контрагент = Контрагент;
// Устанавливаем номер, полученный из банка
ДокППИ.НомерПоручения = НомерИзФайлаБанка; 
ДокППИ.Комментарий = "Импорт из клиент-банка";
ДокППИ.ОтражатьВБухгалтерскомУчете = Истина;

// Включаем режим загрузки данных
ДокППИ.ОбменДанными.Загрузка = Истина; 

ДокППИ.Записать(РежимЗаписиДокумента.Запись);

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

Решение №2: Поиск скрытых процедур и подписок на события

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

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

Решение №3: Двухэтапная запись (обход условия «ЭтоНовый»)

Если конфигурация сильно изменена и использование ОбменДанными.Загрузка блокирует важную бизнес-логику, которую нельзя пропускать, можно использовать небольшую хитрость. Поскольку проблема часто кроется в проверке ЭтоНовый(), мы можем сначала создать «пустой» документ, чтобы он получил ссылку в базе, а затем наполнить его данными.

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


ДокППИ = Документы.ПлатежноеПоручениеИсходящее.СоздатьДокумент();
// Записываем пустой документ, чтобы он перестал быть "новым" для системы
ДокППИ.Записать(); 

// Теперь документ уже существует в базе, ЭтоНовый() вернет Ложь
ДокППИ.НомерПоручения = НомерИзБанка;
ДокППИ.Комментарий = "Мой комментарий";
// Заполняем остальные реквизиты...

ДокППИ.Записать(РежимЗаписиДокумента.Запись);

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

Проблема с флагами учета и комментарием

Если у вас пропадают значения ОтражатьВБухгалтерскомУчете или Комментарий, проанализируем, не вызывается ли в вашем коде метод ДокППИ.Заполнить() после того, как вы уже присвоили значения этим полям. Метод Заполнить() сбрасывает реквизиты объекта к значениям, установленным в настройках пользователя.

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

Таким образом, мы выяснили, что основной причиной проблемы является типовой код в модуле объекта, ориентированный на интерактивную работу пользователя. Для программного заполнения наиболее стабильным решением является использование ОбменДанными.Загрузка = Истина.

← На главную