При разработке внешних печатных форм (ВПФ) нередко возникает задача запросить у пользователя дополнительную информацию перед формированием печатного документа — например, комментарий, должность подписанта или дату доверенности. Для этого традиционно используется диалог ввода строки. Однако стандартная реализация сохранения настроек формы часто приводит к тому, что сохраняется лишь последнее введенное значение для обработки целиком. В результате при печати документа №1 вводится один текст, а при открытии документа №2 этот же текст подставляется снова, перезаписывая контекст.
Разберем, как правильно организовать сохранение данных так, чтобы для каждого отдельного документа сохранялась и восстанавливалась своя собственная строка, не требуя при этом снятия типовой конфигурации с поддержки.
Прежде чем сохранять данные, обратим внимание на механизм работы диалога ввода строки. В платформе «1С:Предприятие» метод ВвестиСтроку (или современный асинхронный аналог ПоказатьВводСтроки) использует начальное значение переданной в него переменной как текст по умолчанию в поле ввода.
Посмотрим на пример базового вызова:
Подсказка = "Введите текст для печатной формы:";
Если ВвестиСтроку(Текст, Подсказка, 0, Истина) Тогда
// Пользователь нажал "ОК", значение помещено в переменную Текст
КонецЕсли;
Если перед вызовом диалога переменная Текст уже содержит строку, полученную из базы или настроек, пользователь увидит ее в поле ввода и сможет отредактировать либо оставить без изменений. Следовательно, вся задача сводится к надежному сохранению и чтению этой переменной в привязке к конкретному документу.
В современных конфигурациях на платформе 8.3 для сохранения пользовательских данных предназначен системный объект ХранилищеОбщихНастроек. Данные в нем хранятся в специальной системной таблице базы данных на сервере, что гарантирует их сохранность при очистке локального кэша пользователя.
Проанализируем структуру методов ХранилищеОбщихНастроек.Сохранить и ХранилищеОбщихНастроек.Загрузить. Они принимают параметры:
Разберем по шагам реализацию данного подхода на сервере:
// Формируем уникальный строковый ключ документа на основе его ссылки
СсылкаСтрокой = Строка(СсылкаНаОбъект.УникальныйИдентификатор());
ИмяНастройкиВПФ = "ВПФ_ПроизвольныйТекст";
// Загружаем ранее сохраненное значение для данного документа
Текст = ХранилищеОбщихНастроек.Загрузить(ИмяНастройкиВПФ, СсылкаСтрокой);
Если Текст = Неопределено Тогда
Текст = "";
КонецЕсли;
// После интерактивного ввода пользователем сохраняем новое значение:
ХранилищеОбщихНастроек.Сохранить(ИмяНастройкиВПФ, СсылкаСтрокой, Текст);
Важная деталь: по умолчанию ХранилищеОбщихНастроек сохраняет данные индивидуально для текущего пользователя информационной базы. Если требуется, чтобы текст, введенный одним сотрудником, видели и другие пользователи при печати того же документа, в методы сохранения и загрузки пятым параметром передается имя пользователя (например, пустая строка "" для общесистемных настроек). Однако следует помнить, что сохранение настроек для пустой строки требует наличия административной роли «Сохранение данных пользователя».
В конфигурациях с обычными формами часто применялась связка глобальных методов СохранитьЗначение и ВосстановитьЗначение. Чтобы эти функции не перезаписывали данные разных документов, имя ключа формируется динамически с добавлением идентификатора объекта.
Посмотрим на практический пример такого кода:
УникальныйИдентификатор = Строка(СсылкаНаОбъект.УникальныйИдентификатор());
КлючХранилища = "Печать_Текст_" + УникальныйИдентификатор;
// Восстанавливаем значение
Текст = ВосстановитьЗначение(КлючХранилища);
Текст = ?(ЗначениеЗаполнено(Текст), Текст, "");
Подсказка = "Введите текст:";
Если ВвестиСтроку(Текст, Подсказка, 0, Истина) Тогда
// Сохраняем обновленный текст с привязкой к документу
СохранитьЗначение(КлючХранилища, Текст);
КонецЕсли;
Выясним причину, почему этот способ не рекомендуется для современных управляемых форм:
Если в конфигурации внедрена «Библиотека стандартных подсистем» (БСП), наиболее надежным и правильным с точки зрения архитектуры решением является использование механизма дополнительных сведений.
В отличие от дополнительных реквизитов, дополнительные сведения не модифицируют структуру самого документа и хранятся в отдельном регистре сведений ДополнительныеСведения. Это дает существенные преимущества:
УправлениеСвойствами.Рассмотрим пример чтения и программной записи свойства через БСП:
// Свойство - предопределенный или созданный в режиме предприятия элемент плана видов характеристик "ДополнительныеРеквизитыИСведения"
Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ТекстВПФ");
// Чтение значения
Текст = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаОбъект, Свойство);
Если Текст = Неопределено Тогда
Текст = "";
КонецЕсли;
// Запись нового значения после ввода
УправлениеСвойствами.ЗаписатьЗначениеСвойства(СсылкаНаОбъект, Свойство, Текст);
Для версий платформы 8.3.8 и выше доступен механизм расширений. Если типовых механизмов БСП недостаточно, можно создать немодифицирующее расширение конфигурации и добавить собственный регистр сведений (например, ПараметрыПечатиДокументов), где ведущим измерением будет ссылка на документ, а ресурсом — строка введенного текста. Внешняя печатная форма сможет обращаться к этому регистру в серверном контексте без риска потери данных.
Подведем итог и определим, какой подход выбрать для конкретной ситуации:
Ссылка.УникальныйИдентификатор() и использовать СохранитьЗначение / ВосстановитьЗначение.ХранилищеОбщихНастроек с ключом настроек на базе UUID документа.