В практике разработки на платформе 1С:Предприятие 8 часто возникают задачи, когда стандартного поведения реквизитов недостаточно. Одной из таких задач является необходимость различать «пустую строку» и «отсутствие значения» (аналог NULL в SQL или Undefined в JavaScript) в обычном строковом поле табличной части. Рассмотрим подробнее, почему это нельзя сделать напрямую, и разберем проверенные способы решения этой задачи.
Для начала проанализируем ситуацию с точки зрения архитектуры платформы. В 1С существует три похожих, но принципиально разных понятия:
NULL нельзя присвоить реквизиту объекта. Он появляется только в результатах запросов (например, при левом соединении).Когда вы создаете реквизит типа Строка, платформа на уровне базы данных (MS SQL или PostgreSQL) помечает колонку как NOT NULL. Это означает, что физически в таблице всегда будет какая-то строка, даже если она пустая. Выясним, как обойти это ограничение.
Это самый «правильный» с точки зрения платформы способ. Если вам нужно иметь возможность записывать Неопределено, вы должны разрешить реквизиту принимать этот тип.
Рассмотрим по шагам:
Строка и добавьте любой другой ссылочный тип (например, какую-нибудь пустую ссылку) или просто оставьте возможность выбора нескольких типов.В этом случае в коде вы сможете написать:
Объект.Товары[0].Спецификация = Неопределено;
В запросах к такому полю вы сможете проверять его на Неопределено. Однако помните, что составной тип данных немного увеличивает размер базы и может снижать производительность при массовых операциях, так как в SQL создаются дополнительные служебные поля для хранения типа.
Если вы не хотите использовать составной тип (например, чтобы не усложнять структуру или не замедлять запросы), воспользуйтесь классическим паттерном. Суть его заключается в добавлении вспомогательного реквизита.
Разберем реализацию:
ЭтоПустоеЗначение (тип Булево).ЭтоПустоеЗначение = Истина.Проанализируем пример кода при обработке данных:
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если СтрокаТЧ.ЭтоПустоеЗначение Тогда
// Трактуем как NULL, даже если в поле Строка что-то написано
КонецЕсли;
КонецЦикла;
Это «быстрый», но опасный способ. Вы можете договориться, что если в поле записан текст "NULL", то программа считает это отсутствием значения. Посмотрим на пример работы с запросом в такой ситуации.
Чтобы в запросе получить реальный NULL из такой строки, используйте конструкцию ВЫБОР:
ВЫБРАТЬ
ВЫБОР
КОГДА Т.Реквизит = "NULL" ТОГДА NULL
ИНАЧЕ Т.Реквизит
КОНЕЦ КАК ОбработанныйРеквизит
ИЗ
Документ.ВашДокумент.ВашаТЧ КАК Т
Важно: Этот метод плох тем, что пользователь может случайно ввести слово "NULL" вручную, и система воспримет это как отсутствие данных. Также возникнут сложности при соединении таблиц напрямую без предварительной обработки вложенным запросом.
Иногда программисты используют символы, которые визуально не отличимы от пустой строки, но программно имеют другой код. Например, неразрывный пробел или специальные управляющие символы.
Рассмотрим алгоритм:
"" считается просто пустым значением.Символ(160) (неразрывный пробел) считается признаком NULL.Этот метод позволяет сохранить тип Строка и не добавлять лишних колонок, но он крайне труден в отладке, так как визуально в таблице обе строки будут выглядеть одинаково.
Если вам нужно хранить абсолютно любой тип данных в колонке (включая Неопределено, структуры или массивы), можно использовать тип ХранилищеЗначения.
Проанализируем особенности:
Подведем итог. Выбор метода зависит от ваших целей:
Неопределено).null.Помним, что попытка «обмануть» платформу и заставить строковое поле вести себя как NULL на уровне базы данных без изменения метаданных — это путь к трудноуловимым ошибкам в будущем.