Код модуля:
Процедура НайтиПодчиненныеЭлементыДляИтогов(ПодчиненныеЭлементы, ТЗ_Структур, ПропуститьЗаполненныйПодвал)
Перем СледПодчиненныеЭлементы, ЭлементФормы,ПутьКДанным,МассивПоиска,СтрокаПоиска, стрИтоговаяКолонка;
Если ПодчиненныеЭлементы = Неопределено или ПодчиненныеЭлементы.Количество() = 0 Тогда Возврат; КонецЕсли;
Для Каждого ЭлементФормы Из ПодчиненныеЭлементы Цикл
Если ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы") Тогда
СледПодчиненныеЭлементы = ЭлементФормы.ПодчиненныеЭлементы;
НайтиПодчиненныеЭлементыДляИтогов(СледПодчиненныеЭлементы, ТЗ_Структур, ПропуститьЗаполненныйПодвал);
Продолжить;
ИначеЕсли ТипЗнч(ЭлементФормы) <> Тип("ПолеФормы") Тогда
Продолжить;
КонецЕсли;
ПутьКДанным = ЭлементФормы.ПутьКДанным;
Если ПустаяСтрока(ПутьКДанным) Тогда Продолжить; КонецЕсли;
МассивПоиска = ТЗ_Структур.НайтиСтроки(Новый Структура("Использован,ПутьКДанным", Ложь,ПутьКДанным));
Если МассивПоиска.Количество() = 0 Тогда Продолжить; КонецЕсли;
СтрокаПоиска = МассивПоиска[0];
СтрокаПоиска.Использован = Истина;
//Пропустим заполненные подвалы...
Если ПропуститьЗаполненныйПодвал <> Неопределено и ПропуститьЗаполненныйПодвал = Истина и Не ПустаяСтрока(ЭлементФормы.ПутьКДаннымПодвала) Тогда
Продолжить;
КонецЕсли;
стрИтоговаяКолонка = СтрокаПоиска.стрИтоговаяКолонка;
стрИтоговаяКолонка.ИмяЭлемента = ЭлементФормы.Имя;
стрИтоговаяКолонка.Типовой_ПутьКДанным = ЭлементФормы.ПутьКДаннымПодвала;
КонецЦикла;
КонецПроцедуры
//Получить картинку оп наименованию...
Функция ПолучитьИзБиблиотекиКартинку(ИмяКартинки)
Попытка
Возврат БиблиотекаКартинок[ИмяКартинки];
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
Функция НайтиРеквизитПоНаименованию(МассРекв, ИмяРеквизита)
Перем РезФункци,СчИндекса,КолВо,Реквизит;
РезФункци = Неопределено;
СчИндекса = 0;
КолВо = МассРекв.Количество();
Пока КолВо > 0 Цикл
Реквизит = МассРекв[КолВо-1];
СчИндекса = СчИндекса + 1;
Если Реквизит.Имя = ИмяРеквизита Тогда
РезФункци = СчИндекса - 1;
Прервать;
КонецЕсли;
КолВо = КолВо - 1;
КонецЦикла;
Возврат РезФункци;
КонецФункции
Функция ПолучитьЗначениеСтруктуры(СтруктураЗначений,Ключ,ЗначениеПоУмолчанию=Неопределено,ЗначениеНеопределеноЗаменитьПоУмолчанию=Ложь)
Перем Значение;
Попытка
Если ТипЗнч(СтруктураЗначений) <> Тип("Структура") Тогда
Возврат ЗначениеПоУмолчанию;
КонецЕсли;
Значение = Неопределено;
Если СтруктураЗначений.Свойство(Ключ, Значение) = Истина Тогда
Если Значение = Неопределено и ЗначениеНеопределеноЗаменитьПоУмолчанию = Истина Тогда
Значение = ЗначениеПоУмолчанию
КонецЕсли;
Иначе
Значение = ЗначениеПоУмолчанию;
КонецЕсли;
Исключение
Возврат ЗначениеПоУмолчанию;
КонецПопытки;
Возврат Значение;
КонецФункции
//Инициализируем параметры, обработчик и кнопки табличной части...
// Работает только для Табличных частей Справочников, документов или табличных частей Таблиц значений...
Процедура ИнициализироватьИтоговыеПоляТаблиц(Форма, ПараметрыИтогов) Экспорт
Перем Элементы,Команды,ИмяЭлемента,ИмяГруппыПанели,МассивКолонокИсключений,СоотвФормулКолонок,ПропуститьЗаполненныйПодвал,ЭлементФормы,ПутьКДанным,ГруппыПанели;
Перем ИмяРеквизитаИтогов,МассРекв,ИндексРеквизита,ДобавляемыеРеквизиты,ТипНеопределено,НовыйТип,СОГ_НастройкаИтоговыхРеквизитов,КоличествоТаблиц,ИндексТаблицы,ТабличнаяЧасть,ТЗ,МассивЧисловыхКолонок;
Перем ТипЧисло,Колонка,Имя,ПутьКДанным_Таблицы,стрИтоговаяКолонка,Формула,НоваяСтрокаСтруктуры,СледПодчиненныеЭлементы,СчУд,стрНастройкаИтогов;
Перем МассивДопРеквизитов,ИмяРеквизита_Осн,ИмяРеквизита,ИмяЭлемента_,НайденЭлемент,ИмяКоманды_ОИ,ИмяКоманды_ОИ_Элемента,Картинка_ОИ;
Перем Команда,ИмяКоманды_ПИ,ИмяКоманды_ПИ_Элемента,Картинка_ПИ,ГруппаФормы,ЭлементФормы_Кнопка1,ЭлементФормы_Кнопка2,Подвал,ОписОшибки,ТекстСообщения;
Элементы = Форма.Элементы;
Команды = Форма.Команды;
ИмяЭлемента = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "ИмяЭлемента"); // Строка, обязательная.
ИмяГруппыПанели = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "ИмяГруппыПанели"); // Элемент командной панели, или группа элементов командной панели; Необязателен
МассивКолонокИсключений = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "МассивКолонокИсключений"); // Массив строк, необязателен; В качестве строки имя колонки, т.к. она названа в метаданных или в таблице значений на форме.
СоотвФормулКолонок = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "СоотвФормулКолонок"); // Соответствие в вида "Объект.ВосстановленныеРезервы.НомерСтроки", "Счетчик" ("Ключ", "Значение")... Необязателен
ПропуститьЗаполненныйПодвал = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "ПропуститьЗаполненныйПодвал", Ложь, Истина); // Булево, небязателен (по умолчанию Ложь - Подвал будет заменен)
ИспользоватьТиповойПодвал = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "ИспользоватьТиповойПодвал", Ложь, Истина); // Булево, небязателен (по умолчанию Ложь - Если включен, то можно переключаться на итоги, которые прописаны по умолчанию)
ЗаголовокКнопки = ПолучитьЗначениеСтруктуры(ПараметрыИтогов, "ЗаголовокКнопки"); // Строка, можно пустую, можно Неопределено, необязателен
//Если нечего не заполнено, то и ничего не делаем...
Если ИмяЭлемента = Неопределено или ПустаяСтрока(ИмяЭлемента) Тогда Возврат; КонецЕсли;
ЭлементФормы = Элементы.Найти(ИмяЭлемента);
Если ЭлементФормы = Неопределено Тогда Возврат; КонецЕсли;
ПутьКДанным = ЭлементФормы.ПутьКДанным;
ГруппыПанели = Неопределено;
Если ИмяГруппыПанели <> Неопределено Тогда
ГруппыПанели = Элементы.Найти(ИмяГруппыПанели);
КонецЕсли;
Если ГруппыПанели = Неопределено Тогда
ГруппыПанели = ЭлементФормы.КоманднаяПанель;
КонецЕсли;
Попытка
ИмяРеквизитаИтогов = "СОГ_НастройкаИтоговыхРеквизитов";
//Найдем реквизит настройки
МассРекв = Форма.ПолучитьРеквизиты("");
ИндексРеквизита = НайтиРеквизитПоНаименованию(МассРекв, ИмяРеквизитаИтогов);
Если ИндексРеквизита = Неопределено Тогда
ДобавляемыеРеквизиты = Новый Массив;
// Опишем ревизиты формы
ТипНеопределено = Неопределено;
НовыйТип = Новый ОписаниеТипов(ТипНеопределено);
ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы(ИмяРеквизитаИтогов, НовыйТип));
Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
Форма[ИмяРеквизитаИтогов] = Новый Структура;
КонецЕсли;
СОГ_НастройкаИтоговыхРеквизитов = Форма[ИмяРеквизитаИтогов];
//Если свойство есть, то уже обрабатывали...
Если СОГ_НастройкаИтоговыхРеквизитов.Свойство(ИмяЭлемента) = Истина Тогда Возврат; КонецЕсли;
КоличествоТаблиц = СОГ_НастройкаИтоговыхРеквизитов.Количество();
ИндексТаблицы = КоличествоТаблиц + 1;
ТабличнаяЧасть = Неопределено;
Выполнить("ТабличнаяЧасть = Форма."+ПутьКДанным+";");
ТЗ = ТабличнаяЧасть.Выгрузить();
ТЗ.Очистить();
//Подготовим ТЗ для ссылок на структуры...
ТЗ_Структур = Новый ТаблицаЗначений;
ТЗ_Структур.Колонки.Добавить("ПутьКДанным", Новый ОписаниеТипов("Строка"));
ТЗ_Структур.Колонки.Добавить("стрИтоговаяКолонка", Новый ОписаниеТипов("Строка,Структура"));
ТЗ_Структур.Колонки.Добавить("Использован", Новый ОписаниеТипов("Булево"));
МассивЧисловыхКолонок = Новый Массив;
ТипЧисло = Тип("Число");
Для Каждого Колонка Из ТЗ.Колонки Цикл
Имя = Колонка.Имя;
Если МассивКолонокИсключений <> Неопределено и МассивКолонокИсключений.Найти(Имя) <> Неопределено Тогда Продолжить; КонецЕсли;
Если Колонка.ТипЗначения.СодержитТип(ТипЧисло) <> Истина Тогда Продолжить; КонецЕсли;
ПутьКДанным_Таблицы = ПутьКДанным+"."+Имя;
стрИтоговаяКолонка = Новый Структура("ИмяКолонки, ПутьКДанным, ИмяЭлемента, Формула, ИмяРеквизита", Имя,ПутьКДанным_Таблицы,"","", "");
стрИтоговаяКолонка.Вставить("Типовой_ПутьКДанным", ""); //ИспользоватьТиповойПодвал
Если СоотвФормулКолонок <> Неопределено Тогда
Формула = СоотвФормулКолонок.Получить(ПутьКДанным_Таблицы);
Если Формула <> Неопределено и Не ПустаяСтрока(Формула) Тогда
стрИтоговаяКолонка.Формула = Формула;
КонецЕсли;
КонецЕсли;
МассивЧисловыхКолонок.Добавить(стрИтоговаяКолонка);
//Добавим строку, ссылку на структуру.
НоваяСтрокаСтруктуры = ТЗ_Структур.Добавить();
НоваяСтрокаСтруктуры.ПутьКДанным = ПутьКДанным_Таблицы;
НоваяСтрокаСтруктуры.стрИтоговаяКолонка = стрИтоговаяКолонка;
КонецЦикла;
//Найдем все элементы табличной части... куда нам что-то разместить...
СледПодчиненныеЭлементы = ЭлементФормы.ПодчиненныеЭлементы;
НайтиПодчиненныеЭлементыДляИтогов(СледПодчиненныеЭлементы, ТЗ_Структур, ПропуститьЗаполненныйПодвал);
//Удалить лишние записи...
СчУд = МассивЧисловыхКолонок.Количество();
Пока СчУд > 0 Цикл
стрИтоговаяКолонка = МассивЧисловыхКолонок[СчУд-1];
Если ПустаяСтрока(стрИтоговаяКолонка.ИмяЭлемента) = Истина Тогда
МассивЧисловыхКолонок.Удалить(СчУд-1);
КонецЕсли;
СчУд = СчУд - 1;
КонецЦикла;
//Возврат, т.к. нечего нет... для итогов...
Если МассивЧисловыхКолонок.Количество() = 0 Тогда Возврат; КонецЕсли;
//Запечетлим Основную Настройку - СОГ_НастройкаИтоговыхРеквизитов
стрНастройкаИтогов = Новый Структура;
СОГ_НастройкаИтоговыхРеквизитов.Вставить(ИмяЭлемента, стрНастройкаИтогов);
стрНастройкаИтогов.Вставить("Колонки", МассивЧисловыхКолонок);
стрНастройкаИтогов.Вставить("ПутьКДанным", ПутьКДанным);
стрНастройкаИтогов.Вставить("ИндексТаблицы", ИндексТаблицы);
стрНастройкаИтогов.Вставить("ИспользоватьТиповойПодвал", ИспользоватьТиповойПодвал);
стрНастройкаИтогов.Вставить("Подвал", ЭлементФормы.Подвал); //Запомним подвал, какой был по умолчанию...
//... ... ...
// Создадим реквизиты на форме...
МассивДопРеквизитов = Новый Массив;
ИмяРеквизита_Осн = "СОГ_ДИ"+СокрЛП(Формат(ИндексТаблицы,"ЧДЦ=0; ЧН=0; ЧГ="))+"_";
Для Каждого стрИтоговаяКолонка Из МассивЧисловыхКолонок Цикл
ИмяРеквизита = "" + ИмяРеквизита_Осн + стрИтоговаяКолонка.ИмяКолонки;
стрИтоговаяКолонка.ИмяРеквизита = ИмяРеквизита;
МассивДопРеквизитов.Добавить(Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("Число")));
КонецЦикла;
Форма.ИзменитьРеквизиты(МассивДопРеквизитов);
//Реквизиты добавили, давайте их определим в итоги...
Если ИспользоватьТиповойПодвал <> Истина Тогда
Для Каждого стрИтоговаяКолонка Из МассивЧисловыхКолонок Цикл
ИмяРеквизита = стрИтоговаяКолонка.ИмяРеквизита;
ИмяЭлемента_ = стрИтоговаяКолонка.ИмяЭлемента;
НайденЭлемент = Элементы.Найти(ИмяЭлемента_);
Если НайденЭлемент = Неопределено Тогда Продолжить; КонецЕсли;
НайденЭлемент.ПутьКДаннымПодвала = ""+ИмяРеквизита;
КонецЦикла;
КонецЕсли;
//Добавим на форму кнопки... .......................................
//Создадим команды, если их нет...
ИмяКоманды_ОИ = "СОГ_ОбновитьИтогиТаблицы";
ИмяКоманды_ОИ_Элемента = ИмяКоманды_ОИ+"_"+ИмяЭлемента;
Если Команды.Найти(ИмяКоманды_ОИ_Элемента) = Неопределено Тогда
Картинка_ОИ = ПолучитьИзБиблиотекиКартинку("Обновить");
Команда = Команды.Добавить(ИмяКоманды_ОИ_Элемента); //Имя команды
Команда.Заголовок = "Итоги";
Команда.Действие = "СОГ_ОбработатьИтогиТаблицы"; //Имя связанной процедуры
Команда.Подсказка = "Обновить итоги табличной части";
Команда.Отображение = ?(Картинка_ОИ = Неопределено,ОтображениеКнопки.Текст,ОтображениеКнопки.КартинкаИТекст);
Команда.Картинка = Картинка_ОИ;
КонецЕсли;
ИмяКоманды_ПИ = "СОГ_ПоказатьИтогоТаблицы";
ИмяКоманды_ПИ_Элемента = ИмяКоманды_ПИ+"_"+ИмяЭлемента;
Если Команды.Найти(ИмяКоманды_ПИ_Элемента) = Неопределено Тогда
Картинка_ПИ = ПолучитьИзБиблиотекиКартинку("РазвернутьВсе");
Если ЗаголовокКнопки = Неопределено или ПустаяСтрока(ЗаголовокКнопки) Тогда
ЗаголовокКнопки_ = "панель итогов (показать / скрыть)";
Иначе
ЗаголовокКнопки_ = ЗаголовокКнопки;
КонецЕсли;
Команда = Команды.Добавить(ИмяКоманды_ПИ_Элемента); //Имя команды
Команда.Заголовок = ЗаголовокКнопки_;
Команда.Действие = "СОГ_ОбработатьИтогиТаблицы"; //Имя связанной процедуры
Команда.Подсказка = "Показать / Скрыть итоги табличной части";
Команда.Отображение = ?(Картинка_ПИ = Неопределено,ОтображениеКнопки.Текст,ОтображениеКнопки.КартинкаИТекст);
Команда.Картинка = Картинка_ПИ;
КонецЕсли;
//Добавим кнопки... (группа)
ГруппаФормы = Элементы.Добавить("СОГ_ГруппаКнопокИтоговТаблицы_"+ИмяЭлемента, Тип("ГруппаФормы"), ГруппыПанели);
ГруппаФормы.Вид = ВидГруппыФормы.ГруппаКнопок;
ГруппаФормы.Отображение = ОтображениеГруппыКнопок.Компактное;
//Добавим кнопки... (кнопки)
ЭлементФормы_Кнопка1 = Элементы.Добавить(ИмяКоманды_ОИ_Элемента, Тип("КнопкаФормы"), ГруппаФормы);
ЭлементФормы_Кнопка1.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
ЭлементФормы_Кнопка1.ИмяКоманды = ИмяКоманды_ОИ_Элемента;
ЭлементФормы_Кнопка1.ТолькоВоВсехДействиях = Ложь;
ЭлементФормы_Кнопка2 = Элементы.Добавить(ИмяКоманды_ПИ_Элемента, Тип("КнопкаФормы"), ГруппаФормы);
ЭлементФормы_Кнопка2.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
ЭлементФормы_Кнопка2.ИмяКоманды = ИмяКоманды_ПИ_Элемента;
ЭлементФормы_Кнопка2.ТолькоВоВсехДействиях = Ложь;
//Пока в разработке...
Если ИспользоватьТиповойПодвал = Истина Тогда
Если ЗаголовокКнопки = Неопределено или ПустаяСтрока(ЗаголовокКнопки) Тогда
ЗаголовокКнопки_ = "панель итогов (ГГЕ / типовая)";
Иначе
ЗаголовокКнопки_ = ЗаголовокКнопки;
КонецЕсли;
ЭлементФормы_Кнопка2.Заголовок = ЗаголовокКнопки_;
КонецЕсли;
//Подкорректируем доступность панелей и кнопок...
ЭлементФормы_Кнопка1.Доступность = Ложь;
ЭлементФормы_Кнопка2.Пометка = Ложь;
Исключение
ОписОшибки = ОписаниеОшибки();
ТекстСообщения = "Ошибка при создании итоговых конопок для табличной части %1. Описание: %2";
ТекстСообщения = СтрШаблон(ТекстСообщения, ИмяЭлемента,ОписОшибки);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецПопытки;
КонецПроцедуры
Процедура ОбработатьИтогиТаблицы(Форма, ПараметрыСервера) Экспорт
Перем ИмяЭлемента,Пометка,СОГ_НастройкаИтоговыхРеквизитов,стрНастройкаИтогов,Элементы,ЭлементФормы,Колонки,ИспользоватьТиповойПодвал,стрИтоговаяКолонка;
Перем ИмяРеквизита,ИмяЭлемента_,Типовой_ПутьКДанным,НайденЭлемент;
ИмяЭлемента = ПолучитьЗначениеСтруктуры(ПараметрыСервера,"ИмяЭлемента");
Пометка = ПолучитьЗначениеСтруктуры(ПараметрыСервера,"Пометка", Ложь, Истина);
Если ИмяЭлемента = Неопределено Тогда Возврат; КонецЕсли;
СОГ_НастройкаИтоговыхРеквизитов = Форма.СОГ_НастройкаИтоговыхРеквизитов;
Если СОГ_НастройкаИтоговыхРеквизитов = Неопределено или ТипЗнч(СОГ_НастройкаИтоговыхРеквизитов) <> Тип("Структура") Тогда Возврат; КонецЕсли;
стрНастройкаИтогов = Неопределено;
СОГ_НастройкаИтоговыхРеквизитов.Свойство(ИмяЭлемента, стрНастройкаИтогов);
Если стрНастройкаИтогов = Неопределено Тогда Возврат; КонецЕсли;
Элементы = Форма.Элементы;
ЭлементФормы = Элементы.Найти(ИмяЭлемента);
Если ЭлементФормы = Неопределено Тогда Возврат; КонецЕсли;
Колонки = стрНастройкаИтогов.Колонки;
ИспользоватьТиповойПодвал = стрНастройкаИтогов.ИспользоватьТиповойПодвал;
Если ИспользоватьТиповойПодвал = Истина Тогда
Для Каждого стрИтоговаяКолонка Из Колонки Цикл
ИмяРеквизита = стрИтоговаяКолонка.ИмяРеквизита;
ИмяЭлемента_ = стрИтоговаяКолонка.ИмяЭлемента;
Типовой_ПутьКДанным = стрИтоговаяКолонка.Типовой_ПутьКДанным;
НайденЭлемент = Элементы.Найти(ИмяЭлемента_);
Если НайденЭлемент = Неопределено Тогда Продолжить; КонецЕсли;
Если Пометка = Истина Тогда
НайденЭлемент.ПутьКДаннымПодвала = ""+ИмяРеквизита;
Иначе
НайденЭлемент.ПутьКДаннымПодвала = ""+Типовой_ПутьКДанным;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры