Как в 1С 7.7 добавить отбор по реквизиту субконто в отчет на бухгалтерских итогах?

Программист 1С v7.7 Бухгалтерский учет Промышленность, строительство и АПК
← На главную

При доработке типовых и самописных отчетов в платформе 1С:Предприятие 7.7, построенных на объекте БухгалтерскиеИтоги, разработчики часто сталкиваются с задачей добавления фильтра по дополнительному параметру. Типичная ситуация: отчет анализирует данные по счетам с субконто (например, справочник ВидыРабот), а пользователю требуется отфильтровать данные по определенному типу (значению перечисления ТипРабот).

Объект БухгалтерскиеИтоги не поддерживает обращение «через точку» к реквизитам субконто непосредственно в условиях выборки. Разберем правильные архитектурные подходы и готовые варианты реализации такого отбора.

Анализ структуры данных: реквизит или отдельное субконто?

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

  1. Отсутствие исторических данных: после добавления нового вида субконто на счет старые проводки останутся незаполненными. Чтобы фильтр заработал для прошлых периодов, потребуется полное перепроведение всех документов.
  2. Ограничение платформы 1С 7.7: на одном бухгалтерском счете по умолчанию поддерживается не более трех видов субконто.

Если нужный параметр (например, ТипРаботы) уже присутствует в качестве реквизита у существующего субконто (Справочник.ВидыРабот), менять план счетов не требуется. Достаточно применить программную фильтрацию.

Способ 1. Предварительный сбор элементов в СписокЗначений (рекомендуемый)

Рассмотрим основной и самый эффективный способ: перед выполнением запроса по бухгалтерским итогам мы выбираем из справочника только те элементы, у которых реквизит совпадает с выбранным пользователем значением, помещаем их в СписокЗначений и передаем в метод ИспользоватьСубконто.

Посмотрим на пример реализации с перебором справочника:


// Создаем список значений для передачи в метод отбора
СпВидовРабот = СоздатьОбъект("СписокЗначений");

Если ПустоеЗначение(ВыбТипРаботы) = 0 Тогда
    // Если фильтр на форме заполнен, отбираем подходящие элементы
    Спр = СоздатьОбъект("Справочник.ВидыРабот");
    Спр.ВыбратьЭлементы();
    Пока Спр.ПолучитьЭлемент() = 1 Цикл
        Если Спр.ЭтоГруппа() = 0 Тогда
            Если Спр.ТипРаботы = ВыбТипРаботы Тогда
                СпВидовРабот.ДобавитьЗначение(Спр.ТекущийЭлемент());
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    // Если нет ни одного подходящего элемента, прерываем выполнение
    Если СпВидовРабот.РазмерСписка() = 0 Тогда
        Предупреждение("Не найдено видов работ с выбранным типом!");
        Возврат;
    КонецЕсли;
КонецЕсли;

// Инициализация объекта бухгалтерских итогов
Ит = СоздатьОбъект("БухгалтерскиеИтоги");

// Настройка фильтрации по субконто
Если СпВидовРабот.РазмерСписка() > 0 Тогда
    // Передаем сформированный список значений (1 - детализация по каждому элементу)
    Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, СпВидовРабот, 1);
Иначе
    // Если фильтр не задан, выбираем все элементы
    Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, , 1);
КонецЕсли;

Ит.ВыполнитьЗапрос(ДатаНач, ДатаКон, ВыбСчет);

Разберем параметры метода ИспользоватьСубконто(ВидСубконто, Значение, ТипОтбора) при передаче списка:

  1. ТипОтбора = 1: разворачивать выборку по каждому элементу переданного списка (каждый вид работ будет получен отдельной строкой).
  2. ТипОтбора = 2: свернуть данные по переданному списку в единый суммарный итог без разбивки по конкретным элементам.

Важный нюанс производительности: если справочник содержит тысячи записей, полный перебор методом ВыбратьЭлементы() может выполняться медленно. Если для реквизита в конфигураторе включен признак «Отбор по реквизиту» или «Сортировка», оптимально применить быстрый метод Спр.ВыбратьЭлементыПоРеквизиту("ТипРаботы", ВыбТипРаботы).

Способ 2. Фильтрация при обходе результатов запроса

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

Посмотрим на пример кода:


Ит = СоздатьОбъект("БухгалтерскиеИтоги");
// Выбираем все субконто без предварительного фильтра
Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, , 1);
Ит.ВыполнитьЗапрос(ДатаНач, ДатаКон, ВыбСчет);

Ит.ВыбратьСубконто(1);
Пока Ит.ПолучитьСубконто(1) = 1 Цикл
    ТекВидРабот = Ит.Субконто(1);
    
    // Проверяем соответствие реквизита условию отбора
    Если ПустоеЗначение(ВыбТипРаботы) = 0 Тогда
        Если ТекВидРабот.ТипРаботы <> ВыбТипРаботы Тогда
            // Пропускаем строки, не удовлетворяющие фильтру
            Продолжить;
        КонецЕсли;
    КонецЕсли;
    
    // Вывод строки отчета в таблицу
    Таб.ВывестиСекцию("Строка");
КонецЦикла;

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

← На главную