При разработке в среде 1С начинающие программисты часто сталкиваются с ситуацией, когда созданная на форме Таблица значений (ТЗ) после закрытия и повторного открытия объекта оказывается пустой. В этой статье мы подробно разберем, почему данные в ТаблицеЗначений не сохраняются автоматически, и проанализируем все доступные способы реализации постоянного хранения табличных данных.
Для начала выясним причину, по которой компьютер «забывает» данные. Рассмотрим архитектуру платформы 1С. Таблица значений — это универсальная коллекция значений, которая существует исключительно в оперативной памяти. Она предназначена для промежуточных вычислений в коде. Когда вы закрываете форму или завершается работа процедуры, память очищается, и данные ТЗ исчезают.
В отличие от ТЗ, Табличная часть (ТЧ) справочника — это объект метаданных, описанный в Конфигураторе. Платформа заранее знает структуру ТЧ и автоматически создает таблицы в базе данных SQL для хранения этих строк. Таким образом, главное правило звучит так: в базу записываются только те данные объекта, которые определены в его метаданных.
Самый простой и правильный путь для сохранения данных, имеющих постоянную структуру, — это создание Табличной части в самом справочнике. Разберем по шагам, как это работает:
Объект.ИмяВашейТабличнойЧасти.При таком подходе платформа 1С берет на себя все заботы по записи данных в базу при нажатии кнопки «Записать» и их чтению при открытии формы. Это наиболее производительный и стандартный метод.
Иногда требуется хранить данные не в самом справочнике, а во внешнем объекте, например, в Регистре сведений. В этом случае программисту необходимо реализовать связь «ручками». Проанализируем, как это сделать программно:
Во-первых, нам нужно реализовать запись данных из ТЗ в регистр. Это обычно делается в обработчике события ПередЗаписьюНаСервере или ПриЗаписиНаСервере.
// Пример записи данных из таблицы формы в Регистр сведений
Для Каждого СтрокаТЗ Из Объект.МояТаблица Цикл
МенеджерЗаписи = РегистрыСведений.ИмяВашегоРегистра.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.Владелец = Объект.Ссылка;
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, СтрокаТЗ);
МенеджерЗаписи.Записать();
КонецЦикла;
Во-вторых, нам нужно восстановить эти данные при открытии формы. Для этого используем процедуру ПриЧтенииНаСервере:
// Пример чтения данных из регистра в таблицу на форме
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ * ИЗ РегистрСведений.ИмяВашегоРегистра ГДЕ Владелец = &Владелец";
Запрос.УстановитьПараметр("Владелец", Объект.Ссылка);
Результат = Запрос.Выполнить().Выгрузить();
Объект.МояТаблица.Загрузить(Результат);
Рассмотрим более сложную ситуацию: что делать, если структура вашей таблицы заранее неизвестна (динамические колонки), и вы не можете создать стандартную Табличную часть? В этом случае на помощь приходит ХранилищеЗначения.
Мы можем создать в справочнике реквизит с типом ХранилищеЗначения. В него можно упаковать всю таблицу целиком как бинарный объект. Разберем алгоритм:
ТаблицуЗначений в ХранилищеЗначения и записываем в реквизит.Пример программного кода для такой реализации:
// Сохранение ТЗ в реквизит справочника "ДанныеТаблицы"
Объект.ДанныеТаблицы = Новый ХранилищеЗначения(МояТЗ.Выгрузить());
// Восстановление данных при открытии
ДанныеИзХранилища = Объект.ДанныеТаблицы.Получить();
Если ТипЗнч(ДанныеИзХранилища) = Тип("ТаблицаЗначений") Тогда
МояТЗ.Загрузить(ДанныеИзХранилища);
КонецЕсли;
Важно помнить, что в управляемом приложении (v8.3) данные таблицы на экране — это не совсем ТаблицаЗначений. Это специальный объект ДанныеФормыКоллекция. Чтобы эффективно работать с ними на сервере, рассмотрим использование методов преобразования:
РеквизитФормыВЗначение("Объект", Тип("СправочникОбъект.ИмяСправочника")) — преобразует данные формы в объект для обработки.ЗначениеВРеквизитФормы(ОбъектТЗ, "ИмяРеквизитаФормы") — отправляет обработанную таблицу обратно на экран пользователю.Проанализируем современные подходы к «заморозке» данных. Если вам нужно сохранить таблицу в текстовом виде (например, для передачи через веб-сервис или сохранения в длинную строку), рекомендуется использовать сериализацию. Методы типа ЗначениеВСтрокуВнутр считаются устаревшими. Вместо них лучше использовать XDTO-сериализатор или ЗаписьJSON. Это позволяет превратить таблицу в структурированный текст, который легко сохранить в обычный реквизит строкового типа и восстановить позже без потери данных.
Подводя итог, выясним, какой метод выбрать. Если структура данных статична и понятна — всегда выбирайте Табличную часть. Это обеспечит максимальную скорость работы и простоту поддержки кода. Если же вы создаете сложный механизм подбора или промежуточных расчетов — используйте Таблицу значений как временный инструмент, не забывая о том, что ее связь с базой данных (через регистры или хранилище) полностью лежит на плечах программиста.