首次通过代码Excel VBA运行时错误438

我是一个新手自学的VBA程序员,知道只是足够的Excel / Access文件在这里和那里。 我有一个神秘的438错误,只有当一个同事制作了我的工作簿(Excel 2013 .xlsm)的副本时popup,然后通过电子邮件发送给某人。

打开文件时,将模块中的variables设置为表单上的ActiveXcombobox时,会出现运行时438错误。 如果我结束并重新运行子,它没有问题。

模块1:

Option Private Module Option Explicit Public EventsDisabled As Boolean Public ListBox1Index As Integer Public cMyListBox As MSForms.ListBox Public cMyComboBox As MSForms.Combobox Public WB As String Sub InitVariables() Stop '//for breaking the code on Excel open. WB = ActiveWorkbook.Name Set cMyListBox = Workbooks(WB).Worksheets("Equipment").Listbox1 Set cMyComboBox = Workbooks(WB).Worksheets("Equipment").Combobox1 '//438 here End Sub Sub PopulateListBox() '//Fills list box with data from data sheet + 1 blank Dim y As Integer If WB = "" Then InitVariables ListBox1Index = cMyListBox.ListBoxIndex With Workbooks(WB).Worksheets("Equipment-Data") y = 3 Do While .Cells(y, 1).Value <> "" y = y + 1 Loop End With Call DisableEvents cMyListBox.ListFillRange = "'Equipment-Data'!A3:A" & y cMyListBox.ListIndex = ListBox1Index cMyListBox.Height = 549.75 Call EnableEvents End Sub ... 

在“设备”工作表的Worksheet_activate子部分中调用PopulateListBox。

我所有的代码都在“设备”表中,直到我读到这是坏的表单并将其移动到Module 1。 这打破了我所有的列表框和combobox代码,但基于这个post中的答案,我创build了InitVariables Sub并使其工作。

我最初在Workbook_open中调用了一次InitVariables,但是在一次点击同时打开的不同工作簿之后,WB失去了它的值之后,添加了If WB =“”检查。 我相信这是由于私人/公共/全局variables的不当使用(我试图理解这个有限的成功),但我不认为这是与438错误有关。

在启动时(从Windows资源pipe理器打开没有运行Excel实例的Excel文件),如果我在代码在“停止”中断后再向cMyComboBox添加一个监视,然后逐步执行(F8),则会正确设置cMyComboBox,而不会出错。 手表的上下文似乎不影响它是否防止错误。 如果我刚刚开始步进或注释停止线,那么我得到438当它设置cMyComboBox。

如果我在InitVariables中添加“On Error Resume Next”,那么我不会错误并且项目“工作”,因为在需要cMyComboBoxvariables之前,InitVariables会再次被调用,而且sub似乎总是能够第二次正常工作。 如果可以的话,我宁愿避免在我的代码中进行另一种黑客攻击。

马特

而不是On Error Resume Next ,实现一个实际的处理程序 – 这里这将是一个“重试循环”; 我们通过限制尝试次数来防止无限循环:

 Sub InitVariables() Dim attempts As Long On Error GoTo ErrHandler DoEvents ' give Excel a shot at finishing whatever it's doing Set cMyListBox = ActiveWorkbook.Worksheets("Equipment").Listbox1 Set cMyComboBox = ActiveWorkbook.Worksheets("Equipment").Combobox1 On Error GoTo 0 Exit Sub ErrHandler: If Err.Number = 438 And attempts < 10 Then DoEvents attempts = attempts + 1 Resume 'try the assignment again Else Err.Raise Err.Number 'otherwise rethrow the error End If End Sub 

Resume执行完全相同的导致错误的指令

注意DoEvents调用; 这使Excel恢复正在做的事情,例如加载ActiveX控件 ; 有可能DoEvents本身就解决了这个问题,而且整个重试循环也变得没有意义…但是比对不起更安全。

也就是说,我会认真考虑另外一种devise,它不会严重依赖于全局variables和状态。