Как посчитать сумму по вычисляемой колонке справочника с отбором в 1С 7.7

Программист 1С v7.7 Управленческий учет IT и автоматизация бизнеса
← На главную

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

Почему в форме списка справочника 1С 7.7 не работает стандартный итог

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

  1. Порционная отрисовка строк: Платформа запрашивает из базы данных и отображает на экране только те записи, которые физически помещаются в видимую область таблицы. Если изменить высоту окна, количество вычисляемых строк изменится.
  2. Локальность формул в колонках: Формула текстовой колонки выполняется исключительно в момент прорисовки конкретной видимой строки. Платформа не выполняет эти выражения для элементов, которые находятся выше или ниже видимой области скролла.
  3. Отсутствие встроенного метода подсчета итога: Метод Итог() реализован только для табличных частей документов и объектов типа ТаблицаЗначений. Для списков справочников встроенной агрегации колонок не предусмотрено.

Рассмотрим рабочие способы решения этой задачи в зависимости от архитектурных требований.

Способ 1. Программный подсчет итога через перебор выборки

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

Разберем пример кода для модуля формы списка справочника:


Процедура ПересчитатьИтог()
    ВсегоСумма = 0;
    
    Спр = СоздатьОбъект("Справочник.Опоздания");
    
    // Если используется отбор по сотруднику (владельцу или реквизиту)
    Если ПустоеЗначение(ВыбСотрудник) = 0 Тогда
        Спр.ИспользоватьВладельца(ВыбСотрудник);
    КонецЕсли;
    
    Спр.ВыбратьЭлементы();
    Пока Спр.ПолучитьЭлемент() = 1 Цикл
        // Проверяем условия отбора, например период
        Если (Спр.ДатаОпоздания >= ВыбНачПериода) И (Спр.ДатаОпоздания <= ВыбКонПериода) Тогда
            СуммаСтроки = Спр.КоличествоМинут * Спр.Тариф;
            ВсегоСумма = ВсегоСумма + СуммаСтроки;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Вызов процедуры ПересчитатьИтог() необходимо привязать к ключевым событиям формы:

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

Способ 2. Расчет итоговой суммы с помощью объекта «Запрос»

Если справочник содержит большой объем данных, простой цикл ВыбратьЭлементы() может выполняться медленно. В таких случаях эффективнее использовать встроенный язык запросов 1С 7.7. Запрос агрегирует числовые данные на уровне движка базы.

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


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

Способ 3. Перенос интерфейса на форму с объектом «ТаблицаЗначений»

Если сотруднику требуется возможность интерактивно просматривать список, корректировать минуты и сразу видеть мгновенный пересчет общей суммы по документному принципу, наилучшим решением является создание специализированной обработки с элементом диалога ТаблицаЗначений.

Разберем по шагам, как устроен этот механизм:

  1. На форму обработки помещается элемент диалога типа ТаблицаЗначений с идентификатором ТЗ.
  2. При выборе сотрудника и периода таблица программно заполняется строками из справочника.
  3. Для колонок включается возможность редактирования прямо в строке таблицы.
  4. При изменении значений ячеек вызывается штатный метод ТЗ.Итог("СуммаШтрафа"), который моментально возвращает точную сумму по всем строкам таблицы без повторных обращений к базе данных.
  5. При нажатии кнопки «Сохранить» измененные строки записываются обратно в элементы справочника.

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


Процедура ПриИзмененииМинут()
    ТекСтр = ТЗ.ТекущаяСтрока();
    Если ТекСтр > 0 Тогда
        ТЗ.ПолучитьСтрокуПоНомеру(ТекСтр);
        ТЗ.СуммаШтрафа = ТЗ.КоличествоМинут * ТЗ.Тариф;
        // Мгновенный пересчет общего итога
        ИтогоШтраф = ТЗ.Итог("СуммаШтрафа");
    КонецЕсли;
КонецПроцедуры

Способ 4. Перенос данных в документы

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

  1. Автоматический подсчет итога по колонкам методом Итог("ИмяРеквизита").
  2. Проведение документа и отражение сумм в регистрах учета.
  3. Разграничение прав доступа на редактирование закрытых периодов.

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

← На главную