Как сохранить табличный документ на форме документа и восстановить его при открытии

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

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

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

Выясним причину, по которой флаг Сохраняемые данные в свойствах реквизита формы не дает ожидаемого результата. В платформе 1С этот флаг лишь управляет «модифицированностью» формы. Он заставляет систему отслеживать изменения в реквизите и при попытке закрытия окна спрашивать пользователя: «Данные были изменены. Сохранить изменения?». Но платформа не знает, в какое именно поле таблицы базы данных нужно упаковать сложный объект ТабличныйДокумент, так как он не является примитивным типом (как строка или число).

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

Метод 1. Динамическое формирование при создании формы (Рекомендуемый)

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

Алгоритм действий:

  1. В процедуре ПриСозданииНаСервере или ПриЧтенииНаСервере вызываем программный код заполнения.
  2. Считываем данные из источника (запрос к базе или ТЧ документа).
  3. Формируем области и выводим их в табличный документ на форме.

Рассмотрим пример кода:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Вызываем функцию формирования документа
    СформироватьТабличныйДокументНаФорме();
КонецПроцедуры

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

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

Метод 2. Использование ХранилищаЗначений

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

Пошаговая реализация:

  1. Добавим в метаданные документа (или в расширение) новый реквизит ДанныеТаблицы с типом ХранилищеЗначений.
  2. В модуле формы перехватим событие записи, чтобы упаковать таблицу в хранилище.
  3. При открытии формы извлечем данные обратно.

Пример кода для сохранения:


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

Пример кода для восстановления данных:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    // Извлекаем объект из хранилища
    СохраненныеДанные = ТекущийОбъект.ДанныеТаблицы.Получить();
    
    Если ТипЗнч(СохраненныеДанные) = Тип("ТабличныйДокумент") Тогда
        ЭтаФорма.РезультатИзменений.Вывести(СохраненныеДанные);
    КонецЕсли;
КонецПроцедуры

Метод 3. Хранение в Регистре сведений

Рассмотрим ситуацию, когда автор использует расширение. Изменение структуры основного документа (добавление реквизита типа ХранилищеЗначений) может быть нежелательным. В этом случае создадим в расширении Регистр сведений (например, КэшТабличныхДокументов) с измерениями Объект (Ссылка на документ) и ресурсом Данные (ХранилищеЗначений).

Этот метод позволяет:

Метод 4. Сохранение в системное хранилище настроек

Если данные табличного документа носят информационный характер и важны для конкретного пользователя, воспользуемся механизмом ХранилищеОбщихНастроек. Это системная таблица, где 1С хранит настройки отчетов, положения окон и т.д.

Рассмотрим пример сохранения:


&НаКлиенте
Процедура СохранитьНастройкуТаблицы()
    КлючОбъекта = "МояТаблицаИзменений_" + Строка(Объект.Ссылка.УникальныйИдентификатор());
    ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, "", ЭтаФорма.РезультатИзменений);
КонецПроцедуры

Важно помнить, что настройки из этого хранилища могут быть очищены при регламентных работах с базой или при использовании обработки «Очистка настроек пользователей», поэтому для критически важных учетных данных этот метод использовать не рекомендуется. Чтобы регламентные задачи выполнялись корректно и по расписанию, применяется инструмент для фонового архивирования, обновления и тестирования баз 1С.

Особенности работы в расширениях

При работе через расширение, как в случае автора темы, важно учитывать режим совместимости конфигурации. Если вы добавляете реквизит с типом ХранилищеЗначений, убедитесь, что расширение не конфликтует с основной базой. Проанализируем ситуацию: наиболее безопасным и стабильным методом для расширения остается Метод №3 (Регистр сведений), так как он минимально влияет на основную конфигурацию и легко удаляется при необходимости без потери данных в основных таблицах.

Подведем итог: для автоматического восстановления табличного документа недостаточно просто разместить его на форме. Необходимо выбрать способ хранения данных (динамический расчет или физическая запись объекта в ХранилищеЗначений) и реализовать программный интерфейс передачи данных между формой и базой в процедурах ПередЗаписьюНаСервере и ПриЧтенииНаСервере.

← На главную