При разработке отчетов и обработок в 1С программисты часто сталкиваются с ситуацией, когда запрос перестает возвращать данные после добавления фильтров по конкретным кодам справочников или планов счетов. В этой статье мы разберем основные ошибки, которые допускают разработчики при работе с методом НайтиПоКоду, проанализируем структуру бухгалтерских регистров и выясним, как правильно передавать параметры в виртуальные таблицы для обеспечения максимальной производительности.
Рассмотрим распространенную ситуацию, когда в коде установки параметров запроса допускается логическая опечатка. Проанализируем пример, предоставленный пользователем:
Запрос.УстановитьПараметр("Контрагент", Конрагент=Справочники.Контрагенты.НайтиПоКоду("000000022"));
Здесь кроется критическая ошибка. Вторым аргументом в метод УстановитьПараметр передается не результат поиска по коду, а результат логического сравнения. Если переменная Конрагент ранее была пустой, а поиск вернул ссылку, система вычислит выражение Ложь (или Истина в редких случаях) и передаст это булево значение в запрос. В итоге в тексте запроса условие Субконто2 = &Контрагент превращается в сравнение ссылки на справочник с логическим типом данных, что всегда приводит к пустому результату.
Чтобы исправить это, необходимо передавать в параметр только результат функции поиска:
// Правильный вариант
НайденныйСсылка = Справочники.Контрагенты.НайтиПоКоду("000000022");
Запрос.УстановитьПараметр("Контрагент", НайденныйСсылка);
При работе с планом счетов через ПланыСчетов.Хозрасчетный.НайтиПоКоду("27.02") важно понимать два момента. Во-первых, если вы работаете в типовой конфигурации (например, "Бухгалтерия предприятия"), счет 27 обычно не используется для расчетов с контрагентами, аналогично счету 62. Если счет создан вручную, необходимо убедиться, что его код точно соответствует строке "27.02" (включая разделители).
Во-вторых, обратите внимание на лидирующие нули в кодах контрагентов. Код "000000022" — это строка. Если в конфигураторе длина кода установлена, например, в 9 символов, а вы передадите 8 или 10, метод НайтиПоКоду вернет ПустуюСсылку. Всегда проверяйте результат поиска перед тем, как использовать его в запросе. Если поиск вернул ЗначениеЗаполнено(Ссылка) = Ложь, выполнение запроса может быть бессмысленным или привести к неверным итогам.
Одной из самых коварных ошибок при работе с виртуальной таблицей ОстаткиИОбороты является жесткая привязка к номерам субконто. В запросе автора мы видим:
ХозрасчетныйОстаткиИОбороты.Субконто1 КАК ДоговорКонтрагент
ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Контрагент
Проанализируем типовой план счетов. На счете 62.01 в большинстве редакций 1С первым субконто является "Контрагенты", а вторым — "Договоры". Если в вашем запросе вы пытаетесь сравнить Субконто2 с ссылкой на справочник "Контрагенты", а там фактически хранится ссылка на "Договоры контрагентов", запрос вернет пустой результат из-за несовпадения типов данных. Рекомендуется всегда проверять порядок видов субконто в конфигураторе или в режиме "1С:Предприятие" для конкретного счета.
В представленном запросе условие по контрагенту наложено в секции ГДЕ:
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(...) КАК ХозрасчетныйОстаткиИОбороты
ГДЕ
ХозрасчетныйОстаткиИОбороты.Субконто2 = &Контрагент
Это классическая ошибка производительности. При таком подходе система сначала выберет все остатки и обороты по всем контрагентам организации за указанный период, и только потом начнет отсеивать лишние строки. На больших базах это вызовет длительное ожидание или перегрузку сервера.
Рассмотрим, как сделать это правильно. Фильтрацию нужно накладывать в параметре Условие самой виртуальной таблицы. Для этого используется массив или фиксированный список видов субконто. Однако, если мы хотим оставить запрос простым, правильнее будет передать отбор в параметр Субконто или использовать общие фильтры. В случае с бухгалтерским регистром правильнее всего передать массив значений субконто в соответствующий параметр виртуальной таблицы.
Часто возникает задача найти данные не по одному, а по списку контрагентов. Использование конструкции ИЛИ в коде запроса неудобно и ограничивает гибкость. Выясним, как использовать оператор В:
СписокЗначений в коде 1С.В (&МассивКонтрагентов).Пример реализации:
СписокСсылок = Новый Массив;
СписокСсылок.Добавить(Справочники.Контрагенты.НайтиПоКоду("000000022"));
СписокСсылок.Добавить(Справочники.Контрагенты.НайтиПоКоду("000000025"));
Запрос.УстановитьПараметр("МассивКонтрагентов", СписокСсылок);
// В тексте запроса:
// ГДЕ ХозрасчетныйОстаткиИОбороты.Субконто1 В (&МассивКонтрагентов)
Если вам нужно обратиться к предопределенному счету или элементу, который точно не изменится, лучше избегать поиска по коду в коде модуля. Вместо передачи параметра Счет62 через НайтиПоКоду, используйте конструкцию ЗНАЧЕНИЕ прямо в тексте запроса:
Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПокупателями))
Это делает запрос более устойчивым к изменениям кодов в пользовательском режиме и упрощает чтение кода другими разработчиками.
Подводя итог, при возникновении проблемы "пустого запроса" при поиске по коду, пройдите по следующему чек-листу:
НайтиПоКоду вернул реальную ссылку, а не Неопределено или ПустаяСсылка.ГДЕ в параметры виртуальной таблицы для ускорения работы.Соблюдение этих правил позволит вам писать надежные и быстрые запросы, которые будут корректно обрабатывать данные даже в сложных иерархических структурах бухгалтерского учета.