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