Итоги в динамическом списке

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

Одна из особенностей динамического списка состоит в том, что как правило, данные в него выводятся порциями (для минимизации трафика между клиентом и сервером). Если в настройках динамического списка установлен флаг «Динамическое считывание данных”, то с сервера клиенту будет передаваться только та часть данных, которая помещается в табличное поле.

В связи с такой особенностью, а возможно и в связи с нецелесообразностью и противоречием клиент-серверным принципам работы, в динамическом списке в отличии от таблицы значений нет стандартной возможности вывода итогов по числовым колонкам. Сегодня я расскажу как можно выйти из положения, если итоги всё-таки нужны.

Решение

Сразу предупрежу, что предложенное ниже решение хотя и является универсальным и наиболее приемлемым для поставленной задачи, все же имеет ряд недостатков (о которых я скажу позже). Поэтому, если есть возможность, то лучше обойтись без использования итогов динамического списка (например сделать отчёт, который будет выводить необходимые пользователю итоги).

За основу для разработки возьмём демо-конфигурацию. Будем добавлять итог по колонке «Сумма долга” динамического списка в форме справочника «Контрагенты” «ФормаСпискаРабочийСтол”. Общая идея состоит в следующем:

  • Создадим пустую схему компоновки данных (далее «СКД”) с ресурсом «Сумма долга” для справочника «Контрагенты”.
  • Программно скопируем текст запроса из динамического списка в «СКД”
  • Программно перенесём отбор, установленный в форме списка в настройки СКД
  • Выведем результат компоновки данных в таблицу и отобразим данные на форме

На том как создать СКД подробно останавливаться не буду. Сделать это не сложно. Для этого достаточно добавить для справочника «Контрагенты” новый макет с типом «Схема компоновки данных”. В СКД добавить набора данных «Запрос” (назовём его «Основной”). Текст запроса должен быть, например, таким:

ВЫБРАТЬ 1 КАК СуммаДолга

Вместо значения «1″ в тексте запроса может быть что угодно, этот текст всё равно будет заменён текстом запроса динамического списка. Затем необходимо перенести поле «СуммаДолга” из доступных полей в поля ресурсов на закладке «Ресурсы” (в поле «Выражение” должно быть «Сумма(СуммаДолга)”). И наконец перейдём на закладку «Настройки”, где добавим группировку по пустому полю (она будет называться «<Детальные записи>”) и перенесём поле «СуммаДолга” в выбранные поля.

Теперь добавим в форму списка контрагентов «ФормаСпискаРабочийСтол” таблицу итогов с колонками «Сумма долга” и «Отбор”.

На закладке «Команды” добавим команду «Пересчитать итоги” и разместим кнопку вызова этой команды в панель инструментов таблицы итогов. Ниже приведён текст модуля формы.

&НаСервере
Функция ИтогиСпискаКонтрагентов()

СКД = Справочники.Контрагенты.ПолучитьМакет(«ИтогиСпискаКонтрагентовСКД»);
// скопируем текст запроса из динамического списка
ТекстЗапроса = Список.ТекстЗапроса;
СКД.НаборыДанных.Основной.Запрос = ТекстЗапроса;

// подготовим таблицу и процессор вывода результата СКД в таблицу
Таб = Новый ТаблицаЗначений;
ПроцессорВыводаВТЗ = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВыводаВТЗ.УстановитьОбъект(Таб);

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);

// загрузим настройки из настроек динамического списка
Для Каждого ЭлементОтбораГП Из Список.Отбор.Элементы Цикл
ЭлементОтбораСКД = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
ЗаполнитьЗначенияСвойств(ЭлементОтбораСКД,ЭлементОтбораГП);
КонецЦикла;

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

ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
Таб = ПроцессорВыводаВТЗ.Вывести(ПроцессорКомпоновкиДанных);
Если Таб.Количество() = 0 Тогда
Возврат Неопределено;
Иначе
Таб.Колонки.Добавить(«Отбор»);
ТекстОтбора = Строка(Список.Отбор);
Таб.Отбор = ?(ТекстОтбора = «»,»Отбор не задан»,ТекстОтбора);
СтруктураДанных = Новый Структура;
Для Каждого Колонка Из Таб.Колонки Цикл
СтруктураДанных.Вставить(Колонка.Имя,Таб);
КонецЦикла;
Возврат СтруктураДанных;
КонецЕсли;
КонецФункции

&НаКлиенте
Процедура ПересчитатьИтоги(Команда)
СтрокаДанных = ИтогиСпискаКонтрагентов();
ТаблицаИтогов.Очистить();
Если СтрокаДанных <> Неопределено Тогда
СтрокаИтогов = ТаблицаИтогов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаИтогов,СтрокаДанных);
КонецЕсли;
КонецПроцедуры

Для того чтобы проверить работу примера запустим конфигурацию, установим отбор в форме списка контрагентов на рабочем столе и нажмём на кнопку «Пересчитать итоги”.

Теперь, как и обещал, перечислю недостатки такого решения.

  • Необходимо нажимать кнопку «Пересчитать итоги” при любых изменениях в списке.
  • Если отбор был изменён или изменилась сумма долга по контрагенту, то данные итогов перестают быть актуальными.
  • Отследить изменения отбора невозможно – для этого нет подходящего обработчика событий.
  • Если вы воспользовались кнопкой «Найти” панели инструментов динамического списка, то в списке отобразятся только строки, соответствующие условию поиска, но при пересчёте итогов сумма не изменится, так как эти условия не являются отбором.

Статья найдена на просторах интернета

Добавить комментарий

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