у меня есть таблица с данными
```
Id;NumberItem;NodeCode;CostName;ISRComment;ContractorComment;UnitOfMeasure;ConsumptionCoefficient;BOCount;TotalCount;MatEquipmPrice;SmpPnpPrice;TotalPrice;MatEquipmCost;SmpPnpCost;TotalCost;ProjectId;TypeCost;HierarchyLevel;ParentId
2;1.1;6;Затраты на строительство;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;16251230.90;14893287.17;31144518.07;1;Работа;1;NULL
3;1.1.1;6.2;СМР корпуса без отделки;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;16251230.90;14842708.53;31093939.43;1;Работа;2;2
4;1.1.1.1;6.2.1;СМР подземной части корпуса;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;143070.00;143070.00;1;Работа;3;3
5;1.1.1.1.1;6.2.1.8;Прочие затраты по СМР подземной части;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;143070.00;143070.00;1;Работа;4;4
6;1.1.1.1.1.1;6.2.1.8.1;Внутренние стены и перегородки подземной части;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;143070.00;143070.00;1;Работа;5;5
7;1.1.1.1.1.1.1;6.2.1.8.1.99;Прочие работы;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;143070.00;143070.00;1;Работа;6;6
8;1.1.1.1.1.1.1.1;6.2.1.8.1.99.2.1;Работы по затарке материалов от места складирования до рабочих мест в техподполье;NULL;применительно для  затарки всех материалов на всех этажах до рабочих мест;т;1.00;NULL;190.00;0.00;753.00;753.00;0.00;143070.00;143070.00;1;Работа;7;7
9;1.1.1.2;6.2.2;СМР надземной части корпуса (без отделки);NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;16251230.90;14699638.53;30950869.43;1;Работа;3;3
10;1.1.1.2.1;6.2.2.4;Внутренние стены и перегородки;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;13677772.58;13112400.03;26790172.61;1;Работа;4;9
11;1.1.1.2.1.1;6.2.2.4.1;Устройство стен;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;9051539.46;7609241.80;16660781.26;1;Работа;5;10
12;1.1.1.2.1.1.1;6.2.2.4.1.2.1;Кладка стен из блоков ячеистого бетона без устройства перемычек, включая армирование, устройство примыканий;Выгружается из БО по объектам BIM-КЦ;С3;м3;1.00;NULL;1193.75;7410.40;6254.00;13664.40;8846165.00;7465712.50;16311877.50;1;Работа;6;11
13;1.1.1.2.1.1.1.1;NULL;Материалы для примыкания / уплотняющий жгут, клей на м3;NULL;NULL;комплект;1.00;NULL;1193.75;175.75;NULL;NULL;209801.56;NULL;NULL;1;Материал;7;12
14;1.1.1.2.1.1.1.2;NULL;Сетка базальтовая b=1000мм, ячейка 50х50, 50/50кН/м;NULL;NULL;пог. м;2.20;NULL;2626.25;88.80;NULL;NULL;233211.00;NULL;NULL;1;Материал;7;12
15;1.1.1.2.1.1.1.3;NULL;"Прочие материалы для кладки / из газобетона / 200 мм ";NULL;NULL;комплект;1.00;NULL;1193.75;326.80;NULL;NULL;390117.50;NULL;NULL;1;Материал;7;12
16;1.1.1.2.1.1.1.4;NULL;Клей для газобетона Путрок_/МС112 F;NULL;NULL;кг;25.00;NULL;29843.75;10.05;NULL;NULL;299929.69;NULL;NULL;1;Материал;7;12
17;1.1.1.2.1.1.1.5;NULL;Блок газобетонный D600 600х200х300мм;NULL;NULL;м3;1.03;NULL;1229.56;6200.00;NULL;NULL;7623290.60;NULL;NULL;1;Материал;7;12
18;1.1.1.2.1.1.1.6;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;12.00;NULL;14325.00;6.27;NULL;NULL;89817.75;NULL;NULL;1;Материал;7;12
19;1.1.1.2.1.1.2;6.2.2.4.1.4.1;Кладка стен из пазогребневых силикатных блоков без устройства перемычек, включая армирование, крепление к стенам, заделку примыканий, зачеканку швов;Выгружается из БО по объектам BIM-КЦ;С2, подземная часть;м3;1.00;NULL;7.80;8948.60;6254.00;15202.60;69799.08;48781.20;118580.28;1;Работа;6;11
20;1.1.1.2.1.1.2.1;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;14.00;NULL;109.20;6.27;NULL;NULL;684.68;NULL;NULL;1;Материал;7;19
21;1.1.1.2.1.1.2.2;NULL;Прочие материалы для кладки / из силикатных блоков / 250;NULL;NULL;комплект;1.00;NULL;7.80;349.65;NULL;NULL;2727.27;NULL;NULL;1;Материал;7;19
22;1.1.1.2.1.1.2.3;NULL;Клей монтажный Гипсовый, эксплуатация при t=-30...+70C, жизнеспособность раствора 30мин;NULL;NULL;кг;27.00;NULL;210.60;7.50;NULL;NULL;1579.50;NULL;NULL;1;Материал;7;19
23;1.1.1.2.1.1.2.4;NULL;Блок силикатный пазогребневый Полнотелый 250мм;NULL;NULL;м3;1.03;NULL;8.03;8066.67;NULL;NULL;64807.63;NULL;NULL;1;Материал;7;19
24;1.1.1.2.1.1.3;6.2.2.4.1.4.1;Кладка стен из пазогребневых силикатных блоков без устройства перемычек, включая армирование, крепление к стенам, заделку примыканий, зачеканку швов;Выгружается из БО по объектам BIM-КЦ;С2 пристройка;м3;1.00;NULL;15.15;8948.87;6254.00;15202.87;135575.38;94748.10;230323.48;1;Работа;6;11
25;1.1.1.2.1.1.3.1;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;14.00;NULL;212.10;6.27;NULL;NULL;1329.87;NULL;NULL;1;Материал;7;24
26;1.1.1.2.1.1.3.2;NULL;Прочие материалы для кладки / из силикатных блоков / 250;NULL;NULL;комплект;1.00;NULL;15.15;349.65;NULL;NULL;5297.20;NULL;NULL;1;Материал;7;24
27;1.1.1.2.1.1.3.3;NULL;Клей монтажный Гипсовый, эксплуатация при t=-30...+70C, жизнеспособность раствора 30мин;NULL;NULL;кг;27.00;NULL;409.05;7.50;NULL;NULL;3067.88;NULL;NULL;1;Материал;7;24
28;1.1.1.2.1.1.3.4;NULL;Блок силикатный пазогребневый Полнотелый 250мм;NULL;NULL;м3;1.03;NULL;15.61;8066.67;NULL;NULL;125880.39;NULL;NULL;1;Материал;7;24
29;1.1.1.2.1.2;6.2.2.4.2;Устройство перегородок;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;3687706.14;5168554.05;8856260.19;1;Работа;5;10
30;1.1.1.2.1.2.1;6.2.2.4.2.1;Устройство перегородок из кирпича и блоков;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;509322.00;509322.00;1;Работа;6;29
31;1.1.1.2.1.2.1.1;6.2.2.4.2.1.7.1;Монтаж, демонтаж, аренда строительных лесов;NULL;NULL;м2;1.00;NULL;1697.74;0.00;300.00;300.00;0.00;509322.00;509322.00;1;Работа;7;30
32;1.1.1.2.1.2.2;6.2.2.4.2.2;Устройство перегородок из пазогребневых плит;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;3687706.14;4659232.05;8346938.19;1;Работа;6;29
33;1.1.1.2.1.2.2.1;6.2.2.4.2.2.1.1;Устройство перегородок из ПГП без устройства перемычек, включая проклейку углов примыкания армирующей лентой, толщ. до 115 мм;Выгружается из БО по объектам BIM-КЦ;NULL;м2;1.00;NULL;59.20;975.09;1331.00;2306.09;57725.33;78795.20;136520.53;1;Работа;7;32
34;1.1.1.2.1.2.2.1.1;NULL;Клей для ПГП_/;NULL;NULL;кг;2.00;NULL;118.40;7.90;NULL;NULL;935.36;NULL;NULL;1;Материал;8;33
35;1.1.1.2.1.2.2.1.2;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;1.71;NULL;101.23;6.27;NULL;NULL;634.72;NULL;NULL;1;Материал;8;33
36;1.1.1.2.1.2.2.1.3;NULL;Силикатный пазогребневый блок / пустотелый / 498х115х248;NULL;NULL;м2;1.02;NULL;60.38;753.50;NULL;NULL;45499.34;NULL;NULL;1;Материал;8;33
37;1.1.1.2.1.2.2.1.4;NULL;Прочий материал для кладки перегородок из ПГП  (скоба,шуруп, дюбель, лента армирующая, лента дихтунгсбанд);NULL;NULL;комплект;1.00;NULL;59.20;169.00;NULL;NULL;10004.80;NULL;NULL;1;Материал;8;33
38;1.1.1.2.1.2.2.1.5;NULL;Материалы для примыкания / мина вата, штукатурная смесь м2;NULL;NULL;комплект;1.00;NULL;59.20;11.00;NULL;NULL;651.20;NULL;NULL;1;Материал;8;33
39;1.1.1.2.1.2.2.2;6.2.2.4.2.2.1.1;Устройство перегородок из ПГП без устройства перемычек, включая проклейку углов примыкания армирующей лентой, толщ. до 115 мм;Выгружается из БО по объектам BIM-КЦ;NULL;м2;1.00;NULL;2525.59;1083.72;1331.00;2414.72;2737032.39;3361560.29;6098592.68;1;Работа;7;32
40;1.1.1.2.1.2.2.2.1;NULL;Клей для ПГП_/;NULL;NULL;кг;2.00;NULL;5051.18;7.90;NULL;NULL;39904.32;NULL;NULL;1;Материал;8;39
41;1.1.1.2.1.2.2.2.2;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;1.71;NULL;4318.76;6.27;NULL;NULL;27078.62;NULL;NULL;1;Материал;8;39
42;1.1.1.2.1.2.2.2.3;NULL;Прочий материал для кладки перегородок из ПГП  (скоба,шуруп, дюбель, лента армирующая, лента дихтунгсбанд);NULL;NULL;комплект;1.00;NULL;2525.59;169.00;NULL;NULL;426824.71;NULL;NULL;1;Материал;8;39
43;1.1.1.2.1.2.2.2.4;NULL;Плита гипсовая пазогребневая Влагостойкая, полнотелая 667х500х80мм;NULL;NULL;м2;1.02;NULL;2576.10;860.00;NULL;NULL;2215447.72;NULL;NULL;1;Материал;8;39
44;1.1.1.2.1.2.2.2.5;NULL;Материалы для примыкания / мина вата, штукатурная смесь м2;NULL;NULL;комплект;1.00;NULL;2525.59;11.00;NULL;NULL;27781.49;NULL;NULL;1;Материал;8;39
45;1.1.1.2.1.2.2.3;6.2.2.4.2.2.1.1;Устройство перегородок из ПГП без устройства перемычек, включая проклейку углов примыкания армирующей лентой, толщ. до 115 мм;Выгружается из БО по объектам BIM-КЦ;С1, С23 подземная часть;м2;1.00;NULL;680.77;975.09;1331.00;2306.09;663812.02;906104.87;1569916.89;1;Работа;7;32
46;1.1.1.2.1.2.2.3.1;NULL;Клей для ПГП_/;NULL;NULL;кг;2.00;NULL;1361.54;7.90;NULL;NULL;10756.17;NULL;NULL;1;Материал;8;45
47;1.1.1.2.1.2.2.3.2;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;1.71;NULL;1164.12;6.27;NULL;NULL;7299.01;NULL;NULL;1;Материал;8;45
48;1.1.1.2.1.2.2.3.3;NULL;Силикатный пазогребневый блок / пустотелый / 498х115х248;NULL;NULL;м2;1.02;NULL;694.39;753.50;NULL;NULL;523219.10;NULL;NULL;1;Материал;8;45
49;1.1.1.2.1.2.2.3.4;NULL;Прочий материал для кладки перегородок из ПГП  (скоба,шуруп, дюбель, лента армирующая, лента дихтунгсбанд);NULL;NULL;комплект;1.00;NULL;680.77;169.00;NULL;NULL;115050.13;NULL;NULL;1;Материал;8;45
50;1.1.1.2.1.2.2.3.5;NULL;Материалы для примыкания / мина вата, штукатурная смесь м2;NULL;NULL;комплект;1.00;NULL;680.77;11.00;NULL;NULL;7488.47;NULL;NULL;1;Материал;8;45
51;1.1.1.2.1.2.2.4;6.2.2.4.2.2.1.1;Устройство перегородок из ПГП без устройства перемычек, включая проклейку углов примыкания армирующей лентой, толщ. до 115 мм;Выгружается из БО по объектам BIM-КЦ;С1, С23 пристройка;м2;1.00;NULL;234.99;975.09;1331.00;2306.09;229136.40;312771.69;541908.09;1;Работа;7;32
52;1.1.1.2.1.2.2.4.1;NULL;Клей для ПГП_/;NULL;NULL;кг;2.00;NULL;469.98;7.90;NULL;NULL;3712.84;NULL;NULL;1;Материал;8;51
53;1.1.1.2.1.2.2.4.2;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;1.71;NULL;401.83;6.27;NULL;NULL;2519.49;NULL;NULL;1;Материал;8;51
54;1.1.1.2.1.2.2.4.3;NULL;Силикатный пазогребневый блок / пустотелый / 498х115х248;NULL;NULL;м2;1.02;NULL;239.69;753.50;NULL;NULL;180606.42;NULL;NULL;1;Материал;8;51
55;1.1.1.2.1.2.2.4.4;NULL;Прочий материал для кладки перегородок из ПГП  (скоба,шуруп, дюбель, лента армирующая, лента дихтунгсбанд);NULL;NULL;комплект;1.00;NULL;234.99;169.00;NULL;NULL;39713.31;NULL;NULL;1;Материал;8;51
56;1.1.1.2.1.2.2.4.5;NULL;Материалы для примыкания / мина вата, штукатурная смесь м2;NULL;NULL;комплект;1.00;NULL;234.99;11.00;NULL;NULL;2584.89;NULL;NULL;1;Материал;8;51
57;1.1.1.2.1.3;6.2.2.4.3;Устройство перемычек и фахверков;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;938526.98;334604.18;1273131.16;1;Работа;5;10
58;1.1.1.2.1.3.1;6.2.2.4.3.2.1;Устройство перемычек металлических с огрунтовкой и окраской;Выгружается из БО по объектам BIM-КЦ;NULL;т;1.00;NULL;3.92;126982.21;47073.00;174055.21;497770.26;184526.16;682296.42;1;Работа;6;57
59;1.1.1.2.1.3.1.1;NULL;Анкерный стержень для перемычек;NULL;NULL;шт;1.00;NULL;933.00;150.10;NULL;NULL;140043.30;NULL;NULL;1;Материал;7;58
60;1.1.1.2.1.3.1.2;NULL;Уголок стальной для перемычек;NULL;NULL;т;1.03;NULL;4.16;83253.35;NULL;NULL;346417.19;NULL;NULL;1;Материал;7;58
61;1.1.1.2.1.3.1.3;NULL;Прочий материал для перемычек (клей, грунт) / для полосы или уголка;NULL;NULL;комплект;1.00;NULL;3.92;2885.15;NULL;NULL;11309.79;NULL;NULL;1;Материал;7;58
62;1.1.1.2.1.3.2;6.2.2.4.3.2.1;Устройство перемычек металлических с огрунтовкой и окраской;Выгружается из БО по объектам BIM-КЦ;подземная часть и пристройка;т;1.00;NULL;0.20;422104.20;47073.00;469177.20;84420.84;9414.60;93835.44;1;Работа;6;57
63;1.1.1.2.1.3.2.1;NULL;Анкерный стержень для перемычек;NULL;NULL;шт;1.00;NULL;441.00;150.10;NULL;NULL;66194.10;NULL;NULL;1;Материал;7;62
64;1.1.1.2.1.3.2.2;NULL;Уголок стальной для перемычек;NULL;NULL;т;1.03;NULL;0.21;83253.35;NULL;NULL;17649.71;NULL;NULL;1;Материал;7;62
65;1.1.1.2.1.3.2.3;NULL;Прочий материал для перемычек (клей, грунт) / для полосы или уголка;NULL;NULL;комплект;1.00;NULL;0.20;2885.15;NULL;NULL;577.03;NULL;NULL;1;Материал;7;62
66;1.1.1.2.1.3.3;6.2.2.4.3.3.1;Устройство металлоконструкций фахверков, стоек, рам, балок, опорных конструкций и усилений с учетом крепления, огрунтовки и окрашивания;NULL;подземная часть и пристройка;т;1.00;NULL;1.66;214660.17;84737.00;299397.17;356335.88;140663.42;496999.30;1;Работа;6;57
67;1.1.1.2.1.3.3.1;NULL;Металлоконструкции (труба, профиль стальной, прокат квадратный, прокат листовой, уголок, арматура и др.);NULL;NULL;т;1.00;NULL;1.66;214263.00;NULL;NULL;355676.58;NULL;NULL;1;Материал;7;66
68;1.1.1.2.1.3.3.2;NULL;Анкер распорный для высоких нагрузок_ / М10;NULL;NULL;шт;1.00;NULL;694.00;0.95;NULL;NULL;659.30;NULL;NULL;1;Материал;7;66
69;1.1.1.2.2;6.2.2.5;Наружные стены;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;2573458.32;1587238.50;4160696.82;1;Работа;4;9
70;1.1.1.2.2.1;6.2.2.5.1;Устройство наружных стен;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;1246445.85;1053298.68;2299744.53;1;Работа;5;69
71;1.1.1.2.2.1.1;6.2.2.5.1.1.1;Кладка стен из блоков ячеистого бетона без устройства перемычек, включая армирование, устройство примыканий;Выгружается из БО по объектам BIM-КЦ;NULL;м3;1.00;NULL;147.80;7410.40;6254.00;13664.40;1095257.12;924341.20;2019598.32;1;Работа;6;70
72;1.1.1.2.2.1.1.1;NULL;Материалы для примыкания / уплотняющий жгут, клей на м3;NULL;NULL;комплект;1.00;NULL;147.80;175.75;NULL;NULL;25975.85;NULL;NULL;1;Материал;7;71
73;1.1.1.2.2.1.1.2;NULL;Сетка базальтовая b=1000мм, ячейка 50х50, 50/50кН/м;NULL;NULL;пог. м;2.20;NULL;325.16;88.80;NULL;NULL;28874.21;NULL;NULL;1;Материал;7;71
74;1.1.1.2.2.1.1.3;NULL;"Прочие материалы для кладки / из газобетона / 200 мм ";NULL;NULL;комплект;1.00;NULL;147.80;326.80;NULL;NULL;48301.04;NULL;NULL;1;Материал;7;71
75;1.1.1.2.2.1.1.4;NULL;Клей для газобетона Путрок_/МС112 F;NULL;NULL;кг;25.00;NULL;3695.00;10.05;NULL;NULL;37134.75;NULL;NULL;1;Материал;7;71
76;1.1.1.2.2.1.1.5;NULL;Блок газобетонный D600 600х200х300мм;NULL;NULL;м3;1.03;NULL;152.23;6200.00;NULL;NULL;943850.80;NULL;NULL;1;Материал;7;71
77;1.1.1.2.2.1.1.6;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;12.00;NULL;1773.60;6.27;NULL;NULL;11120.47;NULL;NULL;1;Материал;7;71
78;1.1.1.2.2.1.2;6.2.2.5.1.1.1;Кладка стен из блоков ячеистого бетона без устройства перемычек, включая армирование, устройство примыканий;Выгружается из БО по объектам BIM-КЦ;С4;м3;1.00;NULL;20.62;7332.14;6254.00;13586.14;151188.73;128957.48;280146.21;1;Работа;6;70
79;1.1.1.2.2.1.2.1;NULL;Материалы для примыкания / уплотняющий жгут, клей на м3;NULL;NULL;комплект;1.00;NULL;20.62;175.75;NULL;NULL;3623.97;NULL;NULL;1;Материал;7;78
80;1.1.1.2.2.1.2.2;NULL;Сетка базальтовая b=1000мм, ячейка 50х50, 50/50кН/м;NULL;NULL;пог. м;2.20;NULL;45.36;88.80;NULL;NULL;4028.32;NULL;NULL;1;Материал;7;78
81;1.1.1.2.2.1.2.3;NULL;"Прочие материалы для кладки / из газобетона / 150 мм ";NULL;NULL;комплект;1.00;NULL;20.62;248.42;NULL;NULL;5122.42;NULL;NULL;1;Материал;7;78
82;1.1.1.2.2.1.2.4;NULL;Клей для газобетона Путрок_/МС112 F;NULL;NULL;кг;25.00;NULL;515.50;10.05;NULL;NULL;5180.78;NULL;NULL;1;Материал;7;78
83;1.1.1.2.2.1.2.5;NULL;Блок газобетонный D600 600х100х300мм;NULL;NULL;м3;1.03;NULL;21.24;6200.00;NULL;NULL;131681.80;NULL;NULL;1;Материал;7;78
84;1.1.1.2.2.1.2.6;NULL;"Смесь сухая цементно-песчаная ";NULL;NULL;кг;12.00;NULL;247.44;6.27;NULL;NULL;1551.45;NULL;NULL;1;Материал;7;78
85;1.1.1.2.2.2;6.2.2.5.2;Устройство перемычек и фахверков;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;1236730.72;488932.49;1725663.21;1;Работа;5;69
86;1.1.1.2.2.2.1;6.2.2.5.2.1.1;Устройство металлоконструкций фахверков, стоек, рам, балок, опорных конструкций и усилений с учетом крепления, огрунтовки и окрашивания;Выгружается из БО по объектам BIM-КЦ;NULL;т;1.00;NULL;5.77;214338.08;84737.00;299075.08;1236730.72;488932.49;1725663.21;1;Работа;6;85
87;1.1.1.2.2.2.1.1;NULL;Металлоконструкции (труба, профиль стальной, прокат квадратный, прокат листовой, уголок, арматура и др.);NULL;NULL;т;1.00;NULL;5.77;214263.00;NULL;NULL;1236297.51;NULL;NULL;1;Материал;7;86
88;1.1.1.2.2.2.1.2;NULL;Анкер распорный для высоких нагрузок_ / М10;NULL;NULL;шт;1.00;NULL;456.00;0.95;NULL;NULL;433.20;NULL;NULL;1;Материал;7;86
89;1.1.1.2.2.3;6.2.2.5.99;Прочие работы;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;90281.75;45007.33;135289.08;1;Работа;5;69
90;1.1.1.2.2.3.1;6.2.2.5.99.1.1;Укладка теплоизоляционных материалов в деформационый шов;NULL;подземная часть и пристройка;м3;1.00;NULL;4.60;6986.49;3483.00;10469.49;32137.85;16021.80;48159.65;1;Работа;6;89
91;1.1.1.2.2.3.1.1;NULL;Пенополистирол экструдированный_;NULL;NULL;м3;1.03;NULL;4.74;6783.00;NULL;NULL;32137.85;NULL;NULL;1;Материал;7;90
92;1.1.1.2.2.3.2;6.2.2.5.99.1.1;Укладка теплоизоляционных материалов в деформационый шов;NULL;NULL;м3;1.00;NULL;8.32;6986.77;3483.00;10469.77;58143.90;28985.53;87129.43;1;Работа;6;89
93;1.1.1.2.2.3.2.1;NULL;Пенополистирол экструдированный_;NULL;NULL;м3;1.03;NULL;8.57;6783.00;NULL;NULL;58143.88;NULL;NULL;1;Материал;7;92
94;1.1.2;6.3;Отделка, столярные работы, мебель и оборудование;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;50578.64;50578.64;1;Работа;2;2
95;1.1.2.1;6.3.1;Отделка нежилых помещений;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;50578.64;50578.64;1;Работа;3;94
96;1.1.2.1.1;6.3.1.3;Отделка кладовых;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;50578.64;50578.64;1;Работа;4;95
97;1.1.2.1.1.1;6.3.1.3.1;Полы;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;50578.64;50578.64;1;Работа;5;96
98;1.1.2.1.1.1.1;6.3.1.3.1.2;Устройство покрытия полов;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;NULL;0.00;50578.64;50578.64;1;Работа;6;97
99;1.1.2.1.1.1.1.1;6.3.1.3.1.2.2.1;Устройство монолитного железобетонного порога;NULL;кладовые и пристройка;м3;1.00;NULL;1.81;0.00;27944.00;27944.00;0.00;50578.64;50578.64;1;Работа;7;98
```
и есть сервис который обрабатывает эти данные
```
// Services/ImportService.cs

using AutoMapper;
using BuildingFlow.Data.Contract;
using BuildingFlow.Data.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace BuildingFlow.Services.CostImportService
{
    public class ImportService
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMapper _mapper;
        private readonly ILogger<ImportService> _logger;

        public ImportService(IUnitOfWork unitOfWork, IMapper mapper, ILogger<ImportService> logger)
        {
            _unitOfWork = unitOfWork;
            _mapper = mapper;
            _logger = logger;
        }

        public async Task ImportCostItemsAsync()
        {
            await _unitOfWork.BeginTransactionAsync();
            try
            {
                var costItemsRepository = _unitOfWork.GetRepository<CostItem>();
                var costsRepository = _unitOfWork.GetRepository<Cost>();
                var projectsRepository = _unitOfWork.GetRepository<Project>();
                var costTypesRepository = _unitOfWork.GetRepository<CostType>();
                var unitsRepository = _unitOfWork.GetRepository<Unit>();
                var materialsRepository = _unitOfWork.GetRepository<Material>();
                var worksRepository = _unitOfWork.GetRepository<Work>();

                // Получаем все записи из старой таблицы, отсортированные по уровню иерархии
                var costItems = await costItemsRepository.AsQueryable()
                    .OrderBy(c => c.HierarchyLevel)
                    .ToListAsync();

                // Словарь для сопоставления старых Id с новыми CostId
                var idMap = new Dictionary<int, int>();

                foreach (var costItem in costItems)
                {
                    // Пропускаем уже импортированные записи
                    if (costItem.IsMigrated)
                    {
                        _logger.LogInformation($"Запись Id {costItem.Id} уже импортирована. Пропуск.");
                        continue;
                    }

                    try
                    {
                        // 1. Обработка Project
                        Project project = null;
                        if (costItem.ProjectId != 0) // Проверка на валидный ProjectId
                        {
                            project = await projectsRepository.AsQueryable()
                                .FirstOrDefaultAsync(p => p.Id == costItem.ProjectId);

                            if (project == null)
                            {
                                // Создаем новый проект, если не найден
                                project = new Project
                                {
                                    Id = costItem.ProjectId,
                                    //Title = $"Project {costItem.ProjectId}" // Настройте логику именования
                                    ////// Заполните другие поля проекта, если есть
                                };
                                projectsRepository.Create(project);
                                await _unitOfWork.SaveChangesAsync();
                                _logger.LogInformation($"Создан новый проект: {project.Id}");
                            }
                        }
                        else
                        {
                            _logger.LogWarning($"Запись Id {costItem.Id} имеет неверный ProjectId.");
                            continue; // Пропускаем запись или можно обработать иначе
                        }

                        // 2. Обработка CostType
                        var costType = await costTypesRepository.AsQueryable()
                            .FirstOrDefaultAsync(ct => ct.TypeName == costItem.TypeCost);

                        if (costType == null)
                        {
                            costType = new CostType
                            {
                                TypeName = costItem.TypeCost
                            };
                            costTypesRepository.Create(costType);
                            await _unitOfWork.SaveChangesAsync();
                            _logger.LogInformation($"Создан новый тип затрат: {costType.TypeName}");
                        }

                        // 3. Обработка Unit
                        Unit unit = null;
                        if (!string.IsNullOrWhiteSpace(costItem.UnitOfMeasure))
                        {
                            unit = await unitsRepository.AsQueryable()
                                .FirstOrDefaultAsync(u => u.UnitName == costItem.UnitOfMeasure);

                            if (unit == null)
                            {
                                unit = new Unit
                                {
                                    UnitName = costItem.UnitOfMeasure,
                                    UnitDescription = "" // Заполните при необходимости
                                };
                                unitsRepository.Create(unit);
                                await _unitOfWork.SaveChangesAsync();
                                _logger.LogInformation($"Создана новая единица измерения: {unit.UnitName}");
                            }
                        }

                        // 4. Обработка ParentCost
                        int? parentCostId = null;
                        if (costItem.ParentId.HasValue)
                        {
                            if (idMap.TryGetValue(costItem.ParentId.Value, out int newParentCostId))
                            {
                                parentCostId = newParentCostId;
                            }
                            else
                            {
                                _logger.LogWarning($"ParentId {costItem.ParentId.Value} не найден для записи Id {costItem.Id}. Запись пропущена.");
                                continue; // Пропускаем запись или можно обработать иначе
                            }
                        }

                        // 5. Создание новой записи Cost
                        var cost = _mapper.Map<Cost>(costItem);
                        cost.ProjectId = project.Id;
                        cost.ParentCostId = parentCostId;
                        cost.CostTypeId = costType.CostTypeId;
                        cost.UnitId = unit?.UnitId;

                        costsRepository.Create(cost);
                        await _unitOfWork.SaveChangesAsync();

                        _logger.LogInformation($"Создана новая затрата: {cost.CostName} (NumberItem: {cost.NumberItem})");

                        // Обновление словаря
                        idMap[costItem.Id] = cost.CostId;

                        // 6. Создание записи Material или Work
                        if (costItem.TypeCost.Equals("Материал", StringComparison.OrdinalIgnoreCase))
                        {
                            var material = new Material
                            {
                                CostId = cost.CostId
                                // Добавьте дополнительные поля, если необходимо
                            };
                            materialsRepository.Create(material);
                            _logger.LogInformation($"Создан материал для затрат: {cost.CostName}");
                        }
                        else if (costItem.TypeCost.Equals("Работа", StringComparison.OrdinalIgnoreCase))
                        {
                            var work = new Work
                            {
                                CostId = cost.CostId
                                // Добавьте дополнительные поля, если необходимо
                            };
                            worksRepository.Create(work);
                            _logger.LogInformation($"Создана работа для затрат: {cost.CostName}");
                        }

                        // 7. Установка флага миграции
                        costItem.IsMigrated = true;
                        //costItemsRepository.Update(costItem);

                        // Сохраняем изменения
                        await _unitOfWork.SaveChangesAsync();
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"Ошибка при обработке записи Id {costItem.Id}");
                        // Приезжая ошибка может прервать весь процесс из-за транзакции
                        throw;
                    }
                }

                // Завершение транзакции
                await _unitOfWork.CommitAsync();
                _logger.LogInformation("Миграция данных завершена успешно.");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при миграции данных. Произошёл откат транзакции.");
                await _unitOfWork.RollbackAsync();
                throw; // Перебрасываем ошибку выше, если необходимо
            }
        }
    }
}
```
измени обработку сущности Work. Замени на сущность ProjectWorkStages. Это будут этапы проектов.
Выбери все работы уровень иерархии которых больше 2, добавь поля сроков выполнения работ, начало текущий день, окончание оставь пустым , примечания возьми из полей ISRComment, ContractorComment, статус установи в значение Планируемое.
Сохрани в новую таблицу в базе данных.
```
Вот пример моего контроллера для понимания используемых технологий.
```
using System.Text.RegularExpressions;
using AutoMapper;
using BuildingFlow.Data.Contract;
using BuildingFlow.Data.Entities;
using BuildingFlow.Services.CostImportService;
using BuildingFlow.Services.Models.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OfficeOpenXml;

