Как исправить ошибку «Поле не найдено» при получении единицы измерения номенклатуры в печатной форме?

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

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

Анализ причины ошибки: Имя элемента vs Путь к данным

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

Выясним причину этой путаницы. В управляемых формах 1С имена элементов (колонок в таблице на форме) часто генерируются автоматически и выглядят как ТоварыНоменклатураЕдиницаИзмерения. Однако это лишь визуальный идентификатор элемента управления на форме. Он нужен для того, чтобы программно изменить цвет текста в колонке, скрыть её или заблокировать для редактирования.

Для получения же данных из базы необходимо использовать Путь к данным. В нашем случае данные «живут» внутри справочника «Номенклатура», ссылка на который хранится в строке табличной части. Таким образом, чтобы добраться до единицы измерения, нам нужно пройти по цепочке: СтрокаТЧ -> Номенклатура -> ЕдиницаИзмерения.

Решение проблемы через прямое обращение

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


Для Каждого Стр Из Ссылка.Товары Цикл
    ОбластьСтрока1.Параметры.ЕдИзм = Стр.Номенклатура.ЕдиницаИзмерения;
    ОбластьСтрока1.Параметры.Кол   = Стр.Количество;
    // Другие параметры...
    ТабДок.Вывести(ОбластьСтрока1);
КонецЦикла;

В данном примере Стр является объектом типа ЧисловаяСтрокаТабличнойЧасти. У этого объекта есть реквизит Номенклатура, который является ссылкой. Обращаясь через точку к Номенклатура.ЕдиницаИзмерения, мы заставляем систему считать данные из соответствующего справочника.

Проблема производительности: «Ловушка» обращения через точку

Хотя решение Стр.Номенклатура.ЕдиницаИзмерения является рабочим и часто используется в простых обработках, профессиональная разработка требует учета производительности. Рассмотрим подробнее, что происходит «под капотом» системы 1С.

Когда вы выполняете код Стр.Номенклатура.ЕдиницаИзмерения внутри цикла, платформа выполняет отдельный неявный SQL-запрос к базе данных на каждой итерации цикла. Если в вашем документе 100 строк с разной номенклатурой, система сделает 100 дополнительных обращений к серверу БД. Это значительно замедляет формирование печатной формы, особенно в клиент-серверном варианте работы или при медленном интернет-соединении.

Рассмотрим, как сделать правильно:

Для формирования качественной печатной формы данные лучше получать одним общим запросом. Это позволяет извлечь всю необходимую информацию (наименование, артикул, единицу измерения) за один «поход» в базу данных.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДокТовары.НомерСтроки КАК Номер,
    |	ДокТовары.Номенклатура.Наименование КАК ТоварНаименование,
    |	ДокТовары.Номенклатура.ЕдиницаИзмерения КАК ЕдИзм,
    |	ДокТовары.Количество КАК Количество
    |ИЗ
    |	Документ.РеализацияТоваровУслуг.Товары КАК ДокТовары
    |ГДЕ
    |	ДокТовары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    ОбластьСтрока1.Параметры.Заполнить(Выборка);
    ТабДок.Вывести(ОбластьСтрока1);
КонецЦикла;

Использование запроса исключает лишнюю нагрузку на сервер и является стандартом разработки в типовых конфигурациях (УТ 11, БП 3.0, ERP).

Работа с методом Заполнить() и именование параметров макета

В коде автора часто встречается метод Параметры.Заполнить(Стр). Разберем по шагам, как он работает. Этот метод берет все свойства переданного объекта (строки таблицы или выборки запроса) и ищет в макете параметры с точно такими же именами. Если имена совпадают, значение подставляется автоматически.

Если вы хотите, чтобы единица измерения заполнялась автоматически через Заполнить(), вам нужно в макете назвать параметр именно так, как называется поле в данных. Однако, если поле получается «через точку», автоматического сопоставления не произойдет, так как в структуре Стр (строки ТЧ) нет поля с именем НоменклатураЕдиницаИзмерения. Именно поэтому ручное присвоение ОбластьСтрока1.Параметры.ЕдИзм = ... становится необходимым, если вы не используете запрос с псевдонимами полей.

Использование отладчика для поиска точных имен

Выясним причину, по которой иногда трудно угадать название поля. В разных конфигурациях реквизит может называться по-разному. Например:

Чтобы не тратить время на гадание, воспользуемся отладчиком. Поставим точку останова (клавиша F9) на строке внутри цикла и запустим формирование печатной формы. Когда программа остановится:

  1. Нажмите Shift+F9 (Вычислить выражение).
  2. Введите переменную Стр.
  3. Нажмите «Показать в отдельном окне» (лупа).
  4. Разверните список свойств. Вы увидите все доступные реквизиты строки табличной части.
  5. Найдите Номенклатура, разверните её и посмотрите, как именно называется поле с единицей измерения.

Особенности единиц измерения в современных конфигурациях (ERP, УТ 11)

Проанализируем нюанс, который часто ставит в тупик новичков в конфигурациях на базе «1С:ERP» или «УТ 11». В этих системах понятие единицы измерения тесно связано с упаковками. В табличной части документа часто хранится ссылка на Упаковку. Если упаковка не задана, то товар отгружается в базовых единицах хранения.

Поэтому в коде для таких конфигураций часто можно встретить проверку:


Если ЗначениеЗаполнено(Стр.Упаковка) Тогда
    ОбластьСтрока1.Параметры.ЕдИзм = Стр.Упаковка.ЕдиницаИзмерения;
Иначе
    ОбластьСтрока1.Параметры.ЕдИзм = Стр.Номенклатура.ЕдиницаИзмерения;
КонецЕсли;

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

Итоги и рекомендации

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

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

← На главную