Почему при записи справочника пропадает выбранное значение группы и как это исправить

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

В практике разработки на платформе «1С:Предприятие 8» программисты часто сталкиваются с ситуацией: в справочник добавляется новый реквизит, он выносится на форму, пользователь выбирает в нем значение (например, конкретную папку/группу), нажимает «Записать», и поле внезапно становится пустым. При этом отладчик может показывать, что в момент записи значение в поле еще есть, но после обновления объекта оно превращается в NULL или неопределено. Давайте подробно разберем, почему это происходит и как правильно настроить свойства метаданных для корректной работы иерархических справочников.

Анализируем корень проблемы: свойство «Использование»

Разберем типичную ситуацию. В иерархическом справочнике (где разрешены группы и элементы) каждый реквизит имеет специфическое свойство в дереве метаданных, которое называется Использование (Use). Это свойство определяет, для каких типов записей в таблице базы данных будет выделено место под этот реквизит.

Рассмотрим доступные варианты этого свойства:

  1. Для элемента: Реквизит будет существовать только у записей, которые не являются папками (ЭтоГруппа = Ложь).
  2. Для группы: Реквизит будет доступен только для групп (папок) справочника (ЭтоГруппа = Истина).
  3. Для группы и элемента: Универсальный режим, когда данные сохраняются для любого типа записи.

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

Как исправить настройку в конфигураторе

Для решения проблемы нам необходимо выполнить следующие шаги:

  1. Перейдем в конфигуратор и найдем нужный справочник.
  2. Откроем список его реквизитов и выберем тот, который не сохраняется.
  3. В палитре свойств найдем строку Использование.
  4. Если мы хотим, чтобы значение (ссылка на группу) хранилось внутри карточки элемента, необходимо изменить значение на Для элемента или Для группы и элемента.
  5. Обновим конфигурацию базы данных.

Важно понимать: Если вы выбираете в поле «Группу», это не значит, что сам реквизит должен иметь использование «Для группы». Использование определяет владельца реквизита (где он хранится), а не тип данных, которые в него записываются.

Настройка типа данных и ограничение выбора

Чтобы пользователь мог выбирать в это поле только группы (папки) и не мог выбрать конечные элементы, нам нужно настроить сам тип данных реквизита. Рассмотрим, как это сделать правильно:

Во-первых, в поле Тип должна быть указана ссылка на соответствующий справочник. Во-вторых, обратим внимание на свойство Выбор групп и элементов. Здесь мы можем жестко ограничить поведение интерфейса:

Для более тонкой настройки на уровне платформы можно использовать Параметры выбора. Проанализируем пример настройки отбора непосредственно в метаданных. В свойстве «Параметры выбора» можно добавить фиксированный отбор:

Отбор.ЭтоГруппа(Истина)

Это гарантирует, что даже если пользователь попытается обойти интерфейсные ограничения, система покажет ему только папки.

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

Иногда в коде (например, в общих модулях или подписках на события) нам нужно проверить, доступен ли конкретный реквизит для текущего объекта, чтобы избежать ошибок при записи. Мы можем сделать это через метаданные. Рассмотрим пример кода:


// Проверяем, можно ли записывать данные в реквизит для данного типа записи
ИмяРеквизита = "ВашРеквизит";
МетаданныеРеквизита = Объект.Метаданные().Реквизиты[ИмяРеквизита];

Если Объект.ЭтоГруппа Тогда
    Доступно = (МетаданныеРеквизита.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) 
               ИЛИ (МетаданныеРеквизита.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента);
Иначе
    Доступно = (МетаданныеРеквизита.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) 
               ИЛИ (МетаданныеРеквизита.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента);
КонецЕсли;

Если Доступно Тогда
    Объект[ИмяРеквизита] = ВыбранноеЗначениеГруппы;
КонецЕсли;

Почему значение становится NULL в базе данных

Выясним техническую причину появления NULL. На уровне СУБД (MS SQL, PostgreSQL) справочник представляет собой таблицу. Если в справочнике включена иерархия групп и элементов, платформа создает структуру, оптимизированную под хранение разных наборов данных. Когда реквизит помечен как «Только для групп», платформа при выполнении SQL-запроса UPDATE или INSERT для элемента просто не включает эту колонку в запрос или принудительно передает NULL, чтобы соблюсти целостность модели данных, описанной в метаданных.

Поэтому никакие манипуляции в форме (события ПриИзменении, ПередЗаписью на форме) не помогут, если свойство в конфигураторе настроено неверно. Платформа произведет очистку на уровне ядра перед самой фиксацией транзакции в базе данных.

Резюме и рекомендации

Подводя итог, если вы столкнулись с «исчезновением» данных в справочнике, пройдите по следующему чек-листу:

  1. Проверьте свойство Использование у реквизита в конфигураторе. Для хранения данных в карточке элемента оно должно быть Для элемента.
  2. Убедитесь, что ПутьКДанным элемента формы (поля ввода) точно указывает на нужный реквизит объекта.
  3. Проверьте, нет ли в модуле объекта в процедуре ПередЗаписью кода, который принудительно очищает это поле.
  4. Если используется расширение, убедитесь, что свойства реквизита в расширении совпадают с основной конфигурацией или перекрывают их корректно.

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

← На главную