Почему в СКД неправильно отображаются остатки по счету на разные даты и как это исправить?

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

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

Причина расхождений: как работает оптимизатор СКД

Главная причина кроется в механизме Автозаполнения. Когда в схеме компоновки установлена эта галочка, СКД берет на себя управление параметрами &НачалоПериода и &КонецПериода. Проанализируем стандартную ошибку в тексте запроса:


ИЗ РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
    НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ), 
    КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ), 
    , , 
    {Счет.*}, , 
    {Субконто1.*}
) КАК ХозрасчетныйОстаткиИОбороты

Для компоновщика не имеет значения, что вы написали внутри круглых скобок преобразование НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ). Если включено автозаполнение, СКД просто подставит в эти поля значения из стандартных параметров периода, игнорируя ваши функции. В итоге вместо начала месяца отчет может сформироваться за одну секунду или за весь период существования базы, что и приводит к неверным остаткам.

Решение №1: Использование фигурных скобок для параметров

Чтобы «объяснить» компоновщику, как правильно интерпретировать даты, необходимо использовать расширение языка запросов — фигурные скобки. Посмотрим на правильный вариант написания параметров виртуальной таблицы:


ИЗ РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
    {НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ)}, 
    {КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)}, 
    , , 
    {(Счет В ИЕРАРХИИ (&СчетУчета))}, , 
    {(Субконто1 = &Контрагент)}
) КАК ХозрасчетныйОстаткиИОбороты

Разберем, что это дает: заключив выражение в {}, мы явно указываем оптимизатору компоновки, что это поле должно заполняться строго по нашему алгоритму. В этом случае СКД не будет подменять параметр &КонецПериода своим стандартным значением в обход функции НАЧАЛОПЕРИОДА.

Решение №2: Настройка ролей полей набора данных

Даже если запрос написан идеально, остатки могут суммироваться неправильно (например, Дт и Кт просто складываются как числа без учета активности счета), если не настроены Роли. Выясним, как их настроить правильно:

  1. Перейдем на закладку Наборы данных в СКД.
  2. Найдем поля остатков: СуммаКонечныйОстатокДт и СуммаКонечныйОстатокКт.
  3. В колонке Роль нажмем на кнопку редактирования.
  4. Для дебетового остатка укажем тип Остаток, выберем имя СуммаКонечныйОстаток и тип остатка Дебет.
  5. Для кредитового — тип Остаток, имя СуммаКонечныйОстаток и тип Кредит.
  6. Обязательно свяжем их с полем Счет и укажем признак Бухгалтерский.

Без этих настроек СКД не понимает, что перед ней бухгалтерские данные, и при группировке может выдать «раздутое» сальдо вместо корректного развернутого или свернутого остатка.

Решение №3: Управление через «Выражения» в параметрах

Самый надежный способ контролировать даты — это создать свой собственный параметр (например, &ПериодОтчета с типом СтандартныйПериод) и отключить доступность стандартных параметров для пользователя. Рассмотрим шаги:

  1. На вкладке Параметры найдем НачалоПериода и КонецПериода.
  2. Установим им галочку Ограничение доступности.
  3. В колонке Выражение для &НачалоПериода пропишем: &ПериодОтчета.ДатаНачала.
  4. Для &КонецПериода пропишем: &ПериодОтчета.ДатаОкончания.

Если нам нужно принудительно заставить отчет всегда брать начало года или месяца, мы можем использовать функции языка выражений СКД прямо в этой колонке, например: ДобавитьКДате(КонецПериода(&МойПараметрДата, "Месяц"), "Секунда", 1). Это гарантирует, что во все виртуальные таблицы запроса попадут именно те значения, которые мы рассчитали.

Важные нюансы при работе с «Границей»

Проанализируем ситуацию с временем 23:59:59. Бухгалтерские регистры чувствительны к моменту времени. Если передать в параметр просто дату конца дня, движения, сделанные в последнюю секунду, могут не попасть в остатки.

СКД при использовании стандартных параметров автоматически пытается создать объект Граница (включая указанный момент). Однако, если мы вручную модифицируем запрос, важно убедиться, что &КонецПериода включает конец дня. Для этого в коде или в выражении параметра используйте КОНЕЦПЕРИОДА(&Дата, "ДЕНЬ").

Таким образом, для получения верных остатков в СКД необходимо:

← На главную