Как исправить ошибку «Поле объекта не обнаружена (ОрганизацияИНН)» при выгрузке данных в 1С?

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

При разработке механизмов обмена данными, особенно при выгрузке документов в формат XML, программисты часто сталкиваются с ошибкой «Поле объекта не обнаружена». Рассмотрим типичную ситуацию на примере выгрузки документа ПриобретениеУслугПрочихАктивов. Эта ошибка возникает в тот момент, когда код пытается обратиться к данным, которые не были получены из базы данных в ходе выполнения запроса.

Проанализируем причину возникновения ошибки

Разберем исходный код, представленный в вопросе. Проблема кроется в обращении к результату запроса внутри цикла Пока РезультатЗап.СледующийЦикл(). Программа пытается выполнить следующую строку:

ЗаписьXML.ЗаписатьАтрибут("ОрганизацииИНН",Строка(РезультатЗап.ОрганизацияИНН));

Выясним, почему 1С выдает ошибку. Переменная РезультатЗап является объектом типа ВыборкаИзРезультатаЗапроса. В отличие от ссылки на объект (например, ссылки на справочник или документ), выборка содержит только те поля, которые были явно перечислены в секции ВЫБРАТЬ текста запроса.

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

Решение №1: Добавление полей в текст запроса (Рекомендуемый способ)

Проанализируем самый правильный с точки зрения производительности метод решения проблемы. Нам необходимо изменить текст запроса так, чтобы система сразу извлекла ИНН из связанных справочников. Для этого мы используем обращение через точку прямо в тексте запроса. Это заставит СУБД выполнить соединение таблиц на уровне сервера.

Изменим фрагмент запроса следующим образом:


Запрос1.Текст="ВЫБРАТЬ
| ПриобретениеУслугПрочихАктивов.Ссылка КАК Ссылка,
| ПриобретениеУслугПрочихАктивов.Организация КАК Организация,
| ПриобретениеУслугПрочихАктивов.Организация.ИНН КАК ОрганизацияИНН,
| ПриобретениеУслугПрочихАктивов.Контрагент КАК Контрагент,
| ПриобретениеУслугПрочихАктивов.Контрагент.ИНН КАК КонтрагентИНН,
...

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

Решение №2: Обращение к реквизитам ссылки в цикле

Посмотрим на другой вариант, который предложили участники форума в сообщении №7. Если по какой-то причине вы не хотите менять текст запроса, вы можете обратиться к ИНН через уже полученную ссылку на организацию:


ЗаписьXML.ЗаписатьАтрибут("ОрганизацииИНН", Строка(РезультатЗап.Организация.ИНН));
ЗаписьXML.ЗаписатьАтрибут("КонтрагентИНН", Строка(РезультатЗап.Контрагент.ИНН));

Важное предупреждение: как верно подмечено в сообщении №8, такой подход считается «плохим тоном» в разработке на платформе 1С. Когда вы пишете РезультатЗап.Организация.ИНН внутри цикла, система для каждой строки результата выполняет отдельный неявный запрос к базе данных, чтобы получить значение ИНН. Если в вашей выборке будет 1000 документов, программа сделает 1000 лишних запросов, что значительно замедлит работу обработки.

Типичная ошибка с Контрагентом

Проанализируем ситуацию дальше. Как только вы исправите ошибку с ОрганизацияИНН, вы неизбежно столкнетесь с аналогичной проблемой для поля КонтрагентИНН. В современных конфигурациях (таких как ERP 2.5 или Управление торговлей 11) важно помнить о различии между Партнерами и Контрагентами.

  1. Партнеры — это управленческие сущности (группы компаний, холдинги). У них может не быть ИНН.
  2. Контрагенты — это юридические лица. ИНН хранится именно в этом справочнике.

Убедитесь, что в вашем документе заполнено именно поле Контрагент, прежде чем пытаться получить его ИНН, иначе вы рискуете получить пустое значение или ошибку при обращении к пустому объекту.

Дополнительные советы по качественному коду

Разберем еще несколько моментов, которые помогут сделать вашу выгрузку более стабильной:

1. Использование функции XMLСтрока

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

2. Проверка на NULL

При использовании левых соединений (или обращений через точку в запросе) значение реквизита может оказаться NULL, если объект не заполнен. В запросе полезно использовать функцию ЕСТЬNULL():


| ЕСТЬNULL(ПриобретениеУслугПрочихАктивов.Организация.ИНН, "") КАК ОрганизацияИНН

3. Режим записи документа

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

Итоги

Мы выяснили, что ошибка «Поле объекта не обнаружена» в контексте запроса всегда означает отсутствие колонки в результирующей таблице. Для исправления достаточно добавить нужное поле в секцию ВЫБРАТЬ вашего запроса, используя путь через точку от основной ссылки. Это обеспечит и работоспособность кода, и высокую скорость выполнения вашей обработки.

← На главную