Почему запрос к остаткам по субконто в 1С возвращает пустой результат

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

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

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

Анализируем исходный код и параметры виртуальной таблицы

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйОстатки.Организация,
    |   ХозрасчетныйОстатки.Счет,
    |   ХозрасчетныйОстатки.СуммаОстатокДт,
    |   ХозрасчетныйОстатки.СуммаОстатокКт,
    |   ХозрасчетныйОстатки.Субконто1 КАК Субконто1,
    |   ХозрасчетныйОстатки.Субконто2 КАК Субконто2
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.Остатки(, , &СписокСубконто, ) КАК ХозрасчетныйОстатки";

СписокСубконто = Новый Массив;
СписокСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
СписокСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);

Запрос.УстановитьПараметр("СписокСубконто", СписокСубконто);
Результат = Запрос.Выполнить().Выгрузить();

Проанализируем параметры виртуальной таблицы Остатки. Согласно документации Синтаксис-помощника, параметры располагаются в следующем порядке:

  1. Период — дата, на которую получаются остатки.
  2. УсловиеСчета — фильтр по счету или группе счетов.
  3. Субконто — виды субконто (типы), по которым нужно получить разрез данных.
  4. Условие — произвольное условие на значения измерений или реквизитов.

В приведенном коде массив видов субконто передается в третий параметр. Это совершенно корректно с точки зрения платформы 1С. Этот параметр определяет, какие именно значения будут подставлены в поля Субконто1, Субконто2 и так далее, исходя из их порядка в массиве, а также накладывает фильтр на счета, у которых данные виды субконто определены в плане счетов.

Проблема версии платформы 8.3.12 и выше

Выясним причину, по которой код может перестать работать после обновления. Как показывает практика, в релизах платформы, начиная с 8.3.12.1412, был изменен внутренний механизм оптимизации запросов к виртуальным таблицам бухгалтерии. В некоторых случаях это привело к возникновению ошибки («бага»), когда использование массива в третьем параметре (Субконто) приводит к формированию некорректного SQL-запроса к базе данных.

Рассмотрим симптомы этой проблемы:

Проанализируем ситуацию: если платформа некорректно обрабатывает типизацию колонок при передаче массива, она может добавить в SQL-запрос заведомо ложное условие (например, WHERE 1=0), что и приводит к пустой выборке.

Решение №1: Использование альтернативной фильтрации в параметре «Условие»

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

Посмотрим на пример измененного запроса:


Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйОстатки.Организация,
    |   ХозрасчетныйОстатки.Счет,
    |   ХозрасчетныйОстатки.Субконто1,
    |   ХозрасчетныйОстатки.СуммаОстаток
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.Остатки(, , , 
    |       Субконто1 ССЫЛКА Справочник.Контрагенты 
    |       ИЛИ Субконто2 ССЫЛКА Справочник.ДоговорыКонтрагентов) КАК ХозрасчетныйОстатки";

Важный нюанс: при таком подходе мы оставляем третий параметр пустым. Это заставляет систему выбирать все доступные субконто, а затем фильтровать их. Это может быть чуть медленнее на огромных базах, но гарантирует получение результата.

Решение №2: Пересчет итогов и проверка актуальности данных

Иногда причина кроется не в коде, а в состоянии базы данных. Посмотрим, какие технические действия могут помочь:

  1. Полный пересчет итогов. Через меню "Операции" — "Управление итогами" необходимо убедиться, что итоги рассчитаны по текущую дату. Иногда помогает полное отключение и повторное включение итогов.
  2. Тестирование и исправление. Выполнение процедуры «Реиндексация таблиц информационной базы» и «Пересчет итогов» в конфигураторе часто решает проблемы с виртуальными таблицами.
  3. Очистка кэша. Рекомендуется очистить локальный кэш пользователя, так как старые определения типов могут кэшироваться платформой.

Решение №3: Явное указание счета

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

Попробуем добавить явный фильтр по счету (например, 60 или 62), где эти субконто точно есть:


Запрос.Текст = 
    "ВЫБРАТЬ ...
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.Остатки(, Счет В ИЕРАРХИИ (&СчетаРасчетов), &СписокСубконто, ) КАК ХозрасчетныйОстатки";

СписокСчетов = Новый Массив;
СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПоставщиками);
СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПокупателями);
Запрос.УстановитьПараметр("СчетаРасчетов", СписокСчетов);

В большинстве случаев явное указание счета "подсказывает" оптимизатору платформы правильный путь к данным и устраняет проблему пустого результата.

Подведем итоги

Если ваш запрос к остаткам возвращает пустую таблицу значений:

Соблюдение этих рекомендаций позволит вам писать отказоустойчивый код, который будет работать корректно вне зависимости от обновлений платформы 1С.

← На главную