【问题标题】:Excel VBA Runtime Error 9 but not when stepping through the codeExcel VBA 运行时错误 9,但在单步执行代码时没有
【发布时间】:2018-09-14 15:56:23
【问题描述】:

带有 EventHandler 类的 VBA 用户表单抛出运行时错误“9”的原因是什么:下标超出范围

但是

如果我按 F8 并进入用户窗体代码,我可以直接通过整个代码而不会崩溃

为了简单起见,这里是我的事件处理程序类 LabelEventHandler

Private WithEvents Innerlabel As MSForms.Label

Private InnerRow As Integer
Private InnerSheet As Worksheet

Public Property Set Label(ByVal InLabel As MSForms.Label)
    Set Innerlabel = InLabel
End Property

Public Property Let Row(ByVal InRow As Integer)
    InnerRow = InRow
End Property

Public Property Set Sheet(ByVal InSheet As Worksheet)
    Set InnerSheet = InSheet
End Property

Private Sub InnerLabel_Click()
    Dim Frame As MSForms.Frame
    Dim ChildLabel As MSForms.Label
    Set Frame = Innerlabel.Parent
    For Each ChildLabel In Frame.Controls
        Select Case ChildLabel.Name
            Case "FullName"
                InnerSheet.Cells(InnerRow, 4).Value = ChildLabel.Caption
            Case "Email"
                InnerSheet.Cells(InnerRow, 5).Value = ChildLabel.Caption
            Case "Phone"
                InnerSheet.Cells(InnerRow, 6).Value = ChildLabel.Caption
        End Select
    Next
 End Sub

这是用户窗体代码

Private Sheet As Worksheet

Private LabelClickArray() As New LabelEventHandler

Public Sub AddUser(FullName As String, Email As String, Phone As String)
    Dim FullNameLabel As MSForms.Label
    Dim EmailLabel As MSForms.Label
    Dim PhoneLabel As MSForms.Label
    Dim UserFrame As Frame
    Dim Top
    Top = FindBottomUserRow()
    Set UserFrame = Me.Controls.Add("Forms.Frame.1")

    With UserFrame
        .Top = Top
        .Left = 5
        .Width = 660
        .Height = 20
        .Font.Name = "Verdana"
        .Font.Size = 12
        .Font.Weight = 400
        .Caption = ""
        .BorderStyle = fmBorderStyleNone
    End With

    Set FullNameLabel = UserFrame.Controls.Add("Forms.Label.1")
    Set EmailLabel = UserFrame.Controls.Add("Forms.Label.1")
    Set PhoneLabel = UserFrame.Controls.Add("Forms.Label.1")

    With FullNameLabel
        .Top = 0
        .Left = 0
        .Width = 200
        .Height = 15
        .Name = "FullName"
        .Caption = FullName
    End With
    With EmailLabel
        .Top = 0
        .Left = 205
        .Width = 300
        .Height = 15
        .Name = "Email"
        .Caption = Email
    End With
    With PhoneLabel
        .Top = 0
        .Left = 510
        .Width = 150
        .Height = 15
        .Name = "Phone"
        .Caption = Phone
    End With

    ReDim Preserve LabelClickArray(UBound(LabelClickArray) + 3)

    Set LabelClickArray(UBound(LabelClickArray) - 2).Label = FullNameLabel
    Set LabelClickArray(UBound(LabelClickArray) - 1).Label = EmailLabel
    Set LabelClickArray(UBound(LabelClickArray)).Label = PhoneLabel

    Set LabelClickArray(UBound(LabelClickArray) - 2).Sheet = Sheet
    Set LabelClickArray(UBound(LabelClickArray) - 1).Sheet = Sheet
    Set LabelClickArray(UBound(LabelClickArray)).Sheet = Sheet

    LabelClickArray(UBound(LabelClickArray) - 2).Row = ActiveCell.Row
    LabelClickArray(UBound(LabelClickArray) - 1).Row = ActiveCell.Row
    LabelClickArray(UBound(LabelClickArray)).Row = ActiveCell.Row
End Sub


Function FindBottomUserRow()
    Dim Frame As Control
    Dim Top
    Top = 30
    For Each Frame In Me.Controls
        If (TypeName(Frame) = "Frame" And Frame.Top > Top) Then Top = Frame.Top
    Next
    If (Top > 30) Then Top = Top + 20
    FindBottomUserRow = Top
End Function

Private Sub UserForm_Initialize()
    Set Sheet = ActiveSheet
    Me.AddUser "Ryan", "ryan@r.com", "2625"
    Me.AddUser "Jeff", "j@k.com", "123-4567"
End Sub

错误

【问题讨论】:

  • 哪一行产生了错误?
  • @Comintern 如果我知道我不必在这里发帖。如果我在用户表单在脚本编辑器中处于活动状态时按 F5 或单击运行按钮,它只会对我大喊运行时错误 9 没有给我行号或任何内容
  • 好吧,那似乎把范围缩小到InnerLabel_Click。该过程中唯一的下标访问是对.Cells 的调用。我会在Select Case ChildLabel.Name 行的正上方扔一个Debug.Print InnerRow,看看有没有什么东西跳出来。
  • 尝试在您的代码中添加几行 Application.Wait DateAdd("s", 0.5, Now) 看看是否可以降低某些部分的速度有助于解决问题

标签: vba excel


【解决方案1】:

您的错误发生在ReDim Preserve 命令中,因为您从未初始化数组。您不能对未初始化的数组执行UBound-函数(如果您尝试,则会收到运行时错误 9)。如果您在运行时无法确定您的数组是否已经初始化,请将您的代码更改为:

If IsArrayAllocated(LabelClickArray) Then
    ReDim Preserve LabelClickArray(UBound(LabelClickArray) + 3)
Else
    ReDim LabelClickArray(3)
End If

函数IsArrayAllocated 如下所示:

Function IsArrayAllocated(arr As Variant) As Boolean

    On Error Resume Next
    IsArrayAllocated = IsArray(arr) _
                   And Not IsError(LBound(arr, 1)) _
                   And LBound(arr, 1) <= UBound(arr, 1)

End Function

(复制自cpearson的代码)

【讨论】:

  • 有趣的是,当我昨晚在一些重构过程中意识到同样的事情时,我只是来这里回答我自己的问题。但是,是的,答案是正确的。我确实喜欢 IsArrayAllocated 函数,我可能会使用它来代替我的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
相关资源
最近更新 更多