UserForm_Initialize-需要帮助来解决运行时错误'91:未设置对象变量或带块变量

时间:2019-09-26 14:57:29

标签: excel vba userform

我似乎无法弄清楚为什么我的UserForm代码在过程的最后失败了。最终结果是完美的。这是我要完成的工作...

1)该过程使用活动的工作簿,在工作簿中标识工作表名称,并将其显示在用户窗体上的列表框中。  UserForm Pic

2)选择工作表后,用户将单击“选择工作表”命令按钮

3)CommanButton激活工作表,将工作表重命名为“ LegacyBillHist”

4)表单关闭,并且选择了单元格A2

我在最后一行收到运行时错误91消息。

我尝试了几种不同的方法来解决此问题,但是我似乎无法使用StackOverflow和其他站点中的信息来弄清楚这一点。任何帮助将不胜感激。

这是代码。

Option Explicit

Private Sub CommandButton1_Click()

    Worksheets(ListBox1.Value).Activate
    ActiveSheet.Name = "LegacyBillHist"
    Unload BillSelect

End Sub

Public Sub UserForm_Initialize()
    Dim wb As Workbook
    Dim sh As Worksheet

    Set wb = ActiveWorkbook

        For Each sh In wb.Sheets
        ListBox1.AddItem sh.Name
        Next sh

    Load BillSelect
    BillSelect.Show

    sh.Range("A2").Select

End Sub

2 个答案:

答案 0 :(得分:1)

Mathieu

好信息。我最终改变了自己的方法。但是,我有另一个无法解决的问题。这是代码...我是从您引用的文章中得到的...

setState()

在CommandButton1例程下,一切都可以很好地工作到End Sub。而不是隐藏UserForm1,而是重新打开表单。

我尝试合并您提供的代码,但是一直循环运行,直到出现堆栈空间不足错误28。也许我没有按照正确的顺序进行操作。

Option Explicit
Private cancelled As Boolean

Public Property Get IsCancelled() As Boolean
    IsCancelled = cancelled
End Property

Private Sub CommandButton2_Click()
   OnCancel
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
    Cancel = True
    OnCancel
    End If
End Sub

Private Sub OnCancel()
   cancelled = True
   Hide
End Sub

Private Sub CommandButton1_Click()
   Dim wb As Workbook
   Dim ws As Worksheet

   Worksheets(ListBox1.Value).Activate
   ActiveSheet.Name = "LegacyBillHist"

   Set wb = ActiveWorkbook
   Set ws = wb.Sheets("LegacyBillHist")

   ws.Activate
   ws.Range("A1").Select

   UserForm1.Hide

End Sub

Private Sub UserForm_Initialize()
   Dim wb As Workbook
   Dim lastSheet As Worksheet
   Dim sh As Worksheet

     Set wb = ActiveWorkbook
     For Each sh In wb.Worksheets
     ListBox1.AddItem sh.Name
     Set lastSheet = sh
     Next

   UserForm1.Show

End Sub

感谢所有帮助。

答案 1 :(得分:0)

    For Each sh In wb.Sheets
    ListBox1.AddItem sh.Name
    Next sh

对象sh仅在For...Next循环内 有意义。

理论上,根据语言规范,sh 应该确实仍引用了迭代集合中的最后一项:

  
      
  • <for-each-statement>执行完毕后,<bound-variable-expression>的值就是<collection>中最后一个元素的数据值。
  •   
     

https://docs.microsoft.com/en-us/openspecs/microsoft_general_purpose_programming_languages/MS-VBAL/b132463a-fd25-4143-8fc7-a443930e0651

无论何时实施VBA时,出现的提示点都没有:循环前For Each的{​​{1}}变量,循环后仍为Nothing-对Nothing进行的成员调用将始终引发错误91。

说实话,我认为这样做也更好:它迫使您的代码更加明确:

Nothing

注意:Dim lastSheet As Worksheet Dim sh As Worksheet For Each sh In wb.Worksheets '<~ note: 'Sheets' collection can have charts, not just worksheets ListBox1.AddItem sh.Name Set lastSheet = sh Next With New BillSelect '<~ forms are objects too; avoid using their global state .Show End With lastSheet.Activate lastSheet.Range("A1").Select 构成New可以在表单代码read this article中显示隐藏的错误,以获取更多信息。


BillSelect处理程序不应该执行此工作,尤其是,如果您不Initialize填写表单并使用其默认实例 >:您无法控制默认实例的创建时间,VBA可以控制。

给出以下代码:

New

如果以前没有代码引用过UserForm1.Show ,那么UserForm1处理程序将在 at Initialize before 上运行返回给调用方,然后运行UserForm1;如果未破坏表单的默认实例,则下次显示该表单时,初始化处理程序将不会再次运行,因为该实例已被初始化。

请考虑改为在.Show处理程序中实现您的逻辑,这将使逻辑在输入Activate调用后 每次运行 >表单已激活(由于这是一个模式对话框,因此意味着每次实际显示该表单)。