Home > Software design >  XML File Mapping to get CSV Value then Open Excel using PowerShell
XML File Mapping to get CSV Value then Open Excel using PowerShell

Time:08-04

I have here my XML, CSV and Excel files.

I'm trying to get all the Numbers from the "Key" of my XML file.

Settings.xml

$DocNo = $XML.Settings.Setting.Key

then get all the Corresponding File Name of that Numbers from my CSV file.

Settings.csv

Foreach ($Line in $CSVContent) {

    # (-split) the Array of Strings by Separating them from ","
    $LineSplit = $Line -split ","

    # Find the $Line that has the Value of $DocNo
    If ($LineSplit -like $DocNo) {
       
       # Store the String Value of $DocNo in "$FileNames" 
       $FileNames = $LineSplit
    }
}
Write-Host $FileNames

then use the $FileNames as the File Name to be opened as a workbook.

# For every Number of Key
ForEach($Files in $DocNo){
    
    # Open their Excel Workbook (INSERT THE FILENAME OF THE FILE NO. FROM CSV)
    $WorkBook = $Excel.Workbooks.Open($Files.$FileNames)
}

The problem is there's no value showing in my $FileNames. I can display the $FileNames but I have to specifically call them one by one. Any suggestions and help will be appreciated :)

CodePudding user response:

In the first block of code, $LineSplit is the result of using -split on a line from a CSV file. $LineSplit is an array, in your case the array contains two elements for each line from the CSV file:

$LineSplit[0] = '1'
$LineSplit[1] = 'File1.xlsx'

The square bracket notation allows you to select an element from the array by its position in the array, starting from zero.

The issue with the first block of code is that a condition ($LineSplit -like $DocNo) is comparing an array to an array using the like operator, I'm not sure what that will do but it's hard to follow. I would consider recoding it as follows:

if ($LineSplit[0] -in $DocNo)

This asks if the first column of the CSV row is in the list pulled from your XML file, then proceed.

The next issue is the building of the $FileNames variable. Each time this statement is executed in your code:

$FileNames = $LineSplit

The two element array $LineSplit representing the current CSV row, split by comma, overwrites the value of $FileNames. By the end of the loop, this only contains the last CSV line which matched the condition. This should be recoded as an array. Before the loop set up an empty array:

$FileNames = @()

Now, during the loop when the condition is met:

$FileNames  = $LineSplit[1]

Recalling that $LineSplit[1] contains the filename, as it is the second element of the CSV row when split by comma. By the end of the loop the $FileNames variable should contain an array of files that are in both the CSV and the XML. The = bit is an operator that adds new elements without overwriting.

Finally, the second block of code is close, but not quite there. The loop runs through the values in $DocNo, which according to your screenshot are:

1,2,3,4,5,6

These values are placed into the $Files variable for each loop - and then the $File.$FileNames syntax is incorrect, it is attempting to retrieve a property from the numbers retrieved from the $DocNo values. The values are just integers, so there is no $FileNames property to retrieve. The loop should run through the list we already constructed

ForEach ($File in $FileNames) {
    # Open their Excel Workbook (INSERT THE FILENAME OF THE FILE NO. FROM CSV)
    $WorkBook = $Excel.Workbooks.Open($File)
}

Final tip, use Write-Host to display the value of variables as you go, e.g.

Write-Host $LineSplit[0]
  • Related