编辑:将代码缩小到问题来源!
当有些人试图运行我的自定义宏启用工作表时,我遇到了一个非常奇怪的问题。正如我现在正在测试的那样,我只是无法弄清楚我的错误。
当我点击'salvar'按钮时,错误发生在'过时'表格中,它表示我的变量没有设置到目标工作表位置的值。
这篇文章如何工作:
它是基于位于“sistemas”表A列中的业务服务名称的表单测验,其中用户必须设置SLA,响应时间和所选服务的重要性。当一个用户想要报告一个服务是否不属于他们时,发生错误,单击“Nãopertencea equipe”按钮并在新窗口上放置一些值,然后单击“salvar”。
示例代码:
UserForm1:
Private Sub CommandButton1_Click()
UserForm2.Show
End Sub
Private Sub UserForm_Initialize()
Dim index
count_total = Sheets("main").Range("A" & Rows.Count).End(xlUp).Row
Application.WindowState = xlMinimized
stop_process = 0
is_obsolete = False
Addition = 1
i = 1
nextComboList
End Sub
Public Sub nextComboList()
If i <= count_total Then
ComboBox1.Value = Sheets("main").Cells(i, "A").Value
End If
End Sub
UserForm2:
Private Sub CommandButton1_Click()
Dim myInput
text_team = TextBox1.Value
text_manager = TextBox2.Value
If text_team = "" And text_manager = "" Then
Unload Me
ElseIf text_team = TextBox1.Value Or text_manager = TextBox2.Value Then
'THE PROBLEM SHOULD START ON THIS LINE!!!! ----- ERROR 9
Worksheets("target").Cells(i, "A").Value = sysName
Worksheets("target").Cells(i, "B").Value = text_team
Worksheets("target").Cells(i, "C").Value = text_manager
Worksheets("target").Cells(i, "D").Value = "N/P"
is_obsolete = True
i = i + 1
UserForm1.nextComboList
Unload Me
End If
If i > count_total Then
MsgBox "all items validated"
Else
Unload Me
End If
End Sub
Private Sub UserForm_Activate()
sysName = UserForm1.ComboBox1.Value
End Sub
模块1:
Public i As Integer
Public sysName As String
Public Addition As Integer
Public text_team As String
Public text_manager As String
Public count_total As Integer
Sub CallUserForm()
If debug_mode = 0 Then
Application.ScreenUpdating = False
Else
UserForm1.Show
End If
End Sub
Sub shutdown_forms()
Unload UserForm2
Unload UserForm1
End Sub
您需要在Sheets("main")
和Worksheets("target")
中明确引用Workbook。这些隐含地引用了活动工作簿。如果用户打开多个工作簿并不巧妙地拥有这些工作表名称,则会出现超出范围错误的下标。请注意,CallUserForm()
是隐式公共的,因此可以从任何活动工作簿调用它们(它们也可以使用您的公共变量,但这可能只是未来有关此代码的问题的答案......)。
您可以通过向每个表单添加自定义属性来传递表单之间的正确工作簿引用,并使用硬引用而不是预先声明的实例。我强烈建议您阅读@MathieuGuindon的this answer,原因是您不应该使用UserForm1.Show
实例化表单。这将帮助您避免在解决当前问题后遇到的其他几个常见且难以追踪的问题。
在您的情况下,最简单的版本是将以下代码添加到您的每个表单:
'In declarations at the top.
Private targetBook As Workbook
Public Property Set TargetWorkbook(Target As Workbook)
Set targetBook = Target
End Property
然后,您可以在调用调用子时传递表单绑定的工作簿引用:
Public Sub CallUserForm()
If debug_mode = 0 Then
Application.ScreenUpdating = False
Else
Dim descriptiveFormName As UserForm1
'Note that this uses the code name, not the ActiveWorkbook.
'If you've changed the code name, use that instead of ThisWorkbook.
descriptiveFormName.TargetWorkbook = ThisWorkbook
descriptiveFormName.Show
End If
End Sub
现在,而不是希望用户在此处为您的呼叫激活正确的工作簿...
Worksheets("target").Cells(i, "A").Value = sysName
...您可以明确确保引用正确的工作簿:
targetBook.Worksheets("target").Cells(i, "A").Value = sysName
在调用第二个表单时,使用相同的方法,传递工作簿引用...
Private Sub CommandButton1_Click() UserForm2.Show End Sub
......在这里做同样的事......
count_total = Sheets("main").Range("A" & Rows.Count).End(xlUp).Row
...以及您使用隐式Active *对象的任何其他位置。否则,您将在代码中的每个位置继续遇到相同类型的错误。