【问题标题】:VBA Data validation dropdown from list (modular sub- no hardcode)列表中的 VBA 数据验证下拉列表(模块化子无硬代码)
【发布时间】:2021-07-13 15:16:09
【问题描述】:

我想通过 VBA EXCEL 代码创建数据验证列表,每个验证都来自一个动态更新的列表(例如,如果将项目添加到验证源列表,则范围将通过代码更新,而不是手动更新)。

我有很多这样的个人验证。

首先,我使用硬代码范围为每个验证创建了单独的 VBA 子程序,但这不是模块化的,代码用类似的代码重复自身,每次我需要更新源和目标范围或添加新的范围时,维护起来并不容易验证。它对编码错误很敏感,不得不提醒自己应该在代码中的确切位置写入范围。 我想要一个通用且模块化的 VBA 验证列表,我可以继续使用而无需一次又一次地重复相同的代码结构。

我有一个带有验证组合框的“数据”表和一个带有验证列表的“信息”表。

这是一个具有硬编码工作表和单元格范围的 VBA 验证结构示例。每次重写真的很头疼:

Public Sub HardcodedValidate()
Dim lastRowSource10 As Long
Dim rangeCombo10  As Range
Const F1_TransalteTo As String = "O"
Const F2_TransalteTo As String = "E"
    lastRowCombo10 = 9999
    lastRowSource10 = Transalte.Cells(Transalte.Rows.Count, "F").End(xlUp).Row
    Set rangeCombo10 = Phones.Range(F2_TransalteTo & "2:" & F2_TransalteTo & lastRowCombo10)
    With rangeCombo10.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
             xlBetween, Formula1:="=Transalte!$F$2:$F$" & lastRowSource10
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = vbNullString
        .ErrorTitle = vbNullString
        .InputMessage = vbNullString
        .ErrorMessage = vbNullString
        .ShowInput = True
        .ShowError = True
    End With
End Sub

【问题讨论】:

    标签: excel vba validation dropdown


    【解决方案1】:
    Option Explicit
    
    '' Validation list with scrollable dropdown.
    '' * General Sub without hardcoded specific ranges (modular).
    '' * No empty cells at the end of each dropdown.
    '' * Calculated Source LastRow.
    '' See at the end an example of Call of main sub by RunGeneralValidate
    
    Public Sub GeneralValidate( _
    ByVal sheetSource As Worksheet, ByVal columnSource As String, ByVal firstRowSource As Long, _
    ByVal sheetCombo As Worksheet, ByVal columnCombo As String, ByVal firstRowCombo As Long, ByVal lastRowCombo As Long)
    
    Dim rangeSource As Range
    Dim rangeCombo As Range
    Dim lastRowSource As Long
    
       lastRowSource = sheetSource.Cells(sheetSource.Rows.Count, columnSource).End(xlUp).Row
    
        Set rangeCombo = sheetCombo.Range(columnCombo & firstRowCombo & ":" & columnCombo & lastRowCombo)
        Set rangeSource = sheetSource.Range("$" & columnSource & "$" & firstRowSource & ":$" & columnSource & "$" & lastRowSource)
        
        With rangeCombo.Validation
            .Delete ''delete previous validation
            .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
                 xlBetween, Formula1:="=" & "'" & sheetSource.Name & "'" & "!" & rangeSource.Address
            .IgnoreBlank = True
            .InCellDropdown = True
            .InputTitle = vbNullString
            .ErrorTitle = vbNullString
            .InputMessage = vbNullString
            .ErrorMessage = vbNullString
            .ShowInput = True
            .ShowError = True
        End With      
    End Sub
       
    Public Sub RunGeneralValidate()
    ''Example of running the sub
    Dim Info As Worksheet
    Dim Data As Worksheet
    
    Call GeneralValidate(Info, "A", 2, _
                         Data, "D", 4, 100)
                         
    Call GeneralValidate(Info, "B", 2, _
                         Data, "E", 4, 100)
    
    Call GeneralValidate(Info, "C", 2, _
                         Data, "F", 4, 100)
    End Sub
    

    【讨论】:

    • 所以基本上你找到了使用范围变量的方法?
    • 是的,你可以这么说。我认为这是一种对代码可读性产生巨大影响的做法。
    • 当然。但我不确定你为什么在 SO 上发布这个
    • 好吧,我接受这不是诺贝尔奖的解决方案,但这是一个我一直困惑且无法在网上找到的真实问题,所以我认为它可能会帮助初学者或节省人们一些时间或学习好的做法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多