Как правильно реализовать счетчики и расчет итогов в печатных формах 1С 8.2

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

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

Анализ типичной ошибки: почему счетчик работает неправильно

Разберем ситуацию, представленную в коде автора. В обработчике печати выполняется обход строк табличной части, и внутри цикла присутствуют условия, проверяющие тип строки (НомерСтрокиРаспечатки). Основная ошибка заключается в расположении инициализации переменной СчИтогТехОтхода = 0;.

Посмотрим на фрагмент кода, вызывающий проблему:


ИначеЕсли стртч.НомерСтрокиРаспечатки=2 Тогда 
    // ... логика заполнения параметров ...
    СчИтогТехОтхода = 0; // ОШИБКА: Обнуление происходит внутри цикла при каждом входе в условие
    Если стртч.ПрименяемостьТретийУровень > 0 Тогда 
        СчИтогТехОтхода = стртч.ПроцентТехОтхода + СчИтогТехОтхода;
        // ... вывод итогов ...
    КонецЕсли;

Проанализируем ситуацию: если мы хотим накопить сумму по нескольким строкам, мы должны обнулить переменную до начала процесса суммирования и прибавлять к ней значения внутри цикла. В приведенном примере при каждой итерации, где НомерСтрокиРаспечатки равен 2, программа сначала стирает всё, что было накоплено ранее, а затем записывает значение только текущей строки. В результате в «итог» попадает только последняя обработанная цифра.

Правильный алгоритм работы со счетчиками

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

  1. Инициализация: Перед началом цикла переменная-счетчик устанавливается в значение 0.
  2. Накопление: Внутри цикла к переменной прибавляется значение текущей строки.
  3. Вывод: Значение переменной передается в параметр макета только после того, как все нужные строки обработаны.

Рассмотрим исправленный пример логики накопления:


// 1. Инициализация итогов перед циклами
ОбщийИтог = 0;

Для Каждого СтрокаТЧ Из ТЧВедомость Цикл
    
    // Выполняем расчеты
    ТекущийПоказатель = СтрокаТЧ.ПроцентТехОтхода;
    
    // 2. Накопление суммы
    ОбщийИтог = ОбщийИтог + ТекущийПоказатель;
    
    // Заполняем область макета данными строки
    ОбластьСтрока.Параметры.Значение = ТекущийПоказатель;
    ТабДок.Вывести(ОбластьСтрока);
    
КонецЦикла;

// 3. Вывод итога после завершения цикла
ОбластьИтог.Параметры.ИтоговоеЗначение = ОбщийИтог;
ТабДок.Вывести(ОбластьИтог);

Использование запросов для расчета итогов

Профессиональным стандартом в 1С является перенос логики расчетов из программного кода на сторону языка запросов. Это значительно ускоряет работу программы и упрощает код формирования печатной формы. Вместо ручного перебора табличной части с условиями Если...Тогда, мы можем использовать конструкцию ИТОГИ СУММА(...) ПО....

Рассмотрим преимущества такого подхода:

Пример структуры кода при использовании запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Ведомость.Компонент,
    |   Ведомость.Количество КАК Кол
    |ИЗ
    |   Документ.Название.ТЧВедомость КАК Ведомость
    |ГДЕ
    |   Ведомость.Ссылка = &Ссылка
    |ИТОГИ
    |   СУММА(Кол)
    |ПО
    |   ОБЩИЕ";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
РезультатЗапроса = Запрос.Выполнить();

// Выводим общий итог из группировки "ОБЩИЕ"
ВыборкаОбщийИтог = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
ВыборкаОбщийИтог.Следующий(); // Переходим к итогам

// Теперь выводим детальные записи
ВыборкаДетали = ВыборкаОбщийИтог.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
    // Вывод строк макета
КонецЦикла;

// В конце выводим накопленный в запросе итог
ОбластьПодвал.Параметры.Всего = ВыборкаОбщийИтог.Кол;
ТабДок1.Вывести(ОбластьПодвал);

Расчет итогов по страницам через ПроверитьВывод

Выясним, как решать задачу, если нужно выводить «Итого на странице». Это специфическая задача, которую невозможно решить простым запросом, так как распределение по страницам зависит от настроек принтера и высоты строк.

В этом случае проанализируем метод ПроверитьВывод(). Логика работы должна быть следующей:

  1. Создаем переменную ИтогНаСтранице и обнуляем её.
  2. В цикле перед выводом строки макета вызываем ТабДок.ПроверитьВывод(МассивВыводимыхОбластей).
  3. Если метод возвращает Ложь (строка не влезает), выводим область «Итого на странице» с накопленным значением.
  4. Выводим ТабДок.ВывестиГоризонтальныйРазделительСтраниц().
  5. Обнуляем ИтогНаСтранице и продолжаем цикл.

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

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

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

Типизация данных: Убедитесь, что прибавляемые значения имеют числовой тип. Если в данных встретится NULL или Неопределено (например, при левом соединении в запросе), это может привести к ошибке или неверному результату. Рекомендуется использовать функцию Число() или метод ЕстьNull(Поле, 0) в запросе.

Области видимости: Если вы используете несколько областей макета (например, Элементы и Элементы1 как в исходном коде сообщения), следите за тем, в какую именно область передается параметр. Часто программисты обновляют значение в одной переменной, а в макет выводят другую область, где параметры остались старыми.

Метод ЗаполнитьЗначенияСвойств: Для сокращения кода и уменьшения вероятности опечаток в именах параметров, используйте ЗаполнитьЗначенияСвойств(ОбластьМакета.Параметры, СтруктураДанных или СтрокаТЧ). Это позволит автоматически сопоставить поля объекта 1С и именованные параметры в ячейках табличного документа.

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

← На главную