Почему Документы.СоздатьДокумент() выдает ошибку Поле объекта не обнаружено и как исправить конфликты имен в 1С

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

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

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

Разбор ситуации: Когда глобальное становится локальным

Рассмотрим типичный сценарий. Разработчик пишет код на сервере для создания документа «Комплектация номенклатуры»:


&НаСервере
Процедура СозданиеИЗаполнениеКомплектации(Организация, Номенклатура, Количество)
    НовыйДокумент = Документы.КомплектацияНоменклатуры.СоздатьДокумент();
    // Дальнейшее заполнение реквизитов...
КонецПроцедуры

Вместо создания объекта система выбрасывает исключение: «Поле объекта не обнаружено (КомплектацияНоменклатуры)». Первое подозрение падает на опечатку в названии документа или на проблемы с кэшем конфигуратора. Однако истинная причина часто кроется глубже — в иерархии пространств имен 1С.

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

  1. Локальные переменные внутри процедуры или функции.
  2. Параметры текущей процедуры или функции.
  3. Реквизиты формы (если код находится в модуле формы).
  4. Реквизиты и методы объекта (если это модуль объекта или форма объекта).
  5. Глобальные переменные и менеджеры (системные коллекции).

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

Как диагностировать перекрытие контекста через отладчик

Выясним причину ошибки с помощью инструментов отладки. Это самый надежный способ понять, что именно «видит» программа в момент исполнения кода. Выполним следующие шаги:

  1. Установим точку останова на строке, где происходит обращение к коллекции Документы.
  2. Запустим конфигурацию в режиме отладки и дойдем до исполнения этой строки.
  3. Вызовем окно «Табло» или нажмем Shift+F9 (Вычислить выражение).
  4. Введем слово Документы и нажмем Enter.

Проанализируем результат. Если тип значения — ДокументыМенеджер, то доступ к глобальному контексту открыт, и проблему нужно искать в правильности написания имени конкретного документа. Но если тип значения — ДанныеФормыКоллекция, ТаблицаЗначений или РеквизитФормы, значит, мы столкнулись с конфликтом имен. Глобальная коллекция перекрыта локальным объектом.

Решение проблемы: Исправление имен и обходные пути

Рассмотрим подробнее способы решения этой проблемы. Самый правильный и рекомендуемый метод — переименование конфликтующего объекта.

Если вы обнаружили, что в вашей обработке или форме реквизит (например, табличная часть или список) называется Документы, его следует переименовать в нечто более специфичное, например, СписокДокументов или ТаблицаПодбора. Это сразу вернет доступ к системному менеджеру Документы.

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

Важность контекста исполнения: Клиент и Сервер

Посмотрим на ситуацию под другим углом. Даже если конфликта имен нет, метод СоздатьДокумент() может не отрабатывать по причине неверного контекста. В управляемом приложении (УП) крайне важно различать, где выполняется код.

Объект Документы (менеджер всех документов) доступен только на сервере. Если вы попытаетесь вызвать Документы.КомплектацияНоменклатуры.СоздатьДокумент() в процедуре с директивой &НаКлиенте, система выдаст ошибку, так как на тонком клиенте типы менеджеров объектов не определены. На клиенте мы работаем только с данными (ДанныеФормыСтруктура), а не с самими объектами базы данных.

Правильная структура вызова должна выглядеть так:


&НаКлиенте
Процедура КомандаСоздать(Команда)
    СоздатьДокументНаСервере();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура СоздатьДокументНаСервере()
    НовыйОбъект = Документы.КомплектацияНоменклатуры.СоздатьДокумент();
    НовыйОбъект.Дата = ТекущаяДатаСеанса();
    НовыйОбъект.Записать();
КонецПроцедуры

Особенности документа «Комплектация номенклатуры» в Бухгалтерии 3.0

Проанализируем специфику конкретного документа, упоминаемого в проблеме. В конфигурации 1С:Бухгалтерия предприятия 3.0 документ КомплектацияНоменклатуры активно использует механизмы подсистемы БСП (Библиотека стандартных подсистем). При программном создании документа недостаточно просто вызвать СоздатьДокумент().

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

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


&НаСервере
Функция СоздатьКомплектациюНаСервере(ДанныеЗаполнения)
    Менеджер = Документы.КомплектацияНоменклатуры;
    НовыйДокумент = Менеджер.СоздатьДокумент();
    
    // Установка стандартных параметров
    НовыйДокумент.Дата = ТекущаяДатаСеанса();
    НовыйДокумент.Организация = ДанныеЗаполнения.Организация;
    
    // Вызов обработчика заполнения (если логика заложена в модуле объекта)
    НовыйДокумент.Заполнить(ДанныеЗаполнения);
    
    // Ручная установка счетов, если они не заполнились автоматически
    // ...
    
    НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
    Возврат НовыйДокумент.Ссылка;
КонецФункции

Рекомендации по предотвращению ошибок в будущем

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

Подводя итог, отметим: если ваш код Документы.Название.СоздатьДокумент() не работает, первым делом проверьте список реквизитов вашей формы. Скорее всего, там затаился объект с именем Документы, который мешает платформе обратиться к глобальному менеджеру. Устранение этого конфликта — залог корректной и предсказуемой работы системы.

← На главную