嵌套的If语句有问题

时间:2013-05-06 20:39:12

标签: excel vba excel-vba

我是VBA的新手,在使用我想写的宏中的If语句时遇到了一些困难。每个月我都会在Excel中收到一份报告,其中列出了我们公司的哪些员工执行了某些任务。我正在编写的宏旨在将每个员工的数据复制并粘贴到主工作簿中。

我遇到的问题是定义我需要复制的范围。正如您在代码中看到的那样,员工列在B列中。我首先在B列中搜索员工。如果它们不存在,宏将在主工作簿中的名称下复制并粘贴(无) 。如果找到了自己的名字,则会将其名称下方的行设置为第一个变量。

这是我遇到问题的地方。下一步是找到列出的下一个员工,并将上面的行设置为第二个变量。然后我使用第一个和第二个变量来复制和粘贴该行范围。我正在使用If语句循环查找下一个列出的员工。但是,我的嵌套If语句在我的第二个Else if语句之后结束。有谁知道我可以写得更好吗?我尝试使用Select Case语句,但无法正确使用语法。

Sub EmployeeActivity()

Dim Employee1 As Integer, Employee2 As Integer, Employee3 As Integer, Employee4 As Integer
Dim EmployeeRange As Range, rngSelectFind As Range, rngPasteFind As Range

Windows("Activities Report.xlsm").Activate

