我正在使用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值创建的数组导致了问题,或者是什么。任何帮助将不胜感激。
答案 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