Excel VBA 代码意外退出,肯定与:“赋值左侧的函数调用应返回 Variant 或 Object”有关

发布于 2025-01-12 21:32:46 字数 1249 浏览 1 评论 0原文

这是我的代码:

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)< 行静默退出函数/code>
  • 如果我压制Dim Rate As Double 然后我遇到错误(从法语翻译):编译错误:赋值左侧的函数调用应返回 Variant 或 Object

我不了解这个错误。

Here is my code:

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

Here is an example of cell on which to apply it, say A1:

[C : 5.1%] azerty
    aaa bbb ccc 
[C : 0.2%] qwerty
    ddd eee fff

Then a call:

= get_best(A1)

Expected result:

[C : 5.1%] azerty

What it does is:

  • Parse the lines in the cell passed as argument
  • Throw all lines that do not contain the tag
  • For the lines containing the tag, returns the ones where the percentage value after the tag is superior to the threshold passed as argument

It fails:

  • With debugger, I can see it silently exit function at line Rate = CDec(sRate)
  • If I suppress Dim Rate As Double then I have the error (translated from french): compilation error: a function call on the left side of assignment should return Variant or Object

I don't understand this error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昔梦 2025-01-19 21:32:46

您的第一个问题是您的变量 pos1 偏移了 1,因此 sRate 得到 .1 而不是 5.1。函数 CDec 不喜欢这样,并抛出一个错误,指出它无法将其转换为 Double。如果你纠正它,它就会起作用。

您的第二个问题是 Rate 是 VBA 中的内置函数。当您将变量 rate 声明为 Double 时,您将隐藏该函数,并且 VBA 运行时知道您要使用变量。如果您没有定义它,它将假定您正在访问该函数,并且您无法为函数赋值,因此会出现编译器错误。但如果你解决这个问题,你仍然会遇到转换错误。

小问题:您可能需要按 vbLf 拆分,而不是按 vbCr 拆分。

顺便说一句,您应该使用 Option Explicit 并声明所有变量。

Your first issue is that your variable pos1 is off by 1, therefore sRate gets .1 instead of 5.1. The function CDec doesn't like that and throws an error that it cannot convert this to a Double. If you correct that, it will work.

Your second issue is that Rate is a build-in function in VBA. When you declare you variable rate as Double, you will hide the function and the VBA runtime knows that you want to use a variable. If you don't define it, it will assume you are accessing the function, and you can't assing a value to a function, therefore the compiler error. But if you fix this, you will still get the conversion error.

Minor issue: You will likely need to split by vbLf, not by vbCr.

You should, by the way, use Option Explicit and declare all your variables.

傲鸠 2025-01-19 21:32:46

主要问题是区域设置: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

The main problem was a locale one: The input data for CDEC shall use the same decimal separator than the one of your locale e.g. if in your locale the decimal separator is a comma ',' and if your input data uses the dot '.' then you have to convert your data with Replace(sRate, ".", ",").

Final code is:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文