ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6455|回复: 11

[原创] [原创]VBA指针教程2

[复制链接]

TA的精华主题

TA的得分主题

发表于 2010-6-1 12:51 | 显示全部楼层 |阅读模式
演示工程源码: VB指针教程2.rar (14.93 KB, 下载次数: 143)
excel.jpg
  1. '我们先理解一下数组的概念,数组是由一组连续的内存区域构成
  2. '比如有一排连续的房间,每个房间都有一个编号,这个编号也是连续的。
  3. '例如房间1、房间2、...房间n,这个n就是房间的编号,如果我对你说“请”到房间2
  4. '拿一本书给我,那么你完成这个任务首先就是找到房间2,然后进入房间2拿到这本书。
  5. '显而易见这个编号实际上就是地址
  6. '那么,如果我们取得数组的首地址,那么我们就可以根据地址对数组进行各种操作。
  7. 'C语言提供了取得数组地址的语言特性,而VB则没有这样的语言特性,但我们依然可以
  8. '通过API得到数组的地址。我们先来认识下这一个DLL--Msvbvm60.dll,这个是vb6.0
  9. '的程序运行库,其就提供了一个可以获得数组地址的API,它的api声明如下:
  10. Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" _
  11.         (ptr() As Any) As Long
  12.       
  13. 'CopyMemory API请参照《VB指针教程1》,地址:http://bbs.bccn.net/thread-305122-1-1.html
  14. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
  15.        (Destination As Any, Source As Any, ByVal Length As Long)



  16. Private Sub UserForm_Activate()
  17.     Dim arr(1 To 3) As Integer
  18.     For i = 1 To 3
  19.         arr(i) = i * 10
  20.     Next
  21.     Dim arraddr As Long
  22.     '取得arr数组的首地址
  23.     arraddr = VarPtrArray(arr)
  24.     Dim arr1 As Integer, arr2 As Integer, arr3 As Integer
  25.     CopyMemory arr1, ByVal arraddr, 2
  26.     CopyMemory arr2, ByVal arraddr + 2, 2
  27.     CopyMemory arr3, ByVal arraddr + 4, 2
  28.     List1.AddItem "arr(1)=" & arr1
  29.     List1.AddItem "arr(2)=" & arr2
  30.     List1.AddItem "arr(3)=" & arr3
  31. End Sub
  32. '观察运行的结果,显然不是我们所预期的,为什么呢?这是因为VB数组的存储结构不同于我们先前所说的。
  33. 'VB数组的存储结构是使用一种叫做SafeArray的结构,而VarPtrArray(arr)取得的即是指向SafeArray结
  34. '构的指针 ,我们现在得先去了解下SafeArray结构:
  35. 'Private Type SafeArray
  36. '    cDims As Integer     '指向数组维数的指针
  37. '    fFeatures As Integer '用来描述数组如何分配和如何被释放的标志
  38. '    cbElements As Long   '指向数组元素所占的字节数的指针
  39. '    cLocks As Long       '一个计数器,用来跟踪该数组被锁定的次数
  40. '    pvData As Long       '指向数组内一个元素的指针,最重要的部分
  41. '    cElements As Long    '数组元素的个数
  42. '    lLbound As Long      '数组的下限
  43. 'End Type
  44. ''以下是fFeatures的常量标志
  45. 'Private Const FADF_AUTO         As Integer = &H1   '在堆栈中执行的分配
  46. 'Private Const FADF_STATIC       As Integer = &H2   '静态分配
  47. 'Private Const FADF_EMBEDDED     As Integer = &H4   '在结构中创建
  48. 'Private Const FADF_FIXEDSIZE   As Integer = &H10   '不能改变数组大小
  49. 'Private Const FADF_RECORD      As Integer = &H20   '记录容器
  50. 'Private Const FADF_HAVEIID     As Integer = &H40   '有IID 身份标记 数组
  51. 'Private Const FADF_HAVEVARTYPE As Integer = &H80   'VT 类型数组
  52. 'Private Const FADF_BSTR       As Integer = &H100   'BSTR数组
  53. 'Private Const FADF_UNKNOWN    As Integer = &H200   'IUnknown* 数组
  54. 'Private Const FADF_DISPATCH   As Integer = &H400   'IDispatch* 数组
  55. 'Private Const FADF_VARIANT    As Integer = &H800   'VARIANTs数组
  56. 'Private Const FADF_RESERVED  As Integer = &HF008   '余留,将来使用

  57. Private Sub Command1_Click()
  58.    List2.Clear
  59.    List3.Clear
  60.    Dim arr(1 To 3) As Integer
  61.    For i = 1 To 3
  62.        arr(i) = i * 10
  63.    Next
  64.    '指向SafeArrayld结构的指针
  65.    Dim SafeArrayldPoint As Long
  66.   
  67.    '把arr数组的首地址复制到SafeArrayldPoint
  68.    CopyMemory SafeArrayldPoint, ByVal VarPtrArray(arr), 4
  69.   
  70.    '数组的维数
  71.    Dim dims As Integer
  72.    CopyMemory dims, ByVal SafeArrayldPoint, 2
  73.    List2.AddItem "数组的维数:" & dims
  74.   
  75.    Dim elements As Long
  76.    CopyMemory elements, ByVal SafeArrayldPoint + 4, 4
  77.    List2.AddItem "数组元素所占的字节数:" & elements
  78.   
  79.    Dim eCount As Long
  80.    CopyMemory eCount, ByVal SafeArrayldPoint + 16, 4
  81.    List2.AddItem "数组元素的个数:" & eCount

  82.    Dim lBd As Long
  83.    CopyMemory lBd, ByVal SafeArrayldPoint + 20, 4
  84.    List2.AddItem "数组的下限:" & lBd
  85.   
  86.   '读取数组的值
  87.    Dim arraddr As Long
  88.    CopyMemory arraddr, ByVal SafeArrayldPoint + 12, 4
  89.    Dim arr1 As Integer, arr2 As Integer, arr3 As Integer
  90.    CopyMemory arr1, ByVal arraddr, 2
  91.    CopyMemory arr2, ByVal arraddr + 2, 2
  92.    CopyMemory arr3, ByVal arraddr + 4, 2
  93.    List3.AddItem "arr(1)=" & arr1
  94.    List3.AddItem "arr(2)=" & arr2
  95.    List3.AddItem "arr(3)=" & arr3
  96.    '修改数组的值
  97.    CopyMemory ByVal arraddr, 13, 2
  98.    CopyMemory ByVal arraddr + 2, 28, 2
  99.    MsgBox "修改后数组后arr(1)=" & arr(1)
  100.    MsgBox "修改后数组后arr(2)=" & arr(2)
  101.    MsgBox "修改后数组后arr(3)=" & arr(3)
  102.    
  103. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2010-6-1 14:07 | 显示全部楼层
先收藏,慢慢学习。

TA的精华主题

TA的得分主题

发表于 2010-6-1 14:22 | 显示全部楼层
很深奥的样子,慢慢学习.谢谢楼主.

TA的精华主题

TA的得分主题

发表于 2010-6-1 15:21 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-6-1 17:09 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2011-4-1 08:39 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2011-4-1 13:30 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2011-10-24 20:38 | 显示全部楼层
头像被屏蔽

TA的精华主题

TA的得分主题

发表于 2011-10-24 21:00 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-7-8 23:08 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-5 20:48 , Processed in 0.033769 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表