В процессе разработки на платформе 1С:Предприятие часто возникает задача создания универсальных хранилищ данных в оперативной памяти, таких как ТаблицаЗначений. Одной из специфических проблем является необходимость задать колонке не просто составной тип (например, строка и число), а составной тип с четко определенными параметрами — квалификаторами (длина, точность, допустимый знак).
Разберем ситуацию, когда в одной колонке должны сосуществовать ссылки на справочники, перечисления и число с конкретной разрядностью, например, 25.5 (25 знаков всего и 5 знаков после запятой). Простой перечислительный метод создания ОписаниеТипов через строку в данном случае не сработает, так как строковый конструктор не умеет интерпретировать переменные с квалификаторами.
Рассмотрим типичную ошибку. Программист пытается передать название переменной, содержащей квалификаторы, прямо в строку конструктора ОписаниеТипов:
КЧ25_5 = Новый КвалификаторыЧисла(25, 5);
Тип_КЧ25_5 = Новый ОписаниеТипов(КЧ25_5);
// Ошибка: система ожидает имя типа в строке, а не имя переменной
ТЗРеквизитыЗаказа.Колонки.Добавить("Значение", Новый ОписаниеТипов("ПеречислениеСсылка.БЗ_ТипДетали, СправочникСсылка.БЗ_ВариантыВыбора, Строка, Тип_КЧ25_5"));
Проанализируем причину неудачи: конструктор ОписаниеТипов при получении строки в качестве первого аргумента ищет в ней только зарезервированные имена типов (например, "Число", "Строка", "Дата" или полные имена ссылочных типов). Он не может "подтянуть" настройки из другой переменной, если она упомянута внутри текста. Чтобы решить эту задачу, нам необходимо использовать возможности конструктора по работе с массивами и объектами квалификаторов.
Для создания корректного описания составного типа, включающего уточненное число, нам нужно выполнить несколько последовательных шагов. Мы подготовим список всех типов, которые должны быть доступны в колонке, и отдельно создадим объект настроек для числовых данных.
Рассмотрим правильный алгоритм действий:
Тип().КвалификаторыЧисла, указав нужную длину и точность.ОписаниеТипов, передав массив первым параметром, а квалификаторы числа — четвертым.Посмотрим на пример реализации этого подхода:
// 1. Подготавливаем квалификаторы для числовой части типа
КвалификаторЧисла = Новый КвалификаторыЧисла(25, 5);
// 2. Формируем массив типов
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("ПеречислениеСсылка.БЗ_ТипДетали"));
МассивТипов.Добавить(Тип("СправочникСсылка.БЗ_ВариантыВыбора"));
МассивТипов.Добавить(Тип("Строка"));
МассивТипов.Добавить(Тип("Число"));
// 3. Создаем итоговое описание типа.
// Параметры конструктора: МассивТипов, КвалификаторыСтроки, КвалификаторыДаты, КвалификаторыЧисла
ОписаниеСоставногоТипа = Новый ОписаниеТипов(МассивТипов, , , КвалификаторЧисла);
// 4. Добавляем колонку в таблицу значений
ТЗРеквизитыЗаказа.Колонки.Добавить("Значение", ОписаниеСоставногоТипа, "Значение реквизита");
Важно понимать внутреннюю логику работы объекта ОписаниеТипов. Когда мы передаем массив, содержащий тип Число, и одновременно передаем объект КвалификаторыЧисла, платформа применяет эти настройки именно к числовой составляющей. Если бы в массиве не было типа Число, переданные квалификаторы просто были бы проигнорированы.
Выясним еще одну важную деталь: в рамках одного объекта ОписаниеТипов нельзя задать разные квалификаторы для разных "чисел". Все числовые значения в этой колонке будут подчиняться правилу (25, 5). Если вам нужно хранить и целые числа, и дробные с разной точностью в одной колонке, придется либо использовать максимальную точность для всех, либо оставлять тип Число без квалификаторов.
Иногда разработчики замечают, что если указать просто Новый ОписаниеТипов("Число"), система позволяет записывать в таблицу значения любой длины и точности без видимых ошибок. Это происходит потому, что в оперативной памяти 1С использует "гибкие" числа.
Однако отсутствие квалификаторов чревато проблемами в следующих случаях:
Проанализируем ситуацию, когда помимо числа нам нужно ограничить и длину строки в том же составном типе. Конструктор позволяет сделать это одновременно. Для этого мы добавим объект КвалификаторыСтроки.
Пример расширенного описания типа:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
МассивТипов.Добавить(Тип("Строка"));
КЧ = Новый КвалификаторыЧисла(15, 2);
КС = Новый КвалификаторыСтроки(100); // Ограничим строку 100 символами
// Второй параметр - КвалификаторыСтроки, четвертый - КвалификаторыЧисла
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КС, , КЧ);
Таким образом, мы получаем максимально контролируемую структуру данных в колонке ТаблицыЗначений, которая гарантирует валидность типов и форматов на уровне платформы еще до момента записи данных в базу.