Войти

Показать полную графическую версию : Вывод элементов списка в виде массива


Страниц : 1 [2]

YuS_2
29-10-2023, 12:51
Да, совсем забыл:
код просто подкорректирован для наличия нескольких однотипных элементов в одном файле, но считать может пока неверно... т.е. его ещё надо проверять.

NickM
29-10-2023, 12:55
По новым примерам было, конечно, проще поправить код... но непонятно, как могут возникать различия при сверке, т.к. Вашим кодом они не обнаружены. »
Всё верно, т.к. в приложенных примерах расхождений не имеется, но как только у физ.лица изменить хоть какой-нибудь сравниваемый тег - ИНН, СНИЛС, сумму в любом месяце квартала в любой из форм, сразу выйдет расхождение;

Вот видите, это пример того, что без внятного ТЗ, как правило и результат ХЗ »
Извините, полагал, что описание в посте (http://forum.oszone.net/post-3018995-9.html) и комментарий в коде окажется достаточным :sorry:
ТЗ.
1. Получить табличное представление каждой из форм, где каждая строка представляет из себя:
ФИО, ИНН, СНИЛС, итоговая сумма за год, ежемесячная сумма за каждый месяц – [1], [2]…[12];

2. Произвести сверку двух форм, где различие составляют как перс.данные(ФИО, ИНН, СНИЛС), как итоговая сумма за год, так и суммы за каждый месяц;

Сверка форм осуществляется в разрезе квартала/ кварталов. Т.е. форм 1151162 всегда кратно 3 количества форм 1151111, т.е. если сверяем один квартал, тогда 1151162= 3шт., 1151111= 1шт., сверяем 2 квартала – 6шт. и 2 шт. соответственно (по сути, это не имеет значения, т.к. для проверки всегда подаётся правильное количество форм).

Некоторые замечания по формам:
В 1151111 могут отсутствовать сравниваемые теги с суммами в следующем узле, как и сам родительский узел: «СвВыплСВОПС»--> «СвВыпл»--> «СвВыплМК».


но для доведения этого кода "до ума", необходимо таки уточнение многих моментов, которые было бы неплохо описать в виде: »
Опять же упомяну приложенный Мною рабочий код, который формирует как табличные данные, так и выполняет сверку;

Основной скелет кода составлен »
Да, Вы показали как использовать процедуры/ функции в powershell и не только это, что возьму на вооружение/ непременно этим воспользуюсь.

YuS_2
29-10-2023, 17:31
но как только у физ.лица изменить хоть какой-нибудь сравниваемый тег - ИНН, СНИЛС, сумму в любом месяце квартала в любой из форм, сразу выйдет расхождение »
Понятно, так и сделал... вылезли ещё баги... поправлены

Извините, полагал, что описание в посте и комментарий в коде окажется достаточным »
Ну, номера форм для меня малоинформативны оказались... а код чужой разбирать... ну, это не очень продуктивно, учитывая, что автор кода мог иметь свой алгоритм для реализации задачи и по коду не всегда его можно легко определить.

ТЗ. »
Так гораздо понятнее!

Примерно так:
# Функция получения кода документа и периода (месяц/квартал)
function Get-NodeAttrDoc ($xml,$node,$enc){
process{
$n = $xml.selectnodes("//$node")
[pscustomobject]@{'КНД' = $n.кнд;'Период' = $n.период}
}
}

# Функция формирования выходных данных
function Get-NodeDataOut ($xml,$node,$pnode,$per,$dat,$fio,$enc,$knd){
process{
$tarr = $xml.selectnodes("//$node")
$out = foreach($t in $tarr){
$s,$sv,$tsv = @(@([double]0)*13),@(@([double]0)*3),$null
if($pnode){
$f,$inn,$sni = $t.$pnode.$fio,$t.$pnode.иннфл,$t.$pnode.снилс
} else {
$f,$inn,$sni = $t.$fio,$t.иннфл,$t.снилс
}
if (($i=[int]$per) -lt 13){$s[$i] = [double]$t.сумвыпл} else {
$tsv = $t.getelementsbytagname($dat)
if ($tsv){
foreach($it in $tsv){
$sv[([int]$it.месяц-1)] = [double]$it.сумвыпл
}
}
switch ($per){
$kv[0]{$s[1]=$sv[0];$s[2]=$sv[1];$s[3]=$sv[2]}
$kv[1]{$s[4]=$sv[0];$s[5]=$sv[1];$s[6]=$sv[2]}
$kv[2]{$s[7]=$sv[0];$s[8]=$sv[1];$s[9]=$sv[2]}
$kv[3]{$s[10]=$sv[0];$s[11]=$sv[1];$s[12]=$sv[2]}
}
$s[0] = ($s|measure -sum).sum
}
[pscustomobject]@{
'КНД' = $knd
'ФИО' = ($f.фамилия,$f.имя,$f.отчество) -join ' '
'ИННФЛ' = $inn
'СНИЛС' = $sni
'СумГод' = $s[0]
'01' = $s[1]
'02' = $s[2]
'03' = $s[3]
'04' = $s[4]
'05' = $s[5]
'06' = $s[6]
'07' = $s[7]
'08' = $s[8]
'09' = $s[9]
'10' = $s[10]
'11' = $s[11]
'12' = $s[12]
}
}
}
end{return $out}
}

# Функция суммирования отдельных документов на единое лицо
function get-sumdoc1162 ($elem,$i){
$b = $i|%{($elem.$_|measure -sum).sum}
[pscustomobject]@{
'КНД' = $elem[0].кнд
'ФИО' = $elem[0].фио
'ИННФЛ' = $elem[0].иннфл
'СНИЛС' = $elem[0].снилс
'СумГод' = ($b|measure -sum).sum
'01' = $b[0]
'02' = $b[1]
'03' = $b[2]
'04' = $b[3]
'05' = $b[4]
'06' = $b[5]
'07' = $b[6]
'08' = $b[7]
'09' = $b[8]
'10' = $b[9]
'11' = $b[10]
'12' = $b[11]
}
}

# Инициализация переменных и сплаттинг
$path = "$psscriptroot\xml"
if ($host.version.major -gt 5) {
$enc = 'windows-1251'
$csv = @{
Encoding = 'utf8'
NoTypeInformation = $true
UseQuotes = 'AsNeed'
}
} else {
$enc = 'default'
$csv = @{
Encoding = 'utf8'
NoTypeInformation = $true
}
}
$flt = 'NO_*.xml'
$nd = 'Документ'
$nd_pssl = 'ПерсСвСтрахЛиц'
$nd_dfl = 'ДанФЛПолуч'
$nd_svmk = 'СвВыплМК'
$nd_psfl = 'ПерсСвФЛ'
$fio = 'ФИО'
$kv = @('21','31','33','34')
$arr1162_i, $arr1111 = @(),@()

# Основной код
dir $path -filt $flt -file|%{
$x = [xml](gc $_.fullname -enc $enc)
$tmp = get-nodeattrdoc $x $nd $enc
$knd = $tmp.кнд
$per = $tmp.период
$ndo = @{XML=$x;PER=$per;FIO=$fio;ENC=$enc;KND=$knd}
if ($knd -eq '1151111'){
$arr1111 += get-nodedataout @ndo -node $nd_pssl -pnode $nd_dfl -d $nd_svmk
} else {
$arr1162_i += get-nodedataout @ndo -node $nd_psfl
}
}
#Получаем список кодов периодов помесячно:
$m = 1.. 12|%{"$_".padleft(2,'0')}
# Суммируем помесячные документы на одно лицо (единый ИННФЛ) в единую строку:
$arr1162 = $arr1162_i|group -prop 'иннфл'|%{get-sumdoc1162 $_.group $m}

# Экспорт в CSV файлы
$arr1162|sort 'ФИО'|export-csv '1162.csv' @csv
$arr1111|sort 'ФИО'|export-csv '1111.csv' @csv

# Вывод в консоль общей таблицы:
$arr1111+$arr1162|sort 'ФИО','КНД'|ft * -a -w

# Получение различий с индикаторами:
diff $arr1111 $arr1162 -prop "ФИО","ИННФЛ",'СумГод','01','02',
'03','04','05','06','07','08','09','10','11','12'|export-csv 'diff.csv' @csv

- подробно комментировать не стал, просто обозначил где что расположено.
Формируются два выходных файла с данными в CSV формате, плюс CSV-файл с различиями в данных, если таковые обнаружатся - файл хоть и один, но у каждой строки будет индикатор из какого массива получены данные: "<=" - ReferenceObject и "=>" - DifferenceObject

NickM
29-10-2023, 18:44
- подробно комментировать не стал, просто обозначил где что расположено. »
Благодарю, код полностью читаем и понятен.

На выборочных данных работает в среднем на 100-150 миллисекунд быстрее (проверку СНИЛС в diff добавить не составило труда :) ).

YuS_2
29-10-2023, 19:33
NickM, а, да, забыл совсем... есть ещё более наглядная визуализация табличных данных.
Замените код здесь:
$arr1111+$arr1162|sort 'ФИО','КНД'|ft * -a -w
на такой:
$arr1111+$arr1162|sort 'ФИО','КНД'|ogv

NickM
29-10-2023, 19:37
есть ещё более наглядная визуализация табличных данных. »
Ага, отображение в гриде.

Спаcибо, но достаточно *.csv для табличного редактора "Excel".




© OSzone.net 2001-2012