这是我的代码:
Public Function get_best(cell As Variant, Optional threshold = 0.5) As String
Dim res As String
Dim Rate As Double
Lines = Split(cell.Value, vbCr)
res = ""
Tag = "[C : "
For i = LBound(Lines, 1) To UBound(Lines, 1)
pos = InStr(Lines(i), Tag)
If pos > 0 Then
pos1 = pos + Len(Tag) + 1
pos2 = InStr(pos1, Lines(i), "%]")
sRate = Mid(Lines(i), pos1, pos2 - pos1)
Rate = CDec(sRate)
If Rate >= threshold Then
res = res & Lines(i) & vbCrLf
End If
End If
Next i
get_best = res
End Function
下面是一个应用它的单元格示例,例如A1:
[C : 5.1%] azerty
aaa bbb ccc
[C : 0.2%] qwerty
ddd eee fff
然后打电话:
= get_best(A1)
预期结果:
[C : 5.1%] azerty
它的作用是:
- 分析作为参数传递的单元格中的行
- 抛出所有不包含标记的行
- 对于包含标记的行,返回标记后的百分比值高于作为参数传递的阈值的行
失败:
- 使用调试器,我可以看到它在
Rate = CDec(sRate)
行静默地退出函数 - 如果我抑制
Dim Rate As Double
,那么我有错误(从法语翻译过来(:compilation error: a function call on the left side of assignment should return Variant or Object
我不理解这个错误。
您的第一个问题是您的变量pos1
关闭了1,因此sRate
得到的是.1
而不是5.1
。函数CDec
不喜欢这样,并抛出一个错误,即它无法将其转换为Double。如果你纠正了这一点,它就会起作用。
第二个问题是Rate
是VBA中的内置函数。当您将变量rate
声明为Double时,您将隐藏该函数,并且VBA运行时知道您要使用某个变量。如果你不定义它,它会假设你正在访问函数,并且你不能向函数赋值,因此会出现编译器错误。但是如果你修复了这个问题,你仍然会得到转换错误。
小问题:您可能需要按vbLf
进行拆分,而不是按vbCr
进行拆分。
顺便说一下,您应该使用Option Explicit
并声明所有变量。
主要问题是区域设置问题:CDEC的输入数据应使用与您的区域设置相同的十进制分隔符。例如,如果在您的区域中,十进制分隔符是逗号','
,如果您的输入数据使用点'.'
,则必须使用Replace(sRate, ".", ",")
转换数据。
最终代码为:
Public Function get_best(cell As Variant, Optional threshold = 0.5) As String
Dim res, sRate As String
Dim fRate As Double
Lines = Split(cell.Value, vbLf)
res = ""
Tag = "[Couverture : "
For i = LBound(Lines, 1) To UBound(Lines, 1)
pos = InStr(Lines(i), Tag)
If pos > 0 Then
pos1 = pos + Len(Tag) + 1
pos2 = InStr(pos1, Lines(i), "%]")
sRate = Mid(Lines(i), pos1, pos2 - pos1)
fRate = CDbl(Replace(sRate, ".", ","))
If fRate >= threshold Then
res = res & Lines(i) & vbLf
End If
End If
Next i
get_best = res
End Function