К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как сохранить таблицу значений на форме 1С

Как сохранить таблицу значений на форме 1С: реквизит формы, хранилище значений, ХранилищеОбщихНастроек и временное хранилище. Примеры кода, ошибки, FAQ.

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

Существует несколько рабочих подходов: держать таблицу в реквизите формы с типом «ТаблицаЗначений», сериализовать её через «ЗначениеВСтрокуВнутр» или JSON и складывать в хранилище настроек, либо сохранять данные в реквизит объекта через «ХранилищеЗначения». Выбор зависит от того, нужно ли сохранение между сеансами, между пользователями или только внутри одного открытого окна.

Ниже разобраны основные сценарии с примерами кода на встроенном языке, ограничениями каждого метода и типичными ошибками, которые приводят к потере данных или ошибкам сериализации.

Реквизит формы типа «ТаблицаЗначений» — базовый способ

Самый простой вариант — добавить в форму реквизит с типом «ТаблицаЗначений» и описать колонки. В конфигураторе это делается через панель реквизитов формы: добавляется реквизит, у него создаются подчинённые колонки с нужными типами. Программно колонки можно добавить через «ИзменитьРеквизиты».

Такой реквизит хранит данные, пока открыта форма. Элемент «Таблица» на форме связывается с реквизитом через свойство «ПутьКДанным», и пользователь видит и редактирует содержимое напрямую. После закрытия формы без дополнительных мер данные теряются — это нормальное поведение, а не ошибка.

// Добавление реквизита формы программно

ДобавляемыеРеквизиты = Новый Массив;

НовыйРеквизит = Новый РеквизитФормы("ТаблицаДанных",

Новый ОписаниеТипов("ТаблицаЗначений"));

ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);

ИзменитьРеквизиты(ДобавляемыеРеквизиты);

// Добавление колонок

ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");

ТЗ.Колонки.Добавить("Номенклатура",

Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТЗ.Колонки.Добавить("Количество",

Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));

ЗначениеВРеквизитФормы(ТЗ, "ТаблицаДанных");

Функции «РеквизитФормыВЗначение» и «ЗначениеВРеквизитФормы» доступны только на сервере и только в управляемой форме. Попытка вызвать их в клиентской процедуре без контекста сервера — частая причина ошибок у начинающих разработчиков.

Сохранение таблицы между сеансами через ХранилищеОбщихНастроек

Если таблицу нужно восстановить при следующем открытии формы, используют «ХранилищеОбщихНастроек». Таблица значений напрямую туда не записывается — её предварительно сериализуют. Классический способ — функции «ЗначениеВСтрокуВнутр» и «ЗначениеИзСтрокиВнутр».

&НаСервере

Процедура СохранитьТаблицуНаСервере()

ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");

СтрокаДанных = ЗначениеВСтрокуВнутр(ТЗ);

ХранилищеОбщихНастроек.Сохранить(

"МояОбработка", "ТаблицаДанных", СтрокаДанных);

КонецПроцедуры

&НаСервере

Процедура ЗагрузитьТаблицуНаСервере()

СтрокаДанных = ХранилищеОбщихНастроек.Загрузить(

"МояОбработка", "ТаблицаДанных");

Если СтрокаДанных <> Неопределено Тогда

ТЗ = ЗначениеИзСтрокиВнутр(СтрокаДанных);

ЗначениеВРеквизитФормы(ТЗ, "ТаблицаДанных");

КонецЕсли;

КонецПроцедуры

Настройки сохраняются привязанными к пользователю, поэтому каждый пользователь получит свою копию таблицы. Если нужны общие данные для всех — этот метод не подходит, используйте реквизит объекта или регистр сведений.

Сохранение в реквизит объекта через ХранилищеЗначения

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

// Запись

ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");

Объект.ДанныеТаблицы = Новый ХранилищеЗначения(ТЗ,

Новый СжатиеДанных(9));

// Чтение

ТЗ = Объект.ДанныеТаблицы.Получить();

Если ТипЗнч(ТЗ) = Тип("ТаблицаЗначений") Тогда

ЗначениеВРеквизитФормы(ТЗ, "ТаблицаДанных");

КонецЕсли;

Обязательно проверяйте тип результата после «Получить()»: для нового объекта хранилище пустое и вернёт «Неопределено». Пропуск проверки приводит к ошибке при вызове «ЗначениеВРеквизитФормы».

Учтите, что данные в хранилище значений не участвуют в запросах и не индексируются. Если по содержимому таблицы нужно строить отчёты или отборы — храните строки в табличной части объекта, а не в хранилище.

