有这样一个需求,需要在某个范围里寻找同时含有2个条件的文本个数,第一想到的时countifs这个公式,可以范围只有一个,条件却有2个;进一步想,将两个条件合并成一个,这样条件1个,范围一个,就能用countif了;但是,棘手的是,两个条件的合并不能直接在范围里找到,因为两个条件的文本顺序与范围内的文本顺序不一样。就比如说条件1是IPHONESE3RDGENWHITE,条件2是64GB,在范围里能查找到的准确值是IPHONESE3RDGEN64GBWHITE。 如图所示: 于是我就编辑了如下命令给AI: FunctionCOUNTIFSPLIT(rngAsRange,criteria1AsString,criteria2AsString)AsLong Dimarr1()AsString Dimarr2()AsString DimcountAsLong DimiAsLong,jAsLong ForEachcInrng arr1Split(criteria1,) arr2Split(criteria2,) count0 Fori0ToUBound(arr1) Forj0ToUBound(arr2) IfInStr(1,c。Value,arr1(i),vbTextCompare)0AndInStr(1,c。Value,arr2(j),vbTextCompare)0Then countcount1 EndIf Nextj Nexti IfcountUBound(arr1)1UBound(arr2)1Then COUNTIFSPLITCOUNTIFSPLIT1 EndIf Nextc EndFunction FunctionCOUNTMATCHEDWORDS(Condition1AsString,Condition2AsString,RangeColumnAsRange)AsInteger DimCondition1Array()AsString Condition1ArraySplit(Condition1,) DimSearchStringAsString SearchStringJoin(Condition1Array,)Condition2 DimMatchCountAsInteger MatchCount0 DimCellAsRange ForEachCellInRangeColumn DimCellArray()AsString CellArraySplit(Cell。Value,) DimIsMatchedAsBoolean IsMatchedTrue DimCondition1WordAsVariant ForEachCondition1WordInCondition1Array IfNotIsInArray(Condition1Word,CellArray)Then IsMatchedFalse ExitFor EndIf NextCondition1Word IfIsMatchedAndIsInArray(Condition2,CellArray)Then MatchCountMatchCount1 EndIf NextCell COUNTMATCHEDWORDSMatchCount EndFunction FunctionIsInArray(WordAsString,WordArray()AsString)AsBoolean DimiAsInteger IsInArrayFalse ForiLBound(WordArray)ToUBound(WordArray) IfWordArray(i)WordThen IsInArrayTrue ExitFunction EndIf Nexti EndFunction PublicFunctionCountCommonText(SearchRangeAsVariant,Criteria1AsString,Criteria2AsString)AsLong Dimarr1AsVariant,arr2AsVariant,cellAsRange DimiAsLong,jAsLong,countAsLong DimisMatchAsBoolean arr1Split(Criteria1,) arr2Split(Criteria2,) ForEachcellInSearchRange IfInStr(1,cell。Value,arr1(0),vbTextCompare)0AndInStr(1,cell。Value,arr2(0),vbTextCompare)0Then isMatchTrue Fori1ToUBound(arr1) IfInStr(1,cell。Value,arr1(i),vbTextCompare)0Then isMatchFalse ExitFor EndIf Nexti Forj1ToUBound(arr2) IfInStr(1,cell。Value,arr2(j),vbTextCompare)0Then isMatchFalse ExitFor EndIf Nextj IfisMatchThencountcount1 EndIf Nextcell CountCommonTextcount EndFunction FunctionFINDMATCHES(rngAsRange,cond1AsString,cond2AsString)AsVariant Dimwords1()AsString Dimwords2()AsString Dimmatches()AsString DimmatchCountAsInteger DimiAsInteger DimjAsInteger Splitconditionsintowords words1Split(cond1,) words2Split(cond2,) Loopthrough FunctionFINDMATCHINGCOUNT(criteria1AsString,criteria2AsString,rangeAsRange)AsLong Dimsplit1()AsString Dimsplit2()AsString DimiAsLong DimcountAsLong 将条件1和条件2按照空格拆分成数列 split1Split(criteria1,) split2Split(criteria2,) ForEachcellInrange 如果范围单元格的文本串包含条件1和条件2的所有值,则计数器加1 IfInStr(cell。Value,split1(0))0AndInStr(cell。Value,split1(1))0AndInStr(cell。Value,split2(0))0Then countcount1 EndIf Nextcell FINDMATCHINGCOUNTcount EndFunction FunctionCOUNTMATCHES(rngAsRange,cond1AsString,cond2AsString)AsLong Dimarr1()AsString,arr2()AsString DimiAsLong,jAsLong,countAsLong 将条件1和条件2拆分为数列 arr1Split(cond1,) arr2Split(cond2,) 循环遍历范围值 Fori1Torng。Cells。Count DimtempArr()AsString tempArrSplit(rng。Cells(i)。Value,) Dimcond1FoundAsBoolean cond1FoundFalse Dimcond2FoundAsBoolean cond2FoundFalse 检查范围值是否包含所有条件1和条件2的值 Forj0ToUBound(arr1) IfInStr(1,rng。Cells(i)。Value,arr1(j),vbTextCompare)0Then cond1FoundTrue Else cond1FoundFalse ExitFor EndIf Nextj Forj0ToUBound(arr2) IfInStr(1,rng。Cells(i)。Value,arr2(j),vbTextCompare)0Then cond2FoundTrue Else cond2FoundFalse ExitFor EndIf Nextj 如果范围值包含所有条件1和条件2的值,并且不包含额外的值,则计数 Ifcond1FoundAndcond2FoundAndUBound(tempArr)UBound(arr1)UBound(arr2)1Then countcount1 EndIf Nexti COUNTMATCHEScount EndFunction 通过运行以上最后一个自定义函数就可以满足要求。如有问题可以接着问AI。 就这样,我通过不到10分钟的过程,让AI帮我完成了自定义函数的编程,这个过程中还不需要自己亲自去写代码。