简体   繁体   English

使用命名范围使用 vba 创建 excel 数据验证

[英]Create excel data validation with vba using named ranges

I have the following code:我有以下代码:

Function createCascadingDropDown(sourceTable As ListObject, targetTable As ListObject, targetTableCorespondingColumn As Integer, targetWs As Worksheet, targetWsDropDownColumn As Integer)
    Dim currentDropDownList As String, dropDownName As String, formula As String
    Dim validationVariable As Validation
    currentDropDownListName = targetWs.Name & "CurrentDropDownList"
    dropDownName = targetWs.Name & "DropDown"
    targetWs.Names.Add Name:=currentDropDownListName, RefersToLocal:="=INDEX(" & targetWs.Name & "!" & currentDropDownListName & ";1;1):INDEX(" & targetWs.Name & "!" & currentDropDownListName & ";COUNTA(" & targetWs.Name & "!" & currentDropDownListName & "))"
    targetWs.Names.Add Name:=dropDownName, RefersToLocal:="=INDEX(" & sourceTable.Name & ";0;MATCH(INDEX(" & targetTable.Name & "[@];" & CStr(targetTableCorespondingColumn) & ");" & sourceTable.Name & "[#Headers];0))"
    formula = "=" & dropDownName
    With targetWs.columns(targetWsDropDownColumn).EntireColumn.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=formula
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .InputMessage = ""
        .ErrorTitle = ""
        .ErrorMessage = ""
        .ShowInput = False
        .ShowError = True
    End With
    targetWs.Cells(1, targetWsColumn).Validation.Delete
End Function

In general I am trying to programmatically build up a cascading drop-down-menu like in https://www.contextures.com/exceldatavaldependindextables.html .一般来说,我试图以编程方式建立一个级联下拉菜单,如https://www.contextures.com/exceldatavaldependindextables.html

The problem occurs in the line where I add the validation.问题发生在我添加验证的行中。 Here the error "Application-defined or object-defined error" comes up.这里出现错误“应用程序定义或对象定义的错误”。

When I add a break point and do this step manually it works, despite the fact, that excel tells me "The source currently evaluates to an error. Do you want to continue?".当我添加断点并手动执行此步骤时,它可以工作,尽管事实上,excel 告诉我“源当前评估为错误。您想继续吗?”。 It might be that this is the problem;这可能是问题所在; at least I found this and this , which both did not help.至少我发现了thisthis ,两者都没有帮助。 Wrapping IFERROR around the formula makes it invalid.将 IFERROR 包裹在公式周围使其无效。

So I also tried to set the RefereToLocal to an empty cell (eg "=$A$20") and change it afterwards.所以我还尝试将 RefereToLocal 设置为一个空单元格(例如“=$A$20”),然后再更改它。 Now the problem is, that it does not accept the exact same formula again:现在的问题是,它不再接受完全相同的公式:

targetWs.Names.Item(dropDownName).RefersToLocal ="=INDEX(" & targetWs.Name & "!" & currentDropDownListName & ";1;1):INDEX(" & targetWs.Name & "!" & currentDropDownListName & ";COUNTA(" & targetWs.Name & "!" & currentDropDownListName & "))"

I am really running out of ideas.我真的没有想法了。 In case you have any to solve also the original problem (implement a vba-free cascading drop-down using vba) I would be happy to about them!如果您有任何要解决的原始问题(使用 vba 实现无 vba 级联下拉菜单),我很乐意解决这些问题!

Since nobody around here got an idea up to now I guess this problem is fairly hard to solve or not solvable.由于到目前为止这里没有人有想法,我想这个问题很难解决或无法解决。 In case anybody else wants to create cascading drop-down menus programmatically, here is a workaround, that works without tables, since I think the tables were the problem.如果其他人想以编程方式创建级联下拉菜单,这里有一个解决方法,它可以在没有表格的情况下工作,因为我认为表格是问题所在。 By the way it is possible to format the worksheet as table afterwards :顺便说一句,可以事后格式的工作表为表:

Function createCascadingDropDown(sourceWs As Worksheet, targetWs As Worksheet, targetCorespondingColumn As Integer, targetDropDownColumn As Integer, sourceNumberOfRowsPerColumnAs Object)
    Dim numberOfColumns As Integer, numberOfRows As Integer, targetLastRow As Long
    Dim targetCorespondingColumnSecondRowRange As String, valDataName As String, counterName As String, useListeName As String
    valDataName = "ValData" & sourceWs.Name
    counterName = "Counter" & sourceWs.Name
    useListeName = "UseListe" & sourceWs.Name
    targetLastRow = targetWs.Rows.CountLarge
    numberOfCulumns = sourceNumberOfRowsPerColumn.Count
    'Get the maximum number of rows in the source worksheet
    numberOfRows = 0
    For Each columnKey In sourceNumberOfRowsPerColumn.Keys
        If sourceNumberOfRowsPerColumn(columnKey) > numberOfRows Then
            numberOfRows = sourceNumberOfRowsPerColumn(columnKey)
        End If
    Next columnKey
    targetCorespondingColumnSecondRowRange = targetWs.Cells(1, targetCorespondingColumn).Address(RowAbsolute:=False, ColumnAbsolute:=True)
    targetWs.Names.Add Name:=counterName, RefersTo:="=COUNTA(INDEX(" & valDataName & ",,MATCH(" & targetWs.Name & "!" & targetCorespondingColumnSecondRowRange & "," & sourceWs.Name & "!$1:$1,0)))"
    targetWs.Names.Add Name:=useListeName, RefersTo:="=INDEX(" & valDataName & ",1,MATCH(" & targetWs.Name & "!" & targetCorespondingColumnSecondRowRange & "," & sourceWs.Name & "!$1:$1,0)):INDEX(" & valDataName & "," & counterName & ",MATCH(" & targetWs.Name & "!" & targetCorespondingColumnSecondRowRange & "," & sourceWs.Name & "!$1:$1,0))"
    With targetWs.Range(targetWs.Cells(2, targetDropDownColumn), targetWs.Cells(targetLastRow, targetDropDownColumn)).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=" & useListeName
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .InputMessage = ""
        .ErrorTitle = ""
        .ErrorMessage = ""
        .ShowInput = False
        .ShowError = True
    End With
End Function

Where sourceNumberOfRowsPerColumn has to be a dictionary and the Master -column is created elsewhere in the column targetCorespondingColumn .其中sourceNumberOfRowsPerColumn必须是一个字典,而Master列是在列targetCorespondingColumn其他地方创建的。 Also this solution allows only one cascading-step and the source of the Master -column is in a different worksheet.此外,此解决方案仅允许一个级联步骤,并且Master列的源位于不同的工作表中。

As a basis for this solution I took the example from https://www.contextures.com/xlDataVal15.html .作为此解决方案的基础,我以https://www.contextures.com/xlDataVal15.html 中的示例为例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM