必须声明标量变量_Excel VBA解读(136): 在用户定义函数中的变体、引用、数组、计算表达式、标量...

学习Excel技术,关注微信公众号:

excelperfect

在前面的几篇文章中,我们自定义的函数使用定义为Range的参数来从Excel工作表中获取数据,例如:

Function VINTERPOLATEB(Lookup_Value As Variant, _

   Table_Array As Range, _

   Col_Num As Long)

如果在公式中使用单元格区域作为参数来调用该函数,运转得非常好:

=VINTERPOLATEB($H1,$A$1:$C$10000,2)

但是,如果使用计算表达式或者一组常量作为参数,则返回的结果为#Value:

{=VINTERPOLATEB($H1,($A$1:$C$10000*1),2)}

这个公式是数组公式,因此输入完后按Ctrl+Shift+Enter组合键,Excel自动在公式两边添加花括号。

=VINTERPOLATEB(4.5,{1,3,3.5;4,4,4.5;5,4.5,5},2)

这个公式使用了3行3列的数组常量。

Excel在调用函数之前会检测到这些参数不是单元格区域。

通过将参数定义为Variant型而不是Range可以解决此问题:Variant型参数几乎可以包含任何内容!但用户自定义函数现在必须处理Variant可能包含的所有不同类型的数据。

一种简单的方法是将参数声明为Variant型变量:这会将所有内容强制转换为值:

Function TestFunc(theParameter AsVariant)

   Dim vArr As Variant

   vArr = theParameter

   TestFunc = vArr

End Function

在VBE中,在赋值给函数的返回值的语句行设置断点,如下图1所示

6843423beceaa9490e2a13ab8b324325.png

图1

输入数组公式:

=TestFunc($A$1:$A$5*1)

本地窗口显示如下图2所示。

c1895ca1f1f75b156fc51c2412d0bc35.png

图2

在本地窗口可以看到,vArr变量包含2维Variant型数组,子类型为Double。

输入公式:

=TestFunc({1,2,3;5,6,7})

在本地窗口中可以看到其结果也是2维数组:

24385751101ce291d9d859e52d17946b.png

图3

输入公式:

=TestFunc({1,2,3})

在本地窗口可以看到结果为1维数组:

00f814cceb43761f2e5d6c7cd52eaec2.png

图4

输入公式:

=TestFunc({1;2;3})

在本地窗口可以看到结果为2维数组:

03ad1cc776e27f92ddb4825f658b1d1e.png

图5

输入公式:

=TestFunc(15)

可以看到结果为一个标量,而非数组:

6f3ca18a2420ee23aaf7c2f210e2f67a.png

图6

如果提供单元格区域作为函数参数:

=TestFunc($A$1:$A$5)

则得到:

9d96d3ad9370fe333a643bbcead60a62.png

图7

注意,theParameter变量包含对象子类型Range,意味着必须将它视为Range变量,而vArr包含从该Range变量中提取的值。

因此,在通用目的的用户自定义函数中,希望使用Variant型参数,并且经常需要确定变体的类型以及上限和下限。

为了获得最大效率,不能只使用vArr=theVariant,因为:

  • 不能使用.Value2,因为它可能不是单元格区域。

  • 在许多情况下,希望在强制转换所有值之前操控Range对象或者操控Range对象而不是强制转换所有值。

因此,这里有一个函数用来确定传递的内容以及它的大小:

Function Variant_Type(theVariantAs Variant)

   Dim jRowL As Long

   Dim jRowU As Long

   Dim jColL As Long

   Dim jColU As Long

   Dim jType As Long

   Dim varr As Variant

    '

    ' theVariant可以包含标量, 数组, 或单元格区域

    ' 找到上限和下限以及类型

    'type=1:单元格区域, 2:2维variant数组,

    ' 3:1-维variant数组(列的单行), 4:标量

    '

   On Error GoTo FuncFail

   jType = 0

   jRowL = 0

   jColL = 0

   jRowU = -1

   jColU = -1

   If TypeName(theVariant) = "Range" Then

        jRowL = 1

        jColL = 1

        jRowU = theVariant.Rows.Count

        jColU = theVariant.Columns.Count

        jType = 1

   ElseIf IsArray(theVariant) Then

        jRowL = LBound(theVariant, 1)

        jRowU = UBound(theVariant, 1)

        On Error Resume Next

        jColL = LBound(theVariant, 2)

        jColU = UBound(theVariant, 2)

        On Error GoTo FuncFail

        If jColU < 0 Then

            jType = 3

            jColL = jRowL

            jColU = jRowU

            jRowL = 0

            jRowU = -1

        Else

            jType = 2

        End If

   Else

        jRowL = 1

        jRowU = 1

        jColL = 1

        jColU = 1

        jType = 4

   End If

   Variant_Type = jType

   Exit Function

