Как исключить счет или услугу из отчета 1С 7.7, чтобы они не влияли на общие итоги?

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

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

Разберем подробно, почему возникает такая проблема и как правильно отфильтровать ненужные данные в коде отчета.

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

Проанализируем типовую структуру цикла обработки бухгалтерских итогов в 1С 7.7. Расчет числовых показателей и вывод строк в макет разнесены по разным блокам кода:

  1. Сначала считываются показатели из объекта БухгалтерскиеИтоги (дебетовые и кредитовые остатки, обороты).
  2. Затем значения суммируются в глобальные переменные итогов отчета (например, СальдоНачДИт, НачисленоИт).
  3. В самом конце вызывается метод Т.ВывестиСекцию("Строка").

Если мы просто ограничим вывод строки условием:


Если (Услуга.ПолныйКод <> "08/01") И (Услуга.ПолныйКод <> "08/02") Тогда
    Ном = Ном + 1;
    Т.ВывестиСекцию("Строка");
КонецЕсли;

Печатная форма действительно не покажет строки с этими кодами, но все суммы уже будут включены в переменные СальдоНачДИт, НачисленоИт и т. д. Рассмотрим правильные способы исключения позиций.

Способ 1. Пропуск итерации с помощью оператора Продолжить

Наиболее надежное и простое решение — перенести проверку в самое начало цикла обработки субконто или счета, до того, как начнутся любые математические операции и суммирование.

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


// Внутри цикла обхода субконто
Пока Ит.ПолучитьСубконто(2) = 1 Цикл
    Услуга = Ит.Субконто(2);
    
    // Проверяем исключаемые коды услуг
    Если (СокрЛП(Услуга.Код) = "08/01") 
        Или (СокрЛП(Услуга.Код) = "08/02") 
        Или (СокрЛП(Услуга.Код) = "08/03") Тогда
        Продолжить; // Пропускаем расчет и вывод строки
    КонецЕсли;

    // Далее выполняется расчет показателей
    Если Ит.СНД() > 0 Тогда
        СальдоНачД = Ит.СНД();
        СальдоНачДИт = СальдоНачДИт + Ит.СНД();
    КонецЕсли;
    
    Начислено = Ит.ДО();
    НачисленоИт = НачисленоИт + Начислено;
    
    Ном = Ном + 1;
    Т.ВывестиСекцию("Строка");
КонецЦикла;

Способ 2. Предварительная фильтрация через СписокЗначений

Если требуется исключить определенные значения аналитики еще на этапе выборки бухгалтерских итогов, можно воспользоваться передачей списка значений в метод ИспользоватьСубконто.

Разберем по шагам, как это реализовать:

  1. Создаем объект СписокЗначений.
  2. Заполняем его всеми разрешенными элементами справочника, исключая ненужные.
  3. Передаем список вторым параметром в метод ИспользоватьСубконто с типом фильтрации 2 (по списку).

СписокРазрешенныхУслуг = СоздатьОбъект("СписокЗначений");
СпрУслуг = СоздатьОбъект("Справочник.Услуги");
СпрУслуг.ВыбратьЭлементы();

Пока СпрУслуг.ПолучитьЭлемент() = 1 Цикл
    Если СпрУслуг.ЭтоГруппа() = 0 Тогда
        // Исключаем ненужные услуги
        Если (СокрЛП(СпрУслуг.Код) <> "08/01") 
            И (СокрЛП(СпрУслуг.Код) <> "08/02") 
            И (СокрЛП(СпрУслуг.Код) <> "08/03") Тогда
            СписокРазрешенныхУслуг.ДобавитьЗначение(СпрУслуг.ТекущийЭлемент());
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

// Настройка бухгалтерского запроса
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьСубконто(ВидыСубконто.Население, , 1);
Ит.ИспользоватьСубконто(ВидыСубконто.Услуга, СписокРазрешенныхУслуг, 2);
Ит.ВыполнитьЗапрос(Дата1, Дата2, "АБ", , , 3);

Этот метод исключает лишние данные на уровне выборки, что снижает объем обрабатываемой информации и ускоряет формирование отчета.

Способ 3. Фильтрация по корреспондирующему счету

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


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

    Если Ит.КорСчет = СчетПоКоду("ЛГ") Тогда
        Льгота = Льгота + Ит.КорКО();
        ЛьготаИт = ЛьготаИт + Ит.КорКО();
    КонецЕсли;
КонецЦикла;

Рекомендации по оптимизации проверок

  1. Используйте поиск объектов до цикла: вместо постоянного вызова СчетПоКоду("...") внутри вложенных циклов рекомендуется сохранить ссылку на счет в переменную до начала обработки данных (например, СчетКП = СчетПоКоду("КП");), после чего сравнивать ссылки.
  2. Учитывайте пробелы в строковых кодах: при сравнении кодов справочников всегда применяйте функцию СокрЛП(), чтобы избежать несовпадения из-за разной длины строк или лидирующих нулей.
← На главную