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

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

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

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

Выясняем причину: почему не работает простой вызов Записать()

В старых версиях платформы «1С:Предприятие 8» и конфигурациях на обычных формах (например, УПП 1.3 или УТ 10.3) большинство значений по умолчанию заполнялось при вызове метода Заполнить(), который обращался к обработчику ОбработкаЗаполнения в модуле объекта. В управляемом интерфейсе логика кардинально изменилась по следующим причинам:

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

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

Способ 1. Использование стандартных механизмов БСП на сервере

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

Разберем пример программного создания документа «Заказ клиента» в УТ 11 с автоматическим заполнением реквизитов под текущего пользователя:


// Создаем новый объект документа на сервере
НовыйДокумент = Документы.ЗаказКлиента.СоздатьДокумент();

// Устанавливаем дату и вызываем стандартный обработчик заполнения
НовыйДокумент.Дата = ТекущаяДатаСеанса();
НовыйДокумент.Заполнить(Неопределено);

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

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

// Записываем документ в режиме записи
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);

Использование метода ЗаполнениеСвойствПоУмолчанию.ЗаполнитьРеквизитыОбъекта() позволяет автоматически подтянуть настройки организации, склада, подразделения и автора, которые привязаны к текущему пользователю в регистре сведений «Настройки пользователей».

Способ 2. Эмуляция интерактивного ввода на клиенте (с открытием формы)

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

Для этого мы передаем структуру заполнения в специальный параметр формы ЗначенияЗаполнения. Рассмотрим этот процесс по шагам на клиенте:


&НаКлиенте
Процедура СоздатьИЗаписатьДокументИнтерактивно()
    
    // Подготавливаем параметры для открытия формы нового документа
    ПараметрыЗаполнения = Новый Структура;
    ПараметрыЗаполнения.Вставить("Партнер", ВыбранныйПартнер);
    ПараметрыЗаполнения.Вставить("Соглашение", ВыбранноеСоглашение);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
    
    // Открываем форму нового документа (при этом отрабатывают все серверные процедуры инициализации формы)
    ФормаНовогоДокумента = ОткрытьФорму("Документ.ЗаказКлиента.ФормаОбъекта", ПараметрыФормы);
    
    // Если требуется записать документ сразу же без участия пользователя:
    Если ФормаНовогоДокумента.Модифицированность Тогда
        // Метод Записать() формы инициирует стандартную транзакцию записи на сервере
        ФормаНовогоДокумента.Записать();
        
        // При необходимости автоматически закрываем форму после записи
        // ФормаНовогоДокумента.Закрыть();
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: данный метод гарантирует 100% идентичность ручному вводу данных пользователем, так как платформа полностью воспроизводит весь жизненный цикл формы документа.

Способ 3. Ручное извлечение настроек пользователя (для фоновых заданий)

Бывают ситуации, когда документ создается под системной учетной записью (например, при обмене данными через web-сервис или в регламентном задании), и стандартные методы БСП не могут определить «текущего пользователя». В этом случае нам необходимо вручную прочитать настройки конкретного ответственного лица из информационной базы и заполнить объект.

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


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

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

Рекомендации разработчику

Для эффективной разработки и минимизации ошибок при программном создании документов рекомендуем придерживаться следующих правил:

← На главную