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