Как исключить счет 50.04 из самописного отчета в 1С:Бухгалтерия 8.3

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

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

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

Способ 1. Фильтрация на этапе формирования списка счетов в коде

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

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


// Подготовим список исключений
СписокИсключений = Новый СписокЗначений;
СписокИсключений.Добавить(ПланыСчетов.Хозрасчетный.НайтиПоКоду("50.04"));

// Получаем выборку по всему 50 счету
СчетаВыборка = ПланыСчетов.Хозрасчетный.ВыбратьИерархически(ПланыСчетов.Хозрасчетный.НайтиПоКоду("50"));

КорСчетаДляЗапроса = Новый СписокЗначений;

Пока СчетаВыборка.Следующий() Цикл
    // Проверим, не является ли текущий счет нашим исключением 50.04
    // или его подчиненным субсчетом
    Если СчетаВыборка.Ссылка = ПланыСчетов.Хозрасчетный.НайтиПоКоду("50.04") Тогда
        Продолжить; // Пропускаем сам счет
    КонецЕсли;
    
    // Более надежный метод - использование функции Принадлежит()
    Если СчетаВыборка.Ссылка.Принадлежит(ПланыСчетов.Хозрасчетный.НайтиПоКоду("50.04")) Тогда
        Продолжить; // Пропускаем все субсчета 50.04.1, 50.04.2 и т.д.
    КонецЕсли;
    
    КорСчетаДляЗапроса.Добавить(СчетаВыборка.Ссылка);
КонецЦикла;

Выясним причину, почему метод Принадлежит() предпочтительнее простого сравнения кодов. Строковое сравнение Код = "50.04" крайне хрупкое: если пользователь изменит код в режиме "Предприятие" или добавит субсчета, логика сломается. Метод Принадлежит() работает с объектными ссылками и учитывает всю иерархию плана счетов, что делает код устойчивым к изменениям данных.

Способ 2. Использование параметров виртуальной таблицы в запросе

Теперь рассмотрим более профессиональный и производительный метод — фильтрацию данных непосредственно внутри запроса. В 1С:Предприятие 8 работа с бухгалтерскими итогами ведется через виртуальные таблицы (например, Хозрасчетный.Обороты). Самая частая ошибка — накладывать фильтр в секции ГДЕ. Это заставляет систему сначала прочитать все данные, а потом отсеивать их.

Проанализируем, как правильно передать условия в параметры виртуальной таблицы. Это позволит СУБД выполнить фильтрацию на самом раннем этапе. Посмотрим на пример кода запроса:


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

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("НачПериода", ДатаНачала);
Запрос.УстановитьПараметр("КонПериода", ДатаКонца);
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.НайтиПоКоду("62")); // Пример
Запрос.УстановитьПараметр("КорСчета", КорСчетаДляЗапроса); 
Запрос.УстановитьПараметр("ИсключаемыйСчет", ПланыСчетов.Хозрасчетный.НайтиПоКоду("50.04"));

Обратите внимание на конструкцию НЕ КорСчет В ИЕРАРХИИ (&ИсключаемыйСчет). Оператор В ИЕРАРХИИ — это мощный инструмент, который автоматически включает в проверку не только указанный счет, но и все его вложенные субсчета любой глубины. Если мы просто напишем <> &ИсключаемыйСчет, то субсчета вида 50.04.1 все равно попадут в отчет.

Важные рекомендации по работе с планом счетов

Разберем несколько критически важных моментов, которые помогут избежать ошибок при разработке:

  1. Откажитесь от поиска по коду в теле запроса. Использование НайтиПоКоду("50.04") в коде допустимо, но лучше использовать предопределенные счета, если они созданы в конфигураторе. Например: ПланыСчетов.Хозрасчетный.Касса. Если счет 50.04 не является предопределенным, лучше вынести его выбор в настройки отчета или на форму, чтобы пользователь сам мог указать, что именно исключать.
  2. Проверка на пустые ссылки. Если вы передаете список исключений параметром, убедитесь, что счет действительно найден. Если НайтиПоКоду вернет ПустаяСсылка, запрос может отработать непредсказуемо или выдать ошибку.
  3. Использование СКД (Системы компоновки данных). Если ваш отчет строится на СКД, вам вообще не нужно писать код для исключения счета. Достаточно зайти в настройки отчета, открыть вкладку "Отбор" и добавить условие: Счет Кор. Не в иерархии 50.04. Это самый гибкий метод, который позволяет конечному пользователю управлять видимостью данных без помощи программиста.

Разбор типичной ошибки иерархии

Рассмотрим ситуацию из практики: разработчик пишет ГДЕ НЕ ХозрасчетныйОбороты.Счет В (&СписокИскл), но счет 50.04 всё равно выводится. Почему так происходит?

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

Посмотрим на пример правильного комбинированного фильтра в параметрах виртуальной таблицы:


// В параметрах Обороты:
// 4-й параметр: Условие на Счет
// 7-й параметр: Условие на КорСчет
// Пример исключения из КорСчета:
(КорСчет В (&Весь50Счет) И НЕ КорСчет В ИЕРАРХИИ (&Счет50_04))

Таким образом, мы гарантируем, что система сначала выберет все движения по кассе, а затем "вычтет" из них те, что относятся к специфическому субсчету 50.04. Сочетание программной подготовки списка счетов и грамотного использования параметров виртуальных таблиц запроса обеспечивает максимальную надежность и скорость работы вашего отчета в 1С:Бухгалтерии.

← На главную