При внедрении новых реквизитов, таких как ИКПУ (Идентификационный код продукции и услуг), в классические конфигурации на платформе 1С 7.7, разработчики часто сталкиваются с техническими сложностями при попытке извлечь эти данные из учетных механизмов. Одной из самых распространенных ошибок является попытка обращения к атрибутам объекта через числовые значения остатков в бухгалтерских итогах.
В этой статье мы подробно разберем, почему возникает ошибка Поле агрегатного объекта не обнаружено, проанализируем разницу между методами получения данных и научимся правильно работать с периодическими реквизитами справочников внутри циклов бухгалтерских отчетов.
Рассмотрим ситуацию: вы создали справочник ИКПУ и добавили периодический реквизит КодИКПУ в справочник Номенклатура. При попытке заполнить документ реализации по одной позиции программный код выдает ошибку. Проанализируем проблемный участок кода:
Остаток = Ит.СНД(3);
КодИКПУ = Ит.СНД(3).КодИКПУ.Получить(ДатаДок);
Выясним причину сбоя. В платформе 1С 7.7 метод СНД(3) (Сальдо Начальное Дебетовое по количеству) возвращает значение типа Число. У переменной числового типа не может быть никаких дополнительных свойств или реквизитов вроде КодИКПУ или ШтрихКод. Когда система встречает точку после вызова метода, возвращающего число, она закономерно сообщает, что поле агрегатного объекта не обнаружено.
Для того чтобы получить доступ к реквизитам товара (номенклатуры), нам нужно обратиться непосредственно к объекту субконто, который был выбран в запросе бухгалтерских итогов.
Рассмотрим, как правильно организовать выборку данных, чтобы иметь возможность обращаться к свойствам справочника. При использовании фильтра по конкретному значению (например, когда мы выбираем один товар в накладной), структура обхода итогов меняется.
Если в методе ИспользоватьСубконто вы указали конкретное значение:
Ит.ИспользоватьСубконто(ВидСубконто, Товар, 2);
То внутри цикла по счетам обращаться к этому товару и его реквизитам следует через метод Субконто(), указывая номер фильтра. Посмотрим на исправленный фрагмент кода:
Ит.ВыбратьСчета();
Пока Ит.ПолучитьСчет() = 1 Цикл
Если Ит.СКД(3) > 0 Тогда
// Получаем ссылку на элемент справочника Номенклатура
ТекТовар = Ит.Субконто(1);
// Теперь мы можем обращаться к его реквизитам
// Поскольку КодИКПУ - периодический, используем Получить()
КодИКПУ = ТекТовар.КодИКПУ.Получить(ДатаДок);
Остаток = Ит.СКД(3);
Себестоимость = Ит.СКД(1) / Остаток;
КонецЕсли;
КонецЦикла;
Внедрение ИКПУ (особенно актуально для Узбекистана) требует соблюдения ряда технических условий, которые важно учитывать при написании кода:
Получить(Дата) всегда требует передачи даты. Если на указанную дату значение не задано, 1С вернет пустое значение или значение на ближайшую прошлую дату (в зависимости от настроек).ИКПУ хранить также и код единицы измерения (например, 251 для "штук"), чтобы автоматизировать выгрузку на портал.Почему у автора темы код работал при "заполнении всех остатков", но падал при выборе одной позиции? Разберем по шагам:
При массовом заполнении обычно используется полный обход субконто:
Ит.ВыбратьСубконто(1);
Пока Ит.ПолучитьСубконто(1) = 1 Цикл
Товар = Ит.Субконто(1); // Здесь Товар - это объект, всё работает
КонецЦикла;
При выборе одного товара программисты часто забывают вызвать ПолучитьСубконто() или пытаются сократить код, ошибочно подставляя обращение к реквизиту после метода получения суммы или количества (как в примере Ит.СКД(3).КодИКПУ). Запомните: функции остатков возвращают числа, а функции субконто — ссылки на объекты.
Для повышения стабильности работы программы при внедрении ИКПУ проанализируем следующие советы:
Проверка на пустые значения: Перед тем как присваивать значение ИКПУ в документе, полезно добавить проверку, чтобы избежать вывода пустых строк в печатных формах или при выгрузке в XML.
ТекНоменклатура = Ит.Субконто(1);
ЗначениеИКПУ = ТекНоменклатура.КодИКПУ.Получить(ДатаДок);
Если ПустоеЗначение(ЗначениеИКПУ) = 1 Тогда
Сообщить("Внимание: Для товара " + ТекНоменклатура.Наименование + " не заполнен код ИКПУ!");
КонецЕсли;
Использование глобальных функций: Если получение ИКПУ требуется во многих документах (Счет-фактура, Расходная накладная, Возврат), лучше вынести этот код в глобальный модуль. Это позволит централизованно управлять логикой получения кода, например, если требования законодательства изменятся и ИКПУ перестанет быть периодическим.
Мы выяснили, что ошибка Поле агрегатного объекта не обнаружено в контексте бухгалтерских итогов — это всегда сигнал о неправильной типизации. Никогда не пытайтесь получить атрибуты справочника от результата функций СНД(), СКД(), ОБ(). Всегда используйте метод Субконто() для получения ссылки на элемент справочника и только затем обращайтесь к его периодическим или обычным реквизитам.
Правильный подход к разработке под 1С 7.7 обеспечит корректную выгрузку данных в современные системы налогового учета и избавит пользователей от внезапных завершений работы программы при выборе товаров в документах.