Имя пользователя:
Пароль:
 

Показать сообщение отдельно

Аватара для YuS_2

Crazy


Contributor


Сообщения: 1235
Благодарности: 518

Профиль | Отправить PM | Цитировать


Цитата NickM:
Не, задача предельная ясна и понятна - произвести сверку двух отчётных форм» »
И всё равно, это не ответ на вопрос:
Цитата YuS_2:
а зачем они здесь? »
Если задать его по-другому: а зачем именно списки? Т.е. вот это:
Код: Выделить весь код
New-Object System.Collections.Generic.List[System.Object]
для чего? Чем обычные массивы не устроили?
А на счет сверки двух отчетных форм... что именно сверяется? Вы же не думаете, что скилл телепатии у меня настолько развит?
По Вашим примерам понятно, что есть два вида форм, одна из которых содержит данные за месяц, другая за квартал... так вот каким образом Вам необходимо их сверять? Помесячно, поквартально, за год, за пятилетку и т.д.
Т.е. технически сверку сделать - вообще, не проблема. Тут важно получить данные и получить их в том виде, который требуется...

Цитата NickM:
Ага, у Нас пока платят в рублях и с копейками »
Вот видите, это пример того, что без внятного ТЗ, как правило и результат ХЗ
У нас, например, не в рублях и нет никаких копеек...

Далее...
Цитата NickM:
Вот, добавил пару строк в тестовые файлы, на которых может всплыть ошибка преобразования типов данных. »
На основании имеющихся исходных файлов, предполагалось, что на отдельное физлицо приходится по отдельному же файлу (помесячно и поквартально)... видимо, ошибочное было предположение и естественно, парсер, построенный на неверных предположениях, будет и работать неверно... В общем-то, именно поэтому и требуется описание задачи и примеры наиболее различные между собой и желательно не на единственного человека, а на нескольких, чтобы учесть все нюансы. Ковырять же чужой код для восстановления алгоритма - не самый продуктивный вид программирования...

Мой код опирался, помимо основной, больше на вот эту задачу (собственно, в первом сообщении, это и было главным вопросом):
Цитата NickM:
Мне надо было в табличный вид, для человеческого восприятия »
По коду парсера:
Основной скелет кода составлен, но для доведения этого кода "до ума", необходимо таки уточнение многих моментов, которые было бы неплохо описать в виде:
1. Вот исходные файлы, на одного-два-три-...-n физлиц.
2. Из них необходимо получать вот такие вот две формы (суммы ли в тех формах должны быть, либо только отдельные данные, сведенные по ИННФЛ или по какому-то ещё признаку, что-то ещё важное...).
3. В общем, сами эти итоговые формы, вернее их содержание, для сверки (опять же по нескольким физлицам), которые должны получиться из исходных данных, необходимо "нарисовать" вручную. А также требующийся формат конечных, выходных файлов, тоже было бы неплохо указать.
Так будет проще составить парсер, который будет делать то, что от него требуется.

По новым примерам было, конечно, проще поправить код... но непонятно, как могут возникать различия при сверке, т.к. Вашим кодом они не обнаружены. В том смысле, что вроде бы нужны ещё и четкие примеры таких различий в исходных данных, которые требуется обнаруживать сверкой.
Вот код, в котором можно легко сделать сверку по тем данным, которые Вы предоставили, но за один квартал. Не обращайте внимание, что нет выходных файлов сверки (это организовать несложно), смотрите в консоль, там можете визуально сравнивать данные, сгруппированные по ИННФЛ. В версии powershell 5.1 автоматическое преобразование типов сделает вывод целых чисел, без нулей после запятой (при желании можно сделать принудительную типизацию), а в версии PS 7.3.6, все числа будут выведены, как [double]
Код: Выделить весь код
function Get-NodeAttrDoc ($xml,$node,$enc){
    process{
        $n = $xml.selectnodes("//$node")
        [pscustomobject]@{
            'КНД' = $n.кнд
            'Период' = $n.период
        }
    }
}

function Get-NodeDataOut ($xml,$node,$per,$dat,$fio,$enc,$knd){
    process{
        $tarr = $xml.selectnodes("//$node")
        $out = foreach($t in $tarr){
            $f = $t.$fio
            $s = @(@([double]0)*13)
            if (($i=[int]$per) -lt 13){$s[$i] = [double]$t.сумвыпл} else {
                $sv = [double[]]$xml.selectnodes("//$dat").сумвыпл
                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 ' '
                'ИННФЛ' = $t.иннфл
                'СНИЛС' = $t.снилс
                'СумГод' = $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_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_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}
$arr1162|sort 'ФИО'|export-csv '1162.csv' @csv
$arr1111|sort 'ФИО'|export-csv '1111.csv' @csv
$arr1111+$arr1162|sort 'ФИО'|ft * -a -w

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 29-10-2023 в 12:42.

Это сообщение посчитали полезным следующие участники:

Отправлено: 12:23, 29-10-2023 | #20