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