Как сохранять и восстанавливать данные табличной части во внешней обработке 1С

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

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

Почему возникает ошибка формата объекта настроек

Рассмотрим типичную ситуацию: разработчик пытается сохранить табличную часть напрямую через ХранилищеОбщихНастроек. При этом часто возникает системная ошибка: "Ошибка формата объекта настроек". Проанализируем причину этого поведения. Объект типа ТабличнаяЧасть жестко связан с конкретным экземпляром объекта (документа, справочника или обработки). Он не является независимым типом данных, который можно легко сериализовать в XML-строку для записи в базу данных настроек. Для успешного сохранения нам необходимо преобразовать данные в универсальный формат.

Решение 1: Использование Таблицы Значений

Первый и самый очевидный способ — это выгрузка данных из табличной части в ТаблицуЗначений. Таблица значений является независимым объектом и корректно обрабатывается механизмами сериализации 1С. Разберем по шагам, как реализовать сохранение данных на сервере.

Для начала создадим процедуру сохранения. Мы будем использовать соответствие для хранения данных, так как это позволит нам в будущем легко добавлять другие реквизиты формы в тот же ключ настроек.


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

Обратите внимание на КлючОбъекта. Для внешних обработок крайне важно задавать его строковой константой. Если использовать имя файла, то при переименовании обработки или её перемещении в другую папку настройки "потеряются", так как ключ изменится.

Решение 2: Упаковка в ХранилищеЗначения для максимальной надежности

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

Этот метод превращает любой объект в бинарные данные, которые гарантированно записываются в базу данных без проверки структуры XML. Рассмотрим пример модифицированного кода:


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

При восстановлении данных нам потребуется выполнить обратную операцию. Посмотрим, как это выглядит в процедуре загрузки:


&НаСервере
Процедура ВосстановитьНастройкиНаСервере()
    КлючОбъекта = "УникальныйИдентификаторОбработки";
    
    // Получаем упакованные данные
    ДанныеНастроек = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, "ДанныеТЧ");
    
    Если ДанныеНастроек <> Неопределено Тогда
        // Извлекаем таблицу значений из ХранилищаЗначения
        ТаблицаЗначений = ДанныеНастроек.Получить();
        
        Если ТипЗнч(ТаблицаЗначений) = Тип("ТаблицаЗначений") Тогда
            Объект.СписокАвтомобилей.Загрузить(ТаблицаЗначений);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Штатный механизм управляемых форм

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

  1. Создадим Реквизит формы (не путать с реквизитом объекта) с типом ТаблицаЗначений и точно такой же структурой колонок, как у нашей ТЧ.
  2. В свойствах этого реквизита установим галочку "Сохранение".
  3. В свойствах самой формы установим флаг "Автоматическое сохранение данных в настройках" и выберем режим "Использовать список" или "Сохранять автоматически".

Теперь нам остается только синхронизировать данные между Объект.ТабличнаяЧасть и нашим реквизитом формы при открытии и закрытии. Рассмотрим обработчики событий формы:


&НаСервере
Процедура ПередЗаписьюНастроекНаСервере(Настройки)
    // Перед тем как форма сама сохранит настройки, перенесем данные из ТЧ объекта в сохраняемый реквизит
    РеквизитТаблицаФормы = Объект.СписокАвтомобилей.Выгрузить();
КонецПроцедуры

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

Важные рекомендации и ограничения

При реализации сохранения данных важно помнить о производительности и стабильности системы. Проанализируем основные моменты:

Объем данных: Системное хранилище настроек не предназначено для хранения огромных массивов информации. Если в вашей табличной части предполагаются десятки тысяч строк, база данных может начать работать медленнее при каждом открытии формы. В таких случаях лучше использовать запись в JSON-файл или временные таблицы в базе.

Типы данных: Если в колонках вашей таблицы используются ссылки на объекты, которые могут быть удалены (например, ссылки на другие внешние обработки или временные документы), это может привести к ошибкам "Объект не найден" при восстановлении. Всегда проверяйте типы данных перед загрузкой.

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

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

← На главную