Как посчитать сумму в списке документов

02.06.10

Разработка - Запросы

Часто возникает необходимость посчитать сумму на форме типа ДокументСписок с текущими отборами... И при большом количестве документов методы с ПостроительЗапроса.ИсточникДанных начинают сильно тормозить, т.к. весь список грузится на клиента. Остается единственное решение - Запрос.

Добавляем подвал в ЭлементыФормы, и вот примерный текст обработчика "ПриПолученииДанных()" списка документов:

Запрос = Новый Запрос();
ТекстОтбора = "";
Список = ДокументСписок;
ш = 0;

 Для Каждого ЭлементНастройкиОтбора Из ЭлементыФормы.Список.НастройкаОтбора Цикл

     Если Список.Отбор[ЭлементНастройкиОтбора.Имя].Использование Тогда

         ВидСравненияЭлементаОтбора = Список.Отбор[ЭлементНастройкиОтбора.Имя].ВидСравнения;
   ш = ш + 1;

         Если ВидСравненияЭлементаОтбора = ВидСравнения.Больше Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " > &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.БольшеИлиРавно Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " >= &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ВИерархии Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра"+ш+")";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ВСписке Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " В (&ЗначениеПараметра"+ш+")";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ВСпискеПоИерархии Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра"+ш+")";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Интервал Тогда
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " > &ЗначениеПараметра"+ш; ш = ш + 1;
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " < &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ИнтервалВключаяГраницы Тогда
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " >= &ЗначениеПараметра"+ш; ш = ш + 1;
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " <= &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ИнтервалВключаяНачало Тогда
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " >= &ЗначениеПараметра"+ш; ш = ш + 1;
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " < &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ИнтервалВключаяОкончание Тогда
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " > &ЗначениеПараметра"+ш; ш = ш + 1;
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " <= &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Меньше Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " < &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.МеньшеИлиРавно Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " <= &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеВИерархии Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И (НЕ ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра"+ш+"))";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеВСписке Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И (НЕ ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " В (&ЗначениеПараметра"+ш+"))";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеВСпискеПоИерархии Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И (НЕ ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра"+ш+"))";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеРавно Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " <> &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеСодержит Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И (НЕ ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " ПОДОБНО &ЗначениеПараметра"+ш+")";
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, "%" + Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение + "%");
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Равно Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " = &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
         ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Содержит Тогда
             ТекстОтбора = ТекстОтбора + Символы.ПС + "    И ТаблицаСписка." + ЭлементНастройкиОтбора.Имя + " ПОДОБНО &ЗначениеПараметра"+ш;
             Запрос.УстановитьПараметр("ЗначениеПараметра"+ш, "%" + Список.Отбор[ЭлементНастройкиОтбора.Имя].Значение + "%");
         КонецЕсли;

     КонецЕсли;

 КонецЦикла;

 Если ТекстОтбора <> "" Тогда
     ТекстОтбора = "ГДЕ" + Символы.ПС + "    " + Сред(ТекстОтбора, 8);
 КонецЕсли;

 ТекстЗапроса =
 "ВЫБРАТЬ РАЗРЕШЕННЫЕ
 |    Сумма(СуммаДокумента) КАК Сумма
 |ИЗ
 |    Документ.ПриходныйКассовыйОрдер КАК ТаблицаСписка
 |" + ТекстОтбора;

 Запрос.Текст = ТекстЗапроса;

 Выборка = Запрос.Выполнить().Выбрать();

 Если Выборка.Следующий() Тогда
  ЭлементыФормы.Список.Колонки.СуммаДокумента.ТекстПодвала = Формат(Выборка.Сумма, "ЧЦ=15; ЧДЦ=2");
 Иначе
  ЭлементыФормы.Список.Колонки.СуммаДокумента.ТекстПодвала = 0;
 КонецЕсли;

 


Далее меняем в запросе имя таблицы Документ.ПриходныйКассовыйОрдер

на нужное вам и вуаля! Имеем сумму документов, которая вычисляется мнгновенно, с любым отбором.

По материалам http://www.kb.mista.ru/article.php?id=471

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    228561    1245    415    

1082

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.

1 стартмани

16.05.2025    7453    103    zup_dev    22    

77

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

В данной публикации рассказывается о решении, которое позволяет находить сразу все ошибки в тексте запроса за раз, а не только самую первую.

2 стартмани

05.03.2025    4841    18    XilDen    12    

28

Обновление 1С Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

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

3 стартмани

06.02.2025    4417    28    XilDen    26    

40

Запросы Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

03.12.2024    10060    artemusII    11    

26

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    19320    sergey279    18    

72

Запросы Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    14047    XilDen    38    

108
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Danil.Potapov 523 14.05.10 19:16 Сейчас в теме
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ДокументСписок);
//настройть на вывод только нужного поля.
ПостроительЗапроса.Выполнить();
ПостроительЗапроса.Результат. Выбрать();
//дальше все как у тебя
8. a-novoselov 1160 19.05.10 13:38 Сейчас в теме
(1) Да, ПостроительЗапроса.Результат. Выбрать(); -
получаем выборку всех документов (их например 100 000) и считаем в цикле общую сумму. Или ПостроительЗапроса.Результат. Выгрузить(); - и по таблице на клиенте считаем сумму колонки. Метод намного проще и нисколечко не будет тормозить на клиент-серверном варианте.
Даже при корректной настройке на вывод нужного поля вся колонка будет выгружаться на клиента, что намного дольше возврата 1й цыфры. Только при ручном назначени ИсточникаДанных построителю мы колонки сможем узнать и типизировать после получения свойства ПостроительЗапроса.Результат... а это опять же получение всего списка... может подскажете как настроить вывод нужного поля до получения результата?
2. alexk-is 6551 14.05.10 19:36 Сейчас в теме
Текст модуля в публикации можно раскрасить получше. :)
5. a-novoselov 1160 18.05.10 07:09 Сейчас в теме
6. alexk-is 6551 18.05.10 07:42 Сейчас в теме
(5) Ой. А что так страшно-то? :)
3. Поручик 4598 14.05.10 21:56 Сейчас в теме
Поддерживаю, раскрась по путёвому.
4. tango 548 17.05.10 09:19 Сейчас в теме
(0) "Добавляем подвал в ЭлементыФормы" или в ЭлементыФормы.ДокументСписок?

| Сумма(ТаблицаСписка.СуммаДокумента) КАК Сумма

Если НЕ ПустаяСтрока(ТекстОтбора) Тогда
ТекстОтбора = "ГДЕ Истина " + ТекстОтбора;
КонецЕсли;
7. DoctorRoza 19.05.10 09:59 Сейчас в теме
МногА букоФак .. нИ асилил .. :D )) +
9. vital1c 98 26.12.12 14:27 Сейчас в теме
в динамических списках в отборе также участвуют КриетрииОтбора, поэтому формирование такого запроса например в Списке ЗаказПокупателя в УТ 10.3 при выборе отбора ДокументыПоДоговоруКонтрагента, запрос не выполнится, потому что имя реквизита будет соответсовать критерию отбора, а не реквизита документа.
10. a-novoselov 1160 26.12.12 15:57 Сейчас в теме
(9) Да, согласен. Но публикация была сделана для того, чтобы показать как следует делать, показать направление так сказать. Просто встречал на своей практике случаи, когда делалось то же самое через построитель - кода, конечно, меньше в разы, но после перехода отметки в 1000 документов форма начинала открываться по 20-30 секунд, хотя через запрос при любом количестве документов открывается не больше секунды.
Для отправки сообщения требуется регистрация/авторизация