简体   繁体   English

用VBA编译处理错误?

[英]Error handling with VBA compiling?

How easy would it be for someone with only decent programming experience to add error handling for compiling? 对于仅具有良好编程经验的人来说,添加错误处理进行编译有多容易? I have an Excel-VBA program that on some computers fails to locate the references, so I made a common folder and placed the .dll files there. 我有一个Excel-VBA程序,在某些计算机上无法找到引用,因此我创建了一个公用文件夹并将.dll文件放在那里。 Is there a way I can automate this error handling process? 有没有一种方法可以使这个错误处理过程自动化? It is a compile error for "cannot find library" so I imagine I cannot do this with VBA. 这是“找不到库”的编译错误,因此我想我无法使用VBA进行此操作。 Is this easily doable? 这容易做到吗? Thoughts? 思考?

I did not attach code because there is nothing relevant to show. 我没有附加代码,因为没有相关内容可显示。 I get a compile error on some computers because there is a missing reference that I would like to have a program locate on error, rather than a human. 我在某些计算机上遇到编译错误,因为缺少参考,我希望程序位于错误而非人为的位置。

Error handling refers to run-time errors. 错误处理是指运行时错误。 You can't handle compile-time errors with error handling, since executing the error handling requires compiling and running the code in the first place. 您无法使用错误处理来处理编译时错误,因为执行错误处理首先需要编译并运行代码。

What you can do, is change how you're compiling your code. 可以做的是更改编译代码的方式。 For example, this code requires a compile-time reference to MyLibrary : 例如,此代码需要对MyLibrary的编译时引用:

Dim foo As MyLibrary.Something

This code doesn't: 这段代码没有:

Dim foo As Object

The difference is that member calls against foo are no longer resolved at compile-time - which means you can't get intellisense when coding against it; 不同之处在于,对foo成员调用不再在编译时解决-这意味着在对它进行编码时您无法获得智能感知。 VBA will happily compile a typo and run-time will blow up with error 438 saying it can't find the specified member. VBA会很高兴地编辑一个拼写错误,并且运行时会因错误438爆满而无法找到指定的成员。

foo.DoSomething 'works if foo has a DoSomething member.
foo.IDontExist  'compiles but throws error 438 at run-time.

When your project has a reference to MyLibrary , you're early-binding - meaning code will refuse to compile if, say, the DLL can't be found. 当您的项目引用MyLibrary ,您就处于早期绑定状态 -这意味着如果找不到DLL,则代码将拒绝编译。

When your project doesn't have a reference to MyLibrary , and your code doesn't include any identifier that's defined in that library ( Option Explicit becomes utterly important then), you're late-binding - meaning the compiler will not care to validate the member calls, and the linking happens at run-time. 当您的项目没有对MyLibrary的引用,并且您的代码不包含该库中定义的任何标识符时(那么Option Explicit变得非常重要),您将进行后期绑定 -意味着编译器将不在乎验证成员调用,并且链接在运行时发生。

Converting your early-bound code to late-bound code will require extensive overhaul of every single declaration, replacing every single class with Object , then removing the references to the DLL's. 将您的早期绑定代码转换为后期绑定代码将需要对每个声明进行大修,用Object替换每个单独的类,然后删除对DLL的引用。

Then you can't do this anymore: 然后,您将无法再执行此操作:

Set foo = New MyLibrary.Something

Instead, you use the class' registered ProgId (a GUID works too) to locate the DLL at run-time by hitting the Windows Registry entry for it, using the CreateObject function: 而是使用类的注册ProgId (GUID也起作用)在运行时通过使用CreateObject函数在Windows注册表项中找到它来找到DLL:

Set foo = CreateObject("MyLibrary.Something")

If the MyLibrary.Something ProgID isn't registered on the machine the code is running on, a run-time error will occur, that you can handle at run-time with classic On Error statements. 如果MyLibrary.Something ProgID未在运行代码的计算机上注册,则将发生运行时错误,您可以使用经典的On Error语句在运行时进行处理。 The correct ProgID values to use depend on how the DLLs were registered; 使用的正确ProgID值取决于DLL的注册方式。 they may or may not match the "Library.TypeName" scheme. 它们可能匹配“ Library.TypeName”方案,也可能不匹配。

You can trap some compile errors. 您可以捕获一些编译错误。 In this example, I was able to trap whether the Microsoft Word 16.0 Object Library was missing (which was required later in the code), and instruct the user what to do. 在此示例中,我能够捕获Microsoft Word 16.0对象库是否丢失(在代码的稍后部分中需要这样做),并指示用户该怎么做。

In the Workbook_BeforeSave event, record the version of Office that last saved the Macro workbook; 在Workbook_BeforeSave事件中,记录上次保存宏工作簿的Office版本; then, when it's opened, test whether the current version is older than the version it was saved under. 然后,在打开该文件时,测试当前版本是否早于保存该版本的版本。 Similar code could be used to test whether a specific .dll exists in the filesystem, and then instruct the user how to correct the problem. 类似的代码可以用来测试文件系统中是否存在特定的.dll,然后指示用户如何解决此问题。 It's not a perfect solution, but better than nothing 这不是一个完美的解决方案,但总比没有好

This code goes in ThisWorkbook.: 此代码在ThisWorkbook中。

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
   Me.Sheets("Macros").Activate
   Sheets("Macros").Shapes(1).TextFrame.Characters.Text = "Show Tools" & Chr(10) & "Application Version: " & Application.Version
End Sub

Sub Workbook_Open()
   Dim sAppVersion As String
   Application.EnableEvents = True
   Me.Windows(1).ActivateNext
   sAppVersion = Split(Split(Sheets("Macros").Shapes(1).TextFrame.Characters.Text, "Application Version: ")(1), vbCr)(0)
   If sAppVersion > Application.Version Then
       MsgBox ("You are running these Macros in an older version than it was created in.  If you get an error, end the macro (Run -> Reset) and update the References in the VBA." _
           & vbCr _
           & "To do this, press Alt+F11 and click Tools -> References....  Then uncheck the Missing Reference, scroll down and check " _
           & "Microsoft Word " & Application.Version & " Object Library")
   End If

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM