Расчет итогов по столбцам табличной части на форме с учетом отбора

09.07.24

Разработка - Работа с интерфейсом

Возникла потребность выводить итоги по столбцам в табличной части на форме. Есть стандартная функция "Итоги", но она не учитывает тот нюанс, что пользователь может делать  отбор по табличной части, и, в результате, может получиться так, что на форме мы видим три строки с количеством по 10 единиц, а в итоговой строке, какие-нибудь 9 575.... Неприятно... На просторах интернета есть статьи, описывающие решение подобной проблемы, но, в случае наличия нескольких табличных частей на форме, возникали проблемы, то он не то считает, то отбор сделал, а оно вообще не отреагировало, то выдало ошибку.

Немного отредактировал статью, и код, так как был дан хороший комментарий, и я решил, что надо бы сразу сделать, чтоб было красиво)))...

Чтобы пересчёт итогов реагировал на любое изменение на форме, я подвесил обработку на событие "ПриАктивизацииСтроки" для табличной части. Тогда у меня итоги пересчитывались как на отбор в самой табличной части, так и на внешние элементы. Например, у меня стояло на форме поле, где можно было выбрать отдельно номенклатуру, и по ней проводился отбор сразу во всех табличных частях на форме. А у на форме их было четыре.

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

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

&НаСервере
Процедура ОбновитьДанныеНаСервере()
     //заглушка для перечитывания элементов формы  
     //вызывается из процедур пересчёта итогов по таблицам, для обновления отображения итогов на форме.
     //без серверного вызова не происходит обновление отображения элементов на форме.
КонецПроцедуры 

&НаКлиенте
Процедура ТабличнаяЧасть1ПриАктивизацииСтроки(Элемент)    
    
    Если Элемент.Имя <> "ТабличнаяЧасть1" Тогда
        Возврат;
    КонецЕсли;         
    
    ИтогСтолбец1 = 0;
    ИтогСтолбец2 = 0;
    ИтогСтолбец3 = 0;
    ИтогСтолбец4 = 0;   
    
    Для Каждого СтрокаТЧ из ЭтотОбъект.ТабличнаяЧасть1 Цикл  
        
        ПроверкаНаличияСтроки = Элементы.ТабличнаяЧасть1.ПроверитьСтроку(СтрокаТЧ.ПолучитьИдентификатор());  
        
         // в случае невозможности провести проверку строки, может быть результат равен "Неопределено"    
         // поэтому необходимо делать явное указание сравнения, иначе возможна ошибка преобразования к булево

            Если ПроверкаНаличияСтроки = Истина Тогда
                ИтогСтолбец1  = ИтогСтолбец1 + СтрокаТЧ.Столбец1;  
                ИтогСтолбец2  = ИтогСтолбец2 + СтрокаТЧ.Столбец2;
                ИтогСтолбец3  = ИтогСтолбец3 + СтрокаТЧ.Столбец3; 
                ИтогСтолбец4  = ИтогСтолбец4 + СтрокаТЧ.Столбец4;
            КонецЕсли;    
        
    КонецЦикла;  
    
    Элементы.ТабличнаяЧасть1Столбец1.ТекстПодвала = ИтогСтолбец1;
    Элементы.ТабличнаяЧасть1Столбец2.ТекстПодвала = ИтогСтолбец2;
    Элементы.ТабличнаяЧасть1Столбец3.ТекстПодвала = ИтогСтолбец3;
    Элементы.ТабличнаяЧасть1Столбец4.ТекстПодвала = ИтогСтолбец4;

    ОбновитьДанныеНаСервере();
    
КонецПроцедуры 

 

На какие моменты обратить внимание:

Функция "ПроверитьСтроку" иногда может возвращать значение "Неопределено", и тогда, мы можем поймать ошибку преобразования в значение булево. Поэтому необходимо указать явное сравнение с булевым значением "Истина".

Обязательно в конце, после изменения заголовков элементов на форме, нужно сделать серверный вызов любой процедуры. Тогда после возвращения из этой процедуры 1С перечитает контекст формы и обновит её элементы. Без этого можно долго понимать, почему 1С не обновляет "Итоги". И, к сожалению, "ОбновитьОтображениеДанных()", здесь не работает, так как данный метод вызывает обновление только для тех полей, где есть данные (поля ввода), также проверяя необходимость их заполнения. А мы изменяем не данные, а отдельные элементы формы.

Это был мой опыт построения итогов в табличной части с учётом отборов.

Надеюсь, вам он тоже будет полезен.

Если у кого будут замечания и предложения по данной теме - буду рад услышать.

См. также

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    17553    24    6    

38

Работа с интерфейсом Программист Платформа 1С v8.3 Бесплатно (free)

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

27.05.2024    5280    smielka    37    

95

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    12232    785    elcoan    47    

110

Инструментарий разработчика Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

10.04.2023    10584    158    acces969    31    

120

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    4551    kalyaka    6    

32

Работа с интерфейсом Платформа 1С v8.3 Платные (руб)

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

6000 руб.

18.01.2022    9320    1    2    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. vandalsvq 1573 09.07.24 10:02 Сейчас в теме
Для начала, в коде есть две части с Если для ПроверкаНаличияСтроки. Сначала на <> Неопределено, потом на Истина (в неявном виде). Но можно написать в одну строку
Если ПроверкаНаличияСтроки = Истина Тогда
, в таком случае преобразования не будет происходить до типа булево, программа просто в лоб будет сравнивать как есть, и если там будет Ложь или Неопределено соответственно проверка не пройдет.

Объяснение: код
Если А Тогда
неявно указывает программе на необходимость преобразования А в тип Булево (если оно не такого типа). Код
Если А = Истина Тогда
к преобразованию не приводит, поскольку сравниваются простые типы.

Если создать реквизиты формы под соответствующие итоги колонок, а их указать как путь к данным подвала - то не понадобится делать вызов серверного метода. Я не проверял, но кажется должно быть так.

Сам расчет расположен в обработчике "ПриАктивизацииСтроки" поскольку нет возможности перехватить установленный отбор строк (пользовательский или программный)? Но стоит понимать, что при активизации строки будет срабатывать при зажатом Up/Down, то есть быстром перемещении по табличной части. В таком случае, логичнее проверять время между активизацией строки. Возможно сделать через подключаемый обработчик, тут нужны эксперементы.

В целом идея хорошая, хотя возможно и избыточная с точки зрения реализации (поскольку при каждой активизации пересчет происходит). При табличной части на пару сотен строк перемещение по ТЧ будет вызывать проблемы отклика программы. За идею поставлю 5, за реализацию 4, а вопрос необходимости каждый сам решит ))))
rozer; sifftsov; +2 Ответить
2. sifftsov 13 09.07.24 13:11 Сейчас в теме
(1) Спасибо огромное за комментарий! Действительно - работает! И не нужно лишней проверки на "Неопределено".)))
Да и код стал более читабельным.))) Самое смешное - была мысль так сделать, но поддался тому, что "А вдруг не заработает")))) Хотя никто не мешал сделать и проверить)))
Оставьте свое сообщение