回复 9楼 donholy
当然不直接用变量名来操作数据,通过相对地址来操作。是不是有点象C的指针。
大开眼界
Option Explicit Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Type StuSub Chinese As Integer Math As Integer English As Integer Physics As Integer Chemistry As Integer End Type Dim Stu(5) As StuSub Dim FirstAdd As Long Private Sub Form_Load() Dim i As Integer FirstAdd = VarPtr(Stu(0)) For i = 0 To 5 Stu(i).Chinese = Int((150 - 70 + 1) * Rnd + 70) Stu(i).Math = Int((150 - 70 + 1) * Rnd + 70) Stu(i).English = Int((100 - 40 + 1) * Rnd + 40) Stu(i).Physics = Int((100 - 50 + 1) * Rnd + 50) Stu(i).Chemistry = Int((100 - 50 + 1) * Rnd + 50) Next Calculate End Sub Sub Calculate() Dim temp As Integer Dim i As Integer, j As Integer Dim output(4) As Integer For j = 0 To 4 For i = 0 To 50 Step 10 Call CopyMemory(ByVal VarPtr(temp), ByVal FirstAdd + i + 2 * j, 2) output(j) = output(j) + temp Next Next For i = 0 To 4 Text1.Text = Text1.Text & output(i) & vbCrLf Next End Sub
Option Explicit '要求最好各个字段的数据是一样的,这里定义的是 long ,占4字节。一共是26个字段。 '如果每个字段占用的内存长度不一样,要么有函数计算到某个字段的长度,要么手动计算好长度后保存到一个数组中 '顺序一定不能错。 Private Type OutStatustype A_Value As Long B_Value As Long C_Value As Long D_Value As Long E_Value As Long F_Value As Long G_Value As Long H_Value As Long I_Value As Long J_Value As Long K_Value As Long L_Value As Long M_Value As Long N_Value As Long O_Value As Long P_Value As Long Q_Value As Long R_Value As Long S_Value As Long T_Value As Long U_Value As Long V_Value As Long W_Value As Long X_Value As Long Y_Value As Long Z_Value As Long End Type Private Const OutStatuslen = 4 '每个字段的长度,long=4 ,Integer=2 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Const RecNum = 10 '数据个数,可以为变量,这个示例就使用的常量 Private Outstatus(RecNum) As OutStatustype Private Sub Command1_Click() '示例 Dim k(RecNum) As Long '调用,第一个是 需要取的字段的第一个字母,代表在结构体中的顺序号,第二个是 保存数据的数组 Call TestAll("B", k) '显示取得的数据以及相临的数据 Dim i As Long Cls For i = 0 To RecNum Print k(i), Outstatus(i).A_Value, Outstatus(i).B_Value, Outstatus(i).C_Value Next i End Sub Private Sub Form_Load() Dim i As Long '示例,初始化数据 For i = 0 To RecNum With Outstatus(i) .A_Value = Rnd() * 10000 .B_Value = Rnd() * 10000 .C_Value = Rnd() * 10000 .D_Value = Rnd() * 10000 .E_Value = Rnd() * 10000 .F_Value = Rnd() * 10000 .G_Value = Rnd() * 10000 .H_Value = Rnd() * 10000 .I_Value = Rnd() * 10000 .J_Value = Rnd() * 10000 .K_Value = Rnd() * 10000 .L_Value = Rnd() * 10000 .M_Value = Rnd() * 10000 .N_Value = Rnd() * 10000 .O_Value = Rnd() * 10000 .P_Value = Rnd() * 10000 .Q_Value = Rnd() * 10000 .R_Value = Rnd() * 10000 .S_Value = Rnd() * 10000 .T_Value = Rnd() * 10000 .U_Value = Rnd() * 10000 .V_Value = Rnd() * 10000 .W_Value = Rnd() * 10000 .X_Value = Rnd() * 10000 .Y_Value = Rnd() * 10000 .Z_Value = Rnd() * 10000 End With Next i End Sub Private Sub TestAll(cs As String, data() As Long) '字段名参数仅使用第一个字母。data 为接收数据的数组,VB默认是按地址传递,所以可以用数组把修改后的数据传递出去。 Dim a_start As Long, a_len As Long, address As Long Dim i As Long address = VarPtr(Outstatus(0).A_Value) '首地址 a_start = (Asc(UCase(Left(cs, 1))) - 65) * OutStatuslen '计算成,A=0,B=1 .. 的地址偏移 'a_len = 26 * OutStatuslen '每元素总长度 a_len = Len(Outstatus(0)) '这是另一种取长度的方法,这种更精确 For i = 0 To RecNum Call CopyMemory(ByVal VarPtr(data(i)), ByVal address + i * a_len + a_start , OutStatuslen) '把指定地址和数据复制到指定地址去 'byval 传值 ,Varprt 取地址 Next i End Sub