В процессе разработки в среде 1С:Предприятие мы регулярно сталкиваемся с необходимостью динамического управления типами данных. Объект ОписаниеТипов активно используется при программном создании колонок таблиц значений, реквизитов форм, а также при настройке доступных типов для полей ввода. Однако при попытке динамически расширить уже готовое описание типов разработчики часто сталкиваются с преградой: объект ОписаниеТипов является неизменяемым (immutable). Это значит, что у него нет методов вроде Добавить() или Вставить().
В этой статье мы подробно разберем, как обойти это ограничение, рассмотрим работу конструктора для модификации типов, научимся правильно наследовать квалификаторы и использовать готовые инструменты Библиотеки стандартных подсистем (БСП) для оптимизации нашего кода.
Поскольку мы не можем изменить уже созданный объект, мы должны пойти по пути создания нового объекта ОписаниеТипов на основании старого. Платформа 1С предоставляет для этого мощный и гибкий конструктор. Давайте проанализируем его синтаксис:
Новый ОписаниеТипов(<ИсходноеОписаниеТипов>, <ДобавляемыеТипы>, <ВычитаемыеТипы>, <КвалификаторыЧисла>, <КвалификаторыСтроки>, <КвалификаторыДаты>, <КвалификаторыДвоичныхДанных>)
Для решения нашей задачи ключевыми являются первые два параметра:
Давайте посмотрим на практический пример. Предположим, у нас уже есть исходное описание типов, содержащее ссылки на склады и магазины, и нам нужно программно добавить туда тип кассы:
// Шаг 1. Создаем исходное описание типов
ТипыДанных = Новый ОписаниеТипов("СправочникОбъект.Магазины, СправочникОбъект.Склады");
// Шаг 2. Добавляем новый тип, создавая новое ОписаниеТипов на базе старого
ТипыДанных = Новый ОписаниеТипов(ТипыДанных, "СправочникОбъект.Кассы");
В результате переменная ТипыДанных будет содержать обновленный объект, включающий в себя все три справочника. Старый объект при этом автоматически удалится из памяти сборщиком мусора, если на него больше нет ссылок.
Если структура типов известна заранее на этапе написания кода, лучшим решением будет отказаться от пошагового добавления и сразу перечислить все необходимые типы. Мы можем сделать это двумя способами:
Способ 1. Строковое перечисление (через запятую)
// Самый простой способ для статических типов
ТипыДанных = Новый ОписаниеТипов("СправочникОбъект.Магазины, СправочникОбъект.Склады, СправочникОбъект.Кассы");
Способ 2. Использование массива типов
Этот способ незаменим, когда список типов формируется динамически в цикле или на основе сложных алгоритмов:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникОбъект.Магазины"));
МассивТипов.Добавить(Тип("СправочникОбъект.Склады"));
МассивТипов.Добавить(Тип("СправочникОбъект.Кассы"));
ОписаниеТиповДанных = Новый ОписаниеТипов(МассивТипов);
Обратите внимание на высокую универсальность параметров <ДобавляемыеТипы> и <ВычитаемыеТипы>. Платформа 1С позволяет передавать в них данные самых разных форматов. Вы можете использовать:
Тип (например, Тип("Число")).ОписаниеТипов (все типы из него будут добавлены или исключены пакетно).При создании нового описания типов на основе существующего критически важно понимать, как ведут себя квалификаторы примитивных типов (чисел, строк, дат). Здесь действуют следующие правила:
Иногда перед разработчиком стоит обратная задача: не добавить тип, а исключить конкретный тип из составного типа данных. Для этого используется третий параметр конструктора — <ВычитаемыеТипы>. Это избавляет от необходимости вручную перебирать массив типов и собирать описание заново.
Рассмотрим пример, когда нам нужно получить описание типов для всех ссылок конфигурации, исключив при этом определенный документ:
// Получаем широкое описание типов (например, все ссылки)
ВсеСсылки = Новый ОписаниеТипов("ДокументСсылка.ЗаказПокупателя, ДокументСсылка.РеализацияТоваровУслуг, СправочникСсылка.Номенклатура");
// Исключаем документ РеализацияТоваровУслуг
ТолькоНужныеТипы = Новый ОписаниеТипов(ВсеСсылки, , "ДокументСсылка.РеализацияТоваровУслуг");
Для эффективной работы с объектом ОписаниеТипов не обязательно постоянно выгружать его состав в массив через метод Типы(). Существуют более производительные встроенные инструменты:
СодержитТип(<Тип>) — позволяет мгновенно проверить, входит ли конкретный тип в текущее описание. Это работает значительно быстрее, чем ручной поиск в массиве типов.ПривестиЗначение(<Значение>) — приводит переданное значение к одному из типов, определенных в описании. Если исходное значение невозможно привести ни к одному из допустимых типов, метод вернет пустое значение по умолчанию для первого типа из описания (например, пустую ссылку или пустую строку).Если вы работаете в современной конфигурации, построенной на базе БСП, ручное написание конструкторов для простых типов часто считается избыточным. В общем модуле ОбщегоНазначения предусмотрены готовые функции-помощники, которые делают ваш код чище и понятнее:
ОбщегоНазначения.ОписаниеТипаСтрока(Длина, ДопустимаяДлина) — быстро возвращает описание типа "Строка" с заданными параметрами длины.ОбщегоНазначения.ОписаниеТипаЧисло(Разрядность, ДробнаяЧасть, ДопустимыйЗнак) — формирует описание числового типа.ОбщегоНазначения.ОписаниеТипаДата(ЧастиДаты) — возвращает описание для типа "Дата" (например, только дата, либо дата и время).ОбщегоНазначения.ОписаниеТипаВсеСсылки() — автоматически генерирует описание типов, содержащее все ссылочные типы вашей конфигурации.Используйте эти стандарты разработки, чтобы ваш код оставался лаконичным, производительным и легко читаемым для коллег!