我如何 create/pass 变体以使用 win32com 过滤多个条件

how do i create/pass a variant in order to filter multiple criteria using win32com

我不擅长 VBA,但据我了解 AutoFilter 在 运行 宁 xlFilterValues.[=19 时需要 Array() 变体=]

import win32com.client as win32

excel = win32.gencache.EnsureDispatch('Excel.Application')
mv_wbk = excel.ActiveWorkbook
mv_sht = mv_wbk.Worksheets("mv")

# https://docs.microsoft.com/en-us/office/vba/api/excel.xlautofilteroperator
xlFilterValues = 7
# https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.varianttype?view=net-6.0
arrayId = 8192

fltrs = win32.VARIANT(arrayId,["uno","dos"])
mv_sht.UsedRange.AutoFilter(Field=15,Criteria1=f'<>Array{fltrs}',Operator=xlFilterValues)

当我 运行 这个,它 returns 15.0,我猜是因为那是领域。我已经尝试了我能想到的所有变体,并查看了其他计算器 - 但没有太多关于此的信息。

我发现的最好的: http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/variant.html

但未将其应用于 AutoFilter

谢谢!

我不明白你为什么要这样引用数组。
VBA 上的调用应如下所示

RangeObjectToFilter.AutoFilter 
  Field:=ColumnNumber, 
  Criteria1:=ArrayMultipleCriteria, 
  Operator:=xlFilterValues

我会尝试这样声明数组:

ArrayMultipleCriteria = Array(10, 20, 30, "SomeValue")

您必须相应地调整 python 代码,我相信这应该可以解决问题:

mv_sht.UsedRange.AutoFilter(Field=15,Criteria1=f'Array({', '.join(fltrs)})',
  Operator=xlFilterValues)

从各种来源来看,您似乎无法过滤 out 多个条件(即从过滤器中排除它们)。

您必须将它们从 sheet 中删除。所以带有 <> 的数组不起作用。

xlCellTypeVisible = 12
xlShiftUp = -4162
cols = mv_sht.UsedRange.Columns.Count
    
for owner in ["uno","dos"]:
    mv_sht.UsedRange.AutoFilter(Field=15, Criteria1=owner)
    lastRow = mv_sht.Cells.Find("*", SearchOrder=1, SearchDirection=2).Row
    mv_sht.Range(mv_sht.Cells(2, 1), mv_sht.Cells(lastRow, cols)).SpecialCells(Type=xlCellTypeVisible).Delete(
            Shift=xlShiftUp)

所以,我只是遍历数组的每个值,过滤 sheet,然后删除那些行。

虽然这看起来非常低效。

正如@rnd om 上面所说,您无法过滤out(即<>)多个条件,但您可以过滤。

一种解决方法是在过滤列中创建一个唯一的值列表,删除不需要的值,然后过滤 in 其余值。这可能并不理想,但可能是一个可能的解决方案。顺便说一下,如果您在过滤器中 'Select All' 然后取消选择项目,这就是 Excel 所做的。

测试数据如下:

此 Python 代码 过滤掉第 3 个字母为 'e' 或 'h' 的行 :

import win32com.client

wbPath ='C:\SomePath\Filter.xlsx'

xl = win32com.client.gencache.EnsureDispatch('Excel.Application')
wb = xl.Workbooks.Open(wbPath)
ws = wb.Worksheets(1)

#Access a named range with the table data
rng = ws.Range('TableRange')

#Get all the values from 3rd column in Range
vals = rng.Columns(3).Value

#Create a dictionary of unique values (skipping the header row)
#(there may be more pythonic ways of doing this!)
keepVals = { val[0]:None for val in vals[1:]}

#Remove any values from exclude list
valsToExclude = ['e','h']
[keepVals.pop(v) for v in valsToExclude]

#Create Criteria1 array as a list
crit = ["=" + k for k in keepVals.keys()]

#Apply the filter
rng.AutoFilter(Field=3,Criteria1=crit,Operator=win32com.client.constants.xlFilterValues)

wb.Close(True)
xl.Quit()
xl = None

保存文件中的结果如下: