Next 不带 For, End If 不带 If

时间:2021-05-03 19:02:49

标签: vba for-loop if-statement compiler-errors runtime

我正在为下面的代码而苦苦挣扎。在这个版本中,我得到一个“next without for error”

Option Explicit

Private Sub worksheet_change(ByVal Target As Range)
    
    Dim Lookup As Worksheet, Data As Worksheet, PF As Worksheet
    Dim LastRow As Long, LR As Long, LookupCounter As Long, i As Long, j As Long
  
    With ThisWorkbook
        Set Lookup = .Worksheets("Lookup")
        Set Data = .Worksheets("Data")
        Set PF = .Worksheets("PF")
    End With
    
    LastRow = Data.Cells(Rows.Count, "A").End(xlUp).Row
    LR = PF.Cells(Rows.Count, "A").End(xlUp).Row
    LookupCounter = 2
    
    For i = 2 To LastRow
    For j = 2 To LR
        

    If Intersect(Lookup.Range("A2"), Target) Is Nothing Then
        Exit Sub
    Else
        ' clear sheet
        Application.EnableEvents = False
        Application.ScreenUpdating = False
        Lookup.Range("A2").Value = UCase(Lookup.Range("A2"))
        Lookup.Range("B2:H2000").Clear
        ' get data
        
           If Lookup.Range("A2") = Data.Cells(i, 2) Then
               Lookup.Cells(LookupCounter, 3).Value = Data.Cells(i, 1)
               Lookup.Cells(LookupCounter, 4).Value = Data.Cells(i, 9)
               LookupCounter = LookupCounter + 1
        
            ElseIf Lookup.Range("A2") = PF.Cells(j, 2) Then
                Lookup.Cells(LookupCounter, 6).Value = PF.Cells(j, 1)
                Lookup.Cells(LookupCounter, 7).Value = PF.Cells(j, 12)
                Lookup.Cells(LookupCounter, 8).Value = PF.Cells(j, 10)
                Lookup.Cells(LookupCounter, 9).Value = PF.Cells(j, 2)
                LookupCounter = LookupCounter + 1
        
        Lookup.Range("C2:C2000").NumberFormat = "mm/dd/yyyy"
        Lookup.Range("F2:F2000").NumberFormat = "mm/dd/yyyy"
        Lookup.Range("H2:H2000").Style = "Currency"
        Application.EnableEvents = True
        Application.ScreenUpdating = True
        
    End If
    
    Next
    
End Sub

在这个版本中,我也收到错误“next without for”

Option Explicit

Private Sub worksheet_change(ByVal Target As Range)
    
    Dim Lookup As Worksheet, Data As Worksheet, PF As Worksheet
    Dim LastRow As Long, LR As Long, LookupCounter As Long, i As Long, j As Long
  
    With ThisWorkbook
        Set Lookup = .Worksheets("Lookup")
        Set Data = .Worksheets("Data")
        Set PF = .Worksheets("PF")
    End With
    
    LastRow = Data.Cells(Rows.Count, "A").End(xlUp).Row
    LR = PF.Cells(Rows.Count, "A").End(xlUp).Row
    LookupCounter = 2
    
    For i = 2 To LastRow
    For j = 2 To LR
        

    If Intersect(Lookup.Range("A2"), Target) Is Nothing Then
        Exit Sub
    Else
        ' clear sheet
        Application.EnableEvents = False
        Application.ScreenUpdating = False
        Lookup.Range("A2").Value = UCase(Lookup.Range("A2"))
        Lookup.Range("B2:H2000").Clear
        ' get data
        
           If Lookup.Range("A2") = Data.Cells(i, 2) Then
               Lookup.Cells(LookupCounter, 3).Value = Data.Cells(i, 1)
               Lookup.Cells(LookupCounter, 4).Value = Data.Cells(i, 9)
               LookupCounter = LookupCounter + 1
        
            ElseIf Lookup.Range("A2") = PF.Cells(j, 2) Then
                Lookup.Cells(LookupCounter, 6).Value = PF.Cells(j, 1)
                Lookup.Cells(LookupCounter, 7).Value = PF.Cells(j, 12)
                Lookup.Cells(LookupCounter, 8).Value = PF.Cells(j, 10)
                Lookup.Cells(LookupCounter, 9).Value = PF.Cells(j, 2)
                LookupCounter = LookupCounter + 1
        
        Lookup.Range("C2:C2000").NumberFormat = "mm/dd/yyyy"
        Lookup.Range("F2:F2000").NumberFormat = "mm/dd/yyyy"
        Lookup.Range("H2:H2000").Style = "Currency"
        Application.EnableEvents = True
        Application.ScreenUpdating = True
        
    End If
    
    Next
    
