分享

完善redim preserve语句功能

 hdzgx 2017-10-21

 如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目。例如,如果数组就是一维的,则可以重定义该维的大小,因为它是最末维,也是仅有的一维。不过,如果数组是二维或更多维时,则只有改变其最末维才能同时仍保留数组中的内容。下面的示例介绍了如何在为已有的动态数组增加其最末维大小的同时而不清除其中所含的任何数据。 一维 先定义dim a() as integer 动态修改redim preserve a(i) as integer 二维 先定义dim a() as integer 动态修改redim preserve a(2,i) as integer, 不可以写成redim preserve a(i,2) as integer ReDim Preserve语句可以重定义动态数组大小并保留其中的变量
唯一美中不足的是他只能修改上界而不能修改下界
最近在研究数组结构(1)的时候发现了一个方法

Private Type SAFEARRAY
   cDims As Integer       '这个数组有几维?
   fFeature                 '这个数组有什么特性?
   cbElements As Long    '数组的每个元素有多大?
   cLocks As Long           '这个数组被锁定过几次?
   pvData As Long           '这个数组里的数据放在什么地方?
   'rgsabound() As SFArrayBOUND
End Type
Private Type SFArrayBOUND
       cElements As Long    '这一维有多少个元素?
       lLbound As Long        '它的索引从几开始?
End Type

以上是安全数组大致结构,我们可以发现数组的下界是被保存在lLbound里的
所以只要修改lLbound的值就可以达到修改数组下界的目的
比如数组Arr原来的范围是a-b,现在我们想改成c-b(假设c>=a)并保留其中的变量,可用如下代码:

Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Sub RedimArrayLBound(Arr() As Byte, NewLBound As Long)
   Dim As Long
   Call CopyMemory(Arr(LBound(Arr)), Arr(NewLBound), UBound(Arr) NewLBound 1)
   ReDim Preserve Arr(LBound(Arr) To LBound(Arr) UBound(Arr) NewLBound)
   Call CopyMemory(t, ByVal VarPtrArray(Arr), 4)
   Call CopyMemory(ByVal 20, NewLBound, 4)
End Sub 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多