Подсчёт и отображение количества строк в динамическом списке

Зачастую пользователи хотят видеть, сколько же строк содержится в форме списка, например, товаров. Да ещё и с учётом отборов, полнотекстового или «обычного» поиска, чтобы это работало в многих формах списка конфигурации, да ещё и не тормозило.

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

Получение данных динамического списка

Отображать на форме счетчик решил кнопкой командной панели. Так универсальнее и занимает меньше места. Количество строк лучше считать по необходимости, т.е. когда пользователь нажимает кнопку. Но можно и при обновлении списка.

Чтобы было удобно обновлять конфигурацию и добавлять в другие формы списков, решил кнопку создавать программно. В стандартную процедуру ПриСозданииНаСервере добавляется вызов процедуры программного создания элементов и команды:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

этСозданиеЭлементов();

КонецПроцедуры

 

Процедура этСозданиеЭлементов()

МассивДобавляемыхРеквизитов = Новый Массив;

/////   РЕКВИЗИТЫ   //////////

/////   КОМАНДЫ   //////////
Команда = Команды.Добавить("этПосчитатьКоличествоВручную");
Команда.Действие = "ПосчитатьКоличествоВСписке";
//Команда.Картинка = БиблиотекаКартинок.Сумма; // можно добавить свою картинку
//Команда.Отображение = ОтображениеКнопки.КартинкаИТекст; // и отобразить её с количеством строк


/////   ЭЛЕМЕНТЫ   //////////
НовыйЭлемент = Этаформа.Элементы.Вставить("этПосчитатьКоличествоВручную", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель,);
НовыйЭлемент.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
НовыйЭлемент.ИмяКоманды = "этПосчитатьКоличествоВручную";
НовыйЭлемент.Заголовок = "?";
НовыйЭлемент.Ширина = 3;

КонецПроцедуры

&НаКлиенте
Процедура ПосчитатьКоличествоВСписке()

Элементы.Список.Обновить();
ПосчитатьКоличествоВСпискеНаСервере();

КонецПроцедуры

Процедура подсчета подменяет в тексте запроса динамического списка выбираемые поля на Количество(*), выполняет запрос и отображает результат в заголовке кнопки:

&НаСервере
Процедура ПосчитатьКоличествоВСпискеНаСервере()

Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных();
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

Запрос = Новый Запрос;
Запрос.Текст = МакетКомпоновки.НаборыДанных.НаборДанныхДинамическогоСписка.Запрос;
СтрокаВЫБРАТЬ = Лев(Запрос.Текст, Найти(Запрос.Текст, Символы.ПС));

Запрос.Текст = СтрокаВЫБРАТЬ + "Количество(*) КАК Кол" + Сред(Запрос.Текст, Найти(Запрос.Текст, Символы.ПС + "ИЗ" + Символы.ПС));
Для Каждого парам из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(парам.Имя, парам.Значение);
КонецЦикла;

Результат = Запрос.Выполнить();

Выборка = Результат.Выбрать();
Выборка.Следующий();
Элементы.этПосчитатьКоличествоВручную.Заголовок = " (" + Выборка.Кол + ")";

КонецПроцедуры

Код можно использовать в расширениях конфигурации, можно вынести процедуры в общий модуль, а в модулях форм добавлять только вызов процедуры из общего модуля в ПриСозданииНаСервере

