Работа с большими запросами, содержащими десятки пакетов и временных таблиц, — это настоящий вызов даже для опытного разработчика. Когда запрос состоит, например, из 27 пакетов, а итоговая сумма (допустим, амортизация) считается неверно, легко запутаться в логических связях. В этой статье мы разберем методики и инструменты, которые помогут нам структурировать процесс анализа и найти ошибку.
Первым делом рассмотрим стандартный инструмент, доступный каждому разработчику, — консоль запросов с диска ИТС. Многие используют её только для написания простых выборок, но у неё есть мощный функционал для работы с пакетами.
Разберем, как просмотреть содержимое временных таблиц. Когда мы выполняем пакетный запрос в консоли, нас часто интересует не финальный результат, а промежуточные данные. В современных версиях консоли запросов для управляемых форм рядом с кнопкой Выполнить находится небольшая кнопка со стрелочкой. Если нажать на неё, можно выбрать режим выполнения, который позволит просмотреть содержимое каждой временной таблицы по отдельности. Это критически важно, так как ошибка в расчете амортизации может закрасться в самом начале — например, на этапе получения остатков или коэффициентов.
Если при запуске консоли вы получаете ошибку типа Метод объекта не обнаружен (Количество), это может свидетельствовать о несоответствии версии консоли вашей платформе. В таких случаях рекомендуем обновить консоль до актуальной версии или проверить настройки режима совместимости конфигурации.
Проанализируем более мощную альтернативу — консоль из состава Инструментов разработчика (автор TormozIT). Это, пожалуй, самый продвинутый инструмент для отладки сложных запросов в экосистеме 1С. Основные преимущества, которые нам помогут:
Рассмотрим ситуацию: если по одним контрагентам суммы верные, а по другим — нет, проблема, скорее всего, в данных или в особенностях соединений. Консоль ИР позволит быстро сравнить данные «хорошего» и «плохого» контрагента на каждом этапе выполнения пакетов.
Часто сложные запросы являются частью отчетов на СКД (Система компоновки данных). Отлаживать их напрямую в схеме бывает неудобно, так как СКД динамически модифицирует текст запроса (добавляет отборы, параметры, поля). Выясним, как получить реальный текст запроса, который уходит на сервер СУБД.
Для этого воспользуемся программным выводом в модуле объекта отчета. В процедуре ПриКомпоновкеРезультата мы можем перехватить макет компоновки. Рассмотрим пример кода, который поможет выгрузить итоговый запрос:
// В модуле отчета
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем настройки и компонуем макет
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
// В макете компоновки для наборов данных типа "Запрос" содержится итоговый текст
Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
ТекстЗапросаДляАнализа = НаборДанных.Запрос;
// Теперь этот текст можно скопировать в консоль запросов
ЗаписьЖурналаРегистрации("ОтладкаЗапроса", УровеньЖурналаРегистрации.Примечание, , , ТекстЗапросаДляАнализа);
КонецЕсли;
КонецЦикла;
// Далее идет стандартный вывод...
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Этот метод позволяет увидеть запрос именно в том виде, в котором его «видит» платформа после наложения всех пользовательских фильтров. Это часто открывает глаза на причину пустых строк или задвоения сумм.
Если инструментов недостаточно, применим метод аналитической декомпозиции. Разберем его по шагам:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ с пустой временной таблицей приведет к потере данных во всем последующем дереве запроса.СРЕЗПОСЛЕДНИХ или связь по дате.ЛЕВОЕ СОЕДИНЕНИЕ убедимся, что мы обрабатываем NULL значения функцией ЕСТЬNULL(Поле, 0), особенно если это поле участвует в арифметических операциях.Посмотрим на ситуацию со стороны предметной области. Если расчет неверный только по некоторым контрагентам, выясним следующее:
Во-первых, проверьте параметры виртуальных таблиц. Если в одном из пакетов используется РегистрБухгалтерии.Хозрасчетный.Остатки, убедитесь, что условия (отборы) переданы именно в параметры виртуальной таблицы, а не в секцию ГДЕ. Это не только ускоряет запрос, но и гарантирует корректность среза данных.
Во-вторых, обратите внимание на точность. В запросах 1С промежуточные вычисления могут терять точность, если происходит деление. Старайтесь выполнять умножение до деления, где это возможно.
В-третьих, проанализируйте связи в пакетах. Если пакет 27 соединяет данные из пакета 5 и пакета 26, пройдите по цепочке: гарантирует ли пакет 5 уникальность записей по ключу связи? Если нет, то итоговая сумма будет завышена кратно количеству дублей.
Мы рассмотрели несколько способов анализа гигантских запросов. Начинайте с продвинутых консолей (таких как ИР), которые умеют «препарировать» временные таблицы. Если отчет на СКД — используйте программную компоновку для получения финального текста. И помните: самый надежный способ — это последовательная проверка каждого пакета, начиная с первого. Постепенно отсекайте лишние данные, пока не найдете тот самый стык, где цифры перестают сходиться.