FuncFail:

   Variant_Type = CVErr(xlErrValue)

   jType = 0

   jRowU = -1

   jColU = -1

End Function

注意,首先测试变量是否包含Range,这是为了避免无意中将Range强制转换为其值。在确定变体的子类型时,VBA还有几种方法:

  • If TypeOf theVariant Is Range Then

  • If TypeName(theVariant) = “Range”Then

尝试使用VarType(theVariant)时要特别小心,这会对Range的覆盖范围进行强制转换,然后抛出结果值!

代码的图片版:

67990e16fd3ceda70fe6dea5f17864b2.png

小结:在通用目的的用户自定义函数中,必须使用Variant类型的参数而不是Range类型。可以通过在处理变量之前确定变体包含的内容来有效地处理出现的问题。

cf4cb223974149938f9f6464e2b4db25.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql内部_MySQL SQL语句内部剖析

一条SQL在MySQL体系结构内的执行流程:注意只有查询操作才会走查询缓存&#xff0c;而表的结构和数据发生改变时将会清空查询缓存。所以开启查询缓存的意义不大&#xff0c;8.0后已经废弃了该功能。一条update在存储引擎内部的执行步骤如下:SQL:update t set cc1 where id2;SQL完…

用Backbone.js创建一个联系人管理系统(四)

原文: Build a Contacts Manager Using Backbone.js: Part 4 这一系列教程的第四部分,教我们如何完成对已经存在的Contacts进行编辑和保存. 本教程是基于这一系列的前三个教程. 有不清楚的请先阅读前三部分. 开始 在Contact原模版里添加一个edit按钮. <button class"ed…

mysql默认时间怎么不同步_MYSQL 更新时间自动同步与创建时间默认值共存问题

本文作者&#xff1a;苏生米沿在使用SQL的时候&#xff0c;希望在更新数据的时候自动填充更新时间&#xff0c;那么在mysql中是如何实现的呢&#xff1f;如创建表usersCREATE TABLE RS_SIGNUPUSER (ID VARCHAR(36) COMMENT 主键(业务功能无关),USERNAME VARCHAR(50) COMMENT 姓…

python代码技巧_让你python代码更快的3个小技巧

大家好&#xff01;今天呢&#xff0c;我们来聊一聊如何加速你的 python 代码。Python 语言的优点可以列举出许多&#xff0c;语法简单易懂、模块丰富、应用广泛等等。但是世界上没有有完美的东西&#xff0c;python 一个明显缺点就是运行速度慢&#xff0c;至少跟 C 语言没法比…

从此走上一条iOS程序猿不归路。。。

新的城市&#xff0c;新的生活&#xff01;前不久刚刚结束了苦逼的面试找工作之旅&#xff0c;期间也小有收货&#xff0c;如今正处年底工作闲暇之余&#xff0c;将前一阵子陆陆续续的总结整理了一下&#xff0c;本人菜鸟程序猿一只&#xff0c;水平有限&#xff0c;本文总结的…

springboot mysql事物_在Spring Boot中使用数据库事务

关于数据库访问还有一个核心操作那就是事务的处理了&#xff0c;前面两篇博客小伙伴们已经见识到Spring Boot带给我们的巨大便利了&#xff0c;其实不用猜&#xff0c;我们也知道Spring Boot在数据库事务处理问题上也给我们带来惊喜&#xff0c;OK&#xff0c;废话不多说&#…

cinder连接mysql数据库_Openstack入门篇(十六)之Cinder服务的部署与测试

1.理解块存储服务操作系统获得存储空间的方式一般有两种&#xff1a;通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘&#xff0c;然后分区、格式化、创建文件系统&#xff1b;或者直接使用裸硬盘存储数据(数据库)通过 NFS、CIFS 等 协议&#xff0c;mount 远程的文件系统第一种…

最后关于Pipeline完整的图如下:

最后关于Pipeline完整的图如下&#xff1a; 转载于:https://www.cnblogs.com/aaa6818162/p/5077988.html

amr 转mp3 java_JAVA 音频转换AMR 转MP3,OS,Linux cent os 7

场景近期在做微信开发时&#xff0c;需要获取用户发给公众服务号的语音留言。而从微信服务端下载来的语音格式却是amr的格式&#xff0c;同样的你手机录音、Android语音等也都是生成amr格式文件。但当你想在web页面去播放此文件时&#xff0c;就困难了。因为无论是当前HTML5的标…