Set rngSelectFind = Columns("B:B").Find(What:="Employee 1", After:=Range("B1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)

If Not rngSelectFind Is Nothing Then
    Employee1 = rngSelectFind.Row + 1
ElseIf rngSelectFind Is Nothing Then
    Set rngSelectFind = Columns("B:B").Find(What:="(none)", After:=Range("B1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
    Consultant3 = rngSelectFind.Row
End If

Set rngSelectFind = Columns("B:B").Find(What:="Employee 2", After:=Range("B1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)

If Not rngSelectFind Is Nothing Then
    Employee2 = rngSelectFind.Row - 1
ElseIf rngSelectFind Is Nothing Then
    Set rngSelectFind = Columns("B:B").Find(What:="Employee 3", After:=Range("B1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
        If Not rngSelectFind Is Nothing Then
            Employee2 = rngSelectFind.Row - 1
        End If
ElseIf rngSelectFind Is Nothing Then
    Set rngSelectFind = Columns("B:B").Find(What:="(none)", After:=Range("B1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
        If Not rngSelectFind Is Nothing Then
            Employee2 = rngSelectFind.Row - 1
        End If
End If

If Employee1 > 0 And Employee2 > 0 Then
    Set EmployeeRange = Range(Cells(Employee1, 2), Cells(Employee2, 7))
ElseIf Employee3 > 0 Then
    Set EmployeeRange = Range(Cells(Employee3, 2), Cells(Employee3, 7))
End If

EmployeeRange.Select
Selection.Copy


Windows("Monthly Activity Report.xlsm").Activate
Sheets("April '13").Activate
Set rngPasteFind = Columns("A:A").Find(What:="Employee Activities", After:=Range("A1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not rngPasteFind Is Nothing Then
Employee4 = rngPasteFind.Row + 1
End If

Range(Cells(Employee4, 1), Cells(Employee4, 6)).Select
Selection.Insert (xlShiftDown)


End Sub

提前感谢您的帮助。如果我能提供更多背景信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

我注意到的事情很少。

  1. 请不要使用.ActivateSelection。直接使用该对象。您可能希望看到THIS

  2. 如果您使用的是.Find,那么当您找不到匹配项时,请提供实例。你已经在几个地方做过这件事,但后来又错过了一些。

  3. 请勿将Employee1Employee2等声明为Integer。在Excel 2007+中,这可能会给您一个错误,因为Excel 2007+支持1048576行。请改用Long

  4. 我不确定为什么你不打算将它粘贴到任何地方时复制范围EmployeeRange?我看到你宣布Paste范围虽然......

  5. 请参阅此代码。这是你在尝试什么? (的 UNTESTED

    Sub EmployeeActivity()
        Dim Employee1 As Long, Employee2 As Long, Employee3 As Long, Employee4 As Long
        Dim EmployeeRange As Range, rngSelectFind As Range, rngPasteFind As Range
        Dim wb As Workbook, ws As Worksheet
        Dim wb1 As Workbook, ws1 As Workbook
    
        '~~> Change path as applicable
        Set wb = Workbooks.Open("C:\Activities Report.xlsm")
        '~~> Change this to the relevant sheet
        Set ws = wb.Sheets("Sheet1")
    
        '~~> Change path as applicable
        Set wb1 = Workbooks.Open("C:\Monthly Activity Report.xlsm")
        Set ws1 = wb.Sheets("April '13")
    
        With ws
            Set rngSelectFind = .Columns("B:B").Find(What:="Employee 1", _
                                LookIn:=xlValues, LookAt:=xlPart, _
                                SearchOrder:=xlByRows, _
                                SearchDirection:=xlNext)
    
            If Not rngSelectFind Is Nothing Then
                Employee1 = rngSelectFind.Row + 1
            Else
                Set rngSelectFind = .Columns("B:B").Find(What:="(none)", _
                                    LookIn:=xlValues, LookAt:=xlPart, _
                                    SearchOrder:=xlByRows, _
                                    SearchDirection:=xlNext)
    
                If Not rngSelectFind Is Nothing Then
                    Consultant3 = rngSelectFind.Row
                End If
            End If
    
            Set rngSelectFind = Nothing
    
            Set rngSelectFind = .Columns("B:B").Find(What:="Employee 2", _
                                 LookIn:=xlValues, LookAt:=xlPart, _
                                 SearchOrder:=xlByRows, _
                                 SearchDirection:=xlNext)
    
            If Not rngSelectFind Is Nothing Then
                Employee2 = rngSelectFind.Row - 1
            Else
                Set rngSelectFind = .Columns("B:B").Find(What:="Employee 3", _
                                    LookIn:=xlValues, LookAt:=xlPart, _
                                    SearchOrder:=xlByRows, _
                                    SearchDirection:=xlNext)
    
                If Not rngSelectFind Is Nothing Then
                    Employee2 = rngSelectFind.Row - 1
                Else
                    Set rngSelectFind = .Columns("B:B").Find(What:="(none)", _
                                        LookIn:=xlValues, LookAt:=xlPart, _
                                        SearchOrder:=xlByRows, _
                                        SearchDirection:=xlNext)
                    If Not rngSelectFind Is Nothing Then
                        Employee2 = rngSelectFind.Row - 1
                    End If
                End If
            End If
    
            If Employee1 > 0 And Employee2 > 0 Then
                Set EmployeeRange = .Range(.Cells(Employee1, 2), _
                                           .Cells(Employee2, 7))
            ElseIf Employee3 > 0 Then
                Set EmployeeRange = .Range(.Cells(Employee3, 2), _
                                           .Cells(Employee3, 7))
            End If
        End With
    
        '~~> I am not sure why are you copying this range???
        If Not EmployeeRange Is Nothing Then EmployeeRange.Copy
    
        With ws1
            Set rngPasteFind = .Columns("A:A").Find(What:="Employee Activities", _
                               LookIn:=xlValues, LookAt:=xlPart, _
                               SearchOrder:=xlByRows, _
                               SearchDirection:=xlNext)
            If Not rngPasteFind Is Nothing Then
                Employee4 = rngPasteFind.Row + 1
                .Range(.Cells(Employee4, 1), .Cells(Employee4, 6)).Insert (xlShiftDown)
            End If
        End With
    End Sub
    

    提示:您可以创建一个可以接受参数的公共.Find函数。这样你可以大大减少上面的代码;)

    修改

    请参阅此示例( UNTESTED )以演示上述提示。这样您就不需要在代码中反复使用.Find

    Sub EmployeeActivity()
        Dim Employee1 As Long, Employee2 As Long
        Dim Employee3 As Long, Employee4 As Long
        Dim EmployeeRange As Range, rngSelectFind As Range, rngPasteFind As Range
        Dim wb As Workbook, ws As Worksheet
        Dim wb1 As Workbook, ws1 As Workbook
    
        '~~> Change path as applicable
        Set wb = Workbooks.Open("C:\Activities Report.xlsm")
        '~~> Change this to the relevant sheet
        Set ws = wb.Sheets("Sheet1")
    
        '~~> Change path as applicable
        Set wb1 = Workbooks.Open("C:\Monthly Activity Report.xlsm")
        Set ws1 = wb.Sheets("April '13")
    
        With ws
            Employee1 = GetRow(ws, 2, "Employee 1")
    
            If Employee1 <> 0 Then
                Employee1 = Employee1 + 1
            Else
                Consultant3 = GetRow(ws, 2, "(none)")
            End If
    
            '
            'And So on
            '
    End Sub
    
    Function GetRow(wks As Worksheet, ColNo As Long, SearchString As String) As Long
        Dim rng As Range
    
        Set rng = wks.Columns(ColNo).Find(What:=SearchString, _
                                    LookIn:=xlValues, LookAt:=xlPart, _
                                    SearchOrder:=xlByRows, _
                                    SearchDirection:=xlNext)
    
        If rng Is Nothing Then
            GetRow = 0
        Else
            GetRow = rng.Row
        End If
    End Function