Почему пустой результат у запроса к регистру в 1С 7.7 и как это исправить?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Рассмотрим частую проблему, с которой сталкиваются разработчики в 1С:Предприятие 7.7 при написании запросов к регистрам. Зачастую код выполняется без ошибок, транслятор сообщает об успешном выполнении, но результат оказывается пустым, и цикл обхода не инициируется. Разберем по шагам, почему так происходит и как правильно составить запрос, чтобы данные загружались корректно.

Проанализируем исходную ситуацию

Посмотрим на классический пример проблемного кода, который возвращает пустой результат:


ПЕРИОД С '01.10.20' ПО '31.12.20';
ОБРАБАТЫВАТЬДОКУМЕНТЫ ВСЕ;
Фирма = Регистр.ГТД.Фирма;
Товар = Регистр.ГТД.Товар;
ГТД = Регистр.ГТД.ГТД;
ОстатокТовара = Регистр.ГТД.ОстатокТовара;
ТекущийДокумент = Регистр.ГТД.ТекущийДокумент;
ГРУППИРОВКА ТекущийДокумент;

На первый взгляд, все нужные переменные объявлены, группировка задана, но при вызове метода обхода система не находит ни одной записи. Выясним причину такого поведения движка 1С 7.7 и исправим недочеты.

Шаг 1. Добавим обязательные агрегатные функции

Главная ошибка кроется во внутреннем механизме работы компилятора «черных запросов». В версии 1С 7.7, когда мы обращаемся к регистрам (как остатков, так и оборотов), система определяет физические таблицы для чтения исключительно на основании объявленных функций. Если в тексте запроса нет ни одной агрегатной функции, платформа считает, что вычислять нечего, и вообще не инициирует выборку данных из базы.

Добавим в текст запроса функцию расчета конечного остатка:

Функция КолКонОст = КонОст(ОстатокТовара);

Для регистров остатков также подойдут НачОст, Приход, Расход, а для оборотных регистров — Сумма.

Шаг 2. Настроим правильную группировку по документу

В исходном коде используется явное объявление переменной ТекущийДокумент = Регистр.ГТД.ТекущийДокумент;. Разберем, почему это излишне. В языке запросов 7.7 слово Документ является системным и зарезервированным. При обращении к регистру оно автоматически ссылается на документ-регистратор, который сделал движение. Упростим наш код, удалив объявление переменной и изменив саму группировку:

ГРУППИРОВКА Документ;

Шаг 3. Исключим инструкцию обработки документов

Проанализируем строку ОБРАБАТЫВАТЬДОКУМЕНТЫ ВСЕ;. Эта директива имеет смысл только тогда, когда базовым объектом выборки являются сами документы (например, при выборке элементов справочников или журналов документов). При работе с регистрами чтение всегда идет из таблиц движений, в которых физически хранятся только данные проведенных документов. Наличие этой директивы в запросе к регистру может замедлить работу или сбить логику транслятора. Рекомендуем её полностью удалить.

Шаг 4. Оптимизируем обращение к базе данных в цикле

Посмотрим на цикл обхода результата. Изначальный вариант выглядел так:

Сообщить(Запрос.ТекущийДокумент.ТекущийДокумент());

Метод ТекущийДокумент() в 1С 7.7 используется для явного позиционирования на объекте, и его вызов заставляет систему выполнять дополнительный (и довольно ресурсоемкий) SQL- или DBF-запрос к базе данных. Так как наша новая группировка называется Документ, системная переменная Запрос.Документ уже содержит готовую ссылку на документ. Ускорим обход, исключив лишние методы:


Пока Запрос.Группировка("Документ") = 1 Цикл
    Сообщить(Запрос.Документ);
КонецЦикла;

Итоговый рабочий код запроса

Соберем все наши улучшения и оптимизации воедино. Проанализируем итоговый правильный текст запроса к регистру:


ПЕРИОД С '01.10.20' ПО '31.12.20';
Фирма = Регистр.ГТД.Фирма;
Товар = Регистр.ГТД.Товар;
ГТД = Регистр.ГТД.ГТД;
ОстатокТовара = Регистр.ГТД.ОстатокТовара;

// Обязательная функция для инициализации выборки движком
Функция КолКонОст = КонОст(ОстатокТовара); 

// Системная группировка по регистратору без лишних переменных
ГРУППИРОВКА Документ;

С таким кодом платформа корректно обратится к физическим таблицам регистра, соберет данные об остатках и сгруппирует их по документам-регистраторам. Применяйте этот подход при разработке и доработке конфигураций в 1С 7.7, чтобы избегать ошибок пустых результатов и неоправданной нагрузки на базу данных.

← На главную