Разработка и Конфигурация · 11 мин
Как задать тип списка значений в 1С
Как задать тип списка значений в 1С через ОписаниеТипов: примеры кода, составные типы, работа с формой, типичные ошибки и проверка результата.
Список значений в 1С (объект СписокЗначений) по умолчанию не ограничивает тип хранимых данных — в него можно добавить строку, число и ссылку одновременно. Это удобно, но часто требуется строгое ограничение: чтобы пользователь мог выбрать только контрагентов, только номенклатуру или только строки определённой длины. Для этого у списка есть свойство ТипЗначения, которое заполняется объектом ОписаниеТипов.
Ограничение типа влияет сразу на несколько уровней: на проверку значений при добавлении программно, на поведение поля ввода на форме (какие типы предлагаются для выбора, какие кнопки выбора доступны) и на корректность сохранения данных. Если тип не задан, платформа разрешает всё, и ошибки всплывают уже на этапе обработки данных — поздно и дорого.
Материал ниже разбирает практические сценарии: создание описания типов, присвоение его списку значений, работу с составными типами, использование на управляемой форме, проверку результата и типичные ошибки, которые приводят к потере данных или невозможности выбора.
Что такое ОписаниеТипов и зачем оно списку значений
ОписаниеТипов — это объект платформы, который описывает допустимые типы данных: примитивные (Строка, Число, Дата, Булево), ссылочные (СправочникСсылка.Имя, ДокументСсылка.Имя, ПеречислениеСсылка.Имя) и их комбинации. Для строк и чисел дополнительно задаются квалификаторы: длина строки, точность и разрядность числа, состав даты.
Именно этот объект присваивается свойству ТипЗначения списка. После присвоения список начинает контролировать каждое добавляемое значение: если тип не совпадает с описанием, значение либо приводится к допустимому типу, либо заменяется на пустое значение этого типа (поведение зависит от того, возможно ли приведение). Это важно понимать: платформа не всегда выдаёт ошибку — иногда она молча подставляет неопределённое или пустую ссылку.
Как задать одиночный тип списка значений
Простейший сценарий — список должен хранить значения только одного типа. Создайте описание типов конструктором со строковым именем типа и присвойте его свойству ТипЗначения:
СписокНоменклатуры = Новый СписокЗначений;
СписокНоменклатуры.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
СписокНоменклатуры.Добавить(Справочники.Номенклатура.НайтиПоКоду("000000001"));
Для примитивных типов с квалификаторами конструктор принимает дополнительные параметры. Например, список строк фиксированной длины:
КвалификаторыСтроки = Новый КвалификаторыСтроки(50, ДопустимаяДлина.Переменная);
ОписаниеСтроки = Новый ОписаниеТипов("Строка", , КвалификаторыСтроки);
СписокКодов = Новый СписокЗначений;
СписокКодов.ТипЗначения = ОписаниеСтроки;
Аналогично для чисел используется КвалификаторыЧисла (разрядность, точность, знак), для дат — КвалификаторыДаты (состав: дата, время или дата и время). Если квалификаторы не задать, строка будет неограниченной длины, а число — с параметрами по умолчанию, что не всегда желательно при последующей записи в базу.
Как задать составной тип (несколько допустимых типов)
Когда список должен принимать, например, и контрагентов, и физических лиц, типы перечисляются через запятую в строке конструктора:
Описание = Новый ОписаниеТипов("СправочникСсылка.Контрагенты,СправочникСсылка.ФизическиеЛица");
СписокВладельцев = Новый СписокЗначений;
СписокВладельцев.ТипЗначения = Описание;
Альтернативный способ — передать массив объектов Тип. Он удобен, когда набор типов формируется динамически:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Номенклатура"));
МассивТипов.Добавить(Тип("СправочникСсылка.Контрагенты"));
Список.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
Учтите ограничение: составной тип, включающий примитивные типы вместе со ссылочными, на форме может вести себя неочевидно — поле ввода предложит выбор типа, и пользователю придётся сначала указать, что именно он вводит. Если интерфейсная простота важна, лучше ограничить список одним ссылочным типом.
Как задать тип списка значений на управляемой форме
На практике чаще всего список значений является реквизитом формы — например, для подбора нескольких значений. Если реквизит добавлен в конфигураторе, тип задаётся в палитре свойств реквизита, и дополнительный код не нужен. Но когда реквизит создаётся программно или тип нужно переопределить при открытии, ограничение задаётся в коде модуля формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
СписокТоваров.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
КонецПроцедуры
Здесь СписокТоваров — реквизит формы типа СписокЗначений. Присвоение выполняется на сервере, потому что объект ОписаниеТипов создаётся серверным контекстом при обращении к типам конфигурации. После этого связанное поле ввода автоматически ограничит выбор: кнопка выбора откроет форму выбора именно номенклатуры, а ввод несоответствующего значения будет заблокирован.
Если список связан с элементом формы через ДанныеФормы, убедитесь, что тип реквизита в метаданных формы не конфликтует с присваиваемым описанием. Конфликт проявляется как сброс значений при открытии формы или ошибка приведения типов.
- 1Добавьте реквизит формы типа СписокЗначений и свяжите его с элементом формы
- 2В обработчике ПриСозданииНаСервере присвойте свойству ТипЗначения нужное ОписаниеТипов
- 3Откройте форму и проверьте, что кнопка выбора открывает нужный справочник
- 4Попробуйте ввести значение другого типа — оно не должно сохраниться в списке
Как изменить или снять ограничение типа у существующего списка
Свойство ТипЗначения можно переназначить в любой момент. Важный нюанс: при смене типа уже добавленные элементы не пересчитываются автоматически — они остаются как есть, и контроль начинает действовать только на новые операции. Поэтому перед сменой типа имеет смысл проверить и при необходимости очистить список:
Список.Очистить();
Список.ТипЗначения = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(20));
Чтобы полностью снять ограничение, присвойте описание без указания типов — пустой конструктор Новый ОписаниеТипов() создаёт описание, не ограничивающее тип. Это эквивалентно состоянию «произвольный тип».
Если нужно не заменить, а расширить существующее описание, используйте метод СодержитТип() для проверки текущего состава и сформируйте новое описание с добавленным типом — готового метода «добавить тип к описанию списка» у свойства нет, описание всегда присваивается целиком.
Как проверить, что тип задан правильно
После присвоения убедитесь, что ограничение реально работает. Программно это делается через метод СодержитТип() объекта описания типов:
Если Список.ТипЗначения.СодержитТип(Тип("СправочникСсылка.Номенклатура")) Тогда
// ограничение установлено
КонецЕсли;
Практическая проверка на форме: откройте форму, нажмите кнопку выбора в поле списка — должна открыться форма выбора именно того объекта, который указан в описании. Попробуйте вставить значение другого типа через буфер обмена или ввод строки: платформа должна отклонить ввод или очистить поле.
Дополнительно проверьте добавление программным путём в отладчике: попытка Список.Добавить(123) в список со ссылочным типом должна привести к пустой ссылке или значению Неопределено в элементе, а не к числу 123 в списке.
Как проверить результат
Открывается форма выбора нужного справочника или документа
Открывается универсальный выбор типа или не тот объект
Значение не сохраняется как есть, приводится к пустому значению заданного типа
Чужеродное значение спокойно ложится в список
Возвращает Истина
Возвращает Ложь — описание не присвоилось
Типичные ошибки и ограничения
Самая частая ошибка — опечатка в строковом имени типа, например "СправочникСсылка.Номенклатуры" вместо "СправочникСсылка.Номенклатура". Конструктор в этом случае выбрасывает исключение, и код падает. Используйте точное имя объекта метаданных из конфигуратора.
Вторая группа ошибок — ожидание, что платформа выдаст ошибку при добавлении неподходящего значения. В ряде случаев вместо ошибки значение приводится к пустому значению заданного типа, и логика обработки молча работает с пустыми ссылками. Всегда проверяйте заполненность элементов списка перед использованием.
Третья типичная ситуация — попытка задать тип для колонки таблицы значений через свойство списка. У таблицы значений типы колонок задаются отдельно при добавлении колонки: Таблица.Колонки.Добавить("Товар", Новый ОписаниеТипов("СправочникСсылка.Номенклатура")). Это разные механизмы, не путайте их.
Если список значений используется как параметр запроса с оператором В (&Список), задавайте тип явно и однородно. Смешанный список с пустыми значениями ухудшает план запроса и может заметно замедлить выборку на больших таблицах.
Часто задаваемые вопросы
Можно ли задать тип списка значений без кода, в конфигураторе?
Да, если список является реквизитом объекта метаданных или формы. В палитре свойств реквизита откройте свойство «Тип» и отметьте нужные типы в диалоге редактирования. Код потребуется только для динамически создаваемых списков или переопределения типа в runtime.
Как задать тип «любая ссылка» для списка?
Используйте описание Новый ОписаниеТипов("СправочникСсылка, ДокументСсылка") с нужным набором видов ссылок, либо перечислите конкретные объекты. Полностью универсального типа «любая ссылка одной строкой» нет — перечисляйте группы явно.
Почему после задания типа старые элементы списка не изменились?
Присвоение ТипЗначения не выполняет обратную проверку уже добавленных элементов — ограничение действует только на последующие операции добавления и редактирования. Очистите список или пройдите по элементам и приведите значения вручную.
Как ограничить список строками фиксированной длины?
Создайте КвалификаторыСтроки с нужной длиной и допустимой длиной «Фиксированная», передайте их в конструктор ОписаниеТипов вместе с типом «Строка» и присвойте результат свойству ТипЗначения. При вводе более длинной строки значение будет обрезано или отклонено в зависимости от контекста.
Работает ли ТипЗначения при передаче списка в запрос?
Нет, параметр запроса не наследует ограничение типа из списка — в запрос уходит набор значений как есть. Контролируйте тип до передачи: отфильтруйте пустые и несоответствующие элементы, чтобы не ухудшать план выполнения запроса.
Как проверить тип конкретного элемента списка?
Обратитесь к значению элемента и используйте функцию ТипЗнч(): ТипЗнч(Список[0].Значение). Сравнить результат с ожидаемым типом можно через Тип("СправочникСсылка.Номенклатура") или методом СодержитТип() у описания типов списка.
Что важно запомнить
Тип списка значений задаётся свойством ТипЗначения через объект ОписаниеТипов — одиночным типом, составным списком типов или массивом типов. Ограничение действует на новые операции и выбор на форме, но не перепроверяет старые элементы. Всегда проверяйте результат через СодержитТип() и поведение кнопки выбора на форме.