2017-12-14 14 views
0

Microsoft Accessからテーブルを取得しようとしていて、CSVファイルの各列がプロパティになる のテーブルがPowerShellにあります行内の項目がプロパティ値になります。「Import-CSV」のようなPowershellカスタムオブジェクトを作成するには

$ColumnCount = 0; 
$contactObject = new-object PSObject; 
if ($rs.RecordCount -ne 0) { 
    do { 
     $rs.MoveFirst() 
     $valueArray = @(); 
     do { 
      foreach ($columnHeader in $rs.fields.item($ColumnCount).name) { 
       $value = $rs.Fields.Item($columnHeader).Value; 
       $valueArray += $value  
      } 
      $rs.MoveNext() 
     } until ($rs.EOF -eq $True) 
     $contactObject | Add-Member -MemberType NoteProperty -Name $columnHeader -Value $valueArray;  
     $ColumnCount++ 
    } until ($ColumnCount -eq $rs.fields.count) 
} 

そしてそれは、この出力::私が持っていただけに近い成功はこれです

EquipmentPackageID  ElementID   ArchitectureID Delete       

------------------  ---------   -------------- ------       

{117, 117, 126, 126...} {32, 32, 32, 32...} {-1, 1, -1, 1...} {False, False, False, False...} 

しかし、私は個々のアレイを望んでいません。

基本的に1つのテーブルにしたいです。また、この関数は異なるサイズのテーブルと名前付きテーブルをアクセスから受け入れることができなければなりません。 この4列テーブルに合わせたカスタムオブジェクトを作成することはできません。

また
$MyFiles = Get-ChildItem C:\Windows\ | ForEach-Object { 
    [pscustomobject]@{ 
     Name = $_.Name; 
     FullName = $_.FullName; 
     CreationDate = $_.CreationTime.Date; 
    } 
} 

、このパターンを避ける:

$Array = @() 
$x | ForEach-Object { 
    $Record = [...] 
    $Array += $Record 
} 

Basic .NETの配列のサイズを変更することはできません

+1

コードを内側にして、データベースの各レコードから1つのカスタムオブジェクトを作成し、カスタムオブジェクトを配列に追加してみてください。 –

+0

私はそれを試してみました。各値のadd-memberをループして、それらを一緒に追加します。それは動作するようですが、**のエラーが発生します: "add-member:その名前のメンバが既に存在するため、" Delete "という名前のメンバを追加できません。あなたのコマンドにパラメータを強制してください。 "**そして、もし私がそれを加えると、それはまだ動作しません。しかし、それは最初のレコードのための素晴らしいテーブルを出力します。 – matt

答えて

1

PowerShellのバージョン3.0 +のための基本的なパターンは、このようなものです。つまり、$Array += [...]は完全に新しい配列を作成し、すべてをコピーしてから、古い配列を破棄する必要があります。配列が大きくなればなるほど、この操作が高価になり、消費するメモリが増え、スクリプトが遅くなります。任意の通常のO(n)複雑度ループをO(n^2)複雑度ループに変換します。

$Array = $x | ForEach-Object { [...] } 

またはこの:あなたがこれを行う必要があるのいずれかを意味

$Array = New-Object -TypeName System.Collections.ArrayList; 
$x | ForEach-Object { 
    $Record = [...] 
    $Array.Add($Record) 
} 

はここで動的ヘッダを引っ張る何かの例です。この場合、最初の10個のファイルのString型とDateTime型のすべてのプロパティをC:\Windows\にプルします。

# Get the data 
$Data = Get-ChildItem C:\Windows\ -File | Select-Object -First 10; 

# Get the headers that meet our criteria 
# It's not important what this code is doing, it's just establishing headers 
# dynamically 
$Headers = $Data[0].PSObject.Properties | 
    Where-Object TypeNameOfValue -in @('System.String', 'System.DateTime') | 
    Select-Object -ExpandProperty Name; 

# Iterate through the Data 
$Results = $Data | ForEach-Object { 
    # Create a hash table to save the properties in. 
    $Record = @{}; 

    # For each header, create a property in the hash table and assign it the corresponding value from the object in the stream 
    foreach ($Header in $Headers) { 
     $Record.$Header = $_.$Header; 
    } 

    # Convert the hash table we've saved to a PSCustomObject 
    [PSCustomObject]$Record; 
} 

残念ながら、私は$rsが何であるか、または1つを作成する方法を知りません。私はそれがADO RecordSetのようなものだと想定していますが、あなたのロジックは私を幾分かエスケープします。 (すなわち、それは私がRecordSet.MoveFirst()がやって覚えて何をしなければ、それは間違っているループにありますように$rs.MoveFirst()が見えますが、私はmisrememberingすることができる。)

ここでの考え方は、しかし、同じです。

($ RS.EOF -eq $真)まで
+0

これは、多くの異なるテーブルで動作するようにしたいので、Name、FullName、CreationDateでカスタムオブジェクトを作成すると、ハードコードが機能しません。インポートしたい次の表には、これらの3つの列がない可能性があるためです。だから、私は列とレコードの数に基づいてループを実行しようとしているのです。しかし、アレイのヘッドアップのおかげで、私はそれをより効率的に変更しました。 – matt

+0

@mattそれでもやることができます。 '$ rs'が何であるか、あるいはそのタイプのオブジェクトを作成する方法がわからないので、私はあなたに特定の答えを与えることはできません。実行時にヘッダーを決定する例については、私の更新されたコードを参照してください。 –

+0

ご協力いただきありがとうございます! – matt

0
$resultsArray = New-Object -TypeName System.Collections.ArrayList; 
$ColumnCount = 0; 
$contactObject = new-object PSObject; 

if ($rs.RecordCount -ne 0){ 

$rs.MoveFirst() 

do { 
$ColumnCount = 0; 
do{ 
$columnHeader = $rs.fields.item($ColumnCount).name 
$value = $rs.Fields.Item($columnHeader).Value; 

$contactObject | add-member -membertype NoteProperty -name $columnHeader - 
Value $value; 

$columncount++ 

}until($ColumnCount -eq $rs.fields.count) 

$resultsArray.add($contactObject) 
$rs.MoveNext()   
$contactObject= new-object PSObject; 

}

} 

} 
    $resultsarray 

私はそれをやった!!!!トリックは、配列にレコードを追加して、オブジェクトを削除し、メンバを追加し、配列に追加し、オブジェクトをクリアするというものでした。

関連する問題