【问题标题】:Store Jagged array in Defined name in VBA在 VBA 中以定义的名称存储锯齿状数组
【发布时间】:2021-02-23 08:12:49
【问题描述】:

我需要以定义的名称存储一个锯齿状数组,以便可以保存它并在重新打开工作簿时引用其内容。下面的代码以正确的尺寸漂亮地创建了锯齿状数组,但 Names.Add 方法会产生“运行时错误 '1004':应用程序定义的或对象定义的错误”。
在调试相关行时将鼠标悬停在“名称”一词上会出现“对象变量或未设置块变量”的线索。我尝试更改变量名称,使用“Set”语句将 Fee3 数组转换为对象,以及我能想到的任何其他内容。请帮忙。

Sub GetFee3Codes()
Dim r1 As Integer, r2 As Integer, r3 As Integer, r4 As Integer, r5 As Integer, c5 As Integer
Dim Fee3, UserType, ClientType, StartDate, PayerType, RateOrAmt
ReDim Fee3(1), UserType(1), ClientType(3), StartDate(3), PayerType(14), RateOrAmt(14, 3)
    For r1 = 1 To 1
        Fee3(r1) = UserType
        For r2 = 1 To 1
            Fee3(r1)(r2) = ClientType
            For r3 = 1 To 3
                Fee3(r1)(r2)(r3) = StartDate
                For r4 = 1 To 3
                    Fee3(r1)(r2)(r3)(r4) = PayerType
                    For c5 = 1 To 3
                        For r5 = 1 To 14
                            Fee3(r1)(r2)(r3)(r4)(r5) = RateOrAmt
                        Next r5
                    Next c5
                Next r4
            Next r3
        Next r2
    Next r1
    Names.Add Name:="Fee3", RefersTo:=Fee3, Visible:=True
    ThisWorkbook.Save
End Sub

【问题讨论】:

  • @FaneDuru 定义的名称必须引用一个范围。可以放公式、常量(包括1/2D数组常量)
  • 定义的名称本质上必须是可以存储为公式的东西,我想不出任何方法可以在公式中表示这样的锯齿状数组。
  • @FaneDuru 例如,您可以定义引用 =1="some text"={1,2,3} 的名称。
  • 不是问题的根源,但像 Fee3 这样的名称不是合法名称。您不能有一个可以解释为单元格地址的名称。
  • 也许您可以使用Workbooks_Open 事件创建锯齿状数组,并将其存储在全局变量中。然后开发你的用户界面来访问它而不是Name

标签: excel vba jagged-arrays


【解决方案1】:

这是我在 cmets 中提到的方法。由于您可以将文本存储在命名范围中,因此您可以将数组序列化为 JSON,然后在需要时反序列化。不过,正如 Ron Rosenfeld 指出的那样,我认为仅在 Workbooks_Open 事件上运行您所拥有的方法会更简单。

您需要添加下面代码中引用的 VBA JSON 项目。

Option Explicit

'You'll need the VBA JSON Project installed https://github.com/VBA-tools/VBA-JSON
'Also, will need a reference to Microsoft Scripting Runtime added
Sub AddJaggedArrayAsName()
    'Create an array
    Dim arrayExample As Variant
    ReDim arrayExample(1 To 2, 1 To 2)
    
    arrayExample(1, 1) = "A"
    arrayExample(1, 2) = "B"
    arrayExample(2, 1) = "C"
    arrayExample(2, 2) = "D"
    
    'Convert the array to JSON and add to name range
    Dim Json As String
    Json = JsonConverter.ConvertToJson(arrayExample, Whitespace:=2)
    ThisWorkbook.Names.Add Name:="Something", RefersTo:=Json, Visible:=True
        
    'Parse the JSON back to an object and iterate
    Dim JsonObject As Object
    Dim RefersToString As String: RefersToString = ThisWorkbook.Names("Something").RefersTo
    Dim JsonStringFromNamedRange As String
    
    'Remove starting equal sign and extra quotes
    JsonStringFromNamedRange = Replace(Mid$(RefersToString, 3, Len(RefersToString) - 3), """""", """")
    Debug.Print JsonStringFromNamedRange 'JSON here
    
    Set JsonObject = JsonConverter.ParseJson(JsonStringFromNamedRange)
    Dim key As Variant
    Dim item As Variant
    
    'Iterate and show values
    For Each key In JsonObject
        For Each item In key
            Debug.Print item
        Next
    Next
    
End Sub

【讨论】:

  • 非常感谢,伙计们。我会尝试这些想法。我会继续关注这个话题。
  • 我不认为问题中的锯齿状数组导致的这么大的字符串可以通过RefersTo名称参数保存...但是可以很容易地保存在文本文件中并阅读必要时进行转换。
  • @FaneDuru 这是一个概念演示。如果字符串变得很长,只需将文本添加到 Range 并引用它。在这种情况下它可以留在 Excel 中
  • 我明白这一点。将这种锯齿状数组转换为字符串(可以在需要时重新转换)是一个绝妙的主意,可以以多种方式保存/使用。由于这个方面,我投了赞成票。我只是想强调,问题中锯齿状数组的所有元素都会产生一个巨大的字符串(可能)在尝试添加名称时无法使用。即使这是一个(合理的)假设,我也没有测试它...... :)
  • 非常感谢所有回答我最初问题的人。每种建议的方法都有优点和缺点。我的最终解决方案是降低自己的野心,让用户将数据存储在工作表中,并在需要时创建一个数组——最接近@Ron Rosenfeld 的方法。但要特别感谢 Rory、Ryan 和 Fane 的努力。
猜你喜欢
  • 2013-04-21
  • 2015-05-06
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
  • 2012-03-15
  • 2013-04-04
  • 2019-06-12
相关资源
最近更新 更多