Home » excel » excel – Split Excelfile .xlxs with Powershell based on column values

excel – Split Excelfile .xlxs with Powershell based on column values

Posted by: admin May 14, 2020 Leave a comment

Questions:

I need to split and save an excel file based on the values of the first column via a powershell script. Here is how the excel file is build up (app 30.000 rows)

´´´Column1 # Column2 # Column3´´´
´´´AA # data # data # data´´´
´´´AA # data # data # data´´´
´´´AB # data # data # data´´´
´´´AC # data # data # data´´´
´´´AC # data # data # data´´´

The result should be multiple files with filenames AA.xlxs, AB.xlxs, AC.xlxs and of course the according rows data.

What I have so far is the following code:

$objexcel = New-Object -ComObject Excel.Application
$wb = $objexcel.WorkBooks.Open("C:\Test.xlsx")
$objexcel.Visible = $true
$objexcel.DisplayAlerts = $False
$ws = $wb.Worksheets.Item(1)
$doc = $ws.Range("A:A")

foreach ($doc in $docs) {
$newfile,$objexcel = $objexcel.where({$doc -eq $doc})
$newfile | Export-Excel "C:$doc.xlxs"
}

It just opens the file, but nothing happens.
It would be great if some coder could have a look at the code or provide a working one.
Thanks in advance.

How to&Answers:

Following is a working code that will iterate through unique elements in column one and make a copy of it in a new spreadsheet and save it.

Function Create-Excel-Spreadsheet {
    Param($NameOfSpreadsheet)

    # open excel
    $excel = New-Object -ComObject excel.application
    $excel.visible = $true

    # add a worksheet
    $workbook = $excel.Workbooks.Add()
    $xl_wksht= $workbook.Worksheets.Item(1)
    $xl_wksht.Name = $NameOfSpreadsheet

    return $workbook
}


$objexcel = New-Object -ComObject Excel.Application
$wb = $objexcel.WorkBooks.Open("C:\Temp\Test.xlsx") # Changing path for test.xlsx file.

$objexcel.Visible = $true
$objexcel.DisplayAlerts = $False
$ws = $wb.Worksheets.Item(1)

$usedRange = $ws.UsedRange
$usedRange.AutoFilter()

$totalRows = $usedRange.Rows.Count


$rangeForUnique = $usedRange.Offset(1, 0).Resize($UsedRange.Rows.Count-1) 
[string[]]$UniqueListOfRowValues = $rangeForUnique.Columns.Item(1).Value2 | sort -Unique

for ($i = 0; $i -lt $UniqueListOfRowValues.Count; $i++) {
    $newRange = $usedRange.AutoFilter(1, $UniqueListOfRowValues[$i])

    $workbook = Create-Excel-Spreadsheet $UniqueListOfRowValues[$i]
    $wksheet = $workbook.Worksheets.Item(1)

    $range = $ws.UsedRange.Cells
    $range.Copy()

    $wksheet.Paste($wksheet.Range("A1"))
    $workbook.SaveAs("C:\temp\" + $UniqueListOfRowValues[$i], $xlFixedFormat)
    $workbook.Close()
}

Answer:

Reason nothing is happening is because you are iterating over $docs which does not contain any elements. It is currently null.

When you make a reference to look up the data, you are using $objexcel, but thats your excel application.. not the worksheet that you want to iterate over. Use $as for accessing the worksheet.

You need to iterate over Cells of your $ws and take the data when cells.Item(x, 0) and create a new file based on that with values in other two columns.

Link to example on SO -> Create and Update excel file