Как в строковом реквизите ТЧ документа хранить NULL или Неопределено

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С:Предприятие 8 часто возникают задачи, когда стандартного поведения реквизитов недостаточно. Одной из таких задач является необходимость различать «пустую строку» и «отсутствие значения» (аналог NULL в SQL или Undefined в JavaScript) в обычном строковом поле табличной части. Рассмотрим подробнее, почему это нельзя сделать напрямую, и разберем проверенные способы решения этой задачи.

Теоретическая база: почему в 1С нельзя просто записать NULL в строку

Для начала проанализируем ситуацию с точки зрения архитектуры платформы. В 1С существует три похожих, но принципиально разных понятия:

  1. Пустая строка ("") — это полноценное значение строкового типа длиной 0 символов.
  2. Неопределено — специальный тип данных, означающий, что значение еще не было установлено. В базе данных для простых типов (число, строка, булево) это значение не хранится.
  3. NULL — это состояние отсутствия данных в СУБД. В 1С NULL нельзя присвоить реквизиту объекта. Он появляется только в результатах запросов (например, при левом соединении).

Когда вы создаете реквизит типа Строка, платформа на уровне базы данных (MS SQL или PostgreSQL) помечает колонку как NOT NULL. Это означает, что физически в таблице всегда будет какая-то строка, даже если она пустая. Выясним, как обойти это ограничение.

Решение 1. Использование составного типа данных

Это самый «правильный» с точки зрения платформы способ. Если вам нужно иметь возможность записывать Неопределено, вы должны разрешить реквизиту принимать этот тип.

Рассмотрим по шагам:

  1. Откройте свойства реквизита табличной части.
  2. Нажмите на выбор типа и установите флажок Составной тип данных.
  3. В списке типов оставьте Строка и добавьте любой другой ссылочный тип (например, какую-нибудь пустую ссылку) или просто оставьте возможность выбора нескольких типов.

В этом случае в коде вы сможете написать:

Объект.Товары[0].Спецификация = Неопределено;

В запросах к такому полю вы сможете проверять его на Неопределено. Однако помните, что составной тип данных немного увеличивает размер базы и может снижать производительность при массовых операциях, так как в SQL создаются дополнительные служебные поля для хранения типа.

Решение 2. Паттерн Nullable (Булево-флаг)

Если вы не хотите использовать составной тип (например, чтобы не усложнять структуру или не замедлять запросы), воспользуйтесь классическим паттерном. Суть его заключается в добавлении вспомогательного реквизита.

Разберем реализацию:

  1. Добавьте в табличную часть реквизит ЭтоПустоеЗначение (тип Булево).
  2. При записи значения, если пользователь или алгоритм хочет установить «NULL», вы устанавливаете ЭтоПустоеЗначение = Истина.
  3. В логике программы (в формах или отчетах) вы проверяете этот флаг.

Проанализируем пример кода при обработке данных:


Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    Если СтрокаТЧ.ЭтоПустоеЗначение Тогда
        // Трактуем как NULL, даже если в поле Строка что-то написано
    КонецЕсли;
КонецЦикла;

Решение 3. Использование строковой константы "NULL"

Это «быстрый», но опасный способ. Вы можете договориться, что если в поле записан текст "NULL", то программа считает это отсутствием значения. Посмотрим на пример работы с запросом в такой ситуации.

Чтобы в запросе получить реальный NULL из такой строки, используйте конструкцию ВЫБОР:


ВЫБРАТЬ
    ВЫБОР 
        КОГДА Т.Реквизит = "NULL" ТОГДА NULL 
        ИНАЧЕ Т.Реквизит 
    КОНЕЦ КАК ОбработанныйРеквизит
ИЗ
    Документ.ВашДокумент.ВашаТЧ КАК Т

Важно: Этот метод плох тем, что пользователь может случайно ввести слово "NULL" вручную, и система воспримет это как отсутствие данных. Также возникнут сложности при соединении таблиц напрямую без предварительной обработки вложенным запросом.

Решение 4. Использование специфических символов (Unicode)

Иногда программисты используют символы, которые визуально не отличимы от пустой строки, но программно имеют другой код. Например, неразрывный пробел или специальные управляющие символы.

Рассмотрим алгоритм:

  1. Обычная пустая строка "" считается просто пустым значением.
  2. Символ с кодом Символ(160) (неразрывный пробел) считается признаком NULL.

Этот метод позволяет сохранить тип Строка и не добавлять лишних колонок, но он крайне труден в отладке, так как визуально в таблице обе строки будут выглядеть одинаково.

Решение 5. ХранилищеЗначения

Если вам нужно хранить абсолютно любой тип данных в колонке (включая Неопределено, структуры или массивы), можно использовать тип ХранилищеЗначения.

Проанализируем особенности:

Итоги и рекомендации

Подведем итог. Выбор метода зависит от ваших целей:

Помним, что попытка «обмануть» платформу и заставить строковое поле вести себя как NULL на уровне базы данных без изменения метаданных — это путь к трудноуловимым ошибкам в будущем.

← На главную