namespace BuildingFlow.Web.Controllers;

public class CostItemsImportController : Controller
{
  private readonly IUnitOfWork _unitOfWork;
  private readonly IMapper _mapper;
  private readonly IRepository<CostItem> _costItemRepository;

  public CostItemsImportController(IUnitOfWork unitOfWork, IMapper mapper)
  {
    _unitOfWork = unitOfWork;
    _mapper = mapper;
    _costItemRepository = _unitOfWork.GetRepository<CostItem>();
  }

  // GET: CostItems
  public async Task<IActionResult> Index()
  {
    var costItems = await _costItemRepository.AsReadOnlyQueryable()
      .Where(ci => ci.ProjectId == 1)
      .ToListAsync();

    var costItemViewModel = _mapper.Map<IEnumerable<CostItemViewModel>>(costItems);

    return View(costItemViewModel);
  }

  //GET: CostItems/Upload
  [HttpGet]
  public IActionResult Upload()
  {
    return View();
  }

  [HttpPost]
  public async Task<IActionResult> Upload(IFormFile file)
  {
    if (file == null || file.Length == 0)
    {
      ModelState.AddModelError("", "Please upload a file.");
      return View();
    }

    var costItems = new List<CostItemAddViewModel>();

    using (var stream = new MemoryStream())
    {
      await file.CopyToAsync(stream);
      ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
      using (var package = new ExcelPackage(stream))
      {
        var worksheet = package.Workbook.Worksheets.First();
        var rowCount = worksheet.Dimension.Rows;

        for (int row = 2; row <= rowCount; row++) // Начинаем со второй строки, чтобы пропустить заголовки
        {
          var costItem = new CostItemAddViewModel();

          costItem.NumberItem =
            string.IsNullOrWhiteSpace(worksheet.Cells[row, 2].Text) ? null : worksheet.Cells[row, 2].Text;
          costItem.NodeCode = string.IsNullOrWhiteSpace(worksheet.Cells[row, 3].Text)
            ? null
            : worksheet.Cells[row, 3].Text;
          costItem.CostName = string.IsNullOrWhiteSpace(worksheet.Cells[row, 4].Text)
            ? null
            : worksheet.Cells[row, 4].Text;
          costItem.ISRComment =
            string.IsNullOrWhiteSpace(worksheet.Cells[row, 5].Text) ? null : worksheet.Cells[row, 5].Text;
          costItem.ContractorComment = string.IsNullOrWhiteSpace(worksheet.Cells[row, 6].Text)
            ? null
            : worksheet.Cells[row, 6].Text;
          costItem.UnitOfMeasure = string.IsNullOrWhiteSpace(worksheet.Cells[row, 7].Text)
            ? null
            : worksheet.Cells[row, 7].Text;
          costItem.ConsumptionCoefficient = ParseNullableDecimal(worksheet.Cells[row, 8].Text);
          costItem.BOCount = ParseNullableInt(worksheet.Cells[row, 9].Text);
          costItem.TotalCount = ParseNullableDecimal(worksheet.Cells[row, 10].Text);
          costItem.MatEquipmPrice = ParseNullableDecimal(worksheet.Cells[row, 11].Text);
          costItem.SmpPnpPrice = ParseNullableDecimal(worksheet.Cells[row, 12].Text);
          costItem.TotalPrice = ParseNullableDecimal(worksheet.Cells[row, 13].Text);
          costItem.MatEquipmCost = ParseNullableDecimal(worksheet.Cells[row, 14].Text);
          costItem.SmpPnpCost = ParseNullableDecimal(worksheet.Cells[row, 15].Text);
          costItem.TotalCost = ParseNullableDecimal(worksheet.Cells[row, 16].Text);
          costItem.ProjectId = 1;
          
          // Определение типа записи
          costItem.TypeCost = DetermineType(costItem.NodeCode, costItem.UnitOfMeasure);
          costItems.Add(costItem);
        }

        var entities = _mapper.Map<List<CostItem>>(costItems);
        _costItemRepository.CreateRange(entities);
        await _unitOfWork.SaveChangesAsync();
      }


    } 

    return RedirectToAction("MigrateHierarchy"); // Перенаправление на другую страницу после загрузки
  }

