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