Ошибка системного объекта при экспорте результатов в CSV

Я пытаюсь экспортировать свои результаты из объекта сравнения в csv, но получаю сообщение об ошибке при экспорте. Это выглядит нормально, когда я просто вызываю его в Excel. Я предполагаю, что всякий раз, когда выводится более одного значения, вместо значения помещается ошибка.

Вот мои файлы csv в прошлом.csv

VKEY
V-12345
V-23456
V-1111

текущий.csv

VKEY
V-12345
V-6789
V-23456
V-256

Мой новый csv должен сказать

Past, Current
V-6789,V-1111
V-256

То, что я получаю сейчас, это

Past, Current
System.Object[],@{vkey=V-1111}

.

$Past = Import-CSV "past.csv"
$Current = Import-CSV "Current.csv"

$pastchange = Compare-Object $Past $Current -Property vkey | Where-Object {$_.SideIndicator -eq '=>'} | Select-Object VKEY
$currentchange = Compare-Object $Past $Current -Property vkey | Where-Object {$_.SideIndicator -eq '<='} | Select-Object VKEY

$obj = New-Object PSObject
$obj | Add-Member NoteProperty Past $pastchange
$obj | Add-Member NoteProperty Current $currentchange
$obj | Export-Csv "ChangeResults.csv" -NoTypeInformation

person ShanayL    schedule 10.06.2016    source источник


Ответы (1)


Этот System.Object[], отображаемый в столбце $obj.Past, представляет собой просто массив пользовательских объектов, похожих на @{vkey=V-1111} в столбце $obj.Past. Доказательство:

PS D:\PShell> $obj
$obj.Past.Gettype() | Format-Table
$obj.Current.Gettype()
"---"
$obj.Past | ForEach-Object { $_.Gettype() }

Past                                       Current                                  
----                                       -------                                  
{@{vkey=V-6789}, @{vkey=V-256}}            @{vkey=V-1111}                           

IsPublic IsSerial Name                                     BaseType                 
-------- -------- ----                                     --------                 
True     True     Object[]                                 System.Array             

IsPublic IsSerial Name                                     BaseType                 
-------- -------- ----                                     --------                 
True     False    PSCustomObject                           System.Object            
---
True     False    PSCustomObject                           System.Object            
True     False    PSCustomObject                           System.Object            

В моем решении используется класс ArrayList ( .NET Фреймворк):

$csvOutFile = "d:\test\ChangeResults.csv"    # change to fit your circumstances
$PastInFile = "d:\test\past.csv"
$CurrInFile = "d:\test\curr.csv"

$Past = Import-CSV $PastInFile
$Curr = Import-CSV $CurrInFile

# compare CSV files and convert results to arrays
$PastCh=@(,                                     <# always return an array           #>
            $( Compare-Object $Past $Curr -Property vkey | 
                 Where-Object { $_.SideIndicator -eq '=>' } ) |
             ForEach-Object { $_ | Select-Object -ExpandProperty vkey }
          )
$CurrCh=@(,                                     <# even if no SideIndicator matches #>
            $( Compare-Object $Past $Curr -Property vkey | 
                 Where-Object { $_.SideIndicator -eq '<=' } ) |
             ForEach-Object { $_ | Select-Object -ExpandProperty vkey }
          )

[System.Collections.ArrayList]$csvout = New-Object System.Collections.ArrayList($null)
$auxHash = @{}                                       # an auxiliary hash object

$max = ($CurrCh.Count, $PastCh.Count | Measure-Object -Maximum).Maximum
for ($i=0; $i -lt $max; $i++) {
    Try { $auxHash.Past = $PastCh.GetValue($i) } Catch { $auxHash.Past = '' }
    Try { $auxHash.Curr = $CurrCh.GetValue($i) } Catch { $auxHash.Curr = '' }
    $csvout.Add((New-Object PSObject -Property $auxHash)) > $null
}
$csvout | Format-Table -AutoSize      #  show content: 'variable $csvout'

$csvout | Export-Csv $csvOutFile -NoTypeInformation 
Get-Content $csvOutFile               #  show content: "output file $csvOutFile"

Вывод:

PS D:\PShell> D:\PShell\SO\37753277.ps1

Past   Curr  
----   ----  
V-6789 V-1111
V-256        


"Past","Curr"
"V-6789","V-1111"
"V-256",""

PS D:\PShell> 

Вот альтернатива блокам TryCatch:

    <# another approach instead of `Try..Catch`:
    if ($i -lt $PastCh.Count) { $auxHash.Past = $PastCh.GetValue($i)
                       } else { $auxHash.Past = '' }
    if ($i -lt $CurrCh.Count) { $auxHash.Curr = $CurrCh.GetValue($i)
                       } else { $auxHash.Curr = '' }
    #>
person JosefZ    schedule 11.06.2016