我如何 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
保存文件中的结果如下:
我不擅长 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
,我猜是因为那是领域。我已经尝试了我能想到的所有变体,并查看了其他计算器 - 但没有太多关于此的信息。
我发现的最好的:
但未将其应用于 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
保存文件中的结果如下: