Как правильно очистить ссылочный реквизит и сделать его пустым в 1С

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

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

Почему нельзя использовать пустую строку для очистки ссылки

Разберем типичную ошибку начинающих разработчиков: попытку присвоить ссылочному полю значение пустой строки "". Рассмотрим, почему конструкция Объект.Реквизит = "" является неверной. В системе 1С жесткая типизация. Реквизит типа СправочникСсылка ожидает на входе уникальный 16-байтовый идентификатор (GUID), в то время как "" — это строковый тип данных.

Проанализируем последствия такого присвоения:

  1. Несоответствие типов: Платформа может выдать ошибку при попытке присвоить значение другого типа, если включена строгая проверка.
  2. Непредсказуемое поведение: Даже если автоматическое преобразование типов сработает, это считается признаком «плохого кода», который сложно поддерживать.
  3. Проблемы в запросах: При проверке такого поля в запросе на равенство пустой ссылке, результат может быть ложным, так как в базе данных может оказаться некорректное значение.

Способ №1: Использование значения Неопределено

Самым универсальным и рекомендуемым способом очистки реквизита является использование системного значения Неопределено. Посмотрим, как это выглядит в коде:


// Правильная очистка реквизита через Неопределено
Объект.Контрагент = Неопределено;
Объект.Договор = Неопределено;

Рассмотрим подробнее, что происходит в этот момент. Если реквизит имеет одиночный тип (например, только СправочникСсылка.Номенклатура), платформа при записи объекта автоматически преобразует Неопределено в пустую ссылку данного типа. Это наиболее безопасный способ, так как он не требует от программиста указывать конкретный тип справочника.

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

Способ №2: Использование метода ПустаяСсылка()

Иногда логика бизнес-процесса требует, чтобы реквизит оставался «пустым», но при этом сохранял информацию о своем типе. Для этого используются методы менеджеров объектов. Рассмотрим на примере справочника Номенклатура:


// Присвоение конкретной пустой ссылки
Объект.Товар = Справочники.Номенклатура.ПустаяСсылка();

Проанализируем ситуацию, когда это необходимо. В составных типах данных (например, «Владелец», который может быть и Контрагентом, и Физическим лицом), присвоение Справочники.Контрагенты.ПустаяСсылка() скажет системе: «Здесь не выбран конкретный контрагент, но мы ожидаем именно контрагента».

Однако, как отметили участники обсуждения, в большинстве случаев для составных типов лучше использовать Неопределено. Если вы установите пустую ссылку конкретного типа в поле из 100 возможных типов документов, это может усложнить написание запросов, где придется проверять каждое конкретное пустое значение вместо одной проверки на НЕОПРЕДЕЛЕНО.

Правильная проверка на «пустоту» в коде

Выяснив, как устанавливать пустое значение, разберем, как его правильно проверять. Использование метода Объект.Реквизит.Пустая() имеет одну существенную опасность. Если в реквизите окажется значение Неопределено, вызов метода .Пустая() приведет к фатальной ошибке «Метод объекта не обнаружен».

Посмотрим на более надежный и универсальный способ проверки — функцию ЗначениеЗаполнено():


// Безопасная проверка любого типа реквизита
Если ЗначениеЗаполнено(Объект.Склад) Тогда
    // Выполняем действия, если склад выбран
Иначе
    // Действия, если поле пустое (пустая ссылка, Неопределено, NULL или 0)
    Сообщить("Склад не заполнен!");
КонецЕсли;

Эта функция является предпочтительной, так как она корректно обрабатывает все варианты «пустоты»:

Особенности работы в запросах

Проанализируем, как работать с очищенными полями внутри запросов 1С. Это важная часть, так как синтаксис здесь отличается от встроенного языка. Для проверки на пустую ссылку конкретного типа в запросе следует использовать конструкцию ЗНАЧЕНИЕ.

Разберем пример кода запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Реализация.Ссылка КАК Документ
    |ИЗ
    |   Документ.РеализацияТоваровУслуг КАК Реализация
    |ГДЕ
    |   Реализация.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)";

Если же мы работаем с составным типом и хотим найти записи, где поле было очищено через Неопределено, мы используем соответствующее ключевое слово:


Запрос.Текст = 
    "ВЫБРАТЬ
    |   Заказы.Ссылка
    |ИЗ
    |   Документ.ЗаказПокупателя КАК Заказы
    |ГДЕ
    |   Заказы.Проект = НЕОПРЕДЕЛЕНО";

Важный момент: никогда не используйте ЕСТЬ NULL для проверки обычных пустых реквизитов. NULL в 1С появляется только при выполнении соединений таблиц, когда в правой (или левой) таблице не найдена соответствующая запись. В обычных полях объекта NULL не хранится.

Хранение пустых ссылок в базе данных (SQL уровень)

Для глубокого понимания процесса заглянем «под капот» системы. На уровне SQL-сервера (будь то MS SQL или PostgreSQL) пустая ссылка представляет собой уникальный идентификатор, состоящий из одних нулей: 00000000-0000-0000-0000-000000000000.

Когда вы используете составной тип, платформа создает в таблице несколько физических колонок для одного реквизита 1С (например, колонку для типа и колонку для самого значения ссылки). Если вы используете Неопределено, система записывает в колонку типа специальный маркер отсутствия типа. Это позволяет базе данных работать быстрее при индексации и поиске, так как уменьшается количество «ложных» типизированных пустых ссылок.

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

Подведем итог нашему разбору. Правильная работа с очисткой данных — это залог стабильности вашей конфигурации.

Сформулируем основные правила:

  1. Для программной очистки реквизита в коде используйте Объект.Реквизит = Неопределено;. Это самый универсальный и безопасный путь.
  2. Никогда не пишите .Ссылка при очистке (например, Объект.Реквизит.Ссылка = ...). Это избыточно и может привести к ошибкам, так как свойство Ссылка у объектов обычно доступно только для чтения.
  3. Если вам нужно сохранить информацию о типе в составном поле, используйте Справочники.Имя.ПустаяСсылка().
  4. Для проверки, заполнено ли поле, всегда используйте ЗначениеЗаполнено() вместо сравнения с пустой ссылкой или вызова метода .Пустая().
  5. В запросах используйте ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) или НЕОПРЕДЕЛЕНО в зависимости от того, как поле было очищено и какой тип оно имеет.

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

← На главную