导致崩溃的Excel VBA代码 - 未知原因

时间:2016-11-16 11:15:46

标签: excel vba excel-vba crash

有人可以告诉我为什么以下代码会导致Excel 2010崩溃:

Private Sub Worksheet_Change(ByVal Target As range)
Dim r As range
Dim r1 As range
Dim c As range
Dim i As Long
Dim j As Long
Dim rows As Long
Dim count As Long
Dim sheet As String
Dim sh As Worksheet
Dim range1 As range
Dim range2 As range

If WorksheetFunction.CountA(range("D5:H16")) <= 0 Then
    ActiveSheet.Unprotect
End If

Set c = Target

For i = 4 To 8
    For j = 5 To 16
        If Not i = Target.Column Then
            If r Is Nothing Then
                Set r = ActiveSheet.Cells(j, i)
            Else
                Set r = Application.Union(r, ActiveSheet.Cells(j, i))
            End If
        Else
            If r1 Is Nothing Then
                Set r1 = ActiveSheet.Cells(j, i)
            Else
                Set r1 = Application.Union(r1, ActiveSheet.Cells(j, i))
            End If
        End If
    Next
Next
rows = Target.row

sheet = CStr(ActiveSheet.Cells(rows, 2).Value)
Set sh = ThisWorkbook.Sheets(sheet)
MsgBox (sh.Name)
count = sh.range("J6").End(xlDown).row
MsgBox (count)
Set range1 = ThisWorkbook.Worksheets("Summary").range("J6:J" & count)
Set range2 = ThisWorkbook.Worksheets(sheet).range("J6:J" & count)
range1 = range2.Value

If WorksheetFunction.CountA(range("D5:H16")) <= 0 Then
    ActiveSheet.Unprotect
Else
    ActiveSheet.Unprotect
    r1.Cells.Locked = False
    r.Cells.Locked = True
    ActiveSheet.Protect
End If

End Sub

我尝试做的是允许用户在矩阵中选择多个选项,然后根据矩阵选择显示设备列表

由于

1 个答案:

答案 0 :(得分:0)

可能简化代码可以让您更接近崩溃问题

如果我正确地得到它,您的代码可以归结为:

Private Sub Worksheet_Change(ByVal Target As Range)               
    With Worksheets(CStr(Cells(Target.Row, 2).Value))
        With .Range("J6", .Range("J6").End(xlDown))
            Worksheets("Summary").Range("J6").Resize(.rows.count).Value = .Value
        End With
    End With

    With Range("D5:H16")
        If WorksheetFunction.CountA(.Cells) > 0 Then
            ActiveSheet.Unprotect
            .Locked = True
            Intersect(.Cells, Target.EntireColumn).Locked = False
            ActiveSheet.Protect
        End If
    End With
 End Sub

我将添加以下问题:

  • Target尺寸问题

    在我看来,你假设Target总是1个单元range,因为你正在使用:

       Target.Column
       Target.Row
    

    将返回单个单元格range的行和列索引以及多个单元格的最左侧单元格range

    如果您确实要将1个单元range处理为Target,那么您必须在子元素的开头添加以下行

    If Target.count > 1 Then Exit Sub
    

    否则会被告知您的代码实际上崩溃 Target到最左边的单元格

2)ThisWorkbook问题

如果您开始使用的宏位于与您编码的Change事件处理程序所属的工作表不同的工作簿中,则此问题适用

让我们说:

  • 您的“KickOff”宏位于某些“MyStartingWorkbook”工作簿中

  • 运行时,会影响“MyDataWorkbook”工作簿“dataSheet”工作表的内容

  • 您的Worksheet_Change()事件处理程序适用于后一工作表(即“MyDataWorkbook”工作簿的“dataSheet”工作表)

然后

  • 在“KickOff”宏开始时,ThisWorkbook指向“MyStartingWorkbook”工作簿

  • 但是一旦宏更改了“MyDataWorkbook”工作簿的“dataSheet”工作表的内容,就会触发后者的Worksheet_Change()事件处理程序并且ThisWorkbook切换到“MyDataWorkbook”工作簿

    如果"Summary"sheet工作表属于“MyStartingWorkbook”工作簿

  • ,则可能不是您想要的