dragloader.js帮助你在页面原生滚动下实现Pull Request操作

dragloader.js是一个面向移动Web开发的JavaScript库&#xff0c;帮助开发者在使用页面原生滚动时&#xff0c;模拟上/下拉手势&#xff0c;实现Pull Request操作。 在移动设备上&#xff0c;一般会使用 drag down 手势实现加载最新 使用 drag up 手势实现加载更多 dragloader样…

怎么运行java虚拟机_Java代码如何运行在Java虚拟机中

我们都知道要运行Java代码就必须要有JRE&#xff0c;也就是Java运行时环境&#xff0c;JRE中包含了Java程序的必需组件&#xff0c;包括Java虚拟机以及Java核心类库&#xff0c;然而运行C代码则不需要额外的运行时环境&#xff0c;只需要把代码编译成CPU能识别的指令即可&#…

【AJAX】AJAX实现搜索信息自己主动推荐并补全

好久没有继续看AJAX的视频教程了,今天就将最后一个教程案例做完。我们在搜索引擎中输入文字时文本框下会提示对应的信息&#xff0c;这个案例就是实现这样的基本功能&#xff0c;代码比較粗糙还须要进一步完好&#xff0c;当中有些地方也须要向大神们请教一下。完毕效果截图&am…

使用IntelliJ IDEA 14和Maven创建java web项目

安装Maven 下载安装 去maven官网下载最新版。 解压到安装目录。 配置 右键桌面的计算机图标&#xff0c;属性–>高级系统设置–>环境变量&#xff0c;添加M2_HOME的环境变量&#xff0c;然后将该变量加入的PATH中。 注意 必须要有JAVA_HOME和个环境变量&#xff0c;不然m…

工作那点小事

目录 工作那点小事总结回到顶部工作那点小事 离开了“火龙果”&#xff0c;领导&#xff0c;领导的领导&#xff0c;领导的领导的领导&#xff0c;同事&#xff0c;同事等等&#xff0c;给你上了一堂课。 面试时&#xff0c;问&#xff1a;为什么离开上一家公司&#xff1f;答&…

Testlink1.9.5的安装配置

前两天搭建了Testlink环境&#xff0c;在这里整理记录下过程中遇到的问题以及搭建流程。Testlink版本&#xff1a;1.9.5操作系统&#xff1a;Windows7 32bit 步骤一&#xff1a;安装XAMPP 下载解压xampp压缩包&#xff0c;点击安装包xampp-win32-1.8.0-VC9-installerservice se…

UIAutomator输入中文

之前一直是英文的测试环境&#xff0c;包括手机也是英文的&#xff0c;app也是英文的&#xff0c;涉及不到中文输入法的东西。但现在在写中文的app&#xff0c;所以需要输入中文。看到网上的解决办法如下: 下载https://github.com/sumio/uiautomator-unicode-input-helper源码 …

jni java返回数组_Android开发实践:Java层与Jni层的数组传递

Android开发中&#xff0c;经常会在Java代码与Jni层之间传递数组(byte[])&#xff0c;一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层&#xff0c;由Jni层的Socket代码发送出去&#xff0c;当然&#xff0c;Jni层也需要把从Socket接收到的数据流返回给Java层。我…

jsp mysql 注入_由Jsp+Mysql注入到root权限的全程展 【好久没有安全类文章了,转一篇看看】...

由JspMysql注入到root权限的全程展最近有点空闲,所以写点垃圾文章来消磨一下时间.文中没有什么技术含量,如果要转载,请注明作者并保持文章的完整.很多人可能都知道asp,php的编程要防止sql注入漏洞,而并不知道jsp编程同样也需要防备sql注入漏洞.其实,一旦jsp代码有注入漏洞,将直…

Divide and conquer:Dropping tests(POJ 2976)

最大化平均值 题目大意&#xff1a;给定你n个分数&#xff0c;从中找出k个数&#xff0c;使∑a/∑b的最大值 这一题同样的也可以用二分法来做&#xff08;用DP会超时&#xff0c;可见二分法是多么的实用呵&#xff01;&#xff09;&#xff0c;大体上是这样子&#xff1a;假设最…

java中标准封装结构_java中的构造,封装

今天给大家讲一下面向对象中的构造&#xff0c;封装&#xff1b;构造&#xff1a;构造方法有以下几个特点&#xff1a;1.方法名和类名一致。2.无返回类型。接下来的几种构造样式&#xff0c;直接上代码吧&#xff1a;//这是一个宠物类 有一个属性&#xff1a;名字(name)public …