2013-05-06 96 views
2

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

我遇到的问题是定义我需要复制的范围。正如您在代码中看到的那样,员工在列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

可能会有所帮助,如果你能提供的文件(S),如果有必要的匿名数据(假设它是与工作相关的/可能保密的/ etc。) – 2013-05-06 20:53:57

回答

1

我注意到一些事情。

  1. ,请不要使用.ActivateSelection。直接与对象一起工作。您可能想看到THIS

  2. 如果您使用的是.Find,那么在您找不到匹配项时照顾实例。你已经在几个地方完成了这项工作,但后来又错过了一些。

  3. 请勿声明Employee1,Employee2Integer。在Excel 2007+中,由于Excel 2007+支持1048576行,因此可能会出现错误。用Long来代替。

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

看到这段代码。这是你正在尝试的吗? (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 
+0

优秀谢谢!我花了一点时间用你的建议清理宏,但一切都运行完美。我非常感谢帮助。 – Anthony 2013-05-07 21:04:25