【发布时间】:2018-11-06 02:56:38
【问题描述】:
我想知道是否有任何方法可以更改数组的维数:
- 在 VBA 中,
- 取决于整数
max_dim_bound,它表示 所需的编号。尺寸。 允许维度的起始索引:E.G. `array(4 to 5, 3 to 6) 其中3到6的个数是可变整数。
*在代码本身没有额外的工具
- *不导出代码。
需要明确的是,以下更改不会更改数组维度的 nr(仅是每个维度中元素的起始结束索引):
my_arr(3 to 5, 6 to 10)
'changed to:
my_arr(4 to 8, 2 to 7)
以下示例将成功更改 nr。数组中的维数:
my_arr(3 to 5, 6 to 10)
'changed to:
my_arr(4 to 8, 2 to 7,42 to 29)
这也将是 nr 的变化。数组中的维数:
my_arr(4 to 8, 2 to 7,42 to 29)
'changed to:
my_arr(3 to 5, 6 to 10)
到目前为止,我的尝试包括:
Sub test_if_dynamically_can_set_dimensions()
Dim changing_dimension() As Double
Dim dimension_string_attempt_0 As String
Dim dimension_string_attempt_1 As String
Dim max_dim_bound As String
Dim lower_element_boundary As Integer
Dim upper_element_boundary As Integer
upper_element_boundary = 2
max_dim_bound = 4
For dimen = 1 To max_dim_bound
If dimen < max_dim_bound Then
dimension_string_attempt_0 = dimension_string_attempt_0 & "1 To " & upper_element_boundary & ","
MsgBox (dimension_string_attempt_0)
Else
dimension_string_attempt_0 = dimension_string_attempt_0 & "1 To " & upper_element_boundary
End If
Next dimen
MsgBox (dimension_string_attempt_0)
'ReDim changing_dimension(dimension_string_attempt_0) 'does not work because the "To" as expected in the array dimension is not a string but reserved word that assists in the operation of setting an array's dimension(s)
'ReDim changing_dimension(1 & "To" & 3, 1 To 3, 1 To 3) 'does not work because the word "To" that is expected here in the array dimension is not a string but a reserved word that assists the operation of setting an array's dimension(s).
'ReDim changing_dimension(1 To 3, 1 To 3, 1 To 3, 1 To 3)
'attempt 1:
For dimen = 1 To max_dim_bound
If dimen < max_dim_bound Then
dimension_string_attempt_1 = dimension_string_attempt_1 & upper_element_boundary & ","
MsgBox (dimension_string_attempt_1)
Else
dimension_string_attempt_1 = dimension_string_attempt_1 & upper_element_boundary
End If
Next dimen
MsgBox (dimension_string_attempt_1)
ReDim changing_dimension(dimension_string_attempt_1) 'this does not change the nr of dimensions to 2, but just one dimension of "3" and "3" = "33" = 33 elements + the 0th element
'changing_dimension(2, 1, 2, 1) = 4.5
'MsgBox (changing_dimension(2, 1, 2, 1))
End Sub
*否则解决办法是:
- 导出模块的整个代码,并在维度的行替换数组的静态重新维度,使用准动态字符串
dimension_string。 - 删除当前模块
- 使用准动态字符串
dimension_string导入新模块作为代码中刷新的静态重新维度。
但是,这似乎令人费解,我很好奇是否有人知道更简单的解决方案。
请注意,这不是以下内容的重复:Dynamically Dimensioning A VBA Array? 尽管这个问题似乎意味着我在这里提出的问题,但这个问题的意图似乎是改变 nr。维度中的元素,而不是 nr。尺寸。 (区别在this article by Microsoft中讨论。)
为了尝试应用 Uri Goren 的答案,我分析了每一行并查找了他们所做的事情,并在其背后评论了我的理解,以便我的理解可以得到改进或更正。因为我不仅难以运行代码,而且难以理解它是如何回答问题的。该尝试包括以下步骤:
- 右键代码文件夹->插入->类模块然后点击: Tools>Options>“marked:Require variable declaration”如图 here 00:59。
-
接下来我在类模块 FlexibleArray 中编写了以下代码:
Option Explicit Dim A As New FlexibleArray Private keys() As Integer Private vals() As String Private i As Integer Public Sub Init(ByVal n As Integer) ReDim keys(n) 'changes the starting element index of array keys to 0 and index of last element to n ReDim vals(n) 'changes the starting element index of array keys to 0 and index of last element to n For i = 1 To n keys(i) = i 'fills the array keys as with integers from 1 to n Next i End Sub Public Function GetByKey(ByVal key As Integer) As String GetByKey = vals(Application.Match(key, keys, False)) ' Application.Match("what you want to find as variant", "where you can find it as variant", defines the combination of match type required and accompanying output) 'Source: https://msdn.microsoft.com/en-us/vba/excel-vba/articles/worksheetfunction-match-method-excel ' If match_type is 1, MATCH finds the largest value that is less than or equal to lookup_value. Lookup_array must be placed in ascending order: ...-2, -1, 0, 1, 2, ..., A-Z, FALSE, TRUE. ' If match_type is 0, MATCH finds the first value that is exactly equal to lookup_value. Lookup_array can be in any order. ' If match_type is -1, MATCH finds the smallest value that is greater than or equal to lookup_value. Lookup_array must be placed in descending order: TRUE, FALSE, Z-A, ...2, 1, 0, -1, -2, ..., and so on. 'so with False as 3rd optional argument "-1" it finds the smallest value greater than or equal to the lookup variant, meaning: 'the lowest value of keys that equals or is greater than key is entered into vals, 'with keys as an array of 1 to n, it will return key, if n >= key. (if keys is initialized right before getbykey is called and is not changed inbetween. 'vals becomes the number inside a string. So vals becomes the number key if key >= n. End Function Public Sub SetByKey(ByVal key As Integer, ByVal val As String) vals(Application.Match(key, keys, False)) = val 'here string array vals(element index: key) becomes string val if key >=n (meaning if the element exists) End Sub Public Sub RenameKey(ByVal oldName As Integer, ByVal newName As Integer) keys(Application.Match(oldName, keys, False)) = newName 'here keys element oldname becomes new name if it exists in keys. End Sub -
然后我创建了一个新模块 11 并将下面的代码复制到其中,包括进行修改以尝试使代码正常工作。
Option Explicit Sub use_class_module() Dim A As New FlexibleArray 'this dimensions object A but it is not set yet A.Init (3) 'calls the public sub "Init" in class module FlexibleArray, and passes integer n = 3. 'A.SetByKey(1, "a") 'this means that Objecgt A. in class FlexibleArray function SetByKey sets the private string array vals(1) in class Flexible Array becomes "a" 'A.SetByKey(2, "b") 'this means that Objecgt A. in class FlexibleArray function SetByKey sets the private string array vals(2) in class Flexible Array becomes "b" 'A.SetByKey(3, "c") 'this means that Object A. in class FlexibleArray function SetByKey sets the private string array vals(3) in class Flexible Array becomes "c" 'A.RenameKey(3,5) 'This means that object A in class FlexibleArray keys element 3 becomes 5 so keys(3) = 5 ' Would print the char "c" 'to try to use the functions: 'A.SetByKey(1, "a") = 4 'MsgBox (keys("a")) 'test = A.SetByKey(1, "a") 'this means that Objecgt A. in class FlexibleArray function SetByKey sets the private string array vals(1) in class Flexible Array becomes "a" 'MsgBox (test) 'test_rename = A.RenameKey(3, 5) 'This means that object A in class FlexibleArray keys element 3 becomes 5 so keys(3) = 5 'MsgBox (test_rename) 'Print A.GetByKey(5) 'Method not valid without suitable object 'current problem: 'the A.SetByKey expects a function or variable, even though it appears to be a function itself. End Sub
我目前期望此代码将 my_array(3 到 4,5 到 9..) 替换为存在于/作为类模块 FlexibleArray 中的数组,当它需要在模块中使用时调用。但任何澄清将不胜感激! :)
【问题讨论】:
-
在x To y中,To不是一个字符串,而是一个保留字,辅助设置数组维度的操作.将其放在引号中就像尝试使用
cells(1, 1)."copy";这根本不正确。 -
谢谢你的解释,我很难用语言表达。我对代码进行了修改,以纳入您对几次尝试均无效的原因的评论。
-
您能否提供更多示例来说明您正在尝试做什么?您是否有一个维度为
myArr(4 To 5, 3 To 6)的数组,您想将其重新维度为myArr(4 To 6, 3 To 7)......这是一个有代表性的例子吗? -
在我的答案中添加了一个示例,为您提供一个真正灵活的重新维度数组 - 但您必须从第一个索引访问子元素。它是一个数组数组。可能必须更改访问您重新调整的数组的代码,但它应该适合您???
-
哇,这真是一个很有创意的方法!这不是我提出问题时所考虑的形式的确切传统解决方案,但它确实再次有效地实现了目标,并稍微重写了我访问具有不同维度的数组的方式。而这次没有
max_dim_bound的先决知识。它提醒人们跳出框框思考。非常感谢您的坚持,我已采纳!
标签: vba multidimensional-array dynamic dimensions