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

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 Платные (руб)

Богатый редактор картинок 1С предназначен для обработки изображений в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    62998    44    59    

82

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 Платные (руб)

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

2400 руб.

29.06.2020    18866    26    6    

41

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

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

1500 руб.

06.10.2020    10239    7    7    

10

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

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

20.08.2024    16887    mrXoxot    43    

121

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

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

27.05.2024    7423    smielka    37    

100

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

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

27.12.2023    14825    919    elcoan    47    

117

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

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

2 стартмани

10.04.2023    11923    162    acces969    31    

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

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

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

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

В целом идея хорошая, хотя возможно и избыточная с точки зрения реализации (поскольку при каждой активизации пересчет происходит). При табличной части на пару сотен строк перемещение по ТЧ будет вызывать проблемы отклика программы. За идею поставлю 5, за реализацию 4, а вопрос необходимости каждый сам решит ))))
cleaner_it; Award; rozer; sifftsov; +4 Ответить
2. sifftsov 25 09.07.24 13:11 Сейчас в теме
(1) Спасибо огромное за комментарий! Действительно - работает! И не нужно лишней проверки на "Неопределено".)))
Да и код стал более читабельным.))) Самое смешное - была мысль так сделать, но поддался тому, что "А вдруг не заработает")))) Хотя никто не мешал сделать и проверить)))
3. user1202750 13.07.24 12:18 Сейчас в теме
Недавно сам делал такое, и тоже создал отдельно реквизиты итогов на форме и просто пересчитывал их, всё на самом деле просто
4. KennyHoD 14.07.24 17:56 Сейчас в теме
1) Если найти (CTRL+F) по значению как в уже активной строке, то активная строка не изменится и пересчет не будет вызван. (в 8.3.23.2040)
Чтобы решить похожую задачу вызывал расчет итогов видимых строк через обработчик ожидания.
Это добавило сложностей:
-Проверка "Форма.ВводДоступен()" чтобы не пересчитывать если форма не активна.
-Пересчет выполнять только для таблиц на активной странице формы.
-В случае большого количества строк в таблице менял периодичность выполнения обработки ожидания, в зависимости от количества строк. На 5000 строк +1 секунда между вызовами.
Работает приемлемо с большими таблицами.
Первое прочтение строк как в «Для Каждого СтрокаТЧ из ЭтотОбъект.ТабличнаяЧасть1 Цикл» происходит медленнее последующих. Насколько понял по замеру производительности: клиент обращается к серверу.

2) Метод "ПроверитьСтроку" считает видимой скрытую через условное оформление строку. Конечно скрывать строки через условное оформление спорное решение (как минимум замедление при работе с большими таблицами).

3) Метод "ПроверитьСтроку" в дереве считает скрытые строки верхнего уровня (только их проверял) видимыми.

Склоняюсь к варианту рассчитывать итоги программно по выбранным пользователем строкам, но это требует от пользователя выбрать строки. Решение конечно зависит от ситуации.
5. qwinter 683 14.07.24 19:07 Сейчас в теме
Вот поэтому и нужны нормальные методологи и архитекторы, что бы таких идиотских и вредных задач программистам не поступало.
7. ixijixi 1913 15.07.24 14:47 Сейчас в теме
(5) А в чем вредность и идиотскость? Обычные формы умели такое "искаропки". Неудивительно, что от пользователей часто поступает подобный запрос.
Прикрепленные файлы:
6. Бубузяка 62 15.07.24 09:28 Сейчас в теме
При каждом чихе на клиенте вызывать серверный контекст - "так себе решение".
Что бы все работало само, добавьте реквизиты формы "ИтогСтолбец1, ... ИтогСтолбецN" (число). Элементам формы, где в подвале выводите итоги, заполните свойство "ПутьКДаннымПодвала" ссылкой на реквизит для итогов.
Этот текст

Элементы.ТабличнаяЧасть1Столбец1.ТекстПодвала = ИтогСтолбец1;
ОбновитьДанныеНаСервере();


уберите. Теперь все само отработает.
Ali1976; cleaner_it; 7OH; +3 Ответить
8. rbsoft 230 25.08.24 15:49 Сейчас в теме
(6) Подскажите, как определить видимость строки дерева значений.
Тоже нужно просто выводить итог по видимым строкам.

(4) Метод "ПроверитьСтроку" в дереве считает ВСЕ скрытые строки видимыми.
Оставьте свое сообщение