VBA Target.Address到两个单元格
我必须使用VBA在Excel中构build一个嵌套的filter结构。 该方法是构build两个包含sorting索引的数据validation列表。 我有三个可能的索引索引,即姓氏,名字和公司。 由于在sortingfunction中不允许索引在sorting范围之外被引用。 我build立了6个可能的索引组合,如下所示。
Sub Macro_Sort1() Sheets("Reports").Range("F1:CT10000").Sort Key1:=Sheets("Reports").Range("I1"), Order1:=xlAscending, Key2:=Sheets("Reports").Range("J1"), Order1:=xlAscending, Header:=xlYes End Sub
现在我需要将这个macros分配给这两个数据validation列表,例如
If Target.Address = "$B$1" and "$B$2" Then Select Case Target.Value2 Case "Last" and "First" Call Macro_Sort1 Case "Last" and "Company" Call Macro_Sort2 Case "First" and "Last" Call Macro_Sort3 Case "First" and "Company" Call Macro_Sort4 Case "Company" and "Last" Call Macro_Sort5 Case "Company" and "First" Call Macro_Sort6 End Select End if End Sub
然而,显然这告诉我,THEN的Target.Address Sentence存在错误。
请帮我弄清楚是否有其他方法来实现这一点。
提前致谢!
更新:
正如我所提到的,我有两个filter,第一个可以独立使用,它具有如下所示的macros:
Sub Macro_Sort1() Sheets("Reports").Range("F1:CT10000").Sort Key1:=Sheets("Reports").Range("I1"), Header:=xlYes, Order1:=xlAscending End Sub
所以在这两个filter的代码之前,会有这样的代码:
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$B$17" Then Select Case Target.Value2 Case "Last" Call Macro_Sort1 Case "First" Call Macro_Sort2 Case "Company" Call Macro_Sort3 End Select
基于一些build议,我在前面的部分之后添加了这个部分。
ElseIf Target.Address(0, 0) = "$B$17" Or Target.Address(0, 0) = "$B$18" Then SortUsingDataValidation Range("B17").Value, Range("B18").Value End If End Sub Private Sub SortUsingDataValidation(sFirst As String, sSecond As String) Dim oDict As Object Set oDict = CreateObject("Scripting.Dictionary") With ThisWorknook.shhets("Reports") Set oDict("Last") = .Range("I1") Set oDict("First") = .Range("J1") Set oDict("Company") = .Range("K1") If oDict.exists(sFirst) And oDict.exists(sSecond) Then .Range("F1:CT10000").Sort Key1:=oDict(sFirst), Order1:=xlAscending, key2:=oDict(sSecond), Order1:=xlAscending, Header:=xlYes End If End With End Sub
虽然这是一个非常好的方法,但却无法运行。 没有错误或任何消息框popup。 因此,请检查是否为影响双重过滤代码的第一个filter的代码。
非常感谢你!
编辑:
-
添加
Application.Transpose()
方法到Target
范围,因为B1:B2
是一列“垂直”范围,而Join()
需要一个对应于一行“水平”范围的数组 -
添加了一些代码“味道”来处理不同的环境
改变方法
If Target.Address = "$B$1:$B$2" Then Dim strng As String Dim pos as Long strng = "1LastFirst,2LastCompany,3FirstLast,4FirstCompany,5CompanyLast,6CompanyLast" pos = Instr(strng,Join (Application.Transpose(Target),"")) If pos > 0 then Application.Run "Macro_Sort" & Mid(strng,pos-1,1) End If
最后是一些环境build议:
如果你在Worksheet事件处理程序中运行这个代码,那么
-
If Target.Address = "$B$1:$B$2"
只能在Worksheet_SelectionChange
处理程序中为True
,而处理Target
范围参数的其他相关处理程序将只检测一个单元格范围例如,如果你需要在
Worksheet_Change
事件处理程序中运行它,那么你需要将检查改为:If Not Intersect(Target, Range ("B1:B2")) Is Nothing Then
在许多其他情况下也可以这样做
-
由
Application.Run
方法调用的子必须放在任何模块中,但不能放在Worksheet中
一些事情;
地址将是“B1:B2”
而要使用Select Case进行多重testing,我们要searchTrue并将其格式化为IF / ElseIF:
If target.Address(0, 0) = "B1:B2" Then Select Case True Case Range("B1") = "Last" And Range("B2") = "First" Call Macro_Sort1 Case Range("B1") = "Last" And Range("B2") = "Company" Call Macro_Sort2 Case Range("B1") = "First" And Range("B2") = "Last" Call Macro_Sort3 Case Range("B1") = "First" And Range("B2") = "Company" Call Macro_Sort4 Case Range("B1") = "Company" And Range("B2") = "Last" Call Macro_Sort5 Case Range("B1") = "Company" And Range("B2") = "First" Call Macro_Sort6 End Select End If
If Target.Address = "$B$1" And "$B$2" Then
这是一个语法错误,因为If {boolean-expression} Then
需要一个布尔expression式 – 而且你已经将VBA和expression式的And {string-literal}
部分混淆了。
您可以使用And
关键字构造一个布尔expression式 ,如下所示:
{boolean-expression} And {boolean-expression}
换句话说,你可以做到:
If Target.Address = "$B$1" And Target.Address = "$B$2" Then
但是正如你所怀疑的那样,这个逻辑总是返回False
,因为如果Target.Address
等于"$B$1"
那么它不能等于"$B$2"
。
斯科特的答案有其余的解决scheme。
我要添加另一种方法,因为通常不是一个好主意,有6个不同的macros来做基本相同的事情。 它会起作用,但是更多的代码需要维护,使未来的变化更加困难。
在下面的代码中,validation框的值被传递到一个函数中,(1)将每个值链接到相应的范围,(2)根据相应的范围进行sorting。
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address(0, 0) = "B1" Or Target.Address(0, 0) = "B2" Then SortUsingDataValidation Range("B1").Value, Range("B2").Value End If End Sub Private Sub SortUsingDataValidation(sFirst As String, sSecond As String) Dim oDict As Object 'Create a dictionary (or any collection) to hold references from a data validation 'String to its corresponding cell reference Set oDict = CreateObject("Scripting.Dictionary") With ThisWorkbook.Sheets("Reports") Set oDict("First") = .Range("I1") Set oDict("Last") = .Range("J1") Set oDict("Company") = .Range("K1") If oDict.exists(sFirst) And oDict.exists(sSecond) Then .Range("F1:CT10000").Sort Key1:=oDict(sFirst), Order1:=xlAscending, Key2:=oDict(sSecond), Order1:=xlAscending, Header:=xlYes End If End With End Sub