gri*_*rda 3 excel vba excel-vba
我在Excel VBA中有以下INSTR条件,它不起作用(始终)
STR_TEXT="SKU1234 $100/10' $200/20'" ' < example string
IF INSTR(STR_TEXT,"/10'") AND INSTR(STR_TEXT,"/20'") THEN
' code
ELSE
' code
END IF
Run Code Online (Sandbox Code Playgroud)
由于某些不明原因,它似乎无法检查这两个条件,所以第一个IF,即使两个条件匹配,似乎也不起作用并进入ELSE.
以下工作:
STR_TEXT="SKU1234 $100/10' $200/20'" ' < example string
IF INSTR(STR_TEXT,"/10'") THEN
IF INSTR(STR_TEXT,"/20'") THEN
' code
END IF
ELSE
' code
END IF
Run Code Online (Sandbox Code Playgroud)
如您所见,如果我将第一个IF上的条件分开,它就可以了.但我宁愿在同一个IF中同时具备这两个条件,因为代码是"更清洁"的.
任何人都知道为什么和/或如何修复它而不必将IF放在另一个IF中?
jto*_*lle 10
其他答案指出了最重要的事情,即InStr实际上返回一个字符串在另一个字符串中的数字位置(如果找不到所需的字符串,则返回0).正如他们所说,你应该在你的陈述中测试这个条件 .我只会说明你的观察背后的原因是你的测试"不起作用(所有时间)".这是一个很好的机会,陶醉于一些古老的I- <3-BASIC超棒.<result> > 0If
发生了什么事情,在这种情况下(参见底部的编辑了解更多)VBA的And运算符(Or等等)实际上是一个按位运算符,而不是逻辑运算符.也就是说,如果你传递两个整数操作数,它将逐位执行And,并返回结果整数.例如,42 And 99求值为34,因为(二进制)0101010 And 1100011是0100010.
现在,通常,如果使用VBA Boolean值,And就像逻辑运算符一样工作.这是因为在VBA中,常量True等于数字-1,并且False等于数字零.因为VBA表示-1所有位都设置为二进制数,而零作为二进制数且所有位都清零,您可以看到二进制运算等同于逻辑运算.-1 And <something>总是等于一样<something>.但是如果你只是传递任何旧数字And,你将得到一个数字,并且它不会总是一个等于常数True或数字的数值False.
考虑一个简单的例子(在立即窗口中输入):
x="abc"
?Instr(x,"a")
1
?Instr(x,"b")
2
?Instr(x,"c")
3
?(Instr(x,"a") and Instr(x, "b"))
0
?(Instr(x,"a") and Instr(x, "c"))
1
Run Code Online (Sandbox Code Playgroud)
现在回想一下,VBA的If语句将任何非零数字参数视为相同True,并将零数字参数视为相同False.当你把所有这些放在一起时,你会发现你的例子形式的陈述:
IF INSTR(STR_TEXT,"/10'") AND INSTR(STR_TEXT,"/20'") THEN
Run Code Online (Sandbox Code Playgroud)
有时会选择第一个条件,有时是第二个条件,具体取决于搜索字符串中的内容.这是因为有时按位And操作将返回零,有时它将返回非零.确切的结果将取决于找到的字符串的确切位置,这显然不是您所期望的.所以这就是为什么你已经得到的建议在细节上很重要.
编辑:正如休·艾伦在这篇评论中所指出的那样:
当第一个参数为false时,VBA"And"运算符是否会计算第二个参数?
VBA的And运算符确实返回Boolean了它的两个操作数的值Boolean.所以说它是一个按位运算符并不严格正确.但这对于这个问题是正确的.此外,它可以充当按位运算符的事实意味着它不能像"正常",纯粹逻辑的运算符那样行事.例如,因为它必须评估两个操作数以确定它们是否是数字,所以它不能短路.
示例:
if instr(str_Text,"/10'") > 0 AND instr(str_text,"/20'") > 0 then
Run Code Online (Sandbox Code Playgroud)
Tim 所说的是 instr 函数返回正在搜索的字符串的第一个实例在字符串中的位置。
所以在你的例子中:为 instr(str_Text,"/10') 返回 13。
当 VBA 读取您的版本 instr(str_text,"/10;") (没有 >0)然后它看到结果不是 1(这意味着真)所以它总是命中其他)