Разработка и Конфигурация · 9 мин
Как сохранить таблицу значений на форме 1С
Как сохранить таблицу значений на форме 1С: реквизит формы, хранилище значений, ХранилищеОбщихНастроек и временное хранилище. Примеры кода, ошибки, FAQ.
Таблица значений в 1С — универсальная структура для промежуточных расчётов, загрузки данных из файлов и отображения списков на форме. Проблема в том, что таблица значений «живёт» только в памяти: после закрытия формы или перезапуска сеанса данные пропадают, если разработчик не позаботился о сохранении.
Существует несколько рабочих подходов: держать таблицу в реквизите формы с типом «ТаблицаЗначений», сериализовать её через «ЗначениеВСтрокуВнутр» или JSON и складывать в хранилище настроек, либо сохранять данные в реквизит объекта через «ХранилищеЗначения». Выбор зависит от того, нужно ли сохранение между сеансами, между пользователями или только внутри одного открытого окна.
Ниже разобраны основные сценарии с примерами кода на встроенном языке, ограничениями каждого метода и типичными ошибками, которые приводят к потере данных или ошибкам сериализации.
Реквизит формы типа «ТаблицаЗначений» — базовый способ
Самый простой вариант — добавить в форму реквизит с типом «ТаблицаЗначений» и описать колонки. В конфигураторе это делается через панель реквизитов формы: добавляется реквизит, у него создаются подчинённые колонки с нужными типами. Программно колонки можно добавить через «ИзменитьРеквизиты».
Такой реквизит хранит данные, пока открыта форма. Элемент «Таблица» на форме связывается с реквизитом через свойство «ПутьКДанным», и пользователь видит и редактирует содержимое напрямую. После закрытия формы без дополнительных мер данные теряются — это нормальное поведение, а не ошибка.
// Добавление реквизита формы программно
ДобавляемыеРеквизиты = Новый Массив;
НовыйРеквизит = Новый РеквизитФормы("ТаблицаДанных",
Новый ОписаниеТипов("ТаблицаЗначений"));
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
ИзменитьРеквизиты(ДобавляемыеРеквизиты);
// Добавление колонок
ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");
ТЗ.Колонки.Добавить("Номенклатура",
Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
ЗначениеВРеквизитФормы(ТЗ, "ТаблицаДанных");
Функции «РеквизитФормыВЗначение» и «ЗначениеВРеквизитФормы» доступны только на сервере и только в управляемой форме. Попытка вызвать их в клиентской процедуре без контекста сервера — частая причина ошибок у начинающих разработчиков.
Сохранение таблицы между сеансами через ХранилищеОбщихНастроек
Если таблицу нужно восстановить при следующем открытии формы, используют «ХранилищеОбщихНастроек». Таблица значений напрямую туда не записывается — её предварительно сериализуют. Классический способ — функции «ЗначениеВСтрокуВнутр» и «ЗначениеИзСтрокиВнутр».
&НаСервере
Процедура СохранитьТаблицуНаСервере()
ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");
СтрокаДанных = ЗначениеВСтрокуВнутр(ТЗ);
ХранилищеОбщихНастроек.Сохранить(
"МояОбработка", "ТаблицаДанных", СтрокаДанных);
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьТаблицуНаСервере()
СтрокаДанных = ХранилищеОбщихНастроек.Загрузить(
"МояОбработка", "ТаблицаДанных");
Если СтрокаДанных <> Неопределено Тогда
ТЗ = ЗначениеИзСтрокиВнутр(СтрокаДанных);
ЗначениеВРеквизитФормы(ТЗ, "ТаблицаДанных");
КонецЕсли;
КонецПроцедуры
Настройки сохраняются привязанными к пользователю, поэтому каждый пользователь получит свою копию таблицы. Если нужны общие данные для всех — этот метод не подходит, используйте реквизит объекта или регистр сведений.
Сохранение в реквизит объекта через ХранилищеЗначения
Когда таблица относится к конкретному документу или элементу справочника, правильнее хранить её в базе. В объект добавляют реквизит с типом «ХранилищеЗначения», а таблицу упаковывают через «Новый ХранилищеЗначения(ТЗ, Новый СжатиеДанных(9))».
// Запись
ТЗ = РеквизитФормыВЗначение("ТаблицаДанных");
Объект.ДанныеТаблицы = Новый ХранилищеЗначения(ТЗ,
Новый СжатиеДанных(9));
// Чтение
ТЗ = Объект.ДанныеТаблицы.Получить();
Если ТипЗнч(ТЗ) = Тип("ТаблицаЗначений") Тогда
ЗначениеВРеквизитФормы(ТЗ, "ТаблицаДанных");
КонецЕсли;
Обязательно проверяйте тип результата после «Получить()»: для нового объекта хранилище пустое и вернёт «Неопределено». Пропуск проверки приводит к ошибке при вызове «ЗначениеВРеквизитФормы».
Учтите, что данные в хранилище значений не участвуют в запросах и не индексируются. Если по содержимому таблицы нужно строить отчёты или отборы — храните строки в табличной части объекта, а не в хранилище.
Альтернатива: JSON для обмена и совместимости
Если данные должны читаться внешними системами или передаваться через веб-сервисы, внутренний формат «ЗначениеВСтрокуВнутр» не подойдёт — он понятен только платформе 1С. В этом случае таблицу сериализуют в JSON через «ЗаписьJSON».
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
МассивСтрок = Новый Массив;
Для Каждого СтрокаТЗ Из ТЗ Цикл
СтруктураСтроки = Новый Структура("Номенклатура, Количество");
ЗаполнитьЗначенияСвойств(СтруктураСтроки, СтрокаТЗ);
МассивСтрок.Добавить(СтруктураСтроки);
КонецЦикла;
ЗаписатьJSON(Запись, МассивСтрок);
СтрокаJSON = Запись.Закрыть();
Минус подхода — ссылки придётся хранить как строковые представления GUID и восстанавливать поиском по базе, что медленнее и требует обработки битых ссылок.
Сравнение способов сохранения
| Способ | Где хранятся данные | Когда подходит | Ограничение |
|---|---|---|---|
| Реквизит формы | Память сеанса | Работа в открытой форме | Данные теряются при закрытии |
| ХранилищеОбщихНастроек | Таблица настроек ИБ | Пользовательские настройки формы | Привязка к пользователю |
| ХранилищеЗначения в реквизите | Реквизит объекта базы | Данные, привязанные к объекту | Недоступны в запросах |
| JSON / файл | Файл или строка | Обмен с внешними системами | Ручное восстановление ссылок |
Как выбрать действие
Проверка результата и типичные ошибки
После реализации сохранения проверьте полный цикл: заполнить таблицу, сохранить, закрыть форму, открыть заново, убедиться, что данные и типы колонок восстановились. Особое внимание — ссылочным колонкам: если элемент справочника удалили между сеансами, в таблице останется битая ссылка, и её нужно обработать.
Как проверить результат
Таблица заполнена, типы колонок соответствуют исходным
Таблица пуста или колонки стали строковыми
Старые данные полностью заменяются новыми
Строки дублируются или остаются удалённые записи
Каждый видит свои настройки (для ХранилищеОбщихНастроек)
Пользователи перезаписывают данные друг друга, когда это не планировалось
FAQ
Можно ли сохранить таблицу значений на форме без программирования?
Частично. Если таблица является табличной частью документа или справочника, платформа сохраняет её автоматически при записи объекта. Произвольная таблица в реквизите формы без кода не сохраняется — нужен программный перенос в хранилище или настройки.
Почему после ЗначениеИзСтрокиВнутр колонки потеряли типы?
Внутренняя сериализация обычно сохраняет типы, но если таблица собиралась вручную с колонками без явного описания типов, при восстановлении тип может стать произвольным. Всегда задавайте колонкам явное ОписаниеТипов при создании таблицы.
Как сохранить таблицу значений в файл Excel или CSV?
Для CSV таблицу обходят в цикле и пишут строки через ТекстовыйДокумент с разделителем. Для Excel используют ТабличныйДокумент: выводят значения ячеек и сохраняют методом Записать с типом файла XLSX. Штатного метода «сохранить таблицу значений в файл» у объекта ТаблицаЗначений нет.
Что выбрать: табличную часть или хранилище значений?
Если по данным нужны отчёты, отборы или запросы — только табличная часть. Хранилище значений оправдано, когда данные читаются и пишутся целиком, не участвуют в аналитике и их структура может меняться без доработки конфигурации.
Очищаются ли настройки ХранилищеОбщихНастроек при обновлении конфигурации?
Нет, настройки хранятся в отдельной системной таблице и переживают обновления. Но если вы изменили структуру сохраняемых данных, старые записи могут оказаться несовместимыми — предусмотрите проверку версии формата или обработку ошибок при загрузке.
Как сохранить таблицу, чтобы она была общей для всех пользователей?
ХранилищеОбщихНастроек для этого не подходит — оно работает в разрезе пользователя. Используйте константу с типом ХранилищеЗначения, регистр сведений или реквизит специального справочника-настройки, доступный всем пользователям с учётом прав.
Что важно запомнить
Реквизит формы держит таблицу только в открытом окне. Для сохранения между сеансами сериализуйте таблицу и пишите в ХранилищеОбщихНастроек (личные данные) или в ХранилищеЗначения объекта (данные базы). Всегда проверяйте результат загрузки на Неопределено и контролируйте типы колонок.