Arrays 是否可以创建更新主阵列的子阵列?
假设我有一个主数组:Arrays 是否可以创建更新主阵列的子阵列?,arrays,excel,vba,Arrays,Excel,Vba,假设我有一个主数组:Arr3D(1到4,1到4,1到50)我想把一个子集传递给一个过程,让该过程编辑值。我知道我可以创建一个子数组:Arr(1到50)并传递值,运行过程,然后将它们放回Arr3D 但是VBA将参数传递给过程“ByRef”的能力让我想到可能有一种我不知道的传递子数组“ByRef”的能力 就像我想把Arr3D(1,2,1到50)传递到Sub-DoStuff(ByRef Arr1D()作为变量),这样程序就可以直接编辑主数组的值 这实际上是为了避免传递索引,因为我认为它看起来更干净,我
Arr3D(1到4,1到4,1到50)
我想把一个子集传递给一个过程,让该过程编辑值。我知道我可以创建一个子数组:Arr(1到50)
并传递值,运行过程,然后将它们放回Arr3D
但是VBA将参数传递给过程“ByRef”的能力让我想到可能有一种我不知道的传递子数组“ByRef”的能力
就像我想把Arr3D(1,2,1到50)
传递到Sub-DoStuff(ByRef Arr1D()作为变量)
,这样程序就可以直接编辑主数组的值
这实际上是为了避免传递索引,因为我认为它看起来更干净,我知道我可以传递整个数组,然后插入D1=1,D2=2
就像Arr3D(D1,D2,x)
这在VBA中是否可行?我将如何编写它?如果不是,VBA中在阵列的某些部分上运行过程的最佳实践是什么
VBASIC208要求提供一个示例,因此我制作了我设想的东西:
Const Directory=“\\192.168.2.253\Forms\component Inventory\Entries\”
子示例()
'从输入条目文件获取所有数据
文件夹的Dim作为对象,oFile作为变量,Files()作为对象,file_作为整数计数
Dim应用程序作为新Excel.Application,wb作为工作簿,ws作为工作表
Dim FileData()作为变量
将最后一行设置为整数
集合文件夹=CreateObject(“Scripting.FileSystemObject”).getfolder(目录)
ReDim文件(oFolder.Files.Count)
对于oFolder.Files中的每个文件
如果文件名像“*.xls?”那么
设置文件(文件计数)=oFile
文件计数=文件计数+1
如果结束
下一个文件
重拨保留文件(文件计数-1)
ReDim文件数据(文件计数-1)
对于i=LBound(文件)到UBound(文件)
设置wb=app.Workbooks.Add(文件(i).Path)
设置ws=wb.工作表(1)
lastRow=ws.Cells(ws.Rows.Count,1).End(xlUp).Row
FileData(i)=ws.Cells(1,1).Resize(lastRow,49).Value
wb.Close savechanges:=false
接下来我
应用程序。退出
设置app=Nothing
'输入结束
"解读数据",
对于i=LBound(FileData,1)到UBound(FileData,1)
对于j=LBound(FileData,2)到UBound(FileData,2)
如果FileData(i,j,4)”和FileData(i,j,5)”,则
调用InputFormattedDate(文件数据(i,j))
如果结束
“其他东西
下一个j
接下来我
"世界末日"
"输出数据",
“做事
"产出结束",
端接头
子InputFormattedDate(ByRef ArrRow()作为变量)
'ArrRow是从1到49的一维数组
'我希望ArrRow可以像ArrRow(4)或ArrRow(6)一样引用,而不是ArrRow(D1、D2、4)
以字符串形式列出
MachineNumber=Replace(ArrRow(4),“#”和“)
对于i=6到10
'用于输出上的分离列
如果CStr(i)=机器计数,则
ArrRow(35+i)=截止日期的文本(ArrRow(5))
其他的
ArrRow(35+i)=“[空白]”,以覆盖以前的列值
如果结束
接下来我
端接头
如果“main”数组包含值,那么该数组的一个片段将是另一个数组,其中包含这些值的副本,而数组通过引用传递的事实对此没有任何影响。因此,改变“子数组”(即保存原始值副本的独立/不同数组)中的值不会影响“主”数组的内容
因为它保存的是值而不是引用
你可以让它保存引用,然后你会有一个单独的数组保存指向原始对象的指针副本
添加一个新的类模块,将其命名为WrappedVariant
,并使其如下所示:
Option Explicit
Private EncapsulatedValue As Variant
'@DefaultMember
Public Property Get Value() As Variant
Value = EncapsulatedValue
End Property
Public Property Let Value(ByVal RHS As Variant)
EncapsulatedValue = RHS
End Property
其中,“@DefaultMember
是一个控制过程的hiddenVB_UserMemId
属性值的函数,使其0
(从而使该成员成为类的默认成员;您不需要Rubberduck来实现这一点,只需要使用Rubberduck就可以简单得多)
现在您可以执行以下操作:
Dim v As WrappedVariant
Set v = New WrappedVariant
v.Value = 42 'or just v = 42 for an implicit default member call
Debug.Print v.Value 'or just Debug.Print v for an implicit default member call
然后,v
可以存储在一个3D数组中,该数组随后被分割成一个较小的2D数组,虽然这将是一个完全不相关的单独数组,但其中的对象指针仍将指向WrappedVariant
对象实例,每个都封装了各自的值:如果使用指针的任何副本修改一个特定实例,则无论指针来自哪个数组,它都会修改所指向的单个对象
请记住使用Set
关键字显式分配引用-省略Set
(或使用显式Let
)将通过隐式默认成员调用强制对象为其值:
Dim array1(1 To 1)
Set array1(1) = v
Dim array2(1 To 1)
Set array2(1) = v
array1(1).Value = 25 '<~ mutate the encapsulated state from either pointer
Debug.Print array1(1), array2(1) '<~ prints 25 twice
Dim阵列1(1对1)
设置阵列1(1)=v
尺寸阵列2(1对1)
设置阵列2(1)=v
array1(1).Value=25'在不循环索引的情况下对3D阵列进行切片是不可能的。顺便说一句,你能更具体一点吗?也许可以在你想使用它的地方添加代码,并添加一行伪代码来说明你打算如何使用它。@chrisneilsen二维数组呢?@vbasic208添加了未经测试的示例代码。我还没有在VBA中使用类,这似乎是一个很好的开始理由。