22 Comments

  1. lefthander

    (0)Проще всего вывести список и там уже будет количество строк с учетом отборов. в самом списке это не имеет смысла

    Reply
  2. Xershi

    Добавлю еще что есть такая замечательная кнопка вывести список. Вот там и будет ваш номер!

    Разработчики сознательно не выводили номер строки, т.к. это основа тормозов!

    Reply
  3. sano

    (1),(2) Да, так сначала делал сам и рекомендовал пользователям. Но потом попробовал посчитать количество строк в списке на несколько тысяч записей. Провёл эксперимент. Список из 130 тысяч выводим в список только Код и ждём 10 сек. Моим способом — 1 сек. Теперь считаем количество нажатий на различные кнопки: 6 против 1. Мои пользователи довольны маленькой кнопочкой в командной панели.

    Никого не принуждаю, «Вывести список…» — пожалуйста. Хотите попробовать внедрить к себе этот функционал — даже скачивать не нужно, копируйте код в форму списка, пользуйтесь, получайте удовольствие. Надоело — можно удалить 🙂

    Reply
  4. sano

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

    Reply
  5. Xershi

    (4) согласен что если это нужно это удобно, но это доработка. А потом на кой черт знать количество, что пользователь таким методом анализирует, мне кажется нужно логику пользователю поменять.

    Reply
  6. sano

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

    Reply
  7. Xershi

    (6) такую задачу нужно отчетами решать. Это же статистика. Это как использовать справочник вместо документа, можно но не нужно=))

    Reply
  8. sano

    (7)ага, пользователи так замучали меня своими одноразовыми отчетами, что решил предоставить им возможность быстрого подсчета. Просьбы как рукой сняло. На отчеты жаловались, что долго настраивать отборы по второму кругу (в списке-то уже настроили один раз)

    Reply
  9. Xershi

    (8) похоже еще не научили пользователей использовать сохранение настроек в отчетах)))

    Reply
  10. sano

    (9)пользователи образованные, всё умеют. И время ценят.

    Думаю, каждый сам решит, использовать функционал или нет.

    Reply
  11. yarsort
    Построитель = Новый ПостроительОтчета;
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ДокументыЗаказыПокупателя);
    Выборка = Построитель.Результат.Выгрузить();
    
    СуммаДокумента = Выборка.Итог(«СуммаДокумента»);
    КоличествоДокументов = Выборка.Количество();
    Reply
  12. Ndochp

    (2)Каждый дин список выполняется в режиме «Упорядочить» + «Первые» + «Где номер строки > ХХХХ» иначе просто невозможно отработать стрелку вниз/пейдждаун в конце списка. Так что, все выведенные строки уже посчитаны, вы лукавите.

    Рассказывать, что дополнительный запрос на общее количество строк не может быть оптимизирован так, чтобы не напрягать ни пользователей ни сервер — тоже лукавство. Но чуть меньшее.

    Reply
  13. Xershi

    (12) если речь про план запроса, то это совсем другое.

    Я написал про без доработок, а вы пилить решили.

    Reply
  14. sano

    (11) это Вы к чему?

    Reply
  15. Ndochp

    (13)Вот это «Разработчики сознательно не выводили номер строки, т.к. это основа тормозов! » — ИМХО не правда, так как строки уже проиндексированы и посчитаны. Или вы не про разработчиков платформы, а про разработчиков типовых?

    Reply
  16. yarsort

    // Где «ДокументыЗаказыПокупателя» — динамический список на форме.

    Я такой схемой получения данных на обычных формах пользуюсь. Может и на управляемые можно перенести этот метод.

    Reply
  17. sano

    (16) Тут вижу 3 проблемы:

    1. тормоза, т.к. Выгрузить()

    2. не учитываются отборы и поиски

    3. не универсально

    Но тут и задача другая, считаете Сумму. С такими требованиями в своей практике пока не сталкивался

    В запросе динамического списка можно заменить «Количество(*) КАК Кол» на сумму по конкретной колонке. Суммировать запросом будет быстрее, чем выгружать и использовать Итог. Попробуйте преобразовать мой метод.

    Reply
  18. igor-pn

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

    Результат = Запрос.Выполнить();
    
    Выборка = Результат.Выбрать();
    
    КоличествоЗаписей =  Выборка.Количество() 
    Reply
  19. SlavaKron

    (18) Но ведь тогда будут считываться все данные полей (пусть и на стороне sql). Хотя, ваш способ универсальнее.

    Reply
  20. sano

    (18) Пробовал этот вариант в самом начале. SlavaKron прав. В результате в выборке получите столько записей, сколько в динамическом списке. В моём методе выбирается лишь одна запись с количеством строк. Можно даже не проводить эксперимент, чтобы понять, какой код отработает быстрее 😉

    Reply
  21. igor-pn

    (20) Вы правы, не внимательно посмотрел, Спасибо!

    Reply
  22. qazaz2

    Автору спасибо, отличная идея, использовал правда для другой цели.

    Понятно что каждый данную задачу решит по-своему (каждый др***т как он хочет).

    Крутизна ИМХО в том что бы в понять как устроен мир (1С это как раз мир, не нами придуманный. но данный нам)) и использовать это понимание для решения своих задач. Мне и в голову не приходило изнасиловать запрос макета компоновки)

    Reply

Leave a Comment

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