ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: liu-aguang

[分享] VBA数组进阶--典型编译/运行时错误之成因及解决办法

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-9-10 21:38 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:数组集合和字典
本帖最后由 liu-aguang 于 2014-9-11 13:43 编辑

十、过程中传递整个数组出错

症状:
    试图以ByVal的方式传递整个数组
  1. Sub test()
  2.     Dim a(1) As Integer
  3.     a(0) = 1: a(1) = 2
  4.     Call test2(a)
  5. End Sub
  6. Sub test2(ByVal c()) '错误发生在这里
  7.     c(0) = 10
  8. End Sub
复制代码
原因:
   数组中个别元素可用ByVal传递,但整个数组必须以ByRef传递。如果为了防止对数组元素的更改返回调用者,而必须以ByVal方式传递的话,有两种方法:
办法1:
    可以传递括号中的数组参数:
  1. Sub test1()
  2.     Dim a(1) As Integer
  3.     a(0) = 1: a(1) = 2
  4.     Call test2((a))
  5.     MsgBox a(0)       'a(0)=1
  6. End Sub
  7. Sub test2(ByVal c)
  8.     c(0) = 10
  9. End Sub
复制代码
办法2:
将数组放在Variant变量中,再将此Variant变量传递至ByVal参数:

  1. Sub test1()
  2.     Dim a(1) As Integer
  3.     Dim MyVal As Variant
  4.     a(0) = 1: a(1) = 2
  5.     MyVal = a
  6.     Call test2(MyVal)
  7.     MsgBox a(0)          'a(0)=1
  8. End Sub

  9. Sub test2(ByVal c)
  10.     c(0) = 10
  11. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2014-9-11 10:28 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
liu-aguang 发表于 2014-9-10 21:37
九、工作表函数应用于日期类型数组出错

症状:

日期类型的本质,是类似#2014-09-11# 这样格式的文本字符串。

所以不能直接用工作表函数操作。

但日期类型数据可以由计算机内部转换为Double数值,然后用于比较计算。


…………
内置的日期函数,其实都是先内部转换为Double日期值(如同DateValue函数的作用)
然后再进行比较计算的。
例如:
    Dim MyDate As Double
    MyDate = DateValue("February 12, 1969")
    MyDate = DateValue("02/12/69")
    MyDate = DateValue("2008-08-08")
    MyDate = DateValue(Date)
   
……这就是问题的根源。

点评

那是工作表函数的扯淡问题,跟Date数据类型没半毛钱关系。  发表于 2014-9-11 11:13

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-9-11 10:55 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2014-9-11 10:28
日期类型的本质,是类似#2014-09-11# 这样格式的文本字符串。

所以不能直接用工作表函数操作。

是否这样表述更易理解:
日期/时间的本质是一个Double数据,但当把它赋与日期变量时,则自动按系统日期设置格式转换为字符串形式存储;所以当某些工作表函数应用于日期类型数组时,必须先转换为Double.

TA的精华主题

TA的得分主题

发表于 2014-9-11 11:08 | 显示全部楼层
香川群子 发表于 2014-9-11 10:28
日期类型的本质,是类似#2014-09-11# 这样格式的文本字符串。

所以不能直接用工作表函数操作。

又瞎说。
Date 数据类型
Date 变量存储为 IEEE 64 位(8 个字节)浮点数值形式,其可以表示的日期范围从 100 年 1 月 1 日到 9999 年 12 月 31 日,而时间可以从 0:00:00 到 23:59:59。任何可辨认的文本日期都可以赋值给 Date 变量。日期文字须以数字符号 (#) 扩起来,例如,#January 1, 1993# 或 #1 Jan 93#。
  1. Sub test()
  2.     Dim d#, t#
  3.     d = Date
  4.     t = Now
  5.     Debug.Print d, t
  6. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2014-9-11 11:24 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-9-11 11:29 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-9-11 11:42 | 显示全部楼层
lee1892 发表于 2014-9-11 11:08
又瞎说。
Date 数据类型
Date 变量存储为 IEEE 64 位(8 个字节)浮点数值形式,其可以表示的日期范围从 ...

Date 数据类型 的变量存储形式是一回事、
而该数据在被工作表函数引用时的字符串形式则是另一回事。

总之,日期数据的核心是Double数值没错,但其会以日期格式的字符串形式被返回。

这两者之间虽然等价,但必须通过计算机内部转换。

TA的精华主题

TA的得分主题

发表于 2014-9-11 13:05 | 显示全部楼层
liu-aguang 发表于 2014-9-10 21:38
十、过程中传递整个数组出错

症状:

个人认为第2种方法不贴切:并不需要一个变体型变量做中间的桥。之所以可以可以做传值引用是因为test2 中接收的参数是一个变体型变量,这个形式参数是个变体变量当然支持传值调用。只不过你真实的是传了一个数组过来而已。简单修改了你的示例文件,去掉了myval 的过渡,一样实现了传值调用,一样的结果。
  1. Sub test1()

  2.     Dim a(1) As Integer

  3. '    Dim MyVal As Variant

  4.     a(0) = 1: a(1) = 2

  5. '    MyVal = a
  6.    
  7.     Call test2(a)

  8.     MsgBox a(0)          'a(0£©=1

  9. End Sub


  10. Sub test2(ByVal c)
  11.   
  12.     c(0) = 10

  13. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-9-11 13:57 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
hehex 发表于 2014-9-11 13:05
个人认为第2种方法不贴切:并不需要一个变体型变量做中间的桥。之所以可以可以做传值引用是因为test2 中接 ...

本主题是强调数组不能以ByVal方式传递。无论方法1、方法2,还是你提供的方法都是同一个变通处理方法,即把数组首先赋与一个Variant变量,让这个Variant变量包含数组。你提供的方法,只是数组隐式赋与变量罢了。

TA的精华主题

TA的得分主题

发表于 2014-9-11 14:58 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
liu-aguang 发表于 2014-9-11 10:55
是否这样表述更易理解:
日期/时间的本质是一个Double数据,但当把它赋与日期变量时,则自动按系统日期设 ...

事情的本质是VB中的Date与C、C++语言中的Date不兼容,工作表函数都是C、C++开发的,
解决办法在msdn中有明确的说明,要求转换成Double类型

http://msdn.microsoft.com/zh-cn/library/3eaydw6e(VS.80).aspx
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-18 13:27 , Processed in 0.045859 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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