使IF函数更高效
我正在使用以下格式从基于有限输入列表的有限输出列表中获取输出,但我想知道是否有更快/更有效的执行代码的方法?有没有办法缩短代码?
代码按原样工作,但我一直执行这样的任务,我只是想知道从自我开发的角度来看是否有更好的方法。
If Intersect(Target, Range(Dev_Status & "6:" & Dev_Status & "1000")) = Dev_Raised_IN Then
Target_Column = Dev_Raised
ElseIf Intersect(Target, Range(Dev_Status & "6:" & Dev_Status & "1000")) = Dev_Draft_IN Then
Target_Column = Dev_Draft
ElseIf Intersect(Target, Range(Dev_Status & "6:" & Dev_Status & "1000")) = Dev_Review_IN Then
Target_Column = Dev_Review
ElseIf Intersect(Target, Range(Dev_Status & "6:" & Dev_Status & "1000")) = Dev_Comments_IN Then
Target_Column = Dev_Comments
ElseIf Intersect(Target, Range(Dev_Status & "6:" & Dev_Status & "1000")) = Dev_Approved_IN Then
Target_Column = Dev_Approved
End If
回答
一个很好的重复解决方案通常是抽象。
Dim src As Range
Set src = Me.Range(Dev_Status & "6:" & Dev_Status & "1000")
当指定的参数不相交时,该Intersect函数会产生一个Range对象引用,当它们相交时Nothing,会产生一个Range表示相交单元格的对象引用。假设代码存在于某个Worksheet_Change处理程序中(因此这Me就是Worksheet正在处理的)并且Target被验证为仅是一个单元格,那么我们应该评估交集一次:
Dim intersecting As Range
Set intersecting = Intersect(Target, Me.Range(Dev_Status & "6:" & Dev_Status & "1000"))
代码应该处理的范围是Nothing:
If intersecting Is Nothing Then Exit Sub
然后它的价值可以安全地比较......或者是吗?如果单元格包含工作表错误值,则其数据类型将为Variant/Error,并且我们对该数据类型执行的任何类型的操作不涉及Variant/Error运算符两侧的操作数,都将引发类型不匹配错误。所以我们也应该在这种情况下保释:
If IsError(intersecting.Value) Then Exit Sub
现在我们可以将重复的If...ElseIf...End If块变成一个Select Case块:
Select Case intersecting.Value
Case Dev_Raised_IN
Target_Column = Dev_Raised
Case Dev_Draft_IN
Target_Column = Dev_Draft
Case Dev_Review_IN
Target_Column = Dev_Review
Case Dev_Comments_IN
Target_Column = Dev_Comments
Case Dev_Approved_IN
Target_Column = Dev_Approved
Case Else
'we don't have a target column:
Target_Column = -1
End Select
然后可以使用键控Collection或将整个块进一步简化为简单的单行键查找Dictionary。
当然,这样一个集合需要被初始化,但可以作出发生一次有Static当地,像这样(第一次运行进入条件,第二次运行不):
Static targetColumns As Collection
If targetColumns Is Nothing Then
Set targetColumns = New Collection
targetColumns.Add Dev_Raised, Dev_Raised_IN
targetColumns.Add Dev_Draft, Dev_Draft_IN
targetColumns.Add Dev_Review, Dev_Review_IN
targetColumns.Add Dev_Comments, Dev_Comments_IN
targetColumns.Add Dev_Approved, Dev_Approved_IN
End If
On Error Resume Next '"key not found"
Target_Column = targetColumns(intersecting.Value)
If Err.Number <> 0 Then Target_Column = -1
On Error GoTo 0