gifts2017

Итоговая сумма в формах с динамическими списками и программный вывод в эти же формы доп. реквизитов.

Опубликовал Алексей Северянин (Ledokol-alt) в раздел Программирование - Практика программирования

Итоговая сумма в формах с динамическими списками с учетом текущего отбора. И программный вывод в этиже формы доп. реквизитов.

 

Данная статья является продолжением и развитием этой статьи: http://infostart.ru/public/58224/

Данная доработка актуальна для динамических списков!

 

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

Итого добавлено 7 строчек в «ФормаСписка» объекта и добавлен новый общий модуль. И по желанию можно добавить новую Общую картинку.

Новые Общий модуль и Общая картинка на обновления не влияют, а код в форме списка всегда легко вернуть, если затерся обновлением.

Комментариями по передаваемым параметрам процедуры снабжены.

Итак в форму списка добавляем нижеследующий код:

Процедура Ледокол_ДобавитьЭлементыВФормуСписка_ПересчитатьИтоги()
   
Ледокол_ПоПодпискамНаСобытия.Ледокол_ВывестиИтогиСписка(Новый Структура("СуммаДокумента"), Сред(СокрЛП(ЭтаФорма.ДокументСписок),Найти(СокрЛП(ЭтаФорма.ДокументСписок), ".")+1), ДокументСписок, ЭтаФорма);
КонецПроцедуры
Процедура
Ледокол_ДобавитьЭлементыВФормуСписка_Итоги()
   
Ледокол_ПоПодпискамНаСобытия.Ледокол_ПоказатьСкрытьПересчитатьИтоги(ЭтаФорма, ЭтаФорма.ДокументСписок, ЭлементыФормы.ДействияФормы, Новый Структура("СуммаДокумента"));
КонецПроцедуры

Процедура
ПриОткрытии()
   
Ледокол_ПоПодпискамНаСобытия.Ледокол_ПередОткрытииФормыСписка(ЭтаФорма, ЭлементыФормы.ДействияФормы, Истина, Сред(СокрЛП(ЭтаФорма.ДокументСписок),Найти(СокрЛП(ЭтаФорма.ДокументСписок), ".")+1), "ДокументСписок");
КонецПроцедуры

