При разработке и адаптации типовых конфигураций, таких как 1С:Управление торговлей 11, ERP 2 или Комплексная автоматизация, программисты часто сталкиваются с необходимостью расширения функционала справочника ХарактеристикиНоменклатуры. Одной из популярных задач является добавление собственного реквизита Артикул для характеристик. Однако после добавления реквизита в метаданные стандартный механизм «Помощник создания новых характеристик» может начать выдавать фатальную ошибку: «Поле объекта не обнаружено (Артикул)».
В этой статье мы подробно разберем, почему возникает эта ошибка, как работает внутренний механизм типовых форм и какими способами можно решить проблему, используя возможности платформы и механизм расширений.
Рассмотрим ситуацию глубже. В современных типовых решениях формы создания объектов часто строятся динамически или используют механизмы автоматической настройки видимости элементов. Когда мы добавляем новый реквизит Артикул в объект Справочник.ХарактеристикиНоменклатуры, система на уровне платформы обновляет состав метаданных. Многие общие модули и процедуры форм (например, при создании на сервере) выполняют обход реквизитов объекта.
Проанализируем цикл, на котором спотыкается система:
Для Каждого НастройкаРеквизита Из НастройкиВидимостиПоТипу Цикл
Элементы[НастройкаРеквизита.Ключ].Видимость = НастройкаРеквизита.Значение.Использование;
КонецЦикла;
Проблема заключается в том, что структура НастройкиВидимостиПоТипу формируется программно на основании доступных реквизитов справочника. Если вы добавили реквизит в метаданные, он автоматически попадает в эту структуру. Однако коллекция Элементы содержит только те элементы, которые физически (или программно) добавлены на форму. Поскольку мы «не трогали формы», как указано в описании проблемы, элемента с именем Артикул на форме помощника просто не существует. Программа пытается обратиться к Элементы["Артикул"], не находит его и выбрасывает исключение.
Если мы хотим быстро решить проблему, не перегружая форму визуально в конфигураторе, мы можем воспользоваться программным созданием элемента. Рассмотрим, как это сделать правильно с помощью расширения. Мы будем использовать обработчик ПриСозданииНаСервере формы помощника.
Выполним следующие шаги:
Разберем пример кода, который позволит нам «подсунуть» нужный элемент коллекции Элементы до того, как сработает основной цикл настройки видимости:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПеред(Отказ, СтандартнаяОбработка)
// Добавляем поле программно, чтобы оно появилось в коллекции Элементы
Поле = Элементы.Добавить("Артикул", Тип("ПолеФормы"), Элементы.Шапка);
Поле.ПутьКДанным = "Объект.Артикул";
Поле.Вид = ВидПоляФормы.ПолеВвода;
КонецПроцедуры
В данном примере мы добавляем поле в группу Шапка. Важно убедиться, что родительский элемент (в данном случае Элементы.Шапка) существует на форме помощника в вашей версии конфигурации. После выполнения этого кода цикл по настройке видимости найдет элемент Артикул и успешно установит ему свойство Видимость.
Рассмотрим более современный и «чистый» подход. Вместо написания кода для создания элементов, мы можем использовать визуальный редактор расширений. Это позволит избежать ошибок при обновлении конфигурации и сделает интерфейс более предсказуемым.
Выполним следующие действия:
Объект, а в нем наш новый реквизит Артикул.Артикул.Преимущество этого метода: нам вообще не нужно писать код. Так как элемент теперь физически присутствует на форме, типовой код Элементы[НастройкаРеквизита.Ключ] отработает корректно, найдя добавленное нами поле.
Если по какой-то причине мы не хотим выводить Артикул на форму помощника (например, он должен заполняться только в основной форме элемента или программно), нам нужно научить систему игнорировать этот реквизит при обходе элементов. Выясним, как это реализовать через перехват процедуры в расширении.
Проанализируем ситуацию: нам нужно изменить логику обхода коллекции. Если в форме используется цикл Для Каждого, мы можем применить конструкцию Продолжить. Посмотрим на пример модификации кода:
// В расширении модуля формы используем &Вместо или &После,
// в зависимости от того, где именно объявлен цикл.
Для Каждого НастройкаРеквизита Из НастройкиВидимостиПоТипу Цикл
Если НастройкаРеквизита.Ключ = "Артикул" Тогда
Продолжить; // Пропускаем реквизит, для которого нет элемента на форме
КонецЕсли;
// Безопасная проверка существования элемента перед обращением
ЭлементФормы = Элементы.Найти(НастройкаРеквизита.Ключ);
Если ЭлементФормы <> Неопределено Тогда
ЭлементФормы.Видимость = НастройкаРеквизита.Значение.Использование;
КонецЕсли;
КонецЦикла;
Помимо исправления ошибки в форме помощника, при добавлении реквизита Артикул в характеристики следует учесть еще несколько важных моментов, чтобы решение было полноценным:
1. Индексация данных. Чтобы поиск по артикулу характеристики в списках и подборах не приводил к деградации производительности базы данных, обязательно установите у реквизита Артикул свойство Индексировать. Это позволит SQL-серверу быстрее находить нужные записи.
2. Контроль уникальности. В отличие от стандартного артикула номенклатуры, артикул характеристики часто требует проверки на уникальность в разрезе владельца (номенклатуры). Мы рекомендуем добавить в модуль объекта справочника ХарактеристикиНоменклатуры (через расширение) обработчик ПередЗаписью:
&ПередЗаписью
Процедура Расш1_ПередЗаписью(Отказ)
Если ЗначениеЗаполнено(ЭтотОбъект.Артикул) Тогда
// Здесь можно реализовать запрос к базе для проверки,
// нет ли у этой же номенклатуры другой характеристики с таким же артикулом.
КонецЕсли;
КонецПроцедуры
3. Отображение в подборе. Помните, что добавление реквизита в объект не выводит его автоматически в форму подбора товаров. Чтобы пользователи могли искать товар по артикулу характеристики, вам потребуется расширить динамический список формы выбора или формы подбора, добавив туда колонку с вашим новым реквизитом.
Мы проанализировали проблему возникновения ошибки «Поле объекта не обнаружено» и выяснили, что она напрямую связана с динамической природой типовых форм 1С. Самым надежным и простым в сопровождении методом является визуальное добавление элемента на форму в расширении. Это полностью снимает конфликт с типовым кодом и не требует написания сложных программных перехватчиков. Если же интерфейс помощника должен оставаться неизменным, используйте программную фильтрацию в цикле настройки видимости.