Excel VBA – .xlam(AddIn)引发下标超出范围错误9,但一切工作为xlsm?

基本上锡上的标签说。

我有多个用户表单,多个模块,类模块等。我有工作表,数据被存储和使用的代码。 我已经添加了一个标签和button到function区。

我运行并testing了从“Come Here”到“Sick Em”作为.xlsm文件的所有内容。 每一个forms的每一个领域,每一个代码,每一行代码都是完美的。

我将这个文件保存为一个.xlam文件,并且这个东西在第一个模块中挂在这行代码上:

Worksheets("All Welders Data").Activate 

正如我所说,我得到下标超出范围错误9。

这是我第一次尝试使用VBA项目并将其保存为插件。 我肯定错过了什么。 我已经阅读(John Walkenbach“Excell 2013 …”).xlam文件仍然是工作表的工作簿,一切都应该像.xlsm一样工作。

这是表的参考是错误的? 这是激活吗? 我需要为Something.Worksheets("blah").Activate前缀吗? Something.Worksheets("blah").Activate

我累了,我完全被困住了。 我希望有人对我有一些帮助。 提前致谢!

更新

我想坦克大家的反应和意见。 我确实相信“ThisWorkbook”可能会解决这个问题。 我现在正在接近能够testing它,我会再次更新我的问题与我的结果。

然而,由于在这篇文章中有很多关于我使用激活的讨论,我想提出一个跟所有这些有关的后续问题。

这里是我的一个模块的示例。

 Private Sub UserForm_Initialize() Dim lastRow As Long Dim nameCell As Range Dim box As control 'Set Window size and position With Application .WindowState = xlMaximized Me.Top = .Top * 0.5 Me.Left = .Left * 1.0015 Zoom = Int((.Width * 0.85) / (Width * 0.85) * 40) Width = .Width * 0.995 Height = .Height * 0.992 End With 'Turn off everything except the radio Buttons and thier labels Me.submitButton.Visible = False Me.submitButton.Enabled = False Me.chooseWelderLabel.Visible = False Me.chooseWelderNameComboBox.Visible = False Me.chooseWelderNameComboBox.Enabled = False Me.welderNameLabel.Visible = False Me.welderNameText.Visible = False Me.welderNameText.Enabled = False Me.checkNameButton.Visible = False Me.checkNameButton.Enabled = False Application.ScreenUpdating = False 'Activate the worksheet Application.ThisWorkbook.Worksheets("All Welders Data").Activate Application.ThisWorkbook.Worksheets("All Welders Data").Range("A1").Activate 'sort the data in the active sheet by the welder's last name. With Application.ThisWorkbook.ActiveSheet.Sort .SortFields.Clear .SortFields.Add Key:=Range("B3"), Order:=xlAscending .SetRange ActiveCell.CurrentRegion.Offset(1) .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Application.ScreenUpdating = True 'populate the combox from the active sheet (welder name in the 'first column, welder ID number in the second column. With Application.ThisWorkbook.ActiveSheet lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row For Each nameCell In .Range("E3:E" & lastRow) If nameCell.Value <> "" Then With Me.chooseWelderNameComboBox .ColumnCount = 2 .AddItem nameCell.Value .List(.ListCount - 1, 1) = nameCell.Offset(, -1).Value 'ComboBox now shows the values in column "E" and the values 'in coulmn "D" - in that order, as in "Name" - "ID Number". '(the reverse order of the columns in the worksheet.) End With End If Next End With End Sub 

你会看到一半左右,我激活表。 然后在下一行我激活一个范围。 我需要激活范围,因为我在随后的With块中进行sorting。 sorting完成,因为combobox需要按字母顺序排列。

如果我想激活Range ("A1")我必须确保工作表被激活。 如果不是,那么Range("A1").Activate将失败并出现1004错误,因为除非单元格所在的工作表是活动工作表,否则无法激活单元格。

所以,如果我将是永远不会使用的核心核心激活什么是重构此代码的build议,以便我可以使用Excel中内置的sorting。 我没有兴趣做任何sorting的循环例程。

最后的词

我只想感谢罗宾·麦肯齐(Robin MacKenzie)的回答。 她在正确的轨道上,并给出了一个很好的答案,解决了这个问题。

另外,我只想说,我仍然认为有些时候使用激活不是罪!

关于ThisWorkbook属性的MSDN的评论:

使用此属性来引用包含您的macros代码的工作簿。 此工作簿是从加载项本身内部引用加载项工作簿的唯一方法。 ActiveWorkbook属性不返回外接工作簿; 它将返callback用加载项的工作簿。工作簿属性可能会失败,因为在创build加载项时工作簿名称可能已更改。

(我的重点)

你应该这样做,而不是( Activate ):

 Dim wsData As Worksheet Set wsData = ThisWorkbook.Worksheets("All Welders Data") '<-- use ThisWorkbook ' no need to Activate - just use the data Dim rngStuff As Range Set rngStuff = wsData.Range("A1:G5") '<-- change hardcoded range to whatever you need ' now work with the range 

编辑

关于更新的问题,我会build议类似于下面的代码来填充UserForm上的ComboBox ,而不使用Activate 。 除了处理加载主要是你的工作代码的ComboBox的部分以外,它是经过testing的。

 Option Explicit Sub UserForm_Initialize() Dim wsData As Worksheet Dim rngToSortFirstCell As Range Dim lngLastRow As Long Dim rngNameCell As Range ' set a reference to the sheet Set wsData = ThisWorkbook.Worksheets("All Welders Data") ' clear existing sort fields wsData.Sort.SortFields.Clear ' set a reference to the header of range to sort Set rngToSortFirstCell = wsData.Range("B3") ' sort it by CurrentRegion of first cell rngToSortFirstCell.Sort Key1:=Range("B3").CurrentRegion, _ Order1:=xlAscending, _ Header:=xlYes, _ MatchCase:=False, _ SortMethod:=xlPinYin ' put welder names to combo box With wsData lngLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row For Each rngNameCell In .Range("E3:E" & lngLastRow) If rngNameCell.Value <> "" Then With Me.chooseWelderNameComboBox .ColumnCount = 2 .AddItem rngNameCell.Value .List(.ListCount - 1, 1) = rngNameCell.Offset(, -1).Value 'ComboBox now shows the values in column "E" and the values 'in coulmn "D" - in that order, as in "Name" - "ID Number". '(the reverse order of the columns in the worksheet.) End With End If Next End With End Sub