Как обеспечить неизменный состав свойств характеристик при смене категории номенклатуры в 1С:УНФ

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

В конфигурации 1С:Управление нашей фирмой (УНФ) механизмы работы с характеристиками тесно интегрированы с системой дополнительных реквизитов и сведений. Одной из часто встречающихся задач является необходимость стандартизировать состав свойств для всех характеристик, независимо от того, к какой категории относится номенклатура. По умолчанию система при смене категории в карточке товара автоматически перестраивает набор доступных свойств для характеристик, что может привести к ошибкам ввода данных пользователями.

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

Анализ стандартного механизма работы свойств

Для начала проанализируем, как 1С:УНФ определяет, какие именно поля (свойства) должен увидеть пользователь при создании новой характеристики. В основе лежит справочник НаборыДополнительныхРеквизитовИСведений. Каждый элемент этого справочника соответствует определенному объекту метаданных или его категории.

Когда мы открываем форму создания характеристики, система выполняет следующие действия:

  1. Определяет владельца характеристики (конкретная номенклатура или категория).
  2. Ищет соответствующий набор в справочнике НаборыДополнительныхРеквизитовИСведений.
  3. Если в номенклатуре указана КатегорияНоменклатуры, система обращается к реквизиту этой категории НаборСвойствХарактеристики.
  4. Если категория не заполнена, используется предопределенный или стандартный набор, часто называемый "Без категории" или "Общие".

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

Пользовательская настройка состава свойств

Прежде чем приступать к программной доработке, проанализируем возможности системы с точки зрения администратора. В 1С:УНФ существует понятие Общих свойств. Если вы хотите, чтобы определенное свойство (например, «Размер» или «Цвет») отображалось во всех категориях, его следует создавать как общее свойство в разделе «Дополнительные реквизиты».

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

Разбор программной реализации и поиск ошибки

Рассмотрим ситуацию, когда мы пытаемся программно подменить набор свойств. Часто разработчики пытаются найти нужный набор по наименованию. Рассмотрим пример кода, который на первый взгляд кажется верным, но может не работать:


// Попытка найти набор свойств для характеристик без привязки к категории
Строка.Набор = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("<Без категории>", Истина);

Проанализируем, почему этот код часто возвращает пустой результат или не тот объект, который ожидается. Справочник НаборыДополнительныхРеквизитовИСведений имеет иерархическую структуру. В нем могут существовать несколько элементов с названием <Без категории>. Один может относиться к самой номенклатуре, другой — к характеристикам, третий — к документам или контрагентам. Если мы используем поиск без указания родителя, система может вернуть первый попавшийся элемент, который не имеет отношения к характеристикам, и список свойств на форме останется пустым.

Правильный способ подмены набора свойств

Чтобы гарантированно получить нужный состав свойств, который соответствует «общим» характеристикам (тем, что отображаются, когда категория не выбрана), необходимо выполнять поиск с учетом иерархии. Выясним причину успеха: нам нужно сначала найти родительскую группу «Характеристики», а уже внутри неё искать элемент «<Без категории>».

Посмотрим на пример корректного кода:


// 1. Находим родительскую группу для всех наборов характеристик
РодительХарактеристики = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("Характеристики", Истина);

Если Не РодительХарактеристики.Пустая() Тогда
    // 2. Ищем конкретный набор внутри этой группы
    НужныйНабор = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("<Без категории>", Истина, РодительХарактеристики);
    
    Если Не НужныйНабор.Пустая() Тогда
        // Присваиваем найденный набор в структуру или реквизит формы
        Строка.Набор = НужныйНабор;
    КонецЕсли;
КонецЕсли;

Этот подход позволяет избежать путаницы между наборами свойств разных объектов. После того как мы определили правильный Набор, система БСП (Библиотека стандартных подсистем), на которой построена УНФ, автоматически подтянет все связанные с ним дополнительные реквизиты в таблицу свойств на форме.

Где именно вносить изменения?

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

  1. Общий модуль «УправлениеСвойствами» (или аналогичные в УНФ): Здесь часто находятся процедуры типа ЗаполнитьНаборыСвойствОбъекта.
  2. Форма элемента справочника «ХарактеристикиНоменклатуры»: В модуле формы в процедуре ПриСозданииНаСервере или в специализированных процедурах типа ТаблицаСвойствПриСозданииНаСервере.

Если мы хотим, чтобы состав свойств не менялся именно при указании категории в родительской номенклатуре, мы можем перехватить момент получения категории. Вместо использования значения из Объект.Владелец.КатегорияНоменклатуры, мы принудительно подставляем наш предопределенный набор «Без категории».

Рассмотрим пример модификации логики в обработчике:


&НаСервере
Процедура ПересчитатьСоставСвойствХарактеристики()
    // Вместо стандартного получения набора из категории номенклатуры:
    // Категория = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Номенклатура, "КатегорияНоменклатуры");
    
    // Мы принудительно устанавливаем общий набор
    РодительНаборов = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("Характеристики", Истина);
    ОбщийНабор = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("<Без категории>", Истина, РодительНаборов);
    
    // Далее передаем ОбщийНабор в механизмы отрисовки свойств БСП
    // ...
КонецПроцедуры

Важные замечания по сопровождению

При использовании поиска по наименованию "<Без категории>" стоит помнить, что в локализованных версиях или после ручного переименования групп пользователем этот код может перестать работать. Рассмотрим альтернативу — использование ссылок на предопределенные элементы, если они доступны в вашей версии конфигурации, или поиск по внутреннему идентификатору (UUID), если структура наборов свойств в вашей базе статична.

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

← На главную