Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

psobject property set is losing order – how to retain order?

I’m working with Export-Excel, and the psobject property set I am using is re-ordering itself, which makes my excel heading in the wrong order.

This is my code:

       foreach ($errCode in $ErrCodes) 
       {
          $resultHelp = [System.Collections.Generic.List[psobject]]::new() 
          Write-Host "another:"
          $err = $errCode #get each error code to lookup in mdb file
          Write-Host $err
          $resultHelp = ProcessHelpMDB -mdbLookupError $errCode -mdbFilePath $basePathFull -mdbDeviceSeries $Ver #######

          $result = [ordered] @{
                  "ScreenNumber" = ""
                  "KKey" = ""
                  "EnglishUS" = ""
                  "PictureID" = ""
                  "ImageFound" =""
                  "ImageFileName" = ""
          } #this didn't do anything
          #loop thru results from Help MDB file for $errCode
          ###this loses order:
          $result = foreach($row in $resultHelp.GetEnumerator()) #this is working for each row
          {
              if($row -ne $True) #not sure why it adds true at the top
              {
                Write-Host $row.TextID #prints HELP_JAM; this is key for kapptext.mdb
                #lookup value from kapptext.mdb
                Write-Host $($row.TextID) #prints nothing but looks ok in next function
                $longText = ProcessK_MDB -mdbLookupstring $($row.TextID) #gives English-US from db for parameter given, which is long error instruction
                #export data found above to excel. 
                #### minimal example shows how get each row data since it's part of issue
                #get the data ready to put in spreadsheet
                $result = New-Object psobject -Property @{
                    ScreenNumber = $($row.ScreenNumber)
                    KKey = $($row.TextID)
                    EnglishUS = $($longText)
                    PictureID = $($row.PictureID)
                    ImageFound = ""
                    ImageFileName = ""
                } 
              } #if not true
          } #foreach row $resultHelp
          #######I think something needs to change in data structure above...not sure what
          $date = (Get-Date).tostring("MM-dd-yyyy") 
          [System.String] $help_spreadsheet_File = "COMPONENT MAP HELP_",$($date),".xlsx"
          $out_path = '\\company.net\EndToEnd\ComponentMaps'
          $outFilePath = Join-Path -Path $out_path -ChildPath $help_spreadsheet_File
           #write to dated file at out_path location
           #export content to spreadsheet
           $xlsx = $result | Export-Excel -Path $outFilePath -WorksheetName $errCode -Autosize -AutoFilter -FreezeTopRow -BoldTopRow  -PassThru # -ClearSheet can't ClearSheet every time or it clears previous data  ###seems to have issue over-writing each row below header
          $ws = $xlsx.Workbook.Worksheets[$errCode]
          $ws.Dimension.Columns  #number of columns
          $ws.Dimension.Rows     #number of rows
          $ws.Row(1).Height
          $ws.Row(1).Height = 25
          $ws.Column(5).Width
          $ws.Column(5).Width = 50
          Close-ExcelPackage $xlsx
          Write-Host "Break when done with first errCode $($errCode)" #50-9
        

This is what $resultHelp looks like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

[0] $true (I'm not sure why it puts true at the top)
[1] @(HelpCode=9;ScreenNumber=1;TextID=HELP_...JA;PictureID=HELP_...RIB)
[2] @(HelpCode=9;ScreenNumber=2;TextID=HELP_...ROLL;PictureID=HELP_...ROLL)
[3] @(HelpCode=9;ScreenNumber=3;TextID=HELP_...EDGE;PictureID=HELP_...UT)
...

The output looks like this (re-ordering itself):

ImageFound  ScreenNumber  ImageFileName   KKey   EnglishUS   PictureID
(data here)

I was looking at column ordering and it didn’t change the order output to the spreadsheet. I also tried adding [ordered] here,

$result = New-Object psobject -Property [ordered]@{

but it had error message (and I couldn’t find close enough example to fix it)

New-Object : Cannot bind parameter 'Property'. Cannot convert the "[ordered]@" value of type "System.String" to type "System.Collections.IDictionary".

>Solution :

You’re passing a hashtable to New-Object -Property and hashtables don’t preserve input order.

Change this:

$result = New-Object psobject -Property @{
    ScreenNumber = $($row.ScreenNumber)
    KKey = $($row.TextID)
    EnglishUS = $($longText)
    PictureID = $($row.PictureID)
    ImageFound = ""
    ImageFileName = ""
}

To:

$result = New-Object psobject -Property $([ordered]@{
    ScreenNumber = $($row.ScreenNumber)
    KKey = $($row.TextID)
    EnglishUS = $($longText)
    PictureID = $($row.PictureID)
    ImageFound = ""
    ImageFileName = ""
})

The reason it doesn’t work unless you wrap the [ordered]@{...} expression in $() is that PowerShell employs different rules for parsing command arguments

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading