
本文于2023年4月24日首发于本人同名公众号:Excel活学活用,更多文章敬请关注!
☆本期内容概要☆
上期代码修正
数组元素内容比较(2种方法)
在上期的文章中,我们的代码部分有一点小bug:
原代码33行、50行IF语句InStr函数的第2个参数,没有加限定符:

原代码第45行SQL语句,没有加末级科目的条件:

大家猜猜会不会有什么问题?还是举个简单的例子说明吧:
1、如果不加限定符,InStr("/100101/","1001")>0
2、如果加了限定符,InStr("/100101/","/1001/")=0
3、如果不加末级科目的条件,则比较字段包括所有级别的科目,这样一来,如果导入的凭证数据中,有科目代码为非末级的也会被导入,这样是不行的,我们的制单规则是只能用末级科目填制凭证。
新代码:
……If InStr(strCheck, "/" & xlTitle(i) & "/") = 0 Then……If InStr(strCheck, "/" & xlData(PosAccCode, k) & "/") = 0 Then……arr = clsDQ.GetData("select 科目代码 from tb科目 where 是否末级=True")
改过之后,我把一个科目220301改为2203,结果是这样子的:
当然,这个提示“【2203】科目代码不存在”有点不太准确,应该是提示“【2203】科目代码非末级”,可以实现,但感觉没有必要,不去管它了。
扯远了,回到今天的正题:数组元素内容的比较,也就是检查数组arrA()的各个元素,在arrB()中是否存在,就像上期我们导入凭证的时候,要检查一下导入的科目代码是否已存在,如果不存在,我们要先添加后再导入,否则会引起错乱。
方法我想到2种,一种是用两层循环:
for i=Lbound(arrA) to Ubound(arrA) t=0 for j=Lbound(arrB) to Ubound(arrB) if arrA(i)=arrB(j) then t=1 exit for end if next if t=0 then msgA=msgA & arrA(i) & "不存在" & chr(10) esle msgB=msgB & arrA(i) & "已存在" & chr(10) end if next msgbox msgA & msgB
代码是在这里直接敲的,没有测试,解释一下:
1、这里默认都是一维数组,如果是2维可以通过我们分享过的自定义函数FlattenArray来转换成一维数组后再比较。(Excel VBA 数组应用/核算项目代码组合/VBA代码优化/AI辅助)
2、循环遍历数组arrA(),将它的每个元素与arrB()里的元素进行比较,这里再用一个循环遍历数组arrB()。
3、如果有相等的,则使t=1并退出第2层循环,如果第2层循环都结束了,还是没有找到相等的,这时t=0
4、根据t值,写入字符串msgA(不存在的信息)、msgB(已存在的信息)
6、继续第1层循环
7、结束,输出提示信息
第2种方法,其实就是我们上期、和这期开头修改代码时提到的方法:
strCheck=join(arrB,"/")strcheck="/" & strcheck & "/" '前后都加上限定符"/"for i=Lbound(arrA),Ubound(arrA) if instr(strcheck,"/" & arrA(i) & "/") =0 then msgA=msgA & arrA(i) & "不存在" & chr(10) esle msgB=msgB & arrA(i) & "已存在" & chr(10) end if next msgbox msgA & msgB
这段代码也不复杂,解释一下:
1、把arrB()中的元素通过join函数用"/"连接起来,结果类似"1001/1002/1003",存到字符串变量strcheck里
2、为了能够准确匹配,我们要把strcheck前后再加上限定符"/",结果类似"/1001/1002/1003/"。
3、循环遍历arrA,用instr函数判断每一个元素(前后加上限定符"/")在strcheck中的位置,如果这个元素在strcheck中没有找到,则instr函数返回结果0,否则返回一个大于0的整数(位置)。
4、根据instr返回结果,写入字符串msgA(不存在的信息)、msgB(已存在的信息)
6、结束,输出提示信息
好,今天就分享到这,欢迎点赞、留言、分享,谢谢大家,我们下期再会。
☆猜你喜欢☆

本文使用 文章同步助手 同步,本文于2023年4月24日首发于本人同名公众号:Excel活学活用,更多文章敬请关注!