Skip to content

Commit 1cff1f0

Browse files
committed
Update SpreadsheetWrangler.ps1
Remove ExcelCOM from codebase
1 parent 7acc6b8 commit 1cff1f0

File tree

1 file changed

+8
-274
lines changed

1 file changed

+8
-274
lines changed

SpreadsheetWrangler.ps1

Lines changed: 8 additions & 274 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
# SpreadsheetWrangler.ps1
22
# GUI application for spreadsheet operations and folder backups
33

4-
# Check for Excel and ImportExcel module availability
5-
$script:UseExcelCOM = $false
4+
# Check for ImportExcel module availability
65
$script:UseImportExcel = $false
76

8-
try {
9-
# Try to create Excel COM object to check if Excel is installed
10-
$excelCheck = New-Object -ComObject Excel.Application -ErrorAction Stop
11-
$excelCheck.Quit()
12-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelCheck) | Out-Null
13-
# Excel is installed, but we'll force using ImportExcel module instead
14-
Write-Host "Excel installation detected, but using ImportExcel module for better performance." -ForegroundColor Green
15-
$script:UseExcelCOM = $false # Force to false even when Excel is available
16-
} catch {
17-
Write-Host "Excel is not installed or not accessible. Will use ImportExcel module." -ForegroundColor Yellow
18-
}
19-
207
# Check if ImportExcel module is installed
218
if (-not (Get-Module -ListAvailable -Name ImportExcel)) {
229
Write-Host "ImportExcel module not found. Attempting to install..." -ForegroundColor Yellow
@@ -228,17 +215,8 @@ function Combine-Spreadsheets {
228215
)
229216

230217
try {
231-
# Initialize Excel or ImportExcel based on availability
232-
$excel = $null
233-
234-
if ($script:UseExcelCOM) {
235-
Write-Log "Initializing Excel COM objects..." "White"
236-
$excel = New-Object -ComObject Excel.Application
237-
$excel.Visible = $false
238-
$excel.DisplayAlerts = $false
239-
} else {
240-
Write-Log "Using ImportExcel module (Excel-free mode)..." "White"
241-
}
218+
# Using ImportExcel module for all operations
219+
Write-Log "Using ImportExcel module for all operations..." "White"
242220

243221
# Create a dictionary to store spreadsheets by number
244222
$spreadsheetGroups = @{}
@@ -291,13 +269,6 @@ function Combine-Spreadsheets {
291269
# Check if we found any spreadsheets
292270
if ($spreadsheetGroups.Count -eq 0) {
293271
Write-Log "No spreadsheets with matching numbers found in the selected folders." "Yellow"
294-
295-
# Clean up Excel COM objects if they were used
296-
if ($script:UseExcelCOM -and $excel) {
297-
$excel.Quit()
298-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
299-
}
300-
301272
return $false
302273
}
303274

@@ -328,101 +299,7 @@ function Combine-Spreadsheets {
328299
$isFirstFile = $true
329300
$lastColumn = 0
330301

331-
if ($script:UseExcelCOM) {
332-
#region Excel COM Processing
333-
# Create a new workbook for the combined data
334-
$combinedWorkbook = $excel.Workbooks.Add()
335-
$combinedWorksheet = $combinedWorkbook.Worksheets.Item(1)
336-
$combinedWorksheet.Name = "Combined"
337-
338-
# Process each file in the group
339-
foreach ($file in $files) {
340-
Write-Log " Combining: $file" "White"
341-
342-
# Open the source workbook
343-
$sourceWorkbook = $excel.Workbooks.Open($file)
344-
$sourceWorksheet = $sourceWorkbook.Worksheets.Item(1)
345-
346-
# Get used range
347-
$usedRange = $sourceWorksheet.UsedRange
348-
$lastRow = $usedRange.Rows.Count
349-
$lastColumn = $usedRange.Columns.Count
350-
351-
# Handle headers based on the ExcludeHeaders option
352-
if ($ExcludeHeaders) {
353-
# No headers mode - always skip the first row (header) of all files
354-
$startRow = 2 # Start from row 2 of each source file (skip header)
355-
356-
# For the first file, set up the combined sheet to start at row 1 (no headers)
357-
if ($isFirstFile) {
358-
$rowIndex = 1 # Start at row 1 in combined sheet (no headers)
359-
$isFirstFile = $false
360-
Write-Log " No Headers mode: Skipping header row from all files" "White"
361-
}
362-
} else {
363-
# Include headers mode
364-
if ($isFirstFile) {
365-
# Copy header row from first file only
366-
$headerRange = $sourceWorksheet.Range($sourceWorksheet.Cells(1, 1), $sourceWorksheet.Cells(1, $lastColumn))
367-
$headerRange.Copy() | Out-Null
368-
$combinedWorksheet.Range($combinedWorksheet.Cells(1, 1), $combinedWorksheet.Cells(1, $lastColumn)).PasteSpecial(-4163) | Out-Null
369-
$rowIndex = 2 # Start data at row 2 (after header)
370-
$isFirstFile = $false
371-
}
372-
# For all files in include headers mode, skip the header row except for the first file
373-
$startRow = 2 # Skip header row from source files
374-
}
375-
if ($lastRow -ge $startRow) {
376-
$dataRange = $sourceWorksheet.Range($sourceWorksheet.Cells($startRow, 1), $sourceWorksheet.Cells($lastRow, $lastColumn))
377-
$dataRange.Copy() | Out-Null
378-
$combinedWorksheet.Range($combinedWorksheet.Cells($rowIndex, 1), $combinedWorksheet.Cells($rowIndex + $lastRow - $startRow, $lastColumn)).PasteSpecial(-4163) | Out-Null
379-
$rowIndex += $lastRow - $startRow + 1
380-
381-
# Insert BLANK row between spreadsheets if option is enabled and this is not the last file
382-
if ($InsertBlankRows -and ($file -ne $files[-1])) {
383-
Write-Log " Inserting BLANK row after data from: $file" "White"
384-
385-
# Determine which columns should have BLANK values
386-
if (-not $ExcludeHeaders) {
387-
# If headers are included, add BLANK only to columns that have headers
388-
for ($col = 1; $col -le $lastColumn; $col++) {
389-
$headerText = $combinedWorksheet.Cells(1, $col).Text
390-
if (-not [string]::IsNullOrWhiteSpace($headerText)) {
391-
$combinedWorksheet.Cells($rowIndex, $col).Value = "BLANK"
392-
}
393-
}
394-
} else {
395-
# If no headers, we need to determine which columns actually have data
396-
# Look at the first few rows to determine which columns are used
397-
$usedColumns = @{}
398-
399-
# Check the first 5 rows (or fewer if there aren't that many)
400-
$rowsToCheck = [Math]::Min(5, $rowIndex - 1)
401-
for ($row = 1; $row -le $rowsToCheck; $row++) {
402-
for ($col = 1; $col -le $lastColumn; $col++) {
403-
$cellValue = $combinedWorksheet.Cells($row, $col).Text
404-
if (-not [string]::IsNullOrWhiteSpace($cellValue)) {
405-
$usedColumns[$col] = $true
406-
}
407-
}
408-
}
409-
410-
# Add BLANK only to columns that have data
411-
foreach ($col in $usedColumns.Keys) {
412-
$combinedWorksheet.Cells($rowIndex, $col).Value = "BLANK"
413-
}
414-
}
415-
416-
$rowIndex += 1
417-
}
418-
}
419-
420-
# Close the source workbook without saving
421-
$sourceWorkbook.Close($false)
422-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($sourceWorkbook) | Out-Null
423-
}
424-
#endregion Excel COM Processing
425-
} else {
302+
# Process using ImportExcel
426303
#region ImportExcel Processing
427304
# Process each file in the group
428305
foreach ($file in $files) {
@@ -514,140 +391,9 @@ function Combine-Spreadsheets {
514391
Write-Log " Error processing file $file``: $errorMessage" "Red"
515392
}
516393
}
517-
#endregion ImportExcel Processing
518-
}
519394

520395
# Process special options and save the combined spreadsheet
521396
$combinedFilePath = Join-Path -Path $DestinationPath -ChildPath "Combined_Spreadsheet_$groupNumber.xlsx"
522-
523-
if ($script:UseExcelCOM) {
524-
#region Excel COM Special Options Processing
525-
if ($DuplicateQuantityTwoRows -or $NormalizeQuantities -or $ReverseDataRows) {
526-
# Find the 'Add to Quantity' column if it exists
527-
$addToQuantityColIndex = $null
528-
529-
# Re-open the workbook to process it
530-
$tempWorkbook = $excel.Workbooks.Add()
531-
$tempWorksheet = $tempWorkbook.Worksheets.Item(1)
532-
$tempWorksheet.Name = "Combined"
533-
534-
# Copy all data from combined worksheet to temp worksheet
535-
$combinedWorksheet.UsedRange.Copy() | Out-Null
536-
$tempWorksheet.Range("A1").PasteSpecial(-4163) | Out-Null
537-
538-
# Find the 'Add to Quantity' column if it exists
539-
$lastColumn = $tempWorksheet.UsedRange.Columns.Count
540-
$lastRow = $tempWorksheet.UsedRange.Rows.Count
541-
542-
# Process Duplicate Qty=2 and Normalize Qty to 1 options
543-
if ($DuplicateQuantityTwoRows -or $NormalizeQuantities) {
544-
for ($col = 1; $col -le $lastColumn; $col++) {
545-
$headerText = $tempWorksheet.Cells(1, $col).Text
546-
if ($headerText -eq "Add to Quantity") {
547-
$addToQuantityColIndex = $col
548-
Write-Log " Found 'Add to Quantity' column at index $col" "White"
549-
break
550-
}
551-
}
552-
553-
# Process the column if found
554-
if ($addToQuantityColIndex) {
555-
# First duplicate rows with '2' in the 'Add to Quantity' column if option is enabled
556-
if ($DuplicateQuantityTwoRows) {
557-
Write-Log " Processing 'Duplicate Qty=2' option..." "White"
558-
559-
# We need to process from bottom to top to avoid index shifting issues
560-
$rowsToInsert = @()
561-
562-
for ($row = $lastRow; $row -ge 2; $row--) {
563-
$cellValue = $tempWorksheet.Cells($row, $addToQuantityColIndex).Text
564-
if ($cellValue -eq "2") {
565-
Write-Log " Found row $row with quantity 2, duplicating..." "White"
566-
$rowsToInsert += $row
567-
}
568-
}
569-
570-
foreach ($row in $rowsToInsert) {
571-
# Insert a new row
572-
$range = $tempWorksheet.Rows($row)
573-
$range.Copy() | Out-Null
574-
$tempWorksheet.Rows($row).Insert(-4121) | Out-Null # -4121 is xlShiftDown
575-
$lastRow++
576-
}
577-
578-
Write-Log " Duplicated $($rowsToInsert.Count) rows with quantity 2" "Green"
579-
}
580-
581-
# Then normalize all quantities to '1' if option is enabled
582-
if ($NormalizeQuantities) {
583-
Write-Log " Processing 'Normalize Qty to 1' option..." "White"
584-
$changedCount = 0
585-
586-
for ($row = 2; $row -le $lastRow; $row++) {
587-
$cellValue = $tempWorksheet.Cells($row, $addToQuantityColIndex).Text
588-
if ($cellValue -ne "1") {
589-
$tempWorksheet.Cells($row, $addToQuantityColIndex).Value = "1"
590-
$changedCount++
591-
}
592-
}
593-
594-
Write-Log " Normalized $changedCount cells to quantity 1" "Green"
595-
}
596-
} else {
597-
Write-Log " 'Add to Quantity' column not found, skipping quantity processing" "Yellow"
598-
}
599-
}
600-
601-
# Apply Reverse, Reverse option if enabled
602-
if ($ReverseDataRows) {
603-
Write-Log " Applying 'Reverse, Reverse' option..." "White"
604-
605-
# Determine the range to reverse (exclude header row if headers are included)
606-
$startRow = if (-not $ExcludeHeaders) { 2 } else { 1 }
607-
$lastRow = $tempWorksheet.UsedRange.Rows.Count
608-
$lastColumn = $tempWorksheet.UsedRange.Columns.Count
609-
610-
if ($lastRow -ge $startRow) {
611-
# Create a temporary array to hold the reversed data
612-
$dataArray = @()
613-
614-
# Copy data to array (from bottom to top)
615-
for ($row = $lastRow; $row -ge $startRow; $row--) {
616-
$rowData = @()
617-
for ($col = 1; $col -le $lastColumn; $col++) {
618-
$rowData += $tempWorksheet.Cells($row, $col).Value
619-
}
620-
$dataArray += ,$rowData
621-
}
622-
623-
# Write the reversed data back to the worksheet
624-
for ($i = 0; $i -lt $dataArray.Count; $i++) {
625-
$row = $startRow + $i
626-
for ($col = 1; $col -le $lastColumn; $col++) {
627-
if ($col -le $dataArray[$i].Count) {
628-
$tempWorksheet.Cells($row, $col).Value = $dataArray[$i][$col-1]
629-
}
630-
}
631-
}
632-
633-
Write-Log " Data rows reversed successfully" "Green"
634-
} else {
635-
Write-Log " Not enough data rows to reverse" "Yellow"
636-
}
637-
}
638-
639-
# Save the processed workbook
640-
$tempWorkbook.SaveAs($combinedFilePath)
641-
$tempWorkbook.Close($true)
642-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($tempWorkbook) | Out-Null
643-
} else {
644-
# Save the combined workbook normally
645-
$combinedWorkbook.SaveAs($combinedFilePath)
646-
$combinedWorkbook.Close($true)
647-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($combinedWorkbook) | Out-Null
648-
}
649-
#endregion Excel COM Special Options Processing
650-
} else {
651397
#region ImportExcel Special Options Processing
652398
# Process Duplicate Qty=2 and Normalize Qty to 1 options
653399
if ($DuplicateQuantityTwoRows -or $NormalizeQuantities) {
@@ -751,8 +497,6 @@ function Combine-Spreadsheets {
751497
$errorMessage = $_.Exception.Message
752498
Write-Log " Error exporting combined data``: $errorMessage" "Red"
753499
}
754-
#endregion ImportExcel Special Options Processing
755-
}
756500

757501
Write-Log " Saved combined spreadsheet: $combinedFilePath" "Green"
758502

@@ -761,13 +505,9 @@ function Combine-Spreadsheets {
761505
Update-ProgressBar $progressPercentage
762506
}
763507

764-
# Clean up resources
765-
if ($script:UseExcelCOM -and $excel) {
766-
$excel.Quit()
767-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
768-
[System.GC]::Collect()
769-
[System.GC]::WaitForPendingFinalizers()
770-
}
508+
# No Excel COM resources to clean up
509+
[System.GC]::Collect()
510+
[System.GC]::WaitForPendingFinalizers()
771511

772512
Write-Log "Spreadsheet combining process completed." "Cyan"
773513
Update-ProgressBar 100
@@ -777,13 +517,7 @@ function Combine-Spreadsheets {
777517
catch {
778518
Write-Log "Error during spreadsheet combining: $_" "Red"
779519

780-
# Try to clean up Excel if an error occurs
781-
if ($excel) {
782-
try {
783-
$excel.Quit()
784-
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
785-
} catch {}
786-
}
520+
# No Excel COM resources to clean up
787521

788522
[System.GC]::Collect()
789523
[System.GC]::WaitForPendingFinalizers()

0 commit comments

Comments
 (0)