[英]Having trouble with nested If statement
我是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
预先感谢您的任何帮助。 请让我知道是否可以提供其他上下文。
我注意到的几件事。
请不要使用.Activate
和Selection
。 直接使用对象。 你可能想看看这
如果您使用的是.Find
则可以在找不到匹配项的情况下满足需要。 您已经在几个地方做到了,但是却错过了一些。
不要将Employee1
, Employee2
等声明为Integer
。 在Excel 2007+中,这可能会给您带来错误,因为Excel 2007+支持1048576行。 使用Long
代替。
我不确定为什么不打算将范围EmployeeRange
粘贴到任何地方时,为什么要复制它呢? 我看到您虽然在声明Paste
范围...
请参阅此代码。 这是您要尝试的吗? ( 另 )
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
使用.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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.