专栏首页VBA 学习VBA数据类型Variant

VBA数据类型Variant

官方文档定义: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:数据或地址
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就可以了。

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类型保持一致。

本文分享自微信公众号 - VBA 学习(xyjvba),作者:熊业军

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • VBA实现自己的ArrayPtr取数组地址函数

    在VBA数据类型Array中,我们提到了取数组的函数,是使用1个API函数VarPtrArray ,要声明这么一个不大常用的API总觉得不大方便,我就在想能不能...

    xyj
  • VBA指针Pointer

    与VarPtr得到的变量地址(假设是pv)关系是,pv这个地址保存的4个字节(32位电脑)的值就是ps。

    xyj
  • VBA数据类型String

    前面说到的指针Pointer,其实主要是说了取地址函数。得到了变量的地址,只能赋值给Long类型,并没有指针的作用,无法根据这个记录了变量地址的东西来操作变量。...

    xyj
  • [Linux驱动炼成记] 11-快速修改芯片驱动中寄存器的值

    实际项目的调试中,往往需要快速修改驱动芯片(只针对IIC通讯)中对应寄存器的值,传统的方式一般是编译驱动 -> 烧录固件 -> 测试,而这样的方式往往很繁琐。这...

    程序手艺人
  • OGG学习笔记03-单向复制简单故障处理

    环境:参考:OGG学习笔记02-单向复制配置实例 实验目的:了解OGG简单故障的基本处理思路。

    Alfred Zhao
  • AkShare-股票数据-注册制审核-创业板

    深交所10日消息,近日,深交所在做好常态化疫情防控基础上,举办注册制首期改制上市实务研讨培训班,来自25家拟上市企业的36位董事长、总经理、实际控制人等参加。深...

    AkShare
  • 基于web页面开发串口程序界面---代码实现

    后台web框架和串口操作采用的是Python语言,其中web框架使用的是tornado。

    MiaoGIS
  • mysql datetime查询异常

    异常:Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp (201...

    WindWant
  • 蓝牙ATT_LIST设置服务指令

    02 00 28 是Primary Service UUID,表示后面的数据是service UUID

    心跳包
  • 基于层次聚类的工业数据分析研究

    聚类是将数据分类到不同的类或者簇这样的一个过程,所以同一个簇中的对象有很大的相似性,而不同簇间的对象有很大的相异性。从统计学的观点看,聚类分析是通过数据建模简化...

    用户7623498

扫码关注云+社区

领取腾讯云代金券