End Sub

如果我删除两个“Next”语句,我会得到一个“End if without block if”作为错误...我什至不知道我的代码是否有效,我对在“next”中移动感到沮丧和“结束 if”语句,我无法理解。任何指针将不胜感激。

谢谢,

1 个答案:

答案 0 :(得分:1)

查看您的代码,for 循环中有许多冗余活动。通过一些重组,您可以更清楚地了解正在发生的事情。我不知道下面的代码是否重现了您的意图,但它是如何编写更好的 VBA(恕我直言)的示例。顺便说一下,代码会编译并且不会触发任何 Rubberduck 检查。

Option Explicit

Private Sub worksheet_change(ByVal ipTarget As Range)
    ' if you use consistent naming you always know where to look
    ' for the definition of a variable
    ' I use the following prefixes
    ' * ip for an input parameter
    ' * op for an output only parameter
    ' * iop for a parameter that can have its value changed for use outside the method
    ' * my for variables declared inside a method
    
    ' Avoid using 'With' if you can use a simpler qualifying scheme
    
    Dim myWb As Workbook
    Set myWb = ThisWorkbook
    
    ' The guard clause should come as early as possible
    If Intersect(myWb.Worksheets.Item("Lookup").Range("A2"), ipTarget) Is Nothing Then
        
        Exit Sub
            
    End If
  
   ' Don't put things inside loops if they only need to be done once
    Application.EnableEvents = False
    Application.ScreenUpdating = False
        
    Dim myLookup As worksheet
    Set myLookup = myWb.Worksheets.Item("Lookup")
    
    ' clear sheet
    ' also a clear use case for the With construct
    With myLookup
    
        .Range("A2").Value = UCase$(myLookup.Range("A2").Value)
        .Range("B2:H2000").Clear
        .Range("C2:C2000").NumberFormat = "mm/dd/yyyy"
        .Range("F2:F2000").NumberFormat = "mm/dd/yyyy"
        .Range("H2:H2000").Style = "Currency"
    
    End With
        
    Dim myData As worksheet
    Set myData = myWb.Worksheets.Item("Data")
    Dim myLastRow As Long
    ' Unqualified reference to Rows replaced with myData.Rows
    myLastRow = myData.Cells.Item(myData.Rows.Count, "A").End(xlUp).Row
    
    ' seems like you have another 'lastrow' here?
    Dim myPF As worksheet
    Set myPF = myWb.Worksheets.Item("PF")
    Dim myLR As Long
    'Unqualified reference to Rows replaced with myPfRows.
    myLR = myPF.Cells.Item(myPF.Rows.Count, "A").End(xlUp).Row
    
    Dim myLookupCounter As Long
    myLookupCounter = 2
    
    ' Although you will see it used frequently, i,j,k
    ' as variables for loop counters is poor coding
    ' much better to use meaningful names.
    
    Dim myRow As Long
    For myRow = 2 To myLastRow
    
         ' Sorry no idea what a good name would be here as there isn't
         ' enough information
        Dim myAltRow As Long
        For myAltRow = 2 To myLR
        
            With myLookup
            
               If .Range("A2").Value = myData.Cells.Item(myRow, 2) Then
               
                   .Cells.Item(myLookupCounter, 3).Value = myData.Cells.Item(myRow, 1)
                   .Cells.Item(myLookupCounter, 4).Value = myData.Cells.Item(myRow, 9)
                   myLookupCounter = myLookupCounter + 1
            
                ElseIf .Range("A2").Value = myPF.Cells.Item(myAltRow, 2) Then
                
                    .Cells.Item(myLookupCounter, 6).Value = myPF.Cells.Item(myAltRow, 1)
                    .Cells.Item(myLookupCounter, 7).Value = myPF.Cells.Item(myAltRow, 12)
                    .Cells.Item(myLookupCounter, 8).Value = myPF.Cells.Item(myAltRow, 10)
                    .Cells.Item(myLookupCounter, 9).Value = myPF.Cells.Item(myAltRow, 2)
                    myLookupCounter = myLookupCounter + 1
                    
                ' what happens if neither of the two conditions above is met?
                'else
                
                    '??????
                
                End If
                
            End With
   
        Next myAltRow
    
    Next myRow
    
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    
End Sub

相关问题