При доработке стандартных отчетов в платформе 1С:Предприятие 7.7 разработчики нередко сталкиваются с ситуацией, когда добавление нового поля через цепочку реквизитов приводит к аварийной остановке выполнения запроса с диагностическим сообщением вида: «Запрос : Неверно заданный путь 'ИмяРеквизита'».
Проанализируем ситуацию на конкретном примере, выясним архитектурные причины такого поведения встроенного языка запросов и разберем проверенные способы решения этой задачи.
Посмотрим на путь к данным, вызвавший сбой при формировании отчета:
Регистр.ПартииНаличие.ТекущийДокумент.Реализация.Контрагент.ЮрФизЛицо.ФактАдрес
На первый взгляд цепочка кажется логичной: от регистра через документ-регистратор мы переходим к контрагенту, затем к его юридическому или физическому лицу, а от него хотим получить фактический адрес. Однако транслятор запросов 1С 7.7 сообщает об ошибке на последнем элементе пути. Причина кроется в типизации реквизита ЮрФизЛицо в метаданных конфигурации (например, в конфигурации «Торговля и Склад 7.7»):
ЮрФизЛицо имеет базовый тип Справочник без жестко зафиксированного конкретного вида, так как может ссылаться либо на справочник ЮрЛица, либо на ФизЛица.ФактАдрес.Контрагент.ЮрФизЛицо.ФактАдрес в процедуре, платформа во время выполнения определит реальный вид справочника и вернет значение. Внутри самого текста запроса в секциях объявления переменных и группировок это поведение платформой не поддерживается.Поскольку получить группировку непосредственно в тексте запроса через нетипизированное поле невозможно, стандартным и наиболее надежным решением является выгрузка выборки в объект ТаблицаЗначений с последующим заполнением адреса и сворачиванием данных встроенными средствами встроенного языка.
Разберем по шагам, как переписать логику отчета:
ФактАдрес и группировку по ней. Оставляем группировку по строго типизированному объекту — Покупатель (или Контрагент), а также по номенклатуре.Выгрузить().ЮрФизЛицо.ФактАдрес через стандартный синтаксис языка 1С, где позднее связывание работает корректно.Свернуть() для получения итоговых группировок по адресу и номенклатуре с суммированием числовых показателей.Рассмотрим пример программной реализации:
Перем Запрос, ТЗ;
ТекстЗапроса = "
|Период с ДатаНачала по ДатаКонца;
|Фирма = Регистр.ПартииНаличие.Фирма;
|Номенклатура = Регистр.ПартииНаличие.Номенклатура;
|Покупатель = Регистр.ПартииНаличие.ТекущийДокумент.Реализация.Контрагент;
|Количество = Регистр.ПартииНаличие.Количество;
|Сумма = Регистр.ПартииНаличие.СуммаРуб;
|Функция РасходК = Расход(Количество);
|Функция РасходС = Расход(Сумма);
|Группировка Покупатель без групп;
|Группировка Номенклатура без групп;
|";
Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
ТЗ = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТЗ, 1, 0);
// Добавляем колонку для адреса
ТЗ.НоваяКолонка("ФактАдрес", "Строка");
// Заполняем адрес обычным обращением к объекту
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
Если ПустоеЗначение(ТЗ.Покупатель) = 0 Тогда
Если ТЗ.Покупатель.ЮрФизЛицо.Выбран() = 1 Тогда
ТЗ.ФактАдрес = СокрЛП(ТЗ.Покупатель.ЮрФизЛицо.ФактАдрес);
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Сворачиваем по требуемым группировкам отчета
ТЗ.Свернуть("ФактАдрес,Номенклатура", "РасходК,РасходС");
ТЗ.Сортировать("ФактАдрес+,Номенклатура+");
// Выводим данные в печатную форму
// ...
КонецЕсли;
Если конфигурация находится на поддержке с возможностью внесения изменений и отчет по адресам требуется строить регулярно с высокой скоростью, целесообразно оптимизировать сами метаданные:
Контрагенты строковый реквизит ФактАдрес.ПриЗаписи() справочника Контрагенты реализуем автоматическое копирование фактического адреса из связанного элемента ЮрФизЛицо.После этого путь в тексте запроса сокращается и становится однозначно типизированным:
ФактАдрес = Регистр.ПартииНаличие.ТекущийДокумент.Реализация.Контрагент.ФактАдрес;
Такая конструкция успешно компилируется встроенным генератором запросов 1С 7.7 и позволяет использовать поле ФактАдрес в секции Группировка без необходимости дополнительной постобработки в памяти.
Если информационная база работает под управлением MS SQL Server и в конфигурации подключен компонент прямого доступа (например, библиотека 1С++ через класс ODBCRecordset), ограничение платформы можно обойти на уровне базы данных:
Контрагенты, ЮрЛица и ФизЛица соединяются через операторы LEFT JOIN.