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