1с пересчитать дерево значений

Пересчет итогов по родителям дерева значения

Доброго времени суток Вопрос такой. Имеется дерево значений которое выводит все месяцы (первый уровень- родитель) и номенклатура (второй уровень — дочерние). Необходимо пересчитывать все строки по номенклатурам и итог выводить у родителя.
Проблема заключается в следующем.
После ввода количества и цены у номенклатур итог записывается как надо в родетеля(т.е в строку месяц), но вот если удалять строки номенклатур то итог не отнимается а остается в поле родителя, иногда считается не правильно.
Пример на скрине

На первом скрине все правильно считается ,на втором при удалении номенклатуры не правильный пересчет шел, а когда удалились все номенклатуры то итог всеравно не отнялся.
Вот код

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; Для каждого Стр из Строки Цикл Если Стр.ПолучитьРодителя() = Неопределено тогда Сумма = Сумма + стр.Сумма; КонецЕсли; КонецЦикла; Возврат Сумма; КонецФункции

Источник

Читайте также:  Аструм гель с чайным деревом

ДеревоЗначений.Строки
Метод Итог()

Метод Итог() суммирует значения всех строк по указанной колонке. В том случае, когда тип колонки является составным (включающим несколько типов), суммируются только значения числового типа. Значения остальных типов игнорируются.

Доступность

Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).

Пример использования

Пример кода с использованием метода Итог() :

//создание нового дерева значений ДеревоЗначений = Новый ДеревоЗначений; //добавим колонки ДеревоЗначений.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка")); ДеревоЗначений.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число")); //добавим корневую строку КорневаяСтрока = ДеревоЗначений.Строки.Добавить(); КорневаяСтрока.Наименование = "МЕБЕЛЬ"; КорневаяСтрока.Количество = 0; //добавим подчиненные строки для корневой НоваяСтрока = КорневаяСтрока.Строки.Добавить(); НоваяСтрока.Наименование = "Стол деревянный"; НоваяСтрока.Количество = 1; НоваяСтрока = КорневаяСтрока.Строки.Добавить(); НоваяСтрока.Наименование = "Стул деревянный"; НоваяСтрока.Количество = 3; //обновим количество в коревой строке КорневаяСтрока.Количество = КорневаяСтрока.Строки.Итог("Количество"); 

Читайте также:

Источник

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 Тогда
Продолжить;
КонецЕсли;

Тоесть, если выбирается элемент — у него нет строк, вот его и пропускаем. Просто передать в процедуру само дерево и соответствие колонок по которым нужно суммировать, например План и ПланируемыйРасход:

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

Источник

Оцените статью