В конфигурациях на платформе 1С:Предприятие 8.2, ориентированных на использование в режиме управляемого приложения достаточно часто используются динамические списки. Этот объект позволяет выводить в любой управляемой форме данные справочников, документов (и других объектов конфигурации), а также результаты произвольных запросов.
Одна из особенностей динамического списка состоит в том, что как правило, данные в него выводятся порциями (для минимизации трафика между клиентом и сервером). Если в настройках динамического списка установлен флаг «Динамическое считывание данных”, то с сервера клиенту будет передаваться только та часть данных, которая помещается в табличное поле.
В связи с такой особенностью, а возможно и в связи с нецелесообразностью и противоречием клиент-серверным принципам работы, в динамическом списке в отличии от таблицы значений нет стандартной возможности вывода итогов по числовым колонкам. Сегодня я расскажу как можно выйти из положения, если итоги всё-таки нужны.
Решение
Сразу предупрежу, что предложенное ниже решение хотя и является универсальным и наиболее приемлемым для поставленной задачи, все же имеет ряд недостатков (о которых я скажу позже). Поэтому, если есть возможность, то лучше обойтись без использования итогов динамического списка (например сделать отчёт, который будет выводить необходимые пользователю итоги).
За основу для разработки возьмём демо-конфигурацию. Будем добавлять итог по колонке «Сумма долга” динамического списка в форме справочника «Контрагенты” «ФормаСпискаРабочийСтол”. Общая идея состоит в следующем:
- Создадим пустую схему компоновки данных (далее «СКД”) с ресурсом «Сумма долга” для справочника «Контрагенты”.
- Программно скопируем текст запроса из динамического списка в «СКД”
- Программно перенесём отбор, установленный в форме списка в настройки СКД
- Выведем результат компоновки данных в таблицу и отобразим данные на форме
На том как создать СКД подробно останавливаться не буду. Сделать это не сложно. Для этого достаточно добавить для справочника «Контрагенты” новый макет с типом «Схема компоновки данных”. В СКД добавить набора данных «Запрос” (назовём его «Основной”). Текст запроса должен быть, например, таким:
ВЫБРАТЬ 1 КАК СуммаДолга
Вместо значения «1″ в тексте запроса может быть что угодно, этот текст всё равно будет заменён текстом запроса динамического списка. Затем необходимо перенести поле «СуммаДолга” из доступных полей в поля ресурсов на закладке «Ресурсы” (в поле «Выражение” должно быть «Сумма(СуммаДолга)”). И наконец перейдём на закладку «Настройки”, где добавим группировку по пустому полю (она будет называться «<Детальные записи>”) и перенесём поле «СуммаДолга” в выбранные поля.
Теперь добавим в форму списка контрагентов «ФормаСпискаРабочийСтол” таблицу итогов с колонками «Сумма долга” и «Отбор”.
На закладке «Команды” добавим команду «Пересчитать итоги” и разместим кнопку вызова этой команды в панель инструментов таблицы итогов. Ниже приведён текст модуля формы.
&НаСервере
Функция ИтогиСпискаКонтрагентов()
СКД = Справочники.Контрагенты.ПолучитьМакет(«ИтогиСпискаКонтрагентовСКД»);
// скопируем текст запроса из динамического списка
ТекстЗапроса = Список.ТекстЗапроса;
СКД.НаборыДанных.Основной.Запрос = ТекстЗапроса;
// подготовим таблицу и процессор вывода результата СКД в таблицу
Таб = Новый ТаблицаЗначений;
ПроцессорВыводаВТЗ = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВыводаВТЗ.УстановитьОбъект(Таб);
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);
// загрузим настройки из настроек динамического списка
Для Каждого ЭлементОтбораГП Из Список.Отбор.Элементы Цикл
ЭлементОтбораСКД = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
ЗаполнитьЗначенияСвойств(ЭлементОтбораСКД,ЭлементОтбораГП);
КонецЦикла;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СКД,КомпоновщикНастроек.Настройки, , , Тип(«ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений»));
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
Таб = ПроцессорВыводаВТЗ.Вывести(ПроцессорКомпоновкиДанных);
Если Таб.Количество() = 0 Тогда
Возврат Неопределено;
Иначе
Таб.Колонки.Добавить(«Отбор»);
ТекстОтбора = Строка(Список.Отбор);
Таб.Отбор = ?(ТекстОтбора = «»,»Отбор не задан»,ТекстОтбора);
СтруктураДанных = Новый Структура;
Для Каждого Колонка Из Таб.Колонки Цикл
СтруктураДанных.Вставить(Колонка.Имя,Таб);
КонецЦикла;
Возврат СтруктураДанных;
КонецЕсли;
КонецФункции
&НаКлиенте
Процедура ПересчитатьИтоги(Команда)
СтрокаДанных = ИтогиСпискаКонтрагентов();
ТаблицаИтогов.Очистить();
Если СтрокаДанных <> Неопределено Тогда
СтрокаИтогов = ТаблицаИтогов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаИтогов,СтрокаДанных);
КонецЕсли;
КонецПроцедуры
Для того чтобы проверить работу примера запустим конфигурацию, установим отбор в форме списка контрагентов на рабочем столе и нажмём на кнопку «Пересчитать итоги”.
Теперь, как и обещал, перечислю недостатки такого решения.
- Необходимо нажимать кнопку «Пересчитать итоги” при любых изменениях в списке.
- Если отбор был изменён или изменилась сумма долга по контрагенту, то данные итогов перестают быть актуальными.
- Отследить изменения отбора невозможно – для этого нет подходящего обработчика событий.
- Если вы воспользовались кнопкой «Найти” панели инструментов динамического списка, то в списке отобразятся только строки, соответствующие условию поиска, но при пересчёте итогов сумма не изменится, так как эти условия не являются отбором.
Статья найдена на просторах интернета