如何修复这个已有 8 年历史的 VBA 64 位编译器错误?

Nor*_*ame 58 excel 64-bit ms-access vba class-terminate

所以这是错误:在64 位VBA 主机(例如 Access 365 64 位或 Excel 2016 64 位)中创建一个类模块SomeClass

' this needs to be here to trigger the bug: 
Private Sub Class_Terminate()
End Sub
Run Code Online (Sandbox Code Playgroud)

然后是一些模块Test

Function ReturnFalse(o As Object) As Boolean
    ReturnFalse = False
End Function

Sub Test()
    Debug.Print ReturnFalse(New SomeClass)
    If ReturnFalse(New SomeClass) Then
        Debug.Print True
    Else
        Debug.Print False
    End If    
End Sub
Run Code Online (Sandbox Code Playgroud)

现在,如果您使用的是32 位VBA 主机并在即时窗口中运行“测试” ,则会显示预期结果:

False
False
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用的是64 位VBA 主机,则会出现:

False
True
Run Code Online (Sandbox Code Playgroud)

除了,当您删除或重命名Class_Terminate()sub 时,在这种情况下会出现正确的输出。

我已经将错误追踪到这个最小的例子。显然,问题似乎是,使用临时对象(new SomeClass此处)IF以某种方式破坏了条件的评估,使条件的值看起来True无关紧要。

好吧,这是一个严重的错误,因为 64 位编译器很疯狂,而且都IF遇到了麻烦。

所有IF?怎么样WHILE

While ReturnFalse(New SomeClass)
 Debug.Print "Oh no!"
Wend
Run Code Online (Sandbox Code Playgroud)

是的,WHILE也有麻烦,因为这会打印“哦不!” 在一个循环中。

这很麻烦,我可以在任何地方重现它:

  • 适用于 Microsoft 365 MSO (16.0.14026.20294) 64 位的 Microsoft® Access®
  • Microsoft Access 2016 MSO (16.0.9029.2167) 64 位
  • Microsoft Access 2013 (15.0.4420.1017) MSO (15.0.4420.1017) 64 位

..当然还有Excel

摘要:从 2013 年开始,我可以在我拥有的所有版本的 Office 中找到此错误,并且它可能至少已有 8 年的历史。

好的,这个错误以前影响过其他人吗?是的:

去年的这个帖子:

VBA 在 If 语句中采用错误的分支 - 严重的编译器错误?

2018 年 10 月在 excel.uservoice.com(显然是 Microsoft 的用户意见箱或其他内容)中的这篇文章:

https://excel.uservoice.com/forums/304921-excel-for-windows-desktop-application/suggestions/35735881-fix-inlined-member-calls-on-user-objects-on-64-bi

好的,让我们提交错误报告。

https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_mac-mso_mac2016/how-do-i-report-vba-bugs/bb4e5dea-9996-4232-9b5b-7dd57f76736c

如果在与其他人一起测试后,代码失败并且确实不应该,您可以使用 Excel 中的“微笑”按钮直接向 Microsoft 报告问题。

什么?

https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_win10-mso_2016/excel-2016-vba-bug/b799dfc2-7cef-417d-8a41-96661a360c43

  1. 打开 Excel > 文件 > 反馈 > 发送一个皱眉
  2. 通过 Uservoice - 点击以下链接查看其他人的反馈并提供反馈 - https://excel.uservoice.com/

这不是对新图标配色方案的建议。这是一个 8 年前的错误,它使 Access 应用程序和带有宏的 Excel 工作表计算出错误的答案(并且它还阻止迁移到此处的 Office 64,因为我们无法获取我们的代码)。

现在这是我的问题:

更新:x 发布到

https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-msoffice_custom-mso_2019/invalid-code-by-vba-64-bit-compiler/b91f984a-194c-4453-b8c5-02881afaf83b

更新 2

我有机会在 Office 365 for Mac 安装(其中 Win64 定义为true)上尝试代码,但错误没有出现在那里。所以它现在是 PC 的事情。

更新 3

Post 已发送至 HN 和 The Register:

https://www.theregister.com/2021/08/19/64_bit_microsoft_vba_bug/ https://news.ycombinator.com/item?id=28188251

Pᴇʜ*_*Pᴇʜ 30

Sub Test()
    Debug.Print ReturnFalse(New SomeClass)

    If ReturnFalse(New SomeClass) Then
        Debug.Print True
    Else
        Debug.Print False
    End If
    
    If True = ReturnFalse(New SomeClass) Then
        Debug.Print True
    Else
        Debug.Print False
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

退货

False
True
False
Run Code Online (Sandbox Code Playgroud)

所以If True = ReturnFalse(New SomeClass) Then修复它

对于循环,这也修复了它

Do While True = ReturnFalse(New SomeClass)
    Debug.Print "Oh no!"
    Exit Do
Loop
Run Code Online (Sandbox Code Playgroud)

强烈建议对上述解决方法的每一种用法进行评论,以便True =将来没有人删除它(例如,因为他是在 32 位开发的,甚至没有遇到问题)。

' Don't remove `True =` due to a compiler bug in x64 the condition would always be true. 
' See /sf/ask/4762399001/
If True = ReturnFalse(New SomeClass) Then
Run Code Online (Sandbox Code Playgroud)

甚至If ReturnFalse(New SomeClass) And False = True Then会出现True这个错误。

  • 那太可怕了。有一个变通方法很好,但是如果我在某处的代码中看到它,我会立即删除 `True = ` 部分,不知道我刚刚引入了一个错误。那是开发地雷。 (11认同)
  • @HackSlash True,强烈建议在每次使用“True =”时添加注释行并附上错误注释。• 因此,在 Microsoft 内部修复错误之前,变通方法可能是您最接近解决此问题的方法。 (3认同)
  • @NordicMainframe 好吧,您可以自 VBA 一开始就问自己。MS 从来没有对它投入太多的爱,它总是凌乱、草率和不准确,多年来开发一直停滞不前(他们只做真正需要保持活力的事情)。也许看看 [Office-js](https://github.com/OfficeDev/office-js-docs-reference),它可能是某个时间(或不是)VBA 的继任者。• 即使我讨厌 VBA,有时也可能别无选择,这取决于您正在开发的内容。但这是一个完全偏离主题的讨论。我想 MS 不会在合理的时间内解决这个问题。 (3认同)
  • 问题是,我是否应该投资一个开发平台,该平台没有明确的流程供用户报告错误、修复错误,甚至获取待解决的未解决错误列表。 (2认同)
  • 我奖励您 1000 点 Internet 积分,因为您建议对解决方法的每个用法都进行评论。否则,甚至有可能代码的作者在 6 个月后忘记并删除它。 (2认同)

归档时间:

查看次数:

13224 次

最近记录:

4 年 前