Внимание! Процедура ПриОткрытии() должна быть связана с соответствующим событием формы. В обращении к процедуре Ледокол_ПоПодпискамНаСобытия.Ледокол_ВывестиИтогиСписка( в первый параметр и в обращении к процедуре Ледокол_ПоПодпискамНаСобытия.Ледокол_ПоказатьСкрытьПересчитатьИтоги( в последний параметр: Новый Структура("СуммаДокумента"),можно включать несколько реквизитов которые необходимо просуммировать через запятую, например:

Новый Структура("СуммаДокумента,НДСПоДокументу,ЕщеКакойТоРеквизит")

Если реквизит имеет тип «Число» то по нему рассчитаются итоги в подвале.

Новый общий модуль « Ледокол_ПоПодпискамНаСобытия» (если не брать из cf-ника то вот его параметры):

Глобальный = ложь

Клиент = Истина

Внешнее содинение = Истина

Привилегированный = Ложь

Текс модуля:

//
//ВыводимыйРеквизит - структура с заполненным свойством - ревизиты
//ТипДокумента - строка с именем типа документа, например "ПриходнаяНакладная"
//ИсточникСписок - ДокументСписок или СправочникСписок
//ТекФорма - Форма
Процедура Ледокол_ВывестиИтогиСписка(ВыводимыйРеквизит, ТипДокумента, ИсточникСписок, ТекФорма) Экспорт
   
#Если Клиент Тогда
   
ПостроительЗапроса = Новый ПостроительЗапроса;
   
спВыводимыйРеквизит = Новый СписокЗначений;
    Для Каждого
Стр Из ВыводимыйРеквизит Цикл
        Если
ТекФорма.ЭлементыФормы.ДокументСписок.Колонки.Найти(Стр.Ключ) = Неопределено Тогда
            Продолжить;
        КонецЕсли;
       
спВыводимыйРеквизит.Добавить(Стр.Ключ);
    КонецЦикла;

   
ТекстПостроителя = "ВЫБРАТЬ
                        |"
;
                        Для
Индекс = 0 По спВыводимыйРеквизит.Количество()-1 Цикл
                           
ТекстПостроителя = ТекстПостроителя + "    КассовоеПоступление." + СокрЛП(спВыводимыйРеквизит[Индекс]) + " КАК " + СокрЛП(спВыводимыйРеквизит[Индекс]) + " ";
                            Если
спВыводимыйРеквизит.Количество()-1 <> Индекс Тогда
                               
ТекстПостроителя = ТекстПостроителя + ",";
                            КонецЕсли;
                        КонецЦикла;
                       
ТекстПостроителя = ТекстПостроителя + "
                        |    ИЗ Документ.КассовоеПоступление КАК КассовоеПоступление
                        |ГДЕ
                        |   КассовоеПоступление.Проведен = ИСТИНА
                        |"
;
   
ТекстПостроителя = СтрЗаменить(ТекстПостроителя, "КассовоеПоступление", ТипДокумента);
   
ПостроительЗапроса.Текст = ТекстПостроителя;
   
ОписаниеИсточникаДанных= Новый ОписаниеИсточникаДанных(ИсточникСписок);
   
ПостроительЗапроса.ИсточникДанных = ОписаниеИсточникаДанных;

   
ПостроительЗапроса.Выполнить();
    Если НЕ
ТекФорма.ЭлементыФормы.ДокументСписок.Подвал Тогда
       
ТекФорма.ЭлементыФормы.ДокументСписок.Подвал = Истина;
    КонецЕсли;

   
тз = ПостроительЗапроса.Результат.Выгрузить();
    Для
Индекс = 0 По спВыводимыйРеквизит.Количество()-1 Цикл
       
СуммаПоТЗ = Формат(тз.Итог(СокрЛП(спВыводимыйРеквизит[Индекс])), "ЧЦ=14; ЧДЦ=2");
       
ТекФорма.ЭлементыФормы.ДокументСписок.Колонки[СокрЛП(спВыводимыйРеквизит[Индекс])].ТекстПодвала = СокрЛП(СуммаПоТЗ);
    КонецЦикла;
   
#КонецЕсли
КонецПроцедуры

// Процедура вызывается обработчиком обновляющий элементы формы списка
//ТекФорма - Форма
//ИсточникСписок - ДокументСписок или СправочникСписок
//КоманднаяПанель - КоманднаяПанель на форме куда добавляются кнопки
//ИтоговыеПоля - структура с заполненным свойством - ревизиты
Процедура Ледокол_ПоказатьСкрытьПересчитатьИтоги(ТекФорма, ИсточникСписок, КоманднаяПанель, ИтоговыеПоля) Экспорт
   
#Если Клиент Тогда
   
КнопкаЛедоколКнопкаИтоги = КоманднаяПанель.Кнопки.ЛедоколКнопкаИтоги;
    Если
КнопкаЛедоколКнопкаИтоги.Пометка Тогда
       
КнопкаЛедоколКнопкаИтоги.Пометка = Ложь;

       
Кнопки = КоманднаяПанель.Кнопки;
       
Кнопки.Удалить(Кнопки.ЛедоколКнопкаПересчитатьИтоги);
       
ТекФорма.ЭлементыФормы.ДокументСписок.Подвал = Ложь;
    Иначе
       
КнопкаЛедоколКнопкаИтоги.Пометка = Истина;

       
ЭлементыФормы       = ТекФорма.ЭлементыФормы;
       
ДействиеЛедоколКнопкаДопСвойства = Новый Действие("Ледокол_ДобавитьЭлементыВФормуСписка_ПересчитатьИтоги");
       
КнопкаЛедоколКнопкаИтоги = КоманднаяПанель.Кнопки.Добавить("ЛедоколКнопкаПересчитатьИтоги", ТипКнопкиКоманднойПанели.Действие, "Пересчитать", ДействиеЛедоколКнопкаДопСвойства);
       
КнопкаЛедоколКнопкаИтоги.Отображение = ОтображениеКнопкиКоманднойПанели.НадписьКартинка;
        Попытка
           
КнопкаЛедоколКнопкаИтоги.Картинка = БиблиотекаКартинок.Ледокол_ОбновитьИтогиСписка;
        Исключение
           
КнопкаЛедоколКнопкаИтоги.Отображение = ОтображениеКнопкиКоманднойПанели.Надпись;
        КонецПопытки;
       
КнопкаЛедоколКнопкаИтоги.Пояснение = "Пересчитать итоги списка";
       
КнопкаЛедоколКнопкаИтоги.Подсказка = "Пересчитать итоги списка";

       
Ледокол_ПоПодпискамНаСобытия.Ледокол_ВывестиИтогиСписка(ИтоговыеПоля, Сред(СокрЛП(ТекФорма.ДокументСписок),Найти(СокрЛП(ТекФорма.ДокументСписок), ".")+1), ИсточникСписок, ТекФорма);
    КонецЕсли;
   
#КонецЕсли
КонецПроцедуры

// Процедура вызывается обработчиком обновляющий элементы формы списка
//ФормаИсточник - форма
//КоманднаяПанель - КоманднаяПанель на форме куда добавляются кнопки
//ПоказатьИтоги - признак отображения итогов
//ИмяДокумента - строка, например "ПриходнаяНакладная"
//ВидСписка - строка, имеет два значения "ДокументСписок" или "СправочникСписок"
Процедура Ледокол_ПередОткрытииФормыСписка(ФормаИсточник, КоманднаяПанель = Неопределено, ПоказатьИтоги = Ложь, ИмяДокумента = Неопределено, ВидСписка = Неопределено) Экспорт
   
#Если Клиент Тогда
   
Если (ПоказатьИтоги) И (НЕ КоманднаяПанель = Неопределено) Тогда
       
ЭлементыФормы       = ФормаИсточник.ЭлементыФормы;
       
КоманднаяПанель.Кнопки.Добавить();
       
ДействиеЛедоколКнопкаДопСвойства = Новый Действие("Ледокол_ДобавитьЭлементыВФормуСписка_Итоги");
       
КнопкаЛедоколКнопкаИтоги = КоманднаяПанель.Кнопки.Добавить("ЛедоколКнопкаИтоги", ТипКнопкиКоманднойПанели.Действие, "Итоги", ДействиеЛедоколКнопкаДопСвойства);
       
КнопкаЛедоколКнопкаИтоги.Отображение = ОтображениеКнопкиКоманднойПанели.Надпись;
       
КнопкаЛедоколКнопкаИтоги.Пояснение = "Показать (скрыть) итоги списка";
       
КнопкаЛедоколКнопкаИтоги.Подсказка = "Показать (скрыть) итоги списка";
    КонецЕсли;
    Если НЕ
ИмяДокумента = Неопределено Тогда
        Для Каждого
Реквизит Из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
            Если
Лев(Реквизит.Имя,8) = "Ледокол_" Тогда
               
Список  = ФормаИсточник.ЭлементыФормы[ВидСписка];
               
Колонка = Список.Колонки.Добавить(Реквизит.Имя, Реквизит.Синоним);
               
Колонка.Данные = Реквизит.Имя;
           
КонецЕсли;
        КонецЦикла;
    КонецЕсли;
   
#КонецЕсли
КонецПроцедуры

 

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

В дальнейшем могу выложить статью по работе (программной) с формой документа(справочника) (не формой списка, а формой документа или справочника).

В файле прикреплении будет cf-ник с общим модулем и картинкой и эта статья в Ворде.

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

А так же рад слышать комментарии(отзывы, замечания, предложения).

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
ИтоговыеПоляВПодвале.cf
.cf 8,30Kb
02.07.13
69
.cf 8,30Kb 69 Скачать
ИтоговыеПоляВПодвале.doc
.doc 52,00Kb
02.07.13
21
.doc 52,00Kb 21 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Богдан Суконнов (bogdan_sukonnov) 20.06.13 10:14
Тема интересная, спасибо. Но мысль донесена не очень доходчиво, во всяком случае для моего уровня. Не ясно:
1. Как учитываются отборы списков?
2. Я так понимаю это не будет работать в тонком клиенте на управляемых формах?
2. Алексей Северянин (Ledokol-alt) 23.06.13 16:16
(1) bogdan_sukonnov,
1) Отборы будут учитываться, так как передается "ИсточникДанных"
2) Для управляемых форм этот механизм не подойдет.
3. andrey dyak (dyak84) 05.01.15 09:55
Автор подскажите, а как дела обстоят с производительностью про больших обемах даных не будет тормозов. Веди почемуто 1С типово суммы в журналах не посчитивает. Зарание спасибо за ответ
4. Алексей Северянин (Ledokol-alt) 13.01.15 17:57
(3) dyak84, При больших объемах обрабатывать данные лучше по кнопке, чтоб не было тормозов. Т.е. нажали кнопку "Пересчитать" - обновились суммы итогов и никаких тормозов не будет, только в момент пересчета от мгновения до нескольких секунд задержки, в зависимости от объема данных.
5. Dyuha K (dyuha) 13.01.15 18:24
(3) dyak84,
1С суммы в журналах не подсчитывает, потому что это как бородатых мужиков на эскалаторе считать. Ни какой смысловой нагрузки не несет сумма в журнале документы контрагентов за июль 2014. А если нужны суммы, есть реестры документов, например.
6. andrey dyak (dyak84) 30.01.15 12:49
(5)Позвольте не согласится смысл есть при нашей специфике работы + с нашими доработками.хотя и понимаю что смысл в ваших словах есть.
7. Александр Шахмейстер (Ashaxm) 31.01.15 18:41
8. Dyuha K (dyuha) 15.02.15 21:17
За получение показателей на основании документов на экзамене по спецу снимают баллы.
bogdan_sukonnov; +1 Ответить 2
9. Богдан Суконнов (bogdan_sukonnov) 19.02.15 17:05
(8) dyuha, согласен, так делать это неправильно. Но другая крайность известна - УПП. Иногда очень хочется найти того человека, кто сделал столько регистров.
10. Алексей Северянин (Ledokol-alt) 13.03.15 01:02
(8) dyuha, список документов как и журнал документов оперируют данными документов, а не регистров. Соответственно сумму документов логично брать именно из данных документов, а не регистров.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа