Arrays 在VBA中检查数组
我有一个列表-我刚刚发现这种语法允许从我的列表中进行多次选择:Arrays 在VBA中检查数组,arrays,vba,excel,excel-2013,Arrays,Vba,Excel,Excel 2013,我有一个列表-我刚刚发现这种语法允许从我的列表中进行多次选择: Dim Oldvalue As String Dim Newvalue As String On Error GoTo Exitsub If Target.Address = "$B$1" Then If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then GoTo Exitsub Else: If Target.Value = "" Then
Dim Oldvalue As String
Dim Newvalue As String
On Error GoTo Exitsub
If Target.Address = "$B$1" Then
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
Target.Value = Oldvalue & ", " & Newvalue
End If
End If
End If
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
我可以判断所选值的列表将存储在变量Target.Value
-但是我如何:
1) 检查Target.Value
的长度(这样我就知道我选择了1个还是多个?)
2) 迭代每个选择
您需要将
Target.Value
分配给变量
变量。记住在变量名后面加上括号,以表示正在分配数组
然后,您可以使用LBound
和UBound
查找数组的维度,也可以遍历数组。很确定这就是你想要做的
Sub get_vals()
Dim arr() As Variant
Dim i As Long
arr = Range("A1:A5").Value
Debug.Print UBound(arr, 1) ' Print rows
Debug.Print UBound(arr, 2) ' Print columns
For i = LBound(arr, 1) To UBound(arr, 1) ' Iterate through the rows of the array
Debug.Print arr(i, 1)
Next i
End Sub
编辑
如上所述,您将无法将一个单元格范围分配给数组变量。您可能希望仅使用Dim arr作为变量
。这将允许您为变量指定单个单元格范围。然后,您可以检查该类型以确定是需要迭代数组还是只需要处理单个字符串/整数
If TypeName(arr) = "Variant()" Then
' Iterate
Else
' Work with single string/integer
End If
您需要将
Target.Value
分配给变量
变量。记住在变量名后面加上括号,以表示正在分配数组
然后,您可以使用LBound
和UBound
查找数组的维度,也可以遍历数组。很确定这就是你想要做的
Sub get_vals()
Dim arr() As Variant
Dim i As Long
arr = Range("A1:A5").Value
Debug.Print UBound(arr, 1) ' Print rows
Debug.Print UBound(arr, 2) ' Print columns
For i = LBound(arr, 1) To UBound(arr, 1) ' Iterate through the rows of the array
Debug.Print arr(i, 1)
Next i
End Sub
编辑
如上所述,您将无法将一个单元格范围分配给数组变量。您可能希望仅使用Dim arr作为变量
。这将允许您为变量指定单个单元格范围。然后,您可以检查该类型以确定是需要迭代数组还是只需要处理单个字符串/整数
If TypeName(arr) = "Variant()" Then
' Iterate
Else
' Work with single string/integer
End If
在不指定数组的情况下,可以使用
Target.Rows.Count 'number of rows
Target.Columns.Count 'number of columns
Target.Cells.Count 'number of cells
您可以使用索引或
Dim cl As Range
For Each cl In Target.Cells 'For Each loops are much faster then looping using indices
'do something with cl
Next cl
还请注意Thomas Inzina的评论,即这样即使有不连续的范围,也可以得到所有单元格
编辑:每个循环的比使用索引在单元格中循环更快,即
For i = 1 To Target.Rows.Count
For j = 1 To Target.Columns.Count
'do something with Target.Cells(i, j)
Next j
Next i
按照luke的建议使用数组可能会更快。不指定可以使用的数组
Target.Rows.Count 'number of rows
Target.Columns.Count 'number of columns
Target.Cells.Count 'number of cells
您可以使用索引或
Dim cl As Range
For Each cl In Target.Cells 'For Each loops are much faster then looping using indices
'do something with cl
Next cl
还请注意Thomas Inzina的评论,即这样即使有不连续的范围,也可以得到所有单元格
编辑:每个
循环的比使用索引在单元格中循环更快,即
For i = 1 To Target.Rows.Count
For j = 1 To Target.Columns.Count
'do something with Target.Cells(i, j)
Next j
Next i
按照luke的建议使用数组可能会更快。两个GoTo-Exitsub都可以替换为Exit
。您的意思是希望字符串的长度以数值形式显示吗Len(target.value)
@Andreas-假设列表值是红色、绿色和蓝色-我需要一种方法来知道选择了什么,比如foeach(string pick in target.value)msgBox.Show(pick)next。GoTo Exitsub的两个都可以替换为Exit
。你是想让字符串的长度变成一个数值吗Len(target.value)
@Andreas-假设列表值为红色、绿色和蓝色-我需要一种方法来知道选择了什么,比如foeach(string pick in target.value)msgBox.Show(pick)nextf,如果比较苹果和苹果,则每个循环都比使用索引快得多。luke_t使用的是一个值数组,当您在单元格上迭代时。我猜阵列会更快。然而,你有正确的答案。1) 如果目标是非连续范围,则仅将该范围的第一个区域复制到阵列。2) 直接使用单元格比编辑数组并将值复制回来更直观+1@ThomasInzina是的,我应该指定它比使用索引在单元格中循环快。如果你比较苹果和苹果,每个循环都比使用索引快得多。luke_t使用的是一个值数组,当您在单元格上迭代时。我猜阵列会更快。然而,你有正确的答案。1) 如果目标是非连续范围,则仅将该范围的第一个区域复制到阵列。2) 直接使用单元格比编辑数组并将值复制回来更直观+1@ThomasInzina是的,我应该指定它比使用索引在单元格中循环更快。此解决方案有一个警告:如果目标范围仅为一个单元格,您将得到类型不匹配,因为。Value
将返回变量,而不是变量数组。根据应用程序的不同,可能需要首先检查该区域是否包含多个单元格。非常正确,@arcadeprecinct。分配变量之前需要进行检查。此解决方案有一个警告:如果目标范围仅为一个单元格,则会出现类型不匹配,因为.Value
将返回变量,而不是变量数组。根据应用程序的不同,可能需要首先检查该区域是否包含多个单元格。非常正确,@arcadeprecinct。在分配变量之前,需要进行检查。