Как правильно объединить остатки и обороты по регистратору в запросе 1С и исправить ошибки СКД

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов по накопительным регистрам часто возникает задача получить текущие остатки номенклатуры или подарочных сертификатов вместе с детальной историей движений в разрезе документов-регистраторов. Попытка решить эту задачу «в лоб» через объединение виртуальных таблиц или использование конструкций ИТОГИ ПО в СКД часто приводит к синтаксическим и логическим ошибкам.

В этой статье мы разберем основные ошибки, с которыми сталкиваются разработчики при построении таких запросов, и рассмотрим правильные варианты решения задачи.

Анализ распространенных ошибок разработчика

Разберем ошибки, которые часто возникают при попытке создать запрос для отчета:

  1. Ошибка «Ожидается выражение "ВЫБРАТЬ"» при открытии отчета в СКД.
    Данная ошибка возникает, если в тексте запроса набора данных СКД используется предложение ИТОГИ ПО. Система компоновки данных самостоятельно занимается рассчитыванием итогов по группировкам, поэтому использование секции ИТОГИ ПО внутри запросов для СКД недопустимо и вызывает сбой синтаксического анализатора. Также ошибка может возникать, если пакетный запрос заканчивается помещением данных во временную таблицу без финального оператора ВЫБРАТЬ.
  2. Ошибка конструктора запроса «Ожидается имя таблицы > СГРУППИРОВАТЬ ПО».
    Ошибка свидетельствует о синтаксических нарушениях в структуре запроса. Например, если при обращении к виртуальной таблице указана лишняя запятая (будто выбирается еще одна таблица) или если разработчик пытается обратиться к временной таблице в том же пакете запрос-секции, где она создается с помощью ПОМЕСТИТЬ, не разделив запросы точкой с запятой ;.
  3. Логическая ошибка с виртуальной таблицей ОстаткиИОбороты.
    Если в виртуальной таблице РегистрНакопления.ПодарочныеСертификаты.ОстаткиИОбороты установить периодичность Регистратор, то поля КоличествоКонечныйОстаток и КоличествоНачальныйОстаток рассчитываются на момент конкретного документа-регистратора. Условие ГДЕ КонечныйОстаток <> 0 исключит только те записи-движения, после выполнения которых остаток стал нулевым, но не скроет сам объект полностью, если по нему ранее были приходные или расходные документы.

Решение 1. Пакетный запрос с временной таблицей и левым соединением

Если задача заключается в том, чтобы вывести актуальный остаток только по тем позиции (например, штрихкодам сертификатов), у которых остаток существует на конец периода, и при этом развернуть их движения по документам, оптимальным решением будет использования двухпакетного запроса.

Разберем по шагам логику этого решения:

  1. Первым запросом выбираем конечные остатки из виртуальной таблицы Остатки и помещаем их во временную таблицу ОстаткиСертификатов.
  2. Ставим точку с запятой ; для завершения первого запроса пакета.
  3. Вторым запросом связываем через ЛЕВОЕ СОЕДИНЕНИЕ сформированную временную таблицу с виртуальной таблицей Обороты с периодичностью Регистратор.

Рассмотрим пример готового кода запроса для модуля:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|	ПодарочныеСертификатыОстатки.Штрихкод КАК Штрихкод,
|	ПодарочныеСертификатыОстатки.КоличествоОстаток КАК Остаток
|ПОМЕСТИТЬ ОстаткиСертификатов
|ИЗ
|	РегистрНакопления.ПодарочныеСертификаты.Остатки(&КонецПериода, ) КАК ПодарочныеСертификатыОстатки
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	ОстаткиСертификатов.Штрихкод КАК Штрихкод,
|	ОстаткиСертификатов.Остаток КАК Остаток,
|	ПодарочныеСертификатыОбороты.Регистратор КАК Регистратор,
|	ПодарочныеСертификатыОбороты.КоличествоПриход КАК КоличествоПриход,
|	ПодарочныеСертификатыОбороты.КоличествоРасход КАК КоличествоРасход
|ИЗ
|	ОстаткиСертификатов КАК ОстаткиСертификатов
|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПодарочныеСертификаты.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ) КАК ПодарочныеСертификатыОбороты
|		ПО ОстаткиСертификатов.Штрихкод = ПодарочныеСертификатыОбороты.Штрихкод";

Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);

РезультатЗапроса = Запрос.Выполнить();

Решение 2. Реализация отчета на Системе компоновки данных (СКД)

Если отчет разрабатывается в СКД, нет необходимости писать сложные соединения вручную или использовать секцию ИТОГИ ПО. СКД самостоятельно справляется с расчетом итогов и группировкой данных.

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

  1. В источнике данных пишем простой запрос к виртуальной таблице ОстаткиИОбороты с периодичностью Авто:
    
    ВЫБРАТЬ
    	ПодарочныеСертификатыОстаткиИОбороты.Штрихкод КАК Штрихкод,
    	ПодарочныеСертификатыОстаткиИОбороты.Регистратор КАК Регистратор,
    	ПодарочныеСертификатыОстаткиИОбороты.ПериодСекунда КАК ПериодСекунда,
    	ПодарочныеСертификатыОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
    	ПодарочныеСертификатыОстаткиИОбороты.КоличествоПриход КАК Приход,
    	ПодарочныеСертификатыОстаткиИОбороты.КоличествоРасход КАК Расход,
    	ПодарочныеСертификатыОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
    ИЗ
    	РегистрНакопления.ПодарочныеСертификаты.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК ПодарочныеСертификатыОстаткиИОбороты
    
  2. На вкладке «Ресурсы» отмечаем поля НачальныйОстаток, Приход, Расход и КонечныйОстаток. Для остаточных полей СКД автоматически назначит рассчитываемые роли по периодам.
  3. На вкладке «Настройки» создаем группировку верхнего уровня Штрихкод, а вложенной группировкой делаем Регистратор.
  4. Если необходимо скрыть позицию с нулевым конечным остатком, добавляем условие в настройки отбора отчета на вкладке «Отбор»: КонечныйОстаток Не Равно 0.

Рекомендации по отладке запросов

Для предотвращения ошибок при написании запросов рекомендуется соблюдать следующие правила:

← На главную