  // GET: CostItems/MigrateHierarchy
  public async Task<IActionResult> MigrateHierarchy()
  {
    // Получаем все элементы, отсортированные по NumberItem для корректного определения родителей
    var costItems = await _costItemRepository.AsQueryable()
        .OrderBy(c => c.NumberItem)
        .ToListAsync();

    // Создаём словарь для быстрого поиска по numericNumberItem
    var costItemsDict = costItems
        .Select(c => new
        {
          CostItem = c,
          NumericNumberItem = GetNumericNumberItem(c.NumberItem)
        })
        .ToDictionary(x => x.NumericNumberItem, x => x.CostItem);

    foreach (var item in costItems)
    {
      if (string.IsNullOrEmpty(item.NumberItem))
      {
        // Если NumberItem пустой, пропускаем
        continue;
      }

      // Извлекаем только числовую часть NumberItem
      var numericNumberItem = GetNumericNumberItem(item.NumberItem);
      if (string.IsNullOrEmpty(numericNumberItem))
      {
        // Не удалось извлечь числовую часть, пропускаем
        continue;
      }

      // Разбиваем numericNumberItem на сегменты
      var segments = numericNumberItem.Split('.');
      if (segments.Length > 1)
      {
        // Формируем родительский numericNumberItem, убирая последний сегмент
        var parentNumberItem = string.Join('.', segments.Take(segments.Length - 1));

        // Ищем родителя по numericNumberItem
        if (costItemsDict.TryGetValue(parentNumberItem, out var parent))
        {
          item.ParentId = parent.Id;
          item.HierarchyLevel = parent.HierarchyLevel.HasValue ? parent.HierarchyLevel + 1 : segments.Length;
        }
        else
        {
          // Если родитель не найден, устанавливаем ParentId = null и уровень 1
          item.ParentId = null;
          item.HierarchyLevel = 1;
        }
      }
      else
      {
        // Если это корневой элемент, ParentId = null и уровень 1
        item.ParentId = null;
        item.HierarchyLevel = 1;
      }
    }

    // Сохраняем изменения
    await _unitOfWork.SaveChangesAsync();

    return RedirectToAction("Index");
    //return Content("Миграция иерархии выполнена успешно.");
  }

