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

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Вывод элементов списка в виде массива

Ответить
Настройки темы
PowerShell - Вывод элементов списка в виде массива

Аватара для NickM

Ветеран


Contributor


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


Конфигурация

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


Уважаемые, здравствуйте!

Задалcя вопросом обработки *.xml файлов, вроде бы даже добился какого-никакого решения поставленной перед Собою задачи, но вот одного не могу разрешить: вывод элемента списка в виде массива, Powershell его "подрезает" и отображает только несколько первых символов.

Список объявляю так:
Код: Выделить весь код
$list2 = New-Object System.Collections.Generic.List[System.Object];
Наполняю так:
Код: Выделить весь код
$aSumItog = @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
foreach ($item in $tmplist2) {
	$list2.Add([PSCustomObject]@{cFIO = $item; cSum = $aSumItog})
}
При выводе в консоль или в файл вижу следуюущее:
Код: Выделить весь код
cFIO                            cSum                   
----                            ----                   
Петров Петр Петрович      {0, 0, 0, 0...}
, а хотелось бы видеть все столбцы массива.

Может, кто подскажет как этого добиться?

Отправлено: 19:24, 25-10-2023

 

Аватара для NickM

Ветеран


Contributor


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

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


Вложения
Тип файла: zip Сверка_КНД_1151111_и_1151162.ps1.zip
(2.1 Kb, 19 просмотров)

Цитата YuS_2:
И да, судя по файлам, количество элементов (и атрибутов элементов тоже) в них различное... а могут быть ещё какие-нибудь поля, которых нет в примерах? Если парсить xml, то нужны будут наименования элементов, по которым необходимо делать выборку... или там просто всё подряд, что найдем, то и "выплюнуть" на выход? »
Можно вместо ответа прикреплю сценарий? Это не будет выглядеть наглостью?

UPD: Перезалил файл по причине добавления комментариев к сценарию.

Последний раз редактировалось NickM, 27-10-2023 в 15:47.


Отправлено: 15:24, 27-10-2023 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для Pavel Nagaev

Пользователь


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

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


Придирки по коду :-).

$list1 = New-Object System.Collections.Generic.List[System.Object];
$list3 = New-Object System.Collections.Generic.List[System.Object];

Можно на это поменять

using namespace System.Collections.Generic
$list1 =[List[string]]@()
$list3 =[List[string]]@()


Табуляцию [char]9 на "`t"

Причём вы тут
$tmplist3.Add($item.cFIO + [char]9 + $item.cINN + [char]9 + $item.cSNILS + [char]9 + ($item.cSum -join "`t")

используте "`t", но зачем-то и [char]9


вот это
$list3.Add([PSCustomObject]@{cPeriod = $cPeriod; cFIO = $cFIO; cINN = $cINN; cSNILS = $cSNILS; cmes = $cMes; cSum = $cSum});

на это и в конце строки ; не нужна.

$list3.Add([PSCustomObject]@{cPeriod = $cPeriod;
cFIO = $cFIO;
cINN = $cINN;
cSNILS = $cSNILS;
cmes = $cMes;
cSum = $cSum;
}
)
Это чисто удобство чтения.

Кодировку добавить.

$tmplist3 | Out-File 'КНД_1151111.csv' -Encoding utf8

-------
Видео на русском про PowerShell
Крутые курсы по PowerShell

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

Отправлено: 15:25, 27-10-2023 | #12


Аватара для NickM

Ветеран


Contributor


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

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


Цитата Pavel Nagaev:
Придирки по коду :-). »
Благодарю, приму к сведению;

Цитата Pavel Nagaev:
используете "`t", но зачем-то и [char]9 »
Только учусь

Цитата Pavel Nagaev:
Кодировку добавить. »
Ага, сейчас сохраняет в "UTF16-LE", но в том же "Excel" кириллица отображается корректно.

Отправлено: 15:32, 27-10-2023 | #13


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата NickM:
Можно вместо ответа прикреплю сценарий? Это не будет выглядеть наглостью? »
Да ноу проблемс, но так будет дольше и результат - не факт, что получится то, что требуется. Лучше было бы увидеть результат, который нужен... ну, или алгоритм, что куда и зачем.

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


Отправлено: 18:43, 27-10-2023 | #14


Аватара для NickM

Ветеран


Contributor


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

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


Цитата YuS_2:
ну, или алгоритм, что куда и зачем. »
Цитата NickM:
UPD: Перезалил файл по причине добавления комментариев к сценарию. »
Прокомментировал каждый блок кода.

