Как получить данные реквизита формы для печатной формы в 1С и сохранить их

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

При разработке и кастомизации конфигураций 1С (например, 1С:ERP, 1С:КА или 1С:УТ) разработчики часто сталкиваются с задачей: необходимо дать пользователю возможность ввести вручную некоторые данные (например, номер и дату договора, ФИО сопровождающего лица или произвольный комментарий), которые затем должны отобразиться в печатной форме документа. При этом в самой типовой конфигурации подходящих полей для этого нет.

Типичная ошибка начинающих разработчиков — создать реквизит непосредственно на самой управляемой форме документа, вывести его в виде поля ввода и попытаться прочитать его значение в модуле менеджера или во внешней печатной форме (ВПФ). Выясним причину, почему такой подход не работает, и разберем по шагам правильные архитектурные решения этой задачи.

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

Способ 1. Использование механизма «Дополнительные реквизиты и сведения» (БСП)

Если вам нужно быстро добавить новое поле в документ без изменения структуры конфигурации и без написания кода для сохранения данных, самым лучшим и надежным решением будет использование типового механизма Библиотеки стандартных подсистем (БСП) — «Дополнительные реквизиты и сведения». Именно этот способ помог автору темы оперативно решить задачу.

Рассмотрим подробнее преимущества этого подхода:

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

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

Вариант получения через программный интерфейс общего модуля БСП:


// Находим нужное свойство (дополнительный реквизит) по его наименованию или уникальному идентификатору
СвойствоДоговор = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "НомерДоговора_ххххх");

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

Вариант получения через запрос (рекомендуется для пакетной печати или оптимизации производительности):


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДопРеквизиты.Значение КАК НомерДоговора
    |ИЗ
    |	Документ.РеализацияТоваровУслуг.ДополнительныеРеквизиты КАК ДопРеквизиты
    |ГДЕ
    |	ДопРеквизиты.Ссылка = &СсылкаНаОбъект
    |	И ДопРеквизиты.Свойство = &СвойствоНомерДоговора";

Запрос.УстановитьПараметр("СсылкаНаОбъект", СсылкаНаОбъект);
// Передаем ссылку на элемент ПланаВидовХарактеристик.ДополнительныеРеквизитыИСведения
Запрос.УстановитьПараметр("СвойствоНомерДоговора", СвойствоДоговор);

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

Обратите внимание на разницу между дополнительными реквизитами и дополнительными сведениями. Реквизиты физически хранятся в табличной части самого объекта. При их изменении документ перезаписывается. Сведения же хранятся отдельно, в независимом регистре сведений РегистрСведений.ДополнительныеСведения, что позволяет изменять их даже в закрытых для редактирования периодах без перезаписи самого документа.

Способ 2. Создание собственного реквизита объекта через Расширение конфигурации

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

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

  1. Режим совместимости основной конфигурации должен быть не ниже версии 8.3.15.
  2. Назначение расширения в его свойствах должно быть установлено как «Адаптация» или «Дополнение» (в режиме «Исправление» добавление реквизитов, создающих новые поля в СУБД, запрещено).
  3. Сам документ (например, РеализацияТоваровУслуг) должен быть предварительно добавлен (заимствован) в расширение, после чего в контексте расширения к нему добавляется новый реквизит.

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


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

При таком подходе в модуле печати или во внешней печатной форме вы сможете без проблем обратиться к этому реквизиту напрямую через точку от ссылки на объект: СсылкаНаОбъект.ИмяРеквизитаРасширения.

Способ 3. Передача временных параметров печати без сохранения в базу данных

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

Рассмотрим этот алгоритм подробнее:

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

Посмотрим на пример кода обработки команды печати на клиенте в форме внешней обработки:


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

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

← На главную