【问题标题】:VBA Merge of Dynamic Named Ranges results into a static range i/o keeping dynamic动态命名范围的 VBA 合并导致静态范围 i/o 保持动态
【发布时间】:2018-07-12 03:35:07
【问题描述】:

上下文(VBA7.1、Excel 2013 Pro):
所有工作表和动态命名范围 (DNR) 都是以编程方式创建的。我想将一些 DNR 单元(多列相同数据的情况)合并到一个 DNR 中,以便将它们全部分组。在这个阶段,单元 DNR 及其合并结果都在工作表范围内。

问题
合并的命名范围不保留所有单个 DNR 的动态属性。如果我手动执行,它当然可以,只是为了确认要合并的 DNR 是有效的动态的。

问题
我应该如何应用命名范围合并,以便结果范围也保持为动态命名范围?


主代码

Sub xx()
... some code goes here ...
    Dim DNRnames() As String
    Dim MergedRange As Range
    Dim currentRng As Range
    Dim rngStr As Variant
    Dim strStringToExclude() As String

    ' Get created DNRs on this sheet
        strStringToExclude = Split("_Desc,Headers", ",")
        DNRnames = DNRGetNames(aWS.Name, False, strStringToExclude)

      ' Merge DNRs into 1 
        For Each rngStr In DNRnames
          ' Set currentRng = aWS.Names(CStr(rngStr)).RefersToRange
          Set currentRng = aWS.Range(CStr(rngStr)) ' also this way keeps it static
          If Not MergedRange Is Nothing Then
            Set MergedRange = Union(MergedRange, currentRng)
          Else
            Set MergedRange = currentRng
          End If
        Next rngStr

      ' Add "MergedRange" to the aWS : ISSUE : the MergeRange is NOT dynamic...
      ' as it would be if I would create it in the ws by a named_range=(range1,range2,..)
        aWS.Names.Add Name:=DNRprefix & "All", RefersTo:=MergedRange
...
end sub

GetDNR:将工作表中的命名范围作为字符串数组返回,并排除一些我不想合并的选定命名范围(这是一种解决方法,因为我找到了“Union”但没有VBA中的“减法”函数)

Function DNRGetNames(sheetName As String, WbScope As Boolean, SuffixStringToExclude() As String) As String()  ' all DNR from one specific sheet (with wb scope or ws scope ?)
' https://stackoverflow.com/questions/12663879/adding-values-to-variable-array-vba
' https://stackoverflow.com/questions/4029975/excel-listing-named-range-in-a-worksheet-and-get-the-value

  ' kind of getter and setter
  Dim wb As Workbook
  Dim aWS As Worksheet
  Dim element As Name
  ReDim DNRArray(1 To 1) As String

  Set wb = ThisWorkbook
  Set aWS = wb.Sheets(sheetName)

  ' if SuffixStringToExclude is not defined, fill in the suffic string with a default fake data
  If Not Len(Join(SuffixStringToExclude)) > 0 Then
    SuffixStringToExclude = Split("*FaKe!")
  End If

  ' populate a dynamic array with DNR related to aWS
  For Each element In wb.Names
    If Not ArrayIsInString(element.Name, SuffixStringToExclude) Then '
      If IsNameRefertoSheet(aWS, element) Then
        DNRArray(UBound(DNRArray)) = element.Name
        ReDim Preserve DNRArray(1 To UBound(DNRArray) + 1) As String
      End If
    End If
  Next element

  ' clean exit
  If UBound(DNRArray) > 1 Then
    ReDim Preserve DNRArray(1 To UBound(DNRArray) - 1) As String
    DNRGetNames = DNRArray
  Else
    DNRGetNames = Empty
  End If

End Function

GetDNR 函数返回的 DNR

【问题讨论】:

    标签: excel 64-bit vba7 vba


    【解决方案1】:

    RefersTo 必须是 A1 style notation 字符串(例如 "=A1,B2"):

    Set MergedRange = aWS.Range(Join(DNRnames, ","))
    aWS.Names.Add DNRprefix & "All", "=" & MergedRange.Address
    

    Range.Address 限制为 255 个字符,因此可能需要在合并范围之前创建它。


    对于工作簿范围命名范围:

    MergedRange.Name = DNRprefix & "All"
    

    【讨论】:

    • 谢谢斯莱;我没有得到它 100%。第 2 行就像 aWS.Names.Add... 一样无法编译,我对 VBA 不够熟练,无法找出问题所在。
    • @hornetbzz 我在aWS.Names.Add DNRprefix & "All", "=" & MergedRange.Address 行中看不到任何可能无法编译的内容,但如果您能提供更多详细信息,我可能会想到一些事情。我在 Excel 2016 上尝试过,它与 Sheet1.Names.Add "ab", "=A1,B2" 一起使用
    • aWS.Names.Add Name:=DNRprefix(0) & "_All", "=" & MergedRange.Address(0, 0) 导致此编译错误:expected : named parameter
    • 删除Name:=参数名称或包含RefersTo:=参数名称。
    • @hornetbzz 抱歉,我想我可能误解了这个问题。即使使用, RefersTo:="=Name1,Name2", RefersTo:="=INDIRECT(""Name1,Name2"")", RefersTo:="=EVALUATE(""Name1,Name2"")" 之类的东西,我也找不到保持组合命名范围动态的方法。我猜想引用类似Range("Name1,Name2") 的 VBA UDF 函数可能是一个选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多