2013-05-06 85 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