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