使用数组时,Excel Range.AutoFilter出错(Powershell)

时间:2018-06-15 19:19:04

标签: excel powershell

我正在使用Powershell来处理带有数千个计算机名和IP的.csv文件。我使用的是PowerShell,因为它是我构建的更大脚本的一部分。

我在Excel中使用Range.AutoFilter()方法删除了我不需要的IP。在下面的例子中,我想删除pc1,pc2和pc5。

示例表:

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...

如果我手动创建一个数组,我就没有问题。

$Array1 = "38","210"

但是,我需要通过从第3列中提取唯一值来创建数组,如下所示:

$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

但是当我将$ Array2放入我的autofilter命令时,我收到一个错误:

$Filter = $Array2
$Range = $Sheet1.UsedRange
[void] $Range.AutoFilter(3,$Filter,7)
  

异常设置" AutoFilter":无法转换" 7" type" int"的值输入"对象"。

根据文档,7是XlAutoFilterOperator的xlFilterValues值。再次,如果我将$ Filter切换到$ Array1,过滤器命令工作正常。

我不确定是否有我遗漏的内容,或者是否从Excel值创建的数组导致了问题,或者是什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

好的,这里有几件事情......不要手动迭代,让ComObject使用WorkSheet的UsedRange属性来处理它。然后使用Columns属性将列作为对象,并使用Item()方法选择第4列(Excel不像PowerShell那样基于零)。然后你只想要列中的每个单元格,并且你想要扩展每个单元格的Text属性(跳过标题行),所以这最终看起来像:

$Array2 = $Sheet1.UsedRange.Columns.Item(4).Cells|% text|select -skip 1

但那失败了。我尝试手动创建$array1并将其与$array2进行比较,但我认为没有任何差异。但是我们知道一个字符串数组是有效的,那么如果我们在创建它时键入cast $array2会怎样呢?

[string[]]$Array2 = $Sheet1.UsedRange.Columns.Item(4).Cells|% text|select -skip 1

这很好用,所以看起来这是某种类型的问题。我无法找到方法,但将变量作为特定类型进行修改可以解决问题。最后,您可以使用原始代码,并在创建和修改数组时指定类型。

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