Reputation: 38
I am using Powershell to manipulate a .csv file with thousands of computernames and IPs. I'm using powershell because it's part of a bigger script I'm building.
I am using the Range.AutoFilter() method through Excel to delete the IP's that I don't need. Of the example below, I want to delete pc1,pc2 and pc5.
Example sheet:
Name 1 2 3 4
pc1 10 10 10 10
pc2 10 50 100 1
pc3 10 38 20 55
pc4 10 210 38 100
pc5 10 66 41 23
etc...
If I create an array manually, I have zero issues.
$Array1 = "38","210"
However, I need to create the array by pulling the unique values from column 3, like so:
$Array2 = @()
$row = 2
Do {
$value = $Sheet1.Cells.Item($row,3).Text
$Array2 += "$value"
$row++
} until (!$Sheet1.Cells.Item($row,1).Text) #column 1 is less likely to have blanks
$Array2 = $Array1 | Sort-Object -unique
But when I put $Array2 into my autofilter command, I get an error:
$Filter = $Array2
$Range = $Sheet1.UsedRange
[void] $Range.AutoFilter(3,$Filter,7)
Exception setting "AutoFilter": Cannot convert the "7" value of type "int" to type "Object".
According to documentation, the 7 is the value of xlFilterValues for XlAutoFilterOperator. Again, the filter command works fine if I switch $Filter to $Array1.
I'm not sure if there's something I'm missing, or if the array created from Excel values is causing the issue, or what. Any help would be greatly appreciated.
Upvotes: 1
Views: 671
Reputation: 36332
Ok, a couple things here... don't iterate manually, let the ComObject take care of that with the UsedRange property of the WorkSheet. Then use the Columns property to get columns as objects, and use the Item() method to select the 4th column (Excel is not zero based like PowerShell is). Then you just want each cell in the column, and you want to expand the Text property of each cell (skipping the header row), so this would end up looking like:
$Array2 = $Sheet1.UsedRange.Columns.Item(4).Cells|% text|select -skip 1
But that fails. I tried manually creating $array1
and comparing it to $array2
and I see no differences what so ever. But we know that an array of strings works, so what if we type cast $array2
when it is created?
[string[]]$Array2 = $Sheet1.UsedRange.Columns.Item(4).Cells|% text|select -skip 1
That works fine, so it looks like this was a type issue of some sort. I couldn't find how, but casting the variable as a specific type fixed the issue. In the end you could probably use your original code and just specify the type when creating and modifying the array.
Remove-Variable Array2
$row = 2
Do {
$value = $Sheet1.Cells.Item($row,3).Text
[string[]]$Array2 += "$value"
$row++
} until (!$Sheet1.Cells.Item($row,1).Text) #column 1 is less likely to have blanks
Upvotes: 2