В процессе разработки на платформе «1С:Предприятие 8.3», особенно в конфигурациях уровня УТ 11.5, ERP или КА, программисты часто сталкиваются с необходимостью программного создания таблиц значений (ТЗ). Одной из специфических задач является корректная типизация колонок. Часто возникают ситуации, когда колонка должна содержать не только числовые данные, но и специальный литерал NULL. Это критически важно, если таблица в дальнейшем передается в запрос для создания временной таблицы или если она имитирует структуру, полученную в результате выполнения запроса с левым соединением.
В этой статье мы подробно разберем, как правильно сконструировать ОписаниеТипов, включающее NULL, проанализируем различные способы реализации и выясним, почему стандартные функции БСП не всегда подходят для этой задачи.
Многие разработчики привыкли использовать удобные функции общего назначения из состава БСП (Библиотеки стандартных подсистем), такие как ОбщегоНазначения.ОписаниеТипаЧисло(15, 2). Однако рассмотрим ситуацию: такая функция возвращает «чистый» тип Число. Если мы попытаемся записать значение NULL в колонку с таким описанием типа, платформа либо вызовет ошибку несоответствия типов, либо проигнорирует запись, если тип не является составным.
Проанализируем пример, когда нам нужно получить именно составной тип NULL, Число, как это делает сам механизм запросов 1С при выгрузке результата в таблицу значений. Выясним, как добиться такого же результата программно без выполнения фиктивных запросов.
Самый простой и элегантный способ, который часто упускают из виду — это использование конструктора ОписаниеТипов с перечислением типов в одной строке. Платформа 1С позволяет передавать названия типов через запятую.
Разберем конкретный пример реализации, который можно быстро протестировать, используя консоль кода с ИИ-помощником:
// Определяем квалификаторы числа (длина 15, точность 2)
КвалификаторыЧисла = Новый КвалификаторыЧисла(15, 2);
// Создаем описание типов, указывая "Null" и "Число" в строке
МоеОписаниеТ = Новый ОписаниеТипов("Null, Число", КвалификаторыЧисла);
// Создаем таблицу значений и добавляем колонку
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Сумма", МоеОписаниеТ);
// Проверим возможность записи разных типов
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Сумма = 100.50; // Числовое значение
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Сумма = NULL; // Значение NULL
В данном примере мы видим, что передача строки "Null, Число" первым параметром конструктора автоматически создает объект, поддерживающий оба типа. Обратите внимание, что порядок типов в строке не имеет значения, но использование NULL позволяет системе корректно обрабатывать пустые значения в контексте баз данных.
Иногда требуется более гибкий подход, например, если мы хотим программно дополнить уже существующее ОписаниеТипов типом NULL. В этом случае целесообразно использовать массив типов. Рассмотрим, как это сделать по шагам:
Число и тип NULL.ОписаниеТипов.Посмотрим на пример кода:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
МассивТипов.Добавить(Тип("NULL"));
// Квалификаторы также можно передать в конструктор
Квалификаторы = Новый КвалификаторыЧисла(10, 0);
ОписаниеСНуллом = Новый ОписаниеТипов(МассивТипов, Квалификаторы);
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Количество", ОписаниеСНуллом);
Этот метод считается более «профессиональным» в среде разработчиков, так как он исключает ошибки опечаток в строковых названиях типов и позволяет динамически управлять составом типов (например, в цикле или на основании метаданных).
Важно понимать разницу при работе с ОписаниеТипов. Если вы создаете составной тип, например Число, Строка, и не заполняете ячейку, по умолчанию там будет находиться значение Неопределено. Однако NULL — это не отсутствие значения в логике 1С, а специфический тип данных.
Основные нюансы:
NULL, вы можете явно присвоить ячейке это значение.NULL, попытка присвоить это значение приведет к тому, что в ячейке окажется значение по умолчанию для основного типа (например, 0 для числа).NULL в ОписаниеТипов колонки ТЗ указывает СУБД на необходимость создания поля с признаком ALLOW NULL.Если вы забыли, как правильно пишутся названия типов или какие квалификаторы можно применить, в конфигураторе 1С есть встроенный помощник. Разберем, как им воспользоваться:
ОписаниеТипов.Проанализируем ситуацию: использование конструктора шаблонов экономит время и гарантирует, что вы не ошибетесь в синтаксисе параметров КвалификаторыЧисла, КвалификаторыСтроки или КвалификаторыДаты.
Рассмотрим практический сценарий. Вы формируете таблицу значений ТЗ_Данные и передаете ее в запрос, для отладки которого идеально подойдет управляемая консоль запросов:
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ &ВнешняяТЗ КАК ВнешняяТЗ";
Запрос.УстановитьПараметр("ВнешняяТЗ", ТЗ_Данные);
Запрос.Выполнить();
Если в ТЗ_Данные есть строки, где в числовой колонке стоит NULL, но при создании колонки вы указали просто Новый ОписаниеТипов("Число"), то при выполнении запроса 1С может выдать ошибку «Несоответствие типов». Платформа ожидает, что раз тип жестко задан как числовой, то никаких NULL там быть не может. Явное указание NULL в описании типа снимает это ограничение и позволяет бесшовно передавать данные из объектной модели в табличную модель SQL.
Мы выяснили, что для создания колонки ТЗ с типом «Число и NULL» оптимально использовать прямой конструктор Новый ОписаниеТипов("Null, Число", ...). Это решение является наиболее компактным и полностью заменяет необходимость создавать временные запросы для «подглядывания» типа. Помните о квалификаторах точности, так как при ручном создании описания типов по умолчанию может установиться неограниченная длина, что не всегда эффективно для памяти и производительности базы данных.