1

我是 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

最好的方法是什么?

我知道如果我离开一个固定的范围,它可以工作,但它看起来并不好,因为它留下了很多空白,而且看起来也不整洁。

我希望这是可以理解的。

4

3 回答 3

1

您可以使用以下内容获取列的 las 非空单元格

Worksheets("Sheet1").Range("A1").End(xlDown)

然后,您只需将您的 Formula1 属性从 A1 构建到结果。

Dim strFormula1 as string
strFormula1 = "=$A$1:" & Worksheets("Sheet1").Range("A1").End(xlDown).Address()

希望对你有帮助,没测试过可能有错误

于 2013-04-24T18:09:09.997 回答
1

使用带有公式的命名范围

要创建名称,请转到公式/名称管理器/新建

在 RefersTo 中选择一个名称,例如 DataValidation

=OFFSET(Sheet1!$Z$1,0,0,COUNTA(Sheet1!$Z:$Z),1)

现在,您有了一个动态区间,可以在您的验证中使用。

于 2013-04-24T18:09:38.950 回答
0

其他两个答案更简单,但如果您有需要在验证列表中的非连续非空白单元格,则将不起作用。这种方法应该克服这一点:)

您可以在 VBA 中使用自定义函数来返回过滤后的字符串地址。这将返回过滤后的地址,或者如果过滤后的地址不是有效范围,它将返回原始地址。

注意如果返回的地址超过 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
于 2013-04-24T18:09:30.427 回答