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

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

Как сохранить список значений в документе 1С

Способы сохранить список значений в документе 1С: табличная часть, хранилище значения, строка с разделителем. Примеры кода, сравнение вариантов, ошибки и FAQ.

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

Основные варианты: табличная часть документа, реквизит типа «ХранилищеЗначения», строковый реквизит с разделителем и регистр сведений, связанный с документом. У каждого подхода есть свои ограничения — например, объект СписокЗначений напрямую в реквизит документа записать нельзя, его нужно сериализовать или преобразовать.

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

Почему СписокЗначений нельзя записать в реквизит напрямую

Объект типа СписокЗначений — это объект встроенного языка, который существует только в оперативной памяти сеанса. Конфигуратор не позволяет создать реквизит документа такого типа: в списке допустимых типов реквизита его просто нет. Поэтому попытка присвоить список реквизиту и записать документ закончится либо ошибкой, либо потерей данных.

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

Способ 1. Табличная часть документа — основной вариант

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

Заполнение табличной части из СписокЗначений в коде выглядит так:

ДокументОбъект.ВыбранныеПозиции.Очистить();

Для Каждого ЭлементСписка Из СписокЗначений Цикл

НоваяСтрока = ДокументОбъект.ВыбранныеПозиции.Добавить();

НоваяСтрока.Номенклатура = ЭлементСписка.Значение;

КонецЦикла;

ДокументОбъект.Записать();

Главные преимущества подхода: данные участвуют в запросах и отчётах через СКД, доступны для печатных форм, видны пользователю в форме документа без дополнительного кода. Ограничение — структура табличной части фиксирована на этапе конфигурирования, поэтому произвольный набор полей хранить не получится.

Как добавить табличную часть для списка
  1. 1
    Откройте конфигуратор и найдите нужный документ в дереве объектов
  2. 2
    Добавьте табличную часть и задайте ей имя, например «ВыбранныеЗначения»
  3. 3
    Создайте реквизиты табличной части с нужными типами данных
  4. 4
    Перетащите табличную часть на форму документа
  5. 5
    В коде заполнения перенесите СписокЗначений в строки табличной части и запишите документ
  6. 6
    Проверьте: откройте записанный документ и убедитесь, что строки на месте

Способ 2. Реквизит типа ХранилищеЗначения

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

Запись и чтение выполняются через конструктор Новый ХранилищеЗначения и метод Получить:

// Запись

ДокументОбъект.ДанныеСписка = Новый ХранилищеЗначения(СписокЗначений);

ДокументОбъект.Записать();

// Чтение

СписокЗначений = ДокументОбъект.ДанныеСписка.Получить();

Если СписокЗначений = Неопределено Тогда

СписокЗначений = Новый СписокЗначений;

КонецЕсли;

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

Способ 3. Строка с разделителем

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

// Запись

ДокументОбъект.СписокСтрокой = СтрСоединить(МассивЗначений, ";");

ДокументОбъект.Записать();

// Чтение

МассивЗначений = СтрРазделить(ДокументОбъект.СписокСтрокой, ";");

Метод удобен для интеграций и обмена, где требуется «плоское» представление списка. Но если внутри значения встретится символ разделителя, при чтении список «рассыплется» неправильно. Для ссылок на справочники так хранить не стоит — при переименовании элемента строка станет недействительной, а поиск по ней невозможен.

Способ 4. Регистр сведений, подчинённый документу

Когда список значений нужен для аналитики, но загружать табличную часть нежелательно (например, значений очень много или они формируются обработкой), используют регистр сведений с режимом «Подчинение регистратору». Документ при записи формирует движения — по одной строке на каждое значение списка.

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

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

Табличная часть

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

ХранилищеЗначения

Хранит любые объекты (СписокЗначений, ТаблицуЗначений) без изменения структуры данных. Не подходит для отчётов и поиска по значениям.

Строка с разделителем

Быстро и просто, удобно для обмена. Только короткие строки без служебных символов; ссылки и отчётность не поддерживаются.

Регистр сведений

Максимальные возможности аналитики и отборов. Требует дополнительного объекта и кода формирования движений.

Как выбрать подходящий способ

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

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

Маршрут решения

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

По значениям списка нужны отчёты, отборы или печатьИспользуйте табличную часть документа
Значений очень много или они формируются отдельной обработкой, но аналитика нужнаСоздайте регистр сведений, подчинённый регистратору
Список — служебные настройки с произвольной структурой, отчётность не нужнаСохраните СписокЗначений в реквизит типа ХранилищеЗначения
Нужно быстро передать простой перечень строк в обмен или на формуСоедините значения в строку с разделителем, исключив символ разделителя из данных

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

После внедрения любого из способов проверьте полный цикл: заполните список, запишите документ, закройте и откройте его заново, убедитесь, что значения восстановились полностью и в правильном порядке. Для хранилища значений дополнительно проверьте сценарий, когда реквизит пуст — метод Получить() вернёт Неопределено, и код должен это обрабатывать, иначе пользователь увидит ошибку.

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

Типичные ошибки
01
Попытка присвоить СписокЗначений напрямую реквизиту документа — тип не поддерживается, данные теряются
02
Хранение ссылок строкой — после переименования элементов список становится недействительным
03
Отсутствие проверки на Неопределено при чтении пустого ХранилищаЗначения — ошибка при открытии документа
04
Использование символа-разделителя, который встречается в самих значениях — список разбирается неправильно
05
Хранение данных для отчётов в ХранилищеЗначения — невозможность построить отчёт без перебора всех документов
Контрольные точки

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

Открытие записанного документа
Норма

Все значения списка на месте, порядок сохранён

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

Список пуст, частично заполнен или выдаётся ошибка

Чтение пустого реквизита ХранилищеЗначения
Норма

Код корректно обрабатывает Неопределено и создаёт пустой список

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

Возникает ошибка «Метод объекта не обнаружен» или подобная

Отчёт или отбор по значению списка
Норма

Документ находится запросом по нужному значению (табличная часть или регистр)

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

Значение недоступно для запроса — данные в хранилище или строке

Переименование элемента справочника из списка
Норма

В документе отображается новое наименование (ссылочное хранение)

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

Отображается старое название — значения хранятся строкой

Часто задаваемые вопросы

Можно ли сохранить СписокЗначений в дополнительном сведении документа?

Напрямую — нет, дополнительные сведения поддерживают ограниченный набор типов (строка, число, дата, булево, ссылки). Обходной путь — сериализовать список в строку, например через ЗначениеВСтрокуВнутр, и сохранить как строковое значение, а при чтении восстановить через ЗначениеИзСтрокиВнутр.

Что выбрать для хранения помеченных элементов из динамического списка?

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

Есть ли ограничение на количество строк табличной части?

Жёсткого ограничения со стороны платформы практически нет, но при очень большом числе строк (десятки тысяч и более) замедляется запись документа и открытие формы. В таких случаях рассмотрите регистр сведений или пересмотр структуры хранения.

Как перенести список из ХранилищаЗначения в табличную часть при доработке?

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

Можно ли искать документы по значению внутри ХранилищаЗначения?

Штатными средствами запроса — нет, содержимое хранилища недоступно для СКД и консоли запросов. Единственный путь — перебор документов с распаковкой каждого хранилища, что медленно. Если поиск нужен регулярно, мигрируйте данные в табличную часть или регистр сведений.

Итог

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

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