如何修复这个已有8年历史的VBA64位编译器错误?
所以这是错误:在64 位VBA 主机(例如 Access 365 64 位或 Excel 2016 64 位)中创建一个类模块SomeClass:
' this needs to be here to trigger the bug:
Private Sub Class_Terminate()
End Sub
然后是一些模块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
现在,如果您使用的是32 位VBA 主机并在即时窗口中运行“测试” ,则会显示预期结果:
False
False
但是,如果您使用的是64 位VBA 主机,则会出现:
False
True
除了,当您删除或重命名Class_Terminate()sub 时,在这种情况下会出现正确的输出。
我已经将错误追踪到这个最小的例子。显然,问题似乎是,使用临时对象(new SomeClass此处)IF以某种方式破坏了条件的评估,使条件的值看起来True无关紧要。
好吧,这是一个严重的错误,因为 64 位编译器很疯狂,而且都IF遇到了麻烦。
所有IF?怎么样WHILE?
While ReturnFalse(New SomeClass)
Debug.Print "Oh no!"
Wend
是的,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
- 打开 Excel > 文件 > 反馈 > 发送一个皱眉
- 通过 Uservoice - 点击以下链接查看其他人的反馈并提供反馈 - https://excel.uservoice.com/
这不是对新图标配色方案的建议。这是一个 8 年前的错误,它使 Access 应用程序和带有宏的 Excel 工作表计算出错误的答案(并且它还阻止迁移到此处的 Office 64,因为我们无法获取我们的代码)。
现在这是我的问题:
- 我怎样才能修复这个错误?
- 是否有人在这里拥有相当令人印象深刻的 SLA 或更好的关系,他们会支持我的请求?
- 有没有办法直接报告 VBA 错误?(这是因为我们目前怀疑 64 位 VBA 中存在更多错误)
- 我在用户语音中做了一个新报告。你认为它可以投票吗?https://access.uservoice.com/forums/319956-access-desktop-application/suggestions/43660329-fix-this-64-bit-vba-compiler-bug-temporary-object
更新: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
回答
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
退货
False
True
False
所以If True = ReturnFalse(New SomeClass) Then修复它
对于循环,这也修复了它
Do While True = ReturnFalse(New SomeClass)
Debug.Print "Oh no!"
Exit Do
Loop
强烈建议对上述解决方法的每一种用法进行评论,以便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
甚至If ReturnFalse(New SomeClass) And False = True Then会出现True这个错误。
- 那太可怕了。有一个变通方法很好,但是如果我在某处的代码中看到它,我会立即删除 `True = ` 部分,不知道我刚刚引入了一个错误。那是开发地雷。
- @HackSlash True,强烈建议在每次使用“True =”时添加注释行并附上错误注释。• 因此,在 Microsoft 内部修复错误之前,变通方法可能是您最接近解决此问题的方法。
- @NordicMainframe 好吧,您可以自 VBA 一开始就问自己。MS 从来没有对它投入太多的爱,它总是凌乱、草率和不准确,多年来开发一直停滞不前(他们只做真正需要保持活力的事情)。也许看看 [Office-js](https://github.com/OfficeDev/office-js-docs-reference),它可能是某个时间(或不是)VBA 的继任者。• 即使我讨厌 VBA,有时也可能别无选择,这取决于您正在开发的内容。但这是一个完全偏离主题的讨论。我想 MS 不会在合理的时间内解决这个问题。
- 问题是,我是否应该投资一个开发平台,该平台没有明确的流程供用户报告错误、修复错误,甚至获取待解决的未解决错误列表。
- 我奖励您 1000 点 Internet 积分,因为您建议对解决方法的每个用法都进行评论。否则,甚至有可能代码的作者在 6 个月后忘记并删除它。