前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VBA数据类型Variant

VBA数据类型Variant

作者头像
xyj
发布2020-07-28 10:14:48
1.7K0
发布2020-07-28 10:14:48
举报
文章被收录于专栏:VBA 学习VBA 学习

官方文档定义:A special data type that can contain numeric, string, or date data as well as user-defined types and the special values Empty and Null. The Variant data type has a numeric storage size of 16 bytes and can contain data up to the range of a Decimal, or a character storage size of 22 bytes (plus string length), and can store any character text. The VarType function defines how the data in a Variant is treated. All variables become Variant data types if not explicitly declared as some other data type.

我以前一直好奇为什么能有什么数据都可以保存的类型,现在对内存知识有了一定了解才知道,其实说到底,Variant底层也是一种数据结构,16个字节分别会有不同的意义,对于一些VBA里的对象复制给Variant后,也只是保存了它的地址。至于通过地址怎么就能判断出对象的具体类型就不大清楚了!

所以想知道Variant的16个字节具体代表了什么,我们只需要让它保存不同的数据类型,然后查看16个字节的变化就可以了。

Variant16字节是如何分配的?

  1. 前8字节 b0:标识数据类型(也就是VarType返回的数字) b1:标识后8字节是数据还是指针 - 0x00 8-15数据类型的是数据本身,String是地址 - 0x40 8-11存的是数据地址,String是地址的地址 - 0x20 8-11存的是数组地址 - 0x60 8-11存的是数组地址的地址
  2. 后8字节8-15:数据或地址
代码语言:javascript
复制
Sub TestVariant()
    Dim v As Variant
    Dim i As Byte

    i = &H10
    v = i

    Dim lenth As Long
    lenth = 16

    Dim b() As Byte
    ReDim b(lenth - 1) As Byte

    CopyMemory VarPtr(b(0)), VarPtr(v), lenth
    Printf "VarType(v) = 0x%x, b = 0x% x", VarType(v), b
End Sub

输出:
i定义byte:VarType(v) = 0x11, b = 0x11 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00
i定义Integer:VarType(v) = 0x2, b = 0x02 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00
i定义Long:VarType(v) = 0x3, b = 0x03 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00
i定义Double:VarType(v) = 0x5, b = 0x05 00 00 00 00 00 00 00 00 00 00 00 00 00 30 40
i定义String:VarType(v) = 0x8, b = 0x08 00 00 00 00 00 00 00 74 02 f3 23 00 00 00 00

b1一直都是0,就算用v = VarPtr(i),仍然是0,因为VarPtr返回的也是Long,如何才能让b1出现呢?我们知道,VBA里面,函数的传值默认就是byref,所以加1个Function就可以了。

代码语言:javascript
复制
Sub TestVariant()
        Dim i As Byte

        i = &H10
        TestVariantPtr i
    End Sub

    Function TestVariantPtr(v As Variant)
        Dim lenth As Long
        lenth = 16

        Dim b() As Byte
        ReDim b(lenth - 1) As Byte

        CopyMemory VarPtr(b(0)), VarPtr(v), lenth

        Dim ptr As Long
        CopyMemory VarPtr(ptr), VarPtr(b(8)), 4

        Dim Value As Byte
        CopyMemory VarPtr(Value), ptr, 2

        Printf "VarType(v) = 0x%x, b = 0x% x, ptr = 0x%x, Value = %x", VarType(v), b, ptr, Value
    End Function
    输出:
    i、Value定义byte:VarType(v) = 0x11, b = 0x11 40 00 00 00 00 00 00 52 ef 19 00 00 00 00 00, ptr = 0x19efe4, Value = 10
    i、Value定义Integer:VarType(v) = 0x2, b = 0x02 40 00 00 00 00 00 00 52 ef 19 00 00 00 00 00, ptr = 0x19efe4, Value = 10
    i、Value定义Long:VarType(v) = 0x3, b = 0x03 40 00 00 00 00 00 00 50 ef 19 00 00 00 00 00, ptr = 0x19ef50, Value = 10

其他不多演示,注意Dim Value As语句下面的CopyMemory复制字节数和Value类型保持一致。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 VBA 学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档