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

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

При получении данных из виртуальных таблиц регистров накопления разработчики нередко сталкиваются с ситуацией, когда запрос возвращает не все записи, хотя движения в регистре заведомо присутствуют. Особенно часто это проявляется при разработке отчетов в системе компоновки данных (СКД), когда кастомные параметры интервала начинают конфликтовать со стандартными механизмами платформы «1С:Предприятие».

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

Причина 1. Автозаполнение параметров в схеме компоновки данных (СКД)

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

Рассмотрим, как платформа преобразует исходный запрос. Если разработчик пишет следующее обращение:


ВЫБРАТЬ
    ПродажиОбороты.Контрагент КАК Контрагент
ИЗ
    РегистрНакопления.Продажи.Обороты(&НП, &КП, Запись, ) КАК ПродажиОбороты
СГРУППИРОВАТЬ ПО
    ПродажиОбороты.Контрагент

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


РегистрНакопления.Продажи.Обороты(&НП {&НачалоПериода}, &КП {&КонецПериода}, Запись, ) КАК ПродажиОбороты

В такой конструкции переданные вручную значения &НП и &КП учитываются только тогда, когда параметры &НачалоПериода и &КонецПериода не заполнены. Если в настройках отчета для стандартных параметров установлено значение по умолчанию (например, начало текущего года или текущий месяц), СКД полностью игнорирует параметры &НП и &КП. В результате в выборку попадают только записи за текущий год, а более ранние движения отсекаются.

Для устранения этой коллизии выберем один из следующих вариантов:

  1. Использовать стандартные параметры: отказаться от собственных параметров &НП и &КП, обратившись к таблице без них или напрямую используя стандартные имена &НачалоПериода и &КонецПериода.
  2. Явно зафиксировать параметры в расширении СКД: если требуются уникальные имена, их необходимо заключить в фигурные скобки: РегистрНакопления.Продажи.Обороты({&НП}, {&КП}, , ).
  3. Отключить автозаполнение: снять флажок Автозаполнение на вкладке «Компоновка данных» в конструкторе запроса и самостоятельно определить доступные поля и параметры отбора.

Причина 2. Ошибочное использование объекта «Граница» для таблицы оборотов

Еще одной распространенной ошибкой является передача в параметры виртуальной таблицы Обороты объекта Граница вместо обычной даты.

Объект Граница разработан для виртуальных таблиц остатков (или срезов регистров сведений), где принципиально важно указать, включать ли движения конкретной секунды или документа в момент расчета остатка. Для виртуальной таблицы Обороты правая граница периода всегда включается по условию «меньше либо равно». Передача объекта Граница в параметры таблицы оборотов может привести к ошибкам приведения типов или неожиданному сужению интервала.

Для корректного получения данных за период достаточно передавать дату окончания с применением функции КонецДня():


ПараметрКП = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(Новый ПараметрКомпоновкиДанных("КП"));
ПараметрКП.Значение = КонецДня(КП);
ПараметрКП.Использование = Истина;

Причина 3. Переопределение значений в пользовательских настройках

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

В этом случае передавать значения необходимо непосредственно в пользовательские настройки:


ИдентификаторКП = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(Новый ПараметрКомпоновкиДанных("КП")).ИдентификаторПользовательскойНастройки;
ПараметрПользователя = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдентификаторКП);

Если ПараметрПользователя <> Неопределено Тогда
    ПараметрПользователя.Значение = КонецДня(КП);
    ПараметрПользователя.Использование = Истина;
КонецЕсли;

Причина 4. Влияние периодичности «Запись» и нулевых итогов

В исходном запросе указана периодичность Запись: РегистрНакопления.Продажи.Обороты(&НП, &КП, Запись, ). Рассмотрим особенности этого режима:

  1. Периодичность Запись отключает использование рассчитанных таблиц итогов регистра и заставляет СУБД считывать фактические движения из физической таблицы регистра, что существенно снижает производительность. Если в полях выборки нет регистратора, периода или номера строки, этот параметр следует оставлять пустым.
  2. Виртуальная таблица оборотов исключает из результата строки, по которым суммарные обороты ресурсов свернулись в ноль (например, при наличии прихода и равного ему расхода/возврата). Если цель запроса — получить простой список контрагентов, по которым были любые действия за период, надежнее обратиться напрямую к физической таблице движений регистра:

ВЫБРАТЬ РАЗЛИЧНЫЕ
    Продажи.Контрагент КАК Контрагент
ИЗ
    РегистрНакопления.Продажи КАК Продажи
ГДЕ
    Продажи.Период МЕЖДУ &НП И &КП

Обращение к физической таблице гарантирует попадание контрагента в выборку даже при нулевом сальдо оборотов и исключает неоднозначность работы виртуальных механизмов.

← На главную