我正在尝试从Microsoft Access中提取表格并使其看起来像PowerShell中的Import-CSV
表格,
其中CSV文件中的每一列都成为自定义对象的属性,行中的项成为属性值。我唯一获得的成功就是:
$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...}
但我不想要个别阵列。
我希望它基本上都是一张桌子。此函数必须能够从访问中接受不同大小和命名的表。 因此,我无法创建为此4列表定制的自定义对象。
答案 0 :(得分:1)
PowerShell v3.0 +的基本模式是这样的:
$MyFiles = Get-ChildItem C:\Windows\ | ForEach-Object {
[pscustomobject]@{
Name = $_.Name;
FullName = $_.FullName;
CreationDate = $_.CreationTime.Date;
}
}
另外,请避免使用此模式:
$Array = @()
$x | ForEach-Object {
$Record = [...]
$Array += $Record
}
无法调整基本.NET数组的大小。这意味着$Array += [...]
必须创建一个全新的数组,复制所有内容,然后销毁旧数组。数组越大,此操作越昂贵,消耗的内存越多,脚本越慢。它将任何普通的O(n)复杂性循环转换为O(n ^ 2)复杂性循环。
这意味着您应该这样做:
$Array = $x | ForEach-Object { [...] }
或者这个:
$Array = New-Object -TypeName System.Collections.ArrayList;
$x | ForEach-Object {
$Record = [...]
$Array.Add($Record)
}
这是一个动态提取标题的示例。在这种情况下,它为C:\Windows\
中的前10个文件提取String和DateTime类型的所有属性。
# 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,但是你的逻辑让我有些失望。
(也就是说,$rs.MoveFirst()
看起来像是错误的循环,如果它做了我记得RecordSet.MoveFirst()
做的事情,但我可能会记错了。)
然而,这里的想法是一样的。
答案 1 :(得分: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;
} 直到 ($ rs.EOF -eq $ True)
}
}
$resultsarray
我做到了!!!!诀窍是将记录添加到数组中,然后清除对象,添加成员,添加到数组,清除对象.....太棒了!