首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建/传递变体,以便使用win32com筛选多个条件

如何创建/传递变体,以便使用win32com筛选多个条件
EN

Stack Overflow用户
提问于 2022-02-19 01:33:54
回答 3查看 289关注 0票数 0

我不太擅长VBA,但据我所知,AutoFilter在运行xlFilterValues时需要一个Array()变体。

代码语言:javascript
复制
import win32com.client as win32

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

# https://learn.microsoft.com/en-us/office/vba/api/excel.xlautofilteroperator
xlFilterValues = 7
# https://learn.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)

当我运行它时,它返回15.0,我猜是因为这是字段。我试过所有我能想到的变体,也看过其他的堆栈溢出--但是这方面没有太多的信息。

我发现的最好的:Excel VBA Autofilter error when using criteria2 http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/variant.html

但是没有把它应用到AutoFilter

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-02-20 12:04:15

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

解决方法之一是在filter列中创建一个值的唯一列表,删除不想要的值,并在中筛选其余的值。这也许并不理想,但可能是一种可能的解决办法。顺便提一句,如果您在筛选器中“选择所有”,然后取消选择项,这就是Excel所做的事情。

以下是一些测试数据:

这个Python代码过滤掉第三个字母为'e‘或’h‘的行:

代码语言:javascript
复制
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

在保存的文件中使用此结果:

票数 1
EN

Stack Overflow用户

发布于 2022-02-19 04:12:30

从各种来源来看,您似乎无法将筛选出的多个条件(即从筛选器中排除它们)。

你得把它们从床单上拿出来。因此,一个带有<>的数组不能工作。

代码语言:javascript
复制
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)

因此,我只是循环了数组的每个值,过滤了工作表,并删除了这些行。

不过,这似乎是非常低效的。

票数 1
EN

Stack Overflow用户

发布于 2022-02-19 01:53:01

我不明白你为什么要这样引用数组。

对VBA的调用应该如下所示

代码语言:javascript
复制
RangeObjectToFilter.AutoFilter 
  Field:=ColumnNumber, 
  Criteria1:=ArrayMultipleCriteria, 
  Operator:=xlFilterValues

我会尝试像这样声明数组:

代码语言:javascript
复制
ArrayMultipleCriteria = Array(10, 20, 30, "SomeValue")

您必须相应地调整python代码,我认为这应该能做到这一点:

代码语言:javascript
复制
mv_sht.UsedRange.AutoFilter(Field=15,Criteria1=f'Array({', '.join(fltrs)})',
  Operator=xlFilterValues)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71181641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档