我是VBA编程的新手,我正在尝试使用Excel工作表中的列表验证数据。问题是每次从下拉列表中选择不同的条件时,列表的大小会有所不同。
例如:当我选择中国时,该列表会变成10个不同的卖家。范围A1到A10,但是当我选择日本时,我只有5个卖家,从A1到A5。
所以我每次都需要 Formula1 部分的新范围。
With Selection.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=$Z$1:$Z$30"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
最好的方法是什么?
我知道如果我留下一个固定的范围它可以工作,但它看起来不行,因为它留下了很多空的空间,看起来并不整洁。
我希望这是可以理解的。
答案 0 :(得分:1)
你可以用这样的东西得到列的非空单元格
Worksheets("Sheet1").Range("A1").End(xlDown)
然后,您只需将A1的Formula1属性构建为结果。
Dim strFormula1 as string
strFormula1 = "=$A$1:" & Worksheets("Sheet1").Range("A1").End(xlDown).Address()
希望它有所帮助,未测试可能有错误
答案 1 :(得分:1)
使用公式为
的命名范围要创建名称,请转到公式/名称管理器/新建
在RefersTo中使用
选择一个名称,例如DataValidation=OFFSET(Sheet1!$Z$1,0,0,COUNTA(Sheet1!$Z:$Z),1)
现在,您有一个动态间隔,可用于验证。
答案 2 :(得分:0)
另外两个答案更简单,但如果您有非连续的非空白单元格需要位于验证列表中,则无效。这种方法应该克服:)
您可以在VBA中使用自定义函数来返回已过滤的字符串地址。这将返回过滤后的地址,否则它将返回原始地址 IF 过滤后的地址不是有效范围。
注意如果返回的地址超过255个字符的限制,则可能会失败。
With Selection.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=GetAddress(Range("$Z$1:$Z$30"))
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
将该功能放在普通代码模块中。
Function GetAddress(myRange As Range) As String
Dim cl As Range
Dim c As Long: c = 1
Dim tmpAddress As String
For Each cl In myRange
If cl.Value <> vbNullString Then
'Create a string value of cell address matching criteria'
If tmpAddress = vbNullString Then
tmpAddress = myRange.Cells(c).Address
Else:
tmpAddress = tmpAddress & "," & myRange.Cells(c).Address
End If
End If
c = c + 1
Next
If Not Range(tmpAddress) Is Nothing Then
GetAddress = "=" & tmpAddress
Else:
MsgBox "There are no non-empty cells in this range.", vbInformation
GetAddress = "=" & myRange.Address
End If
End Function