Отправлено: 18:45, 27-10-2023 | #15


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата NickM:
Прокомментировал каждый блок кода. »
если бы эти комментарии могли помочь...
В общем, я предупреждал, что без алгоритма действий, результат может выйти совсем не таким, каким ожидался...
script.ps1 (кодировку скрипта лучше выбрать UTF8)
Код: Выделить весь код
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{
	    $t = $xml.selectnodes("//$node")
	    $f = $t.$fio
	    $s = @(@(0)*13)
	    if (($i=[int]$per) -lt 13){$s[$i] = [int]$t.сумвыпл} else {
	        $sv = [int[]]$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.снилс
			'СумГод' = [int]$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]
		}
	}
}

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

$path = $psscriptroot
if ($host.version.major -gt 5) {
    $enc = 'windows-1251'
    $csv = @{
        Encoding = 'utf8'
        NoTypeInformation = $true
        QuoteFields = 'ФИО'
    }
} 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.период
    if ($knd -eq '1151111'){
        $arr1111 += get-nodedataout -xml $x -node $nd_dfl -per $per -d $nd_svmk -f $fio -enc $enc -knd $knd
    } else {
        $arr1162_i += get-nodedataout -xml $x -node $nd_psfl -per $per -f $fio -enc $enc -knd $knd
    }
}
$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. Ѫ


Отправлено: 18:18, 28-10-2023 | #16


Аватара для NickM

Ветеран


Contributor


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

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


Цитата YuS_2:
результат может выйти совсем не таким, каким ожидался... »
Результат вышел и в принципе по коду всё понятно - Вы вообще не использовали списки и обошлись только массивами, всё завернули в процедуры/ функции и передачами параметров в оные (одной функцией считали данные из двух разных форм), избавились от сравнения текстовых переменных, не учли копейки и возможное отсутствие некоторых тегов.

Круто!

Отправлено: 21:36, 28-10-2023 | #17


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата NickM:
Результат вышел »
Оно и понятно, что даже отсутствие результата - тоже результат... Вопрос только в том, выполняет код необходимую задачу или нет.

Цитата NickM:
не использовали списки »
а зачем они здесь?

Цитата NickM:
не учли копейки »
а их надо учитывать?

Цитата NickM:
и возможное отсутствие некоторых тегов »
примеры, примеры и ещё раз примеры исходных данных... они всегда нужны для тестов.

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


Отправлено: 22:26, 28-10-2023 | #18


Аватара для NickM

Ветеран


Contributor


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

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


Вложения
Тип файла: zip xml.zip
(2.9 Kb, 19 просмотров)

Цитата YuS_2:
а зачем они здесь? »
Цитата NickM:
Не, задача предельная ясна и понятна - произвести сверку двух отчётных форм»
Сам использовал такой код:
Код: Выделить весь код
#Выполним сверку между отчётами и результат сохраним в файл
$tmplist4 | ?{$tmplist3 -notcontains $_} | Out-File 'Отсутствуют_в_КНД_1151111.csv';
$tmplist3 | ?{$tmplist4 -notcontains $_} | Out-File 'Отсутствуют_в_КНД_1151162.csv';
Цитата YuS_2:
а их надо учитывать? »
Ага, у Нас пока платят в рублях и с копейками:
Цитата:
СумВыпл="70000.00"
Цитата YuS_2:
Цитата NickM:
и возможное отсутствие некоторых тегов » »
Сам проверял отсутствие тегов в сравнении с $null:
Код: Выделить весь код
if ($item3.cMes -ne $null) {}
...
if ($aSum[$index] -eq $null) {}
Цитата YuS_2:
примеры, примеры и ещё раз примеры исходных данных... они всегда нужны для тестов. »
Вот, добавил пару строк в тестовые файлы, на которых может всплыть ошибка преобразования типов данных.

Отправлено: 22:49, 28-10-2023 | #19


Аватара для 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



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Вывод элементов списка в виде массива

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
PowerShell - [решено] Анализ элементов числового массива kelevara Скриптовые языки администрирования Windows 8 08-05-2013 16:40
C/C++ - Подсчет суммы положительных элементов массива antoiiika Программирование и базы данных 2 19-11-2011 05:20
PowerShell - Вывод нумерации элементов массива в консоль tarasov.evgeny Скриптовые языки администрирования Windows 0 12-04-2011 13:36
C/C++ - [решено] Найти среднее геометрическое элементов массива А (С++) kmi567 Программирование и базы данных 2 10-12-2010 05:06
С/С++ | Выбор 10 случайных элементов из массива Vovius Программирование и базы данных 5 29-08-2006 19:37




 
Переход