Альтернатива: JSON для обмена и совместимости

Если данные должны читаться внешними системами или передаваться через веб-сервисы, внутренний формат «ЗначениеВСтрокуВнутр» не подойдёт — он понятен только платформе 1С. В этом случае таблицу сериализуют в JSON через «ЗаписьJSON».

Запись = Новый ЗаписьJSON;

Запись.УстановитьСтроку();

МассивСтрок = Новый Массив;

Для Каждого СтрокаТЗ Из ТЗ Цикл

СтруктураСтроки = Новый Структура("Номенклатура, Количество");

ЗаполнитьЗначенияСвойств(СтруктураСтроки, СтрокаТЗ);

МассивСтрок.Добавить(СтруктураСтроки);

КонецЦикла;

ЗаписатьJSON(Запись, МассивСтрок);

СтрокаJSON = Запись.Закрыть();

Минус подхода — ссылки придётся хранить как строковые представления GUID и восстанавливать поиском по базе, что медленнее и требует обработки битых ссылок.

Сравнение способов сохранения

СпособГде хранятся данныеКогда подходитОграничение
Реквизит формыПамять сеансаРабота в открытой формеДанные теряются при закрытии
ХранилищеОбщихНастроекТаблица настроек ИБПользовательские настройки формыПривязка к пользователю
ХранилищеЗначения в реквизитеРеквизит объекта базыДанные, привязанные к объектуНедоступны в запросах
JSON / файлФайл или строкаОбмен с внешними системамиРучное восстановление ссылок
Маршрут решения

Как выбрать действие

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

Проверка результата и типичные ошибки

После реализации сохранения проверьте полный цикл: заполнить таблицу, сохранить, закрыть форму, открыть заново, убедиться, что данные и типы колонок восстановились. Особое внимание — ссылочным колонкам: если элемент справочника удалили между сеансами, в таблице останется битая ссылка, и её нужно обработать.

Типичные ошибки
01
Вызов РеквизитФормыВЗначение на клиенте — метод доступен только на сервере, перенесите код в серверную процедуру
02
Отсутствие проверки Неопределено после ХранилищеОбщихНастроек.Загрузить — при первом запуске настроек нет и код падает
03
Несовпадение состава колонок при восстановлении после изменения конфигурации — старые сериализованные данные могут не соответствовать новой структуре
04
Сохранение таблицы с колонками произвольного типа без контроля — внутренний формат не всегда восстанавливает такие значения корректно
Контрольные точки

Как проверить результат

Открытие формы после сохранения
Норма

Таблица заполнена, типы колонок соответствуют исходным

Тревожный признак

Таблица пуста или колонки стали строковыми

Повторное сохранение
Норма

Старые данные полностью заменяются новыми

Тревожный признак

Строки дублируются или остаются удалённые записи

Работа другого пользователя
Норма

Каждый видит свои настройки (для ХранилищеОбщихНастроек)

Тревожный признак

Пользователи перезаписывают данные друг друга, когда это не планировалось

FAQ

Можно ли сохранить таблицу значений на форме без программирования?

Частично. Если таблица является табличной частью документа или справочника, платформа сохраняет её автоматически при записи объекта. Произвольная таблица в реквизите формы без кода не сохраняется — нужен программный перенос в хранилище или настройки.

Почему после ЗначениеИзСтрокиВнутр колонки потеряли типы?

Внутренняя сериализация обычно сохраняет типы, но если таблица собиралась вручную с колонками без явного описания типов, при восстановлении тип может стать произвольным. Всегда задавайте колонкам явное ОписаниеТипов при создании таблицы.

Как сохранить таблицу значений в файл Excel или CSV?

Для CSV таблицу обходят в цикле и пишут строки через ТекстовыйДокумент с разделителем. Для Excel используют ТабличныйДокумент: выводят значения ячеек и сохраняют методом Записать с типом файла XLSX. Штатного метода «сохранить таблицу значений в файл» у объекта ТаблицаЗначений нет.

Что выбрать: табличную часть или хранилище значений?

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

Очищаются ли настройки ХранилищеОбщихНастроек при обновлении конфигурации?

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

Как сохранить таблицу, чтобы она была общей для всех пользователей?

ХранилищеОбщихНастроек для этого не подходит — оно работает в разрезе пользователя. Используйте константу с типом ХранилищеЗначения, регистр сведений или реквизит специального справочника-настройки, доступный всем пользователям с учётом прав.

Итог

Что важно запомнить

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