Пересчет итогов по родителям дерева значения
Доброго времени суток Вопрос такой. Имеется дерево значений которое выводит все месяцы (первый уровень- родитель) и номенклатура (второй уровень — дочерние). Необходимо пересчитывать все строки по номенклатурам и итог выводить у родителя.
Проблема заключается в следующем.
После ввода количества и цены у номенклатур итог записывается как надо в родетеля(т.е в строку месяц), но вот если удалять строки номенклатур то итог не отнимается а остается в поле родителя, иногда считается не правильно.
Пример на скрине
На первом скрине все правильно считается ,на втором при удалении номенклатуры не правильный пересчет шел, а когда удалились все номенклатуры то итог всеравно не отнялся.
Вот код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
&НаКлиенте Процедура КонфигурационнаяЕдиница1ЦенаПриИзменении(Элемент) СтрокаТабличнойЧасти = Элементы.КонфигурационнаяЕдиница1.ТекущиеДанные; РасчитатьСумму(СтрокаТабличнойЧасти); Родитель = СтрокаТабличнойЧасти.ПолучитьРодителя(); Если Родитель <> Неопределено Тогда КоличествоРодителя = РассчитатьРодителя(Родитель); Родитель.Сумма = КоличествоРодителя; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура КонфигурационнаяЕдиница1КоличествоПриИзменении(Элемент) СтрокаТабличнойЧасти = Элементы.КонфигурационнаяЕдиница1.ТекущиеДанные; РасчитатьСумму(СтрокаТабличнойЧасти); Родитель = СтрокаТабличнойЧасти.ПолучитьРодителя(); Если Родитель <> Неопределено Тогда КоличествоРодителя = РассчитатьРодителя(Родитель); Родитель.Сумма = КоличествоРодителя; КонецЕсли; КонецПроцедуры &НаКлиенте Функция РассчитатьРодителя(Родитель) Строки = Родитель.ПолучитьЭлементы(); Сумма = 0; Для каждого Стр из Строки Цикл Сумма = Сумма + стр.Сумма; КонецЦикла; Возврат Сумма; КонецФункции &НаКлиенте Процедура РасчитатьСумму(СтрокаТабличнойЧасти) СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена; КонецПроцедуры &НаКлиенте Процедура КонфигурационнаяЕдиница1СуммаПриИзменении(Элемент) СтрокаТабличнойЧасти=Элементы.КонфигурационнаяЕдиница1.ТекущиеДанные; Родитель = СтрокаТабличнойЧасти.ПолучитьРодителя(); Если Родитель <> Неопределено Тогда КоличествоРодителя = РассчитатьРодителя(Родитель); Родитель.Сумма = КоличествоРодителя; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура КонфигурационнаяЕдиница1ПриИзменении(Элемент) СтрокаТабличнойЧасти = Элементы.КонфигурационнаяЕдиница1.ТекущиеДанные; РасчитатьСумму(СтрокаТабличнойЧасти); Родитель = СтрокаТабличнойЧасти.ПолучитьРодителя(); Если Родитель <> Неопределено Тогда КоличествоРодителя = РассчитатьРодителя(Родитель); Родитель.Сумма = КоличествоРодителя; КонецЕсли; Объект.ИтоговаяСумма = РассчитатьИтогРодителя(КонфигурационнаяЕдиница); КонецПроцедуры &НаКлиенте Функция РассчитатьИтогРодителя(Родитель) Строки = Родитель.ПолучитьЭлементы(); Сумма = 0; Для каждого Стр из Строки Цикл Если Стр.ПолучитьРодителя() = Неопределено тогда Сумма = Сумма + стр.Сумма; КонецЕсли; КонецЦикла; Возврат Сумма; КонецФункции
Источник
1С 8.x : Пересчет дерева, суммы и коэффициенты.
В ЗУП не исчисляются суммы районного коэффициента и северной надбавки? 1
В Зарплата и управление персоналом 8 почему при расчете среднего заработка для начисления очередного отпуска не исчисляются суммы районного коэффициента и северной надбавки? При исчислении среднего заработка во всех случаях, в том числе для оплаты о Ввод данных по командировкам в программе ЗУП 0
Ввод сведений о командировках в программе 1С: Зарплата и управление персоналом 8 (ред.30) осуществляется в Разделе Кадры — Все кадровые документы — Создать — Командировка Откроется документ: Ввод сведений о командировках в программ Документ «Корректировка записей регистров» — Как программно создать и заполнить? 9
Документ «Корректировка записей регистров» в типовых конфигурациях 1С предназначен для ручной корректировки записей регистров накопления, зависимых регистров сведений и регистров бухгалтерии. Типичные ситуации, в которых может понадобиться документ « Изменился тариф почтового сбора. Как его внести в программу ЗУП? 0
Согласно новому тарифу почтового сбора для Московской области при размере перечисляемой суммы от 1000 руб. до 5000 руб. включительно сбор рассчитывается по формуле: (50 руб. + 4% от суммы) + (1,5 % от суммы свыше 1000 руб.) Эта формула преобразуе Использование предложения ДЛЯ ИЗМЕНЕНИЯ 0
Предложение ДЛЯ ИЗМЕНЕНИЯ позволяет заблаговременно заблокировать некоторые данные (которые могут читаться транзакцией другого соединения) уже при считывании, чтобы исключить взаимные блокировки при записи. ДЛЯ ИЗМЕНЕНИЯ дает возможность указать в Посмотреть все результаты поиска похожих
Еще в этой же категории
Примеры работы с Деревом значений в УП 11
Так как работа с ДеревомЗначений и ТаблицейЗначений в данном контексте практически не отличается, в примере будет использоваться ДеревоЗначений, все тоже самое за исключением иерархии применимо и к ТаблицеЗначений. Как известно, в платформе 1С 8.1 н Преобразование дерева значений в таблицу значений и обратно 6
Хочу поделиться с посетителями сайта своим подходом к преобразованию таблицы значений в дерево значений и обратно. Вообще, при разработке отраслевой задачи, была необходимость почти во всех документах, выводить информацию в виде дерева и хранить ее Как в дереве значений строку перекинуть в другой родитель? 5
Процедура ПереместитьСтрокуДерева(Дерево, ПеремещаемаяСтрока, НовыйРодитель, Уровень = 0) Если Уровень = 0 Тогда НоваяСтрока = НовыйРодитель.Строки.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, ПеремещаемаяСтрока); ПереместитьСтрокуДерева(Де Как Свернуть, Развернуть узлы Дерева значений на форме? 4
Как программно свернуть/развернуть дерево значений на управляемой форме? Желательно НаКлиенте. КоллекцияЭлементовДерева=ДеревоНоменклатуры.ПолучитьЭлементы(); //Свернуть дерево Для Каждого Строка Из КоллекцияЭлементовДерева Цикл ИдентификаторСт ДеревоЗначений в ТекстовыйДокумент 3
// Выводит данные ДереваЗначений в ТекстовыйДокумент, пригодный к рассмотрению в отладчике, окне сообщений и показу. // // Параметры: // рВетка — дерево значений, подлежащее выводу. Может иметь почти любую глубину иерархии, количество и тип ко Посмотреть все в категории Работа с Деревом Значений
Источник
Дерево значений — пересчет итогов иерархии при изменении строки
На форме отчета есть дерево значений, в которое выгрузил выборку запроса.
Как реализовать пересчет итогов?
Пока написал такой обработчик:
Процедура ДеревоРезультатаПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
Если НЕ ОтменаРедактирования Тогда
ЭлементыФормы.ДеревоРезультата.ТекущиеДанные[«Изменение»] = Истина;
КонецЕсли;
КонецПроцедуры
А вот что дальше с ним делать — не пойму.
Хорошо. Построил заново.
Юзер ввёл новое значение и итоги должны пересчитаться интерактивно, после ввода нового значения.
(4) подсказываю:
1. либо пересчитывать вверх ручками вверх по иерархии
2. либо скидывать плоское тз в темпы, строить по нему итогами твое дз и выгружать обратно — если в дз не состав какой то сложной турбины )
3. можно извратить п.2 — выгружать в твое тп не все дз, а только ту ветку, итог которой нужно получить по иерархии. Но это гемор еще тот.
(5) Ок.
Первый пункт кажется путёвым. Возникает вопрос — как отследить, что это уже другая иерархия, соответственно, нужно будет итоги пересчитать и в верхних группировках.
Чуйствую, что без рекурсии не обойтись
Процедура ДеревоПланПродажПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
ТекСтрока = ЭлементыФормы.ДеревоПланПродаж.ТекущиеДанные;
Если ЗначениеНеЗаполнено(ТекСтрока.ТорговаяТочка) Тогда
Возврат;
КонецЕсли;
ВторойУровень = ТекСтрока.Родитель;
Для каждого Колонка Из ДеревоПланПродаж.Колонки Цикл
Если Колонка.ТипЗначения = ТипЧисло И Прав(Колонка.Имя,1)=»П» Тогда
ВторойУровень[Колонка.Имя]=ВторойУровень.Строки.Итог(Колонка);
КонецЕсли;
КонецЦикла;
Процедура ПересчитИтогиИерархически(Элемент, Строка)
ТекСтрока = ЭлементыФормы.ДеревоПланПродаж.ТекущиеДанные;
Если ЗначениеНеЗаполнено(ТекСтрока.ТорговаяТочка) Тогда
Возврат;
КонецЕсли;
ВторойУровень = ТекСтрока.Родитель;
Для каждого Колонка Из ДеревоПланПродаж.Колонки Цикл
Если Колонка.ТипЗначения = ТипЧисло И Прав(Колонка.Имя,1)=»П» Тогда
ВторойУровень[Колонка.Имя]=ВторойУровень.Строки.Итог(Колонка);
КонецЕсли;
КонецЦикла;
ПересчитИтогиИерархически(Элемент, НоваяСтрока)
КонецПроцедуры
Процедура ДеревоПланПродажПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
ТекСтрока = ЭлементыФормы.ДеревоПланПродаж.ТекущиеДанные;
Если ЗначениеНеЗаполнено(ТекСтрока.ТорговаяТочка) Тогда
Возврат;
КонецЕсли;
ПересчитИтогиИерархически(Элемент, НоваяСтрока)
КонецПроцедуры
Всё получилось. Для тех, кто будет искать этот вопрос. Решение подсказал Павел Данилкович:
Процедура СчитатьСуммыДЗ(пСтрокиДЗ, пСуммы) Экспорт
Для Каждого лСтр Из пСтрокиДЗ Цикл
//если уровень группировок — высчитываем итог
Если лСтр.Строки.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
СчитатьСуммыДЗ(лСтр.Строки, пСуммы);
Для Каждого лЗн Из пСуммы Цикл
лСтр[лЗн.Ключ] = лСтр.Строки.Итог(лЗн.Ключ);
КонецЦикла;
КонецЦикла;
КонецПроцедуры // СчитатьСуммыДЗ()
просто рекурсивно проходим все узлы, причем обходим именно узлы, а не элементы.
это условие контролирует кусочек:
//если уровень группировок — высчитываем итог
Если лСтр.Строки.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
Тоесть, если выбирается элемент — у него нет строк, вот его и пропускаем. Просто передать в процедуру само дерево и соответствие колонок по которым нужно суммировать, например План и ПланируемыйРасход:
Процедура ТЗВыборкаПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
соотвКолонок = Новый Соответствие;
соотвКолонок.Вставить(«План»);
соотвКолонок.Вставить(«ПланируемыйРасход»);
СчитатьСуммыДЗ(ДеревоПлан.Строки, соотвКолонок);
КонецПроцедуры
Источник