Показать полную графическую версию : Вывод элементов списка в виде массива
Да, совсем забыл:
код просто подкорректирован для наличия нескольких однотипных элементов в одном файле, но считать может пока неверно... т.е. его ещё надо проверять.
По новым примерам было, конечно, проще поправить код... но непонятно, как могут возникать различия при сверке, т.к. Вашим кодом они не обнаружены. »
Всё верно, т.к. в приложенных примерах расхождений не имеется, но как только у физ.лица изменить хоть какой-нибудь сравниваемый тег - ИНН, СНИЛС, сумму в любом месяце квартала в любой из форм, сразу выйдет расхождение;
Вот видите, это пример того, что без внятного ТЗ, как правило и результат ХЗ »
Извините, полагал, что описание в посте (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 и не только это, что возьму на вооружение/ непременно этим воспользуюсь.
но как только у физ.лица изменить хоть какой-нибудь сравниваемый тег - ИНН, СНИЛС, сумму в любом месяце квартала в любой из форм, сразу выйдет расхождение »
Понятно, так и сделал... вылезли ещё баги... поправлены
Извините, полагал, что описание в посте и комментарий в коде окажется достаточным »
Ну, номера форм для меня малоинформативны оказались... а код чужой разбирать... ну, это не очень продуктивно, учитывая, что автор кода мог иметь свой алгоритм для реализации задачи и по коду не всегда его можно легко определить.
ТЗ. »
Так гораздо понятнее!
Примерно так:
# Функция получения кода документа и периода (месяц/квартал)
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
- подробно комментировать не стал, просто обозначил где что расположено. »
Благодарю, код полностью читаем и понятен.
На выборочных данных работает в среднем на 100-150 миллисекунд быстрее (проверку СНИЛС в diff добавить не составило труда :) ).
NickM, а, да, забыл совсем... есть ещё более наглядная визуализация табличных данных.
Замените код здесь:
$arr1111+$arr1162|sort 'ФИО','КНД'|ft * -a -w
на такой:
$arr1111+$arr1162|sort 'ФИО','КНД'|ogv
есть ещё более наглядная визуализация табличных данных. »
Ага, отображение в гриде.
Спаcибо, но достаточно *.csv для табличного редактора "Excel".
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.