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