I'm trying to get data out of my ordered dictionary, and for some reason it's not printing the data in it. I can get to the first item in the data structure, but I'm having trouble iterating over all the rows. I'm using PowerShell 5.1 and visual studio code.
The code queries an mdb file, and returns multiple rows.
Function ProcessHelpMDB{
[cmdletbinding()]
Param ([string]$mdbLookupError, [string]$mdbFilePath, [string]$mdbPrinterSeries)
Process
{
$adOpenStatic = 3
$adLockOptimistic = 3
$deviceTable = $mdbPrinterSeries + "PP"
$mdbLookupError -Match '[0-9]*-([0-9]*)'
$errLookup = $Matches[1]
$selectQuery = “SELECT [$($deviceTable)].[HelpCode],
[$($deviceTable)].[ScreenNumber],
[$($deviceTable)].[TextID],
[$($deviceTable)].[PictureID]
FROM [$($deviceTable)]
WHERE
[$($deviceTable)].[HelpCode] = $($errLookup)"
$cn = new-object -comobject ADODB.Connection
$rs = new-object -comobject ADODB.Recordset
$cn.Open("Provider = Microsoft.ACE.OLEDB.16.0;Data Source = $mdbFilePath")
$rs.Open($selectQuery,
$cn, $adOpenStatic, $adLockOptimistic)
$i=0
$ret = [ordered]@{}
if($rs.EOF)
{
Write-Host "$mdbLookupString not in $mdbFileName...record set returned emtpy for query"
}#if
else
{
while($rs.EOF -ne $True)
{
$result = [ordered]@{}
foreach ($field in $rs.Fields)
{
$result[$field.name] = $field.Value
}#result
$newObject = [PSCustomObject]$result
$ret.Add($i,$newObject) ###ordered dictionary needs key to add values
$i++
$rs.MoveNext()
} #while
Write-Host "retArr[] $($ret)" #prints retArr[] System.Collections.Specialized.OrderedDictionary
Write-Host "retArr[0] $($ret[0,"TextID"])" #prints retArr[0]
Write-Host "retArr[0] $($ret[0])" #prints retArr[0] @{PictureID=HELP_BLAH; TextID=HELP_INFO; HelpCode=9; ScreenNumber=1}
foreach($row in $ret)
{
foreach($item in $row.value) #it's skipping these
{
Write-Host $item #
Write-Host $item[0] #
Write-Host $item[0].'TextID' #
Write-Host $item.'TextID' #
}#foreach
}
$cn.Close()
return $ret
} #end Process
}# End of Function process mdb's
The data looks like this in the mdb table:
HelpCode ScreenNumber TextID PictureID
1000 1 HELP_INFO HELP_BLAH
1000 2 HELP_INFO2 HELP_BLAH2
...
My question is, how do I print out the data in the table, from the data structure? I'll need to access it later to re-piece it into a string with other data. My problem is that I can't figure out how to access each row. in the data structure, and each item individually in each row. I seem to know how to access the first row, but not other rows.
I've been looking at this most recently: looping over hash table
Update:
I got the TextID
to print for each row of ret
as follows per comments below..thank you!!:
foreach($row in $ret.GetEnumerator()) #this is working for each row, using
{
Write-Host $row.TextID #prints nothing
Write-Host $row.'TextID' #prints nothing
Write-Host $($row.TextID) #prints nothing
Write-Host $($row.'TextID') #prints nothing
Write-Host $($row[0].TextID) #prints nothing
Write-Host $($row[0].'TextID') #prints nothing
Write-Host $($row[0].Value.TextID) #prints TextID value of current row
Write-Host $($row[0].Value.'TextID') #prints TextID value of current row
}
Update2: I'm trying to data structure improvement suggested in the answer below. Thank you!! It's a great simplification.
$ret = [System.Collections.Generic.List[psobject]]::new() #different data struc
if($rs.EOF)
{
Write-Host "$mdbLookupString not in $mdbFileName...record set returned emtpy for query"
}#if
else
{
while($rs.EOF -ne $True)
{
$result = [ordered]@{}
foreach ($field in $rs.Fields)
{
$result[$field.name] = $field.Value
}#result
$newObject = [PSCustomObject]$result
$ret.Add($newObject) ###
$rs.MoveNext()
} #while
}#else
Write-Host "retArr[] $($ret)" #prints retArr[]
Write-Host "retArr[0] $($ret[0,"TextID"])" #prints retArr[0]
Write-Host "retArr[0] $($ret[0])" #prints retArr[0] @{PictureID=...; TextID=...; HelpCode=9; ScreenNumber=1}
$i=0
foreach($row in $ret) #goes thru all rows
{
Write-Host "retArr[] $($ret)" #prints retArr[]
Write-Host "retArr[0] $($ret[$i,"TextID"])" #prints retArr[0] @{HelpCode=9; ScreenNumber=1; TextID=...; PictureID=...}
Write-Host "retArr[0] $($ret[$i].TextID)" #prints retArr[0] HELP_...
Write-Host "retArr[0] $($ret[$i].'TextID')" #retArr[0] HELP_...
####
Write-Host "retArr[] $($row)" #prints retArr[] @{HelpCode=9; ScreenNumber=1; TextID=...; PictureID=HELP_...}
Write-Host "retArr[0] $($row[$i,"TextID"])" #prints retArr[0]
Write-Host "retArr[0] $($row[$i])" #prints retArr[0] @{HelpCode=9; ScreenNumber=1; TextID=HELP_...; PictureID=HELP_...}
Write-Host "retArr[0] $($row[$i].TextID)" #prints retArr[0] HELP_...
Write-Host "retArr[0] $($row[$i].'TextID')" #retArr[0] HELP_...
$i++
}
foreach($row in $ret.GetEnumerator()) #this is working for each row
{
Write-Host $row.TextID #prints HELP_...
Write-Host $row.'TextID' #prints HELP_...
Write-Host $($row.TextID) #prints HELP_...
Write-Host $($row.'TextID') #prints HELP_...
Write-Host $($row[0].TextID) #HELP_...
Write-Host $($row[0].'TextID') #HELP_...
Write-Host $($row[0].Value.TextID) #prints nothing
Write-Host $($row[0].Value.'TextID') #prints nothing
}
This works great. Thanks for the help @mathias!
Update3: I'm trying the pipeline idea from @iRon comment, with update2 (optimized data structure):
$ret | ForEach-Object {
Write-Host TextID= $($_.TextID) #prints TextID= HELP_...
Write-Host TextID= $($_.'TextID') #prints TextID= HELP_...
Write-Host TextID= $($_.Value.TextID) #prints TextID=
Write-Host TextID= $($_.Value.'TextID') #prints TextID=
}
Thanks iRon! That's a good way to access the data in the data structure. :)