  private string GetNumericNumberItem(string numberItem)
  {
    var match = Regex.Match(numberItem, @"^\d+(\.\d+)*");
    return match.Success ? match.Value : string.Empty;
  }

  // GET: CostItems/Hierarchy
  public async Task<IActionResult> Hierarchy()
  {
    var allCostItems = await _costItemRepository.AsReadOnlyQueryable()
      .OrderBy(c => c.NumberItem) // Сортировка для упорядоченного отображения
      .ToListAsync();

    var hierarchy = BuildHierarchy(allCostItems);

    return View(hierarchy);
  }

  private string DetermineType(string? nodeCode, string? unitOfMeasure)
  {
    if (string.IsNullOrWhiteSpace(nodeCode)&& !string.IsNullOrEmpty(unitOfMeasure))
    {
        return "Материал";
    }

    return "Работа"; // По умолчанию считаем запись работой
  }

  private decimal? ParseNullableDecimal(string text)
  {
    return decimal.TryParse(text, out decimal result) ? result : (decimal?)null;
  }

  private int? ParseNullableInt(string text)
  {
    return int.TryParse(text, out int result) ? result : (int?)null;
  }

  private List<CostItemHierarchyViewModel> BuildHierarchy(List<CostItem> costItems)
  {
    var lookup = costItems.ToLookup(ci => ci.ParentId);
    List<CostItemHierarchyViewModel> BuildNodes(int? parentId)
    {
      return lookup[parentId]
        .OrderBy(ci => ci.NumberItem) // Опционально: сортировка по NumberItem
        .Select(ci => new CostItemHierarchyViewModel
        {
          Id = ci.Id,
          NumberItem = ci.NumberItem,
          CostName = ci.CostName,
          MatEquipmCost = ci.MatEquipmCost,
          SmpPnpCost = ci.SmpPnpCost,
          // Добавьте другие свойства по необходимости
          Children = BuildNodes(ci.Id)
        })
        .ToList();
    }

    return BuildNodes(null); // Начинаем с корневых элементов (ParentId == null)
  }
}