Как исправить ошибку «Поле объекта не обнаружено (ВидыНоменклатурыСоздать)» в 1С:Управление торговлей 11?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

{ОбщийМодуль.ПодборТоваровСервер.Модуль(2865)}: Поле объекта не обнаружено (ВидыНоменклатурыСоздать) Форма.Элементы.ВидыНоменклатурыСоздать.Видимость = Ложь;

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

Выясняем причину: почему ломается типовой код?

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

В старых версиях платформы (когда в конфигурации или в расширении используется режим совместимости 8.3.10 и ниже) элементы стандартных команд динамического списка (кнопки «Создать», «Создать группу», «Изменить», «Скопировать») генерировались платформой в коллекции Элементы управляемой формы в любом случае. Даже если у текущего пользователя не было прав на добавление или изменение объектов этого списка (в данном случае — справочника Виды номенклатуры), кнопка на форме все равно существовала, пусть и была недоступна. Разработчики типовых конфигураций 1С использовали это поведение и писали прямой код для управления интерфейсом:

Форма.Элементы.ВидыНоменклатурыСоздать.Видимость = Ложь;

Начиная с версии платформы 8.3.11 (и особенно ярко это проявляется в 8.3.12 и выше при отключенном режиме совместимости), логика работы платформы стала более строгой и оптимизированной:

  1. Если у пользователя нет прав на добавление объектов динамического списка (например, роли на создание видов номенклатуры), платформа при генерации формы автоматически исключает стандартные команды создания и изменения из коллекции Элементы.
  2. Элемент формы с именем ВидыНоменклатурыСоздать физически не создается на сервере.
  3. Когда управление передается в общий модуль ПодборТоваровСервер, система пытается обратиться к несуществующему свойству коллекции по имени. В результате происходит закономерный отказ с ошибкой Поле объекта не обнаружено.

Почему ошибка появляется из-за расширения и не исчезает после его удаления?

Многие разработчики задаются вопросом: почему до подключения расширения все работало хорошо, ведь права пользователя не менялись? Дело в том, что при создании нового расширения платформа по умолчанию может выставить ему режим совместимости «Не использовать» или унаследовать актуальную версию платформы (например, 8.3.11/8.3.12), в то время как основная конфигурация УТ 11 все еще работает в режиме совместимости 8.3.10.

Как только в информационную базу загружается хотя бы одно активное расширение с более высоким режимом совместимости, платформа переводит сеанс работы пользователя на новые, более строгие правила компиляции форм. Отсюда и моментальное появление ошибки.

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

  1. Полностью очистить локальный кэш конфигурации на рабочем компьютере пользователя (удалив базу из списка и добавив ее заново, либо физически очистив папки в каталоге %userprofile%\AppData\Local\1C\1Cv8).
  2. Если база работает в клиент-серверном режиме, перезапустить службу сервера «1С:Предприятие» для сброса серверного кэша метаданных.
  3. Запустить сеанс пользователя с параметром командной строки /ClearCache.

Варианты решения проблемы

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

Решение 1. Использование безопасных методов БСП (Рекомендуемый путь)

В современных версиях Библиотеки Стандартных Подсистем (БСП) разработчики 1С отказались от прямого обращения к элементам формы по их имени. Вместо этого используется безопасный метод, который сначала проверяет физическое наличие элемента на форме, и только потом меняет его свойства.

Для того чтобы исправить ошибку по стандартам БСП, мы можем переопределить поведение системы с помощью расширения. Вместо строки прямого назначения видимости:

Форма.Элементы.ВидыНоменклатурыСоздать.Видимость = Ложь;

Необходимо использовать метод общего модуля:

ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Форма.Элементы, "ВидыНоменклатурыСоздать", "Видимость", Ложь);

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

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

&Вместо("УстановитьСтраницуВариантаНавигации")
Процедура Расш_УстановитьСтраницуВариантаНавигации(Форма, ВариантНавигации)
    
    // Вызываем оригинальный метод, предварительно подготовив элементы,
    // либо полностью переписываем логику инициализации кнопок
    ПродолжитьВызов(Форма, ВариантНавигации);
    
КонецПроцедуры

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


Если Форма.Элементы.Найти("ВидыНоменклатурыСоздать") <> Неопределено Тогда
    Форма.Элементы.ВидыНоменклатурыСоздать.Видимость = Ложь;
КонецЕсли;

Решение 2. Создание программных заглушек в расширении (Элегантный обход без изменения прав)

Если вы не хотите полностью переписывать типовой метод в общем модуле ПодборТоваровСервер, можно применить изящный прием. Мы можем перехватить событие ПриСозданииНаСервере у формы выбора или формы подбора номенклатуры и принудительно добавить недостающие кнопки-заглушки в коллекцию элементов формы, если платформа их не создала из-за отсутствия прав у пользователя. Штатный код УТ 11 найдет эти элементы, без ошибок установит им видимость в Ложь, и работа продолжится в обычном режиме.

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

  1. Добавим форму подбора номенклатуры в расширение.
  2. Создадим для нее обработчик &Перед("ПриСозданииНаСервере").
  3. Напишем код программного добавления кнопок-заглушек:

&НаСервере
&Перед("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервереПеред(Отказ, СтандартнаяОбработка)
    
    // Если у пользователя нет прав, платформа не создает стандартные кнопки.
    // Добавим их программно как заглушки, чтобы избежать падения типового кода.
    
    Если Элементы.Найти("ВидыНоменклатурыСоздать") = Неопределено Тогда
        Элементы.Добавить("ВидыНоменклатурыСоздать", Тип("КнопкаФормы"));
    КонецЕсли;
    
    Если Элементы.Найти("ВидыНоменклатурыСоздатьГруппу") = Неопределено Тогда
        Элементы.Добавить("ВидыНоменклатурыСоздатьГруппу", Тип("КнопкаФормы"));
    КонецЕсли;
    
    Если Элементы.Найти("ВидыНоменклатурыИзменить") = Неопределено Тогда
        Элементы.Добавить("ВидыНоменклатурыИзменить", Тип("КнопкаФормы"));
    КонецЕсли;
    
    Если Элементы.Найти("ВидыНоменклатурыСкопировать") = Неопределено Тогда
        Элементы.Добавить("ВидыНоменклатурыСкопировать", Тип("КнопкаФормы"));
    КонецЕсли;
    
КонецПроцедуры

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

Решение 3. Настройка типовых ролей пользователей (Административный путь)

Если программное вмешательство в код нежелательно, проблему можно решить чисто административными методами 1С, предоставив пользователю необходимые права на метаданные. Ошибка возникает из-за отсутствия прав на справочник Виды номенклатуры. Мы можем дать эти права пользователю тремя путями:

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

Решение 4. Контроль совместимости расширения

Самый простой способ избежать появления подобных «блох» при разработке собственных расширений — всегда следить за тем, чтобы свойства расширения полностью соответствовали свойствам основной конфигурации. Если ваша основная конфигурация УТ 11 использует режим совместимости 8.3.10, обязательно зайдите в свойства созданного расширения и установите аналогичный режим совместимости вместо значения «Не использовать».

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

← На главную