使用VBA编写自定义函数(修改版)

使用VBA编写自定义函数(修改版)
使用VBA编写自定义函数(修改版)

使用VBA编写自定义函数

前言

本教程仅适用于不懂或初学VBA的朋友。

万事开头难,VB的内容繁多庞杂,没接触过VB但想学习编程的朋友可能无所适从,然而,这也远不是一个小教程能说得明白的,所以,本教程没有讲过多的语法、函数,也没有摘录VBA帮助(可以算是主要的参考教程)里的内容,而是以口语的方式讲解编程的一个基本思路,再辅以讲解平常可能遇到情况,让学习者能基本上手编写一段简单的代码,我的目的就达到了,接下去,就是学习者自己去论坛找资料学习了。

一、VBA简介

Visual Basic for Applications(VBA)基于Visual Basic的一种宏语言,是微软用来扩展Windows的应用程序,特别是在Microsoft Office软件中执行通用的自动化(OLE)任务的编程语言。它与VB不同的是,VB的对象主要是可视化窗口,VBA的对象则主要是Microsoft Office应用程序,如EXCEL的单元格、工作表、工作薄等。由于对象不同,那么,对象的属性、方法、事件就会发生相应的变化,所以,学习VBA,或从VB转到VBA,就是要根据具体对象特性而进行不同的处理。

我们在使用EXCEL时,如果仅仅只限于简单的数据处理,那就完全没有发挥出EXCEL强大的功能,我们完全可以使用VBA让我们的工作效率大大提高。

一般情况下,我们通常编写三类程序:

1、自定义函数:它与工作表内置函数使用方法一样,使用简单,适用于固定几个参数得出结果这种类型;

2、表格处理,这种编程较为复杂,适用于对整表进行大批量量数据的处理,对表格进行美化处理等。

3、可视化窗口,可以通过窗口设置对表格数据进行处理。

以上三种并不是独立存在的,可以相互结合使用,更能发挥更大的效率。

本次讲解的主要自定义函数,从较为简单的独立的自定义函数开始,逐渐学习进行大数据处理的能力。

二、几个必须知道的基础知识

1、VBA编辑、使用的相关说明

打开VBE编辑器

EXCEL2003版

EXCEL2007及其以上版本

创建模块,并在模块中编写代码

如果代码(宏)保存在某一个工作薄内(比如A.xls),无论这个A.xls拷贝到任何电脑上,都可以使用这个宏,而其他工作薄要使用这个宏,就必须同时也打这个A.xls;

如果我们把包含程序(宏)的工作薄另存为加载宏文件(xla),并让EXCEL加载它,那么每次EXCEL打开时,都会自动加载这个xla文件,那么当前电脑上所有的工作薄都可以使用这个宏。

宏安全(EXCEL2007及其以上版本在信任中心中设置)

2、对象三要素:属性、事件、方法

对象代表应用程序中的元素(一个实体),比如,工作表、单元格、图表、窗体,或是一份报告、一个人物等。

属性:是指对象的特征,诸如大小、颜色或屏幕位置等;比如单元格的内容,填充颜色、字体颜色、单元格行高及列宽等等,又比如,一个人的年龄、姓名、性别、体重、血型等等。可以通过修改对象的属性值来改变对象的特性。

代码通常写为:对象.属性;好比是张三(.的)年龄

方法指的是对象能执行的动作;比如在单元格添加一个有效性序列(下拉菜单)。

代码通常写为:对象.方法;好比是领导(.下达)政令。

事件是一个对象可以辨认的动作,像单击鼠标或按下某键等,并且可以写某些代码针对此述动作来做响应;比如领导写字。

提示:不同的对象有不同的属性和方法。在VBA模块窗口里,写下一个对象的名称,再写一个.就会出现一个下拉列表,列表里就是该对象的属性和方法集合。

方法与事件的区别,方法好比是一个对象的能力,事件好比是一个对象的动作,不同的人有不同的能力,好比大多数人都能写字,但只有领导才有能力下达政令。对象及其三要素是编程的最基本知识,任何程序语言都如此。

3、数据类型

数据类型,简单来说,就是一个数据它是什么类型的内容,是数字还是文本,或是日期等等,不同的数据类型,程序处理的方法是不同的,处理时数据时所消耗的系统内存也是不一样的。

我们一般常用的几个数据类型有:Byte、Boolean(真假)、Integer 和 Long(长整数)、Single 和 Double(小数)、String(文本字符串)、Date(日期)等。

4、变量

变量好比就是方程式中的未知数X。首先,它只是一个代号(先命名),其次,我们可以给这个代号设置不同的内容(附值)。所以,这个代号的值是不固定的,是会变化的,我们可以用这个代号来任意处理需要计算的内容。于是我们把这个代号称为变量。

变量是相对于常量而言的,常量是固定的内容,比如:π、密度、65,8,-2.3等具体的数值、指定的内容或名称,变量则是相对于不同的情况来设置一个代号。

比如我们要计算一个圆的面积,常量则是π,变量则是半径或直径,当设置给圆不同的半径或直径时,圆的面积就会相应的改变。相对于整个计算而言,我们也可以说,变量就是其中需要处理的数据,而常量则是不变的计算步骤;相对于目标而言,变量就是不同的方法,而常量就是意志和决心。

变量名称:当在 Visual Basic 的模块中为过程、变量命名时,应符合下列命名规则:

①一个字符必须使用英文字母,例如,象1xb、_w这种名称都是错误的,而xb1、w_这

样的名称才是正确的。

②不能在名称中使用空格、` 、~、!、@、、#、$、%、^、&、*、(、)、-、+、=、{、}、

[、]、|、\、;、:、'、"、<、>、,、.、?、/等字符,也就是说,除了字母、数字、下划线_ 可以使用外,其他键盘上的符号都不能使用,而且,一般情况下,名称最好

不要使用全角字符或汉字。

③称的长度不得超过 255 个字符。

④称不能与 Visual Basic 本身的函数、属性、方法的名称相同。例如,命名为 Left 的

变量与函数 Left() 的名称相同,这是不允许的。在VBA中也不要使用如A1、B2等

与单元格相同的命名。

⑤能在范围的相同层次中使用重复的名称。例如,不能在同一过程中声明两个命名为

age 的变量。

注意 :Visual Basic 不区分大小写,但它会在名称被声明的语句处保留大写,例如:Ax4d 与 ax4D 是相同的名称。

参考:可以使用单词、拼音或词组的简拼加前后缀的方式,以帮助记忆和理解,比如,我编写的YCH()自定义函数就是以我自己的名字命名的。

变量的附值,书写格式为:变量 = 值 或 表达式,比如:

A = 0.5

A = A + 1

A = A & “VBA“

为什么A可以等于A+1,因为它不是我们普通数学表达式,而是代码表达式,程序是按顺序逐行处理的,前面附了值以后,下面就会自动代入先前的值,如果前面没有附过值,这时,变量A会自动是0 或 ““(空)。所以,第1行A的值为0.5,第2行A的值为0.5+1=1.5,第3行A的值为1.5VBA。

5、单元格的表示方法

在EXCEL VBA里,最基本的元素就是单元格,通常单元格有以下几种表示方法:

单独的单元格:

①Range(“A1“)

②[A1]

③Cells(1,1)————前1表示行,后1表列

④Y.Offset(1, 2)——此为相对引用,表示Y(某个单元格)向下一行,向右2列的那

个单元格,比如,Y为A1单元格,则本代码表示的单元格是C2

单元格区域:

⑤Range(“A1:B5“)

⑥[A1:B5]

⑦Range(Cells(1,1),Cells(5,2))

⑧Range(“MyRange“)——引用命名区域,比如本工作表上有一个区域命名为MyRange

⑨Range(“A1:B5,C2:E4,G1:I10“) 引用多个区域

本工作表上所有单元格(相当于选中行标和列标在左上角交汇的那个空白处)

Cells.ClearContents

整行表示:

Rows(1) ————第一行

Rows(“1:1“) ———第一行

Rows(“1:5“) ———第一行至第五行

Rows ——————工作表上所有的行

整列表示:

Columns(1) ———第一列

Columns("A") ——第一列

Columns("A:B") —第一列至第二列

Columns ————工作表上所有的列

6、过程

代码并不是零星散乱的随便写在模块里就可以的,它是以一段段以Sub 宏名称() 语句开始,End Sub 语句结束组成的过程,其语句结构如下:

Sub 宏名称()

过程代码

End Sub

但一个过程不可能无限长,即过程代码不能无限多,在VB或VBA中,过程代码大概只能写300多行,超过了程序可能就不执行了。

如果代码过多,那么,我们可以分段写,然后,其他过程再引用执行这段代码就可以了。

Sub 过程1()

过程2

过程3

End Sub

Sub 过程2()

过程2代码

End Sub

Sub 过程3()

过程4

过程3代码

End Sub

Sub 过程4()

过程4代码

过程5

End Sub

Sub 过程5()

过程5代码

End Sub

当然,过程不是直接把代码分几段来连接,而是针对不同的情况,每个小过程单独处理一种数据,或一种处理方式,然后把这些小过程集合起来,就形成了一个大的程序,来处理全部的数据。

我们平常在编写过程中,要注意哪些数据的处理是我们经常会遇到的,那么,对这种数据的处理,可以对应编写一个独立的处理过程,今后在处理大数据时,如果其中用得着这些独立过程,就可以直接引用这个了,而不必重新编写。高塔是一砖一木搭建起来的,而每一砖一木都是独立的,我们编写程序代码也一样,只要注意经常积累这些完善而独立的小过程,将来编写大程序时,直接拿来引用即可,这样就能省去很多功夫,也能构建我们自己的程序高塔。

另外要注意,过程要按照顺序和需要递渐引用,不要形成循环引用,比如 Sub 过程1()

过程2

End Sub

Sub 过程2()

过程1

End Sub

象这样的话,那程序就会无限循环执行下去了,当然,不只是过程,在过程代码的某些循环语句中,如果设计考虑得不周,也可能会形成无限循环,如果发生这种状况,按ESC键可让程序中止。

7、学习VBA的方法和途径

最好找一个懂VB的师父带,因为任何书本、资料、教学录像都是死的,它不能回答你具体遇到的问题,只有人才是活的教学。

在网上寻找相应的OFFICE论坛学习,如:EXCELHOME

VBA帮助:在VBE窗口可以按F1调出帮助,也可以在把光标点在需要学习的代码名称上,再按F1调出这个代码的相应帮助内容。

使用录制宏功能,参考EXCEL本身是编写的代码。

注意收集好的代码。

8、如何让代码更高效,运行得更快

我在这方面水平不够,只能大概说说:

首先,必须要学会更高级的编程知识和编写技巧,这样才能编写出高效的代码;

其次,要有严密而有效的逻辑思维能力;

关闭屏幕更新,代码为:Application.ScreenUpdating = False,为True时打开屏幕更新;运行宏时如果不关闭,会发现表格随着数据的输出在自动移动,关闭后就不会移动了。

处理工作表和单元格时,除非需要,不要去选择单元格(相当于用鼠标点先单元格),比如我们要在A1单元格写入123,录制宏的代码如下:

Range("A1").Select

ActiveCell.FormulaR1C1 = "123"

其中,.Select就是单元格对象被选择到,其实这个代码可以改写为: Range("A1").FormulaR1C1 = "123" 或Range("A1") = "123"

使用数组来处理数据组;

尽可能少的使用循环语句

其他,等等。

三、实例设计讲解

1、编写目标

我们现在需要编写一个计算矩形面积(或长方形体积)的自定义函数。

2、查找相关资料

查找到矩形面积的计算公式为:长×宽

长方体的体积公式为:长×宽×高

3、分析

计算公式中,长、宽、高都是变量,可以分别设为变量1、变量2、变量3

其中:参数高可以有,也可以没有

计算结果根据需要可以是公式的结果(数值)也可以是公式本身(文本),可设为变量4

4、过程结构设计

可以制作一个步骤流程图,让代码编写的思路更加清晰。

5、编写代码

①声明自定义函数名称

声明:就是告诉程序,这个XX是专属名称,在本程序中只能用来表示XXXXX。

语法为:

Function 函数名称(必要参数, Optional 可选参数)定义函数的数据类型 过程代码

[Exit Function]

过程代码

End Function

说明:

Function:起始句,使用Function声明以下过程为自定义函数。

函数和参数其实都是变量,所以,它们名称的命名规则都与变量名称的命名规则相同。

同变量一样,如果需要的话也可以对函数定义数据类型,也可以不用定义,那么,函数的数据类型就是“用户自定义”类型。

可以没有参数,那就如同工作表函数PI()一样,它输出的结果就始终只有一个,即它就是一个常量。

可以只有必要参数,也可以只有可选参数。

如果必要参数和可选参数都有,那么,可选参数必须放在必要参数后面,可选参数必须使用Optional声明。

可选参数可以指定一个常量,表示在没有写入该可选参数时,默认它为这个常量,比如Optional可选参数 = 3.5;必要参数不能指定常量。

参数都可以声明数据类型,也可以不用声明,那么,未声明数据类型的参数就是“用户自定义”类型。

[]是常规的表示方法,表示其中的内容可以有,也可以没有。

Exit Function:在过程中任意位置,都可以使用该语句结束该函数的计算过程。

End Function:函数过程的最终结束处。

过程:从Function起始 到 End Function结束,其中所有的内容称之为过程。

②设置参数

Function YJX(C As Single, K As Single, Optional G As Single, Optional JG As Integer = 0)

End Function

说明:

本次用YJX表示函数名称,C表示长,K表示宽,G表示高,JG表示结果样式 其中,G(高) 和JG(结果样式)参数不一定存在,所以声明为可选参数。

参数在声明数据类型时,语句必须是:变量名 As 类型名称

很显然,C(长)、K(宽)、G(高)都必须是数值,所以定义为Single(小数)

JG(结果样式)用整数来表示就足够了,我们可以设置为:

当JG=0时,输出公式的计算结果,当JG=1时,输出公式本身。

因为我们设置了Optional JG As Integer = 0,即没有这个参数时,就默认为输出计算结果。

因为该函数的输出结果可能是一个数值,也可以是一个文本,所以,不对该函数进行数据类型的声明。

我们在工作表中实际使用这个函数时,公式写法就是:

=YJX(长,宽[,高][,结果样式])

注意:当你计算的是矩形面积时,而且需要输出计算公式时,是没有高这个参数的,那就应该这样写:

=YJX(3,4,,1)——表示输出长=3宽=4的矩形面积公式

即,后面的可选参数没有时可以不管,但前面的可选参数没有时,必须加个逗号表示。

③定义变量

起始行以下,紧接着就是设置本过程的变量,当然,如果计算过程中不需要其他的变量,也可以不设置,本次设置一个变量 GS,该变量是程序在内存处理数据中使用,使用者在工作表使用函数时,不会涉及到。

Function YJX(C As Single, K As Single, Optional G As Single, Optional JG As Integer = 0)

Dim GS

End Function

说明:

定义变量的语句为:Dim 变量名称 As 数据类型名称

也可以使用类型通配符来表示,比如,Dim GS%,表示GS是一个整型变量。当不确定GS 只附值整数时,可以不用指定,让它成为一个用户自定义类型。

④检查错误

检查输入的参数是否正确,以及数据关系是否正常,是保证程序在处理数据时,不会因为数据错误而导致程序中断的必要保障,是任何一个程序员编程时必需要做的功课。假如我们的函数是这样的一个写法:= YJX(3,将军),即实际的计算公式为:3*将军,你认为它能计算出结果么?

所以,要养成在计算之前先检查变量错误的良好习惯,这样编写出来的代码才不会有BUG。

实际上,在自定义函数中,已定义了数据类型的变量是可以不用检查的,如果你已经定义了参数是Single(小数),而你输入的是String(文本)时,那程序会马上中断进程,工作表中会显示#VALUE!;如果你没有定义参数类型,即参数为用户自定义类型时,程序会使用该变量继续计算,直到发生错误后中断进程,但这样一来加重了系统的负担,让它多运算了一些内容,虽然表面上看起来,似乎也没有什么差别,但如果一个计算表中,有一万个函数在同时运算时,这种差别(计算延时)就很明显了。

本函数中,矩形或长方体的长宽高参数都应该是>0的,但如果参数的是负值,我们则认为是错的,但负值也是数值,程序可不知道你是怎么想的,如果你不要求程序检查这个错误,程序就认为参数是正确的,依旧会计算出结果来。所以必须添加对参数是否为负值的检查代码:If IsMissing(C) = False And C < 0 Then '如果 条件符合 那么 YJX = 1 / 0 ' 结果1

Exit Function

Else '否则

YJX = "正确" ' 结果2

End If '结束

说明:

对代码进行注释时,前面加’;注释可以单独写一行,也可以放在代码语句的后面。

IsMissing()为VB函数,作用是判断一个过程的参数是否存在,不存在时为True(真),存在时为False(假);VB中所有这种判断真假的函数,当判断条件为真时,可以省略 “= True”,比如:

If IsNumeric(C) Then '表示:如果JC是数值

If IsNumeric(C) = False Then '表示:如果JC不是数值

And和Or是逻辑运算符,And表示前后条件需要同时成立或同时不成立,Or表示前后条件只需要其中一个成立或不成立即可。

上面代码表示的意思是:如果参数C存在(IsMissing(C) = False)而且C < 0,则函数结果显示为“长小于0!”(结果1),并且退出进程,否则,函数显示“正确”(结果2)。

我们看到结果1有两个语句:

YJX = 1 / 0 '表示参数错误时,我们让函数结果为1/0,即它是个错误值

Exit Function '然后接着退出过程,即中断处理。

为什么要让YJX = 1 / 0呢?直接中断不就可以了么。如果是这样,那么错误参数的计算结果为0,0也是数值,你在数据表最后SUM汇总的结果也仍然是数值,如果数据表有成千上万行,那你根本就发现不了哪里出错了。让错误行的结果为#VALUE!,最后汇总的结果也是#VALUE!,这样你就很容易知道有数据行错误,再去找就容易找到了,反之,你根本就不会想到会有数据出错,简而言之,让YJX = 1 / 0就是给自己一个发现错误的提示。

那为什么又要Exit Function,前面已经说过了,不退出的话,程序会接着执行后面的操作,这样会加重系统运行的负担,也耽误时间。

If…Then…Else是经常用到的条件判断语句,必须熟练运用。

若要把该语句内容写成一行时,也可以这么写:

If IsMissing(C) = False And C < 0 Then YJX 1 / 0: Exit Sub Else YJX = "正确"

:表示将前后两个语句合并写在一行时的分隔符,多个语句如此操作时也一样。

以上YJX = "正确"(结果2)只是为了完整表现If…Then…Else语句而特意添加的,如果不需要结果2,可以省略:

If IsMissing(C) = False And C < 0 Then '如果 条件符合 那么

YJX 1 / 0 ' 结果1

Exit Sub

End If '结束

若要把该语句内容写成一行时,也可以这么写:

If IsMissing(C) = False And C < 0 Then YJX 1 / 0: Exit Function

对长宽高三个参数都依次检查完成后,我还要对变量JG(结果样式)进行检查。我们前面约定了,当JG=0时输出公式结果,JG=1时输出公式,但如果我们代入的参数是2或其他整数呢?那么程序也不知道该怎么办了,只好等于0,这样一来,结果仍是错误的,所以,我们仍然要检查变量JG的错误:

If JG <> 0 And JG <> 1 Then YJX = 1 / 0: Exit Function

如此,本节的代码如下:

Function YJX(Optional C As Single, Optional K As Single, Optional G As Single, Optional JG As Integer = 0)

Dim GS

If IsMissing(C) = False And C < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(K) = False And K < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(G) = False And G < 0 Then YJX = 1 / 0: Exit Function

If JG <> 0 And JG <> 1 Then YJX = 1 / 0: Exit Function

End Function

⑤可选参数的判断及计算过程

计算时,我们必须要考虑可选参数对计算的影响,因为有可选参数与没有可选参数会影响到我们实际的计算需要。

因为我们已经设置了Optional JG As Integer = 0,即无论我们在工作表中写不写这个参数,它实际都存在,我们只是需要判断它是0还是1即可。

而高却可能是不存在的,所以我们现在只需要判断参数G是否存在就可以了:

If IsMissing(G) Then

GS = C & "*" & K

Else

GS = C & "*" & K & "*" & G

End If

说明:

如果这个函数只需要输出公式的结果(数值),那我们可以不需要GS变量,代码可以直接写为:

If IsMissing(G) Then

YJX = C * K

Else

YJX = C * K * G

End If

就因为我们还想着要输出计算公式,所以,要先用变量GS来“装载”计算公式,无论最终的计算公式是什么,我们在最后直接处理这个GS的内容就可以得到结果了。

& 是连接符,表示把两个内容前后连接在一起。比如:3 & "*" & 4,表示“3*4”,如果是3 * 4就表示其计算结果12了;变量在和文本连接时,文本需要用双引号""括起来。

如此,本节的代码如下:

Function YJX(C As Single, Optional K As Single, Optional G As Single, Optional JG As Integer = 0)

Dim GS

If IsMissing(G) Then

GS = C & "*" & K

Else

GS = C & "*" & K & "*" & G

End If

过程代码

End Function

⑥输出结果

现在,我们有了计算公式,下一步就是根据实际需要来处理这个公式内容了:

If JG = 0 Then

YJX = Evaluate("=" & GS)

ElseIf JG = 1 Then

YJX = GS

End If

说明:

以上代码表示,当JG=0时,函数输出公式的计算结果(数值),当JG=1时,直接输出公式。

Evaluate()是宏表函数,其作用是返回一个计算公式的结果,注意其参数为"=" & 公式。

如此,全部的函数代码就完成了:

Function YJX(Optional C As Single, Optional K As Single, Optional G As Single, Optional JG As Integer = 0)

Dim GS

If IsMissing(C) = False And C < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(K) = False And K < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(G) = False And G < 0 Then YJX = 1 / 0: Exit Function

If JG <> 0 And JG <> 1 Then YJX = 1 / 0: Exit Function

If IsMissing(G) Then

GS = C & "*" & K

Else

GS = C & "*" & K & "*" & G

End If

If JG = 0 Then

YJX = Evaluate("=" & GS)

ElseIf JG = 1 Then

YJX = GS

End If

End Function

⑦调试

下面,我们回到工作表中,测试一下这个函数的效果。

为什么会发生这种情况呢?

原来,在D2和E2单元格的公式中,我们引用了C2(高)这个参数,而C2的内容是空,VBA认为空单元格的值为0,于是,这个公式的实际内容其实成了“=3*4*0”。

如果我们把D2单元格的公式改为“=YJX(A2,B2)”倒是也能计算出结果来,但D3单元格的公式却必须为“=YJX(A3,B3,C3)”,如此,我们就不能使用工作表的拖拽功能了,这样使用起来,就非常的麻烦,所以,我们即然是在编写VBA的自定义函数,就应该考虑到应用的对象是工作表,参数可能是引用单元格的特殊性。

所以,我们需要把代码修改为:

If IsMissing(G) Then

GS = C & "*" & K

Else

GS = C & "*" & K & "*" & IIf(G = 0, 1, G)

End If

说明:

IIf()为VB函数,与工作表函数IF()类似,它就相当于简单版的If…Then…Else语句。

这里把判断参数G,当单元格为空时(即G=0),我们就让它等于1,因为任何数值乘以1都等于那个数值,如果单元格有数值,再乘以那个数值。

下面,我们再来看看效果。

这次,计算结果完全正确,但是…

D2单元格的计算公式却为“3*4*1”,可实际C2单元格并没有内容,看来还得修改一下: If IsMissing(G) Then

JX01:

GS = C & "*" & K

Else

If G = 0 Then GoTo JX01

GS = C & "*" & K & "*" & G

End If

这次,增加了一个判断,当单元格为空时(即G=0),程序按没参数G来编写公式。

这里,GoTo 语句的作用是让程序执行到这里时,直接跳到指定的程序标签处。那么,过程中必须存在这样一个标签,标签命名规则与变量相同,且以:结束,:后面不能跟有其他代码,否则那就成两个相连的语句了,而不是标签。

好,我们再来看看效果:

完全符合最初的要求,最后的代码如下:

Function YJX(Optional C As Single, Optional K As Single, Optional G As Single, Optional JG As Integer = 0)

Dim GS

If IsMissing(C) = False And C < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(K) = False And K < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(G) = False And G < 0 Then YJX = 1 / 0: Exit Function

If JG <> 0 And JG <> 1 Then YJX = 1 / 0: Exit Function

If IsMissing(G) Then

JX01:

GS = C & "*" & K

Else

If G = 0 Then GoTo JX01

GS = C & "*" & K & "*" & G

End If

If JG = 0 Then

YJX = Evaluate("=" & GS)

ElseIf JG = 1 Then

YJX = GS

End If

End Function

⑧功能拓展

虽然上面的结果达到了目的,但这样就不会有问题了么?不,其实我们在实际使用过程中,还会经常遇到象这样的情况:

从上面来看,不光是变量G(高)可能不存在,连变量C(长)和变量K(宽)也有可能是不存在的,所以,我们还需要进一步的完善。

既然变量C和变量K也可能不存在,那么,变量C和变量K就都得设为可选参数,如此,从头开始修改:

Function YJX(Optional C As Single, Optional K As Single, Optional G As Single, Optional JG As Integer = 0)

然后把先前对可选参数是否存在的判断修改为判断变量是否=0,即判断单元格是否为空。

GS = Iif(C > 0, C, “”) & _

Iif(C > 0 And (K > 0 Or G > 0), “*”, “”) & _

Iif(K > 0, K, “”) & _

Iif(K > 0 And G > 0, “*”, “”) & _

Iif(G > 0, G, “”)

说明:

_ 为换行符,当一行的内容太长时,可以使用 _ 换行。

最后再检查一下效果:

好,完全符合我们的要求。

全部的代码如下:

Function YJX(Optional C As Single, Optional K As Single, Optional G As Single, Optional JG As Integer = 0)

Dim GS

If IsMissing(C) = False And C < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(K) = False And K < 0 Then YJX = 1 / 0: Exit Function

If IsMissing(G) = False And G < 0 Then YJX = 1 / 0: Exit Function

If JG <> 0 And JG <> 1 Then YJX = 1 / 0: Exit Function

GS = IIf(C > 0, C, "") & _

IIf(C > 0 And (K > 0 Or G > 0), "*", "") & _

IIf(K > 0, K, "") & _

IIf(K > 0 And G > 0, "*", "") & _

IIf(G > 0, G, "")

If JG = 0 Then

YJX = Evaluate("=" & GS)

ElseIf JG = 1 Then

YJX = GS

End If

End Function

⑨最终修改

其实我们从上图还发现了一个不完善的地方,第6行的参数宽为0,但这个0是写在单元格里的,并不是单元格为空,这有可能是手误,比如将10打成0了,而现在的代码是不能发现这种错误的,因为单元格为空,且参数的数据类型为Single(数值),不管单元格是空还是0,它都会自动附值为0,这也是VBA与VB的差别所在。但我们又想发现这种错误,那只有重新定义参数的数据类型,由此可见,声明变量的数据类型会对数据处理的影响有多大。

重新修改的代码如下:

Function YJXR(Optional C As Range, Optional K As Range, Optional G As Range, Optional JG As Integer = 0)

Dim GS

If JG <> 0 And JG <> 1 Then YJXR = 1 / 0: Exit Function

If IsMissing(C) = False Then

If YZS(C) <> -3 And YZS(C) <= 0 Then YJXR = 1 / 0: Exit Function If YZS(C) > 0 Then GS = C

End If

If IsMissing(K) = False Then

If YZS(K) <> -3 And YZS(K) <= 0 Then YJXR = 1 / 0: Exit Function If YZS(K) > 0 Then

If Len(GS) > 0 Then GS = GS & "*" & K Else GS = K

End If

End If

If IsMissing(G) = False Then

If YZS(G) <> -3 And YZS(G) <= 0 Then YJXR = 1 / 0: Exit Function If YZS(G) > 0 Then

If Len(GS) > 0 Then GS = GS & "*" & G Else GS = G

End If

End If

If JG = 0 Then

YJXR = Evaluate("=" & GS)

ElseIf JG = 1 Then

YJXR = GS

End If

End Function

修改说明:

本次将函数名修改为YJXR,区别前面那个函数YJX,意思为这个函数只能用于计算单元格,而前面那个函数可以在工作表和程序内部使用,但它不能判断单元格为空的情况。

参数重新定义为Range数据类型,这个数据类型在前面的表格里录入,因为它是专为EXCEL VBA定制的一个数据类型,只能用于处理单元格变量。这也就是为什么这个函数要分成两种的原因,由于这是程序语言本身的限制所决定,仅靠代码是无法兼容的,所以,具体使用时,可以根据不同的需要来分别使用这两个函数。

本次将检查错误和编写计算公式(蓝粗字)的步骤合并起来,当检查一个参数没有错误时,就直接写出相应的计算公式,而不必等到最后再统一编写了。至于计算公式为什么这么写,可以根据我前面所讲的附值规则思考一下。

Len()是VB函数,作用是返回一个字符串的字符数量,当这个字符串没有内容,即它是空的时候,结果=0。

YZS()是我编写的另一个自定义函数,用来判断数据是哪种类型的,正面我一并附上这个函数的代码,使用方法可以参考它的说明。

'■■■■■■YZS(字符串,类型判断)函数■■■■■■

'判断字符串的数值类型

'字符串为真假值——返回-6

'字符串为错误值——返回-5

'字符串为文本值——返回-4

'字符串为 空 ——返回-3

'字符串为负小数——返回-2

'字符串为负整数——返回-1

'字符串为 0 ——返回 0

'字符串为正整数——返回 1

'字符串为正小数——返回 2

'类型判断为0,字符串为整数——返回 True

'类型判断为1,字符串为奇数——返回 True

'类型判断为2,字符串为偶数——返回 True'

'修改日期:2017-11-12 增加判断真假值=-6

Function YZS(Vax, Optional Lax)

If IsMissing(Lax) Then

If IsError(Vax) Then YZS = -5: Exit Function '数据为错误值

If Len(Vax) = 0 Then YZS = -3: Exit Function '数据为空

If IsNumeric(Vax) = False Then YZS = -4: Exit Function '数据为文本值 If Val(Vax) = 0 And Left(Vax, 1) <> "0" Then YZS = -6: Exit Function '数据为真假值

If Vax = 0 Then YZS = 0: Exit Function

If InStr(Vax, ".") > 0 Then

If Vax > 0 Then YZS = 2 Else YZS = -2 '数据为小数

Else

If Vax > 0 Then YZS = 1 Else YZS = -1 '数据为整数

End If

Else

If Lax = 0 Or Lax = 1 Or Lax = 2 Then

If IsNumeric(Vax) = False Then YZS = False: Exit Function

If Len(Vax) = 0 Then YZS = False: Exit Function

If InStr(Vax, ".") > 0 Then YZS = False: Exit Function

If Lax = 0 Then '判断数值是否为整数

YZS = True

ElseIf Lax = 1 Then '判断数值是否为奇数

If InStr(Vax / 2, ".") > 0 Then YZS = True Else YZS = False ElseIf Lax = 2 Then '判断数值是否为偶数

If InStr(Vax / 2, ".") > 0 Then YZS = False Else YZS = True End If

End If

End If

End Function

最后再次检查一下使用效果:正确!

excel利用vba定义函数的教程全解

excel利用vba定义函数的教程全解 用vba定义函数步骤1:例:下面表格中需要计算一些三角形的 面积 用vba定义函数步骤2:B列是底边长,C列是高,要求在D列 通过公式计算三角形面积。 (通常我们会在D3单元格用公式=B3*C3/2来计算,然后把这个 公式向D列下方拖动复制,得到其他公式。这只是一个简单的例子,通过它来学习编写简单的自定义函数) 用vba定义函数步骤3:打开VBA窗口 按ALT+F11调出VBA窗口,插入一个用户模块。 用vba定义函数步骤4:编写代码 把下面这个自定义函数代码粘贴到刚插入的用户模块中就可以使用了。 Functionsjxmj(di,gao) sjxmj=di*gao/2 EndFunction 这段代码非常简单只有三行,先看第一行,其中sjxmj是自己取的函数名字,括号中的是参数,也就是变量,di表示“底边长”,gao表示“高”,两个参数用逗号隔开。 再看第二行,这是计算过程,将di*gao/2这个公式赋值给sjxmj,即自定义函数的名字。 用vba定义函数步骤5:使用自定义函数 用vba定义函数步骤6:通过上面例子可以了解自定义函数的编 写和使用方法,下面再介绍一个稍微复杂点的自定义函数。

经常对数据进行处理的朋友可以会遇到多条件查找某一个数据,一般这种情况需要编写“数组公式”来解决,公式较长,也不易理解。 比如下面统计成绩的表格,需要根据A1:D7的成绩表,统计出两门功能都在90分以上的学生人数。 大家可以看到在H3单元格中的公式比较长,理解起来也有一定难度。 我们通过自定义函数也可以得到正确结果,函数代码如下: Function统计(a,b,c,d,e) Fori=1Toa.Rows.Count Ifb=a.Cells(i,1)Anda.Cells(i,c)>=eAnda.Cells(i,d)>=eThen 统计=统计+1 EndIf Next EndFunction 这个函数用了五个参数(因为涉及到一个区域和四个条件) 参数a表示要统计的区域,在此例中为B2:E7 参数b表示要统计的是哪一个班级,在此例中为G3单元格 参数d表示数学成绩相对于区域第一列向右的列数,在此例中为4 参数e表示分数,在此例中为90分 提示:要注意参数c和d“相对”于“区域”的列数,并非是从A列开始向右的列数。 把上面这段代码也粘贴到用户模块中就可以使用了

EXCEL VBA 新个人所得税税率自定义函数IN_TAX()及用法

Excel VBA新个人所得税税率自定义函数in_tax()及用法1、VBA代码 Public Function in_tax(in_month As Single)As Single Dim sl As Single,kcs As Single,ynse As Single'定义税率sl,扣除数kcs,应纳税额ynse变量 ynse=in_month-3500 Select Case ynse Case0To1500'如果应纳税额<=1500,税率3%,速算扣除数0。 sl=0.03 kcs=0 Case1501To4500'如果应纳税额(1500,4500],税率10%,速算扣除数105。 sl=0.1 kcs=105 Case4501To9000'如果应纳税额(4500,9000],税率20%,速算扣除数555。 sl=0.2 kcs=555 Case9001To35000'如果应纳税额(9000,35000],税率25%,速算扣除数1005。 sl=0.25

kcs=1005 Case35001To55000'如果应纳税额(35000,55000],税率30%,速算扣除数2755。 sl=0.3 kcs=2755 Case55001To80000'如果应纳税额(55000,80000],税率35%,速算扣除数5505。 sl=0.35 kcs=5505 Case Else'如果应纳税额>80000,税率45%,速算扣除数13505。 sl=0.45 kcs=13505 End Select If ynse<=0Then in_tax=0 Else in_tax=Round(ynse*sl-kcs,2) End If End Function 2、使用方法

史上最全面的计算简体繁体汉字笔画的VBA自定义函数及汉字笔画字库

Function char_wordnum(my_char_word) '史上最权威最全面的计算简体繁体汉字笔画的VBA自定义函数及汉字笔画字库 'from bdQuaker 20140619 '笔画数据库来自在线新华字典 https://www.360docs.net/doc/ad8424554.html, 'VBA中一条语句内的换行符号,不能超过25个。 '函数功能:对输入的汉字,返回其笔画的数量。 Dim char_wordtable(31), wordnum_i, wordnum_j, wordnum_k, temp_wordnum temp_wordnum = "" If my_char_word = "" Then char_wordnum = 0 Exit Function End If char_wordtable(0) = "" char_wordtable(1) = "" char_wordtable(2) = " " char_wordtable(3) = " 亏马亇么门宀万卄女丬丌乞千犭刃刄三山彡上勺饣士尸扌氵巳纟" + _ "夊土乇丸亾兦亡尢囗卫?兀习夕下乡小忄彐卂劜丫幺也弋亿已义于亐与丈夂之子" char_wordtable(4) = "卬夭仈巴办勽贝币比卞仌不仓长尺车丑丒仇刅从亣歹丹邓弔订仃斗队仒厄乏反方分凤 " + _ " " + _ "闩双水亖太天邒厅圡屯屲瓦卐卍罓尣王韦厃为文毋勿午五乌兮心匂凶牙圠爻辷忆刈艺以弌冘引尹尤友肀予元円月曰匀云勻允帀扎兂仄仉爫爪止支中专卆" char_wordtable(5) = "艾屵凹叐叭扒白半包北本夯必弁边丙氷仢癶布卟仺册冊仧仩仦斥叱叺刍処出处丛匆刌打代歺旦石氹辺忉叨氐电叼汈鸟饤忊艼奵帄叮东冬乧叾对戹弍尓尔尒发犯氾払" + _ "冯弗付玍尕轧匃匄仠甘冮夰乬巪仡功句古冎叧瓜叏丱広宄氿归扖邗汉厈号禾仜弘讧乎囘卉屶屷汇伋记饥刉击叽甲加戋匞叫艽讦节钅丼冋匛旧纠凥且卡冚刊尻厼可叩" + _ "凷圦邝兰艻叻扐氻忇乐立厉屴礼辽另令龙卢圥劢邙矛夘卯们汅灭民皿末仫目母奶艿疒尼囜宁奴汃皮庀丕氕平叵圤扑讫邔刋阡仟巧邛卭芁叴犰扏囚玌丘去厺犮冉让讱" + _ "仞仭辸扔宂邚仨壭讪闪邖叶申圣生辻仕世丗示市史矢失朮术帅甩氺四丝司玊亗他它夳冭台叹讨夲朰田芀圢庁汀仝头凸阤仛讬外罒未戊阢务卌邜仚仙屳写阠兄玄穴廵" + _ "讯训疋圧央业凧匇匜仪肊议阣衤印囙用永由甴幼右邘驭玉込夗戉曱孕匝仔庂汄札乍占仗召厇氶正卮汁只主左" char_wordtable(6) = "吖阨伌安犴仰朳玐百阪邦闭毕朼夶邠冰并伧艸奼汊扱扠犲芆忏产辿伥场仯伡尘臣丞成朾弛池驰伬吃充冲虫岀汌舛传闯创朿次此汆伜存忖邨达汏刐伔凼圵当乭导氘朷" + _

“四舍六入五单双”利用VBA自定义函数解决

利用VBA自定义函数解决 业务研究加入时间:2007-3-9 20:42:35 点击:504 Microsoft Office套装办公软件是大家十分熟悉的办公软件,在工作中经常使用。但在水文工作中,仍然感觉到有很不方便的时候!比如,水文行业广泛使用的“四舍六入五单双”,就很难用Microsoft Office中的内部函数进行处理。但是与Microsoft Office套装办公软件绑定的VBA(Visual Basic For Application)语言提供了强大的二次开发功能,笔者以Excel为例,用它来解决上面所提到的问题,就非常容易了。 一、水文及水质资料使用的“四舍六入五单双”,执行《数值修约规范》(GB8170-87)1.拟舍弃数字的最左一位数字小于5时,则舍去,即保留的各位数字不变。 2.拟舍弃数字的最左一位数字大于5时;或者是5,而其后跟有并非全部为0的数字时,则进一,即保留的末位数字加1。 3. 拟舍弃数字的最左一位数字为5,而后面无数字或皆为0时,若所保留的末位数字为奇数(1,3,5,7,9)则进一,为偶数(2,4,6,8)则舍弃。 二、初识VBAIDE 打开Excel,按Alt+F11即进入VBAIDE,在菜单上依次点击[插入]->[模块],然后输入如下代码: ' “四舍六入五单双”自定义函数 ' 函数形式 Round5(x,mm),返回值Round5为 Double 型 ' X为操作数值,mm为保留小数位数 ' mm为 Integer 型,mm = 0 表示取整数 Private Function round5(X As Double, mm As Integer) As Double Dim Temp1, Temp2 As String Temp1 = 1 If mm < 0 Then Temp1 = 10 ^ Abs(mm) X = X / Temp1 mm = 0 End If If ((Int((Abs(X) - Int(Abs(X))) * 10 ^ mm) Mod 2) = 0 And (Abs(X) * 10 ^ mm - Int(Abs(X) * 10 ^ mm)) <= 0.5) And X <> Val(Round(Abs(X), mm) * Sgn(X)) Then round5 = Val((Round(Abs(X) - 10 ^ (-mm) / 5, mm))) Else round5 = Val(Round(Abs(X), mm)) End If round5 = Val( round5 * Sgn(X) * Temp1) End Function 以上程序是在“取绝对值(Abs)”、“取整(Int)”、“四舍五入(Round)”等系统内部函数的基础上完成的,函数的型式及其每个参数需要用户在属性设置中定义和声明,故叫做自定义函数。以上定义“四舍六入五单双”的函数名为Round5,定义成功后便可在Excel 中象系统函数那样引用了,例如对编辑完后按Alt+Q即返回Excel,再在某一单元格输入“= Round5(A1,3)”(A1既可以是单元格,也可以是输入的数值),回车结果就出来了。如果出现

excel中161个VBA_自定义函数(超级实用)(精)

目录 '1.函数作用:返回 Column 英文字 (9) '2.函数作用:查询某一值第num 次出现的值................9 '3.函数作用:返回当个人工资薪金所得为2000元(起征点为850元时的应纳个人所得税税额.............................10 '4.函数作用:从形如"123545ABCDE"的字符串中取出数字....11 '5.函数作用:从形如"ABCD12455EDF"的字符串中取出数字...11 '6.函数作用:按SplitType 取得RangeName 串值中的起始位置12 '7.函数作用:将金额数字转成中文大写....................13 '8.函数作用:计算某种税金..............................18 '9.函数作用:人民币大、小写转换........................19 '10.函数作用:查汉字区位码.............................20 '11.函数作用:把公元年转为农历.........................21 '12.函数作用:返回指定列数的列标.......................42 '13.函数作用:用指定字符替换某字符.....................43 '14.函数作用:从右边开始查找指定字符在字符串中的位置...43 '15.函数作用:从右边开始查找指定字符在字符串中的位置...44 '16.函数作用:计算工龄.................................44 '17.函数作用:计算日期差,除去星期六、星期日.. (45) '18.函数作用:将英文字反转的自定函数 (46) '19.函数作用:计算个人所得税...........................46 '20.函数作用:一个能计算是否有重复单元的函数...........47 '21.数字金额转中文大写................................48 '22.函数 作用:将数字转成英文...........................49 '23.函数作用:人民币大小写转换.........................52 '24.函数作用:获取区域颜色值...........................53 '25.函数作用:获取活动工作表名.........................53 '26.函数作用:获取最后一行行数. (54) '27.函数作用:判断是否连接在线.........................54 '28.函数作用:币种转换.................................54 '29.函数作用:检验工作表是否有可打印内容...............55 '30. 函数作用:查找一字符串(withinstr在另一字符串中(findstr1中某一次(startnum出现 时的位置,返回零表示没找到。..................................................57 '31.函数作用:增加文件路径最后的“\”符号..............58 '32.函数作用:计算所得税...............................58 '33.函数作用:从工作表第一行的标题文字以数字形式返回所在列号..................................................58 '34.函数作用:在多个工作表中查找一个范围内符合某个指定条件的项目对应指定范围加总求和..........................59 '35.函数作用:返回

Excel VBA编程 调用函数

Excel VBA 编程 调用函数 调用函数时,为了使用函数的返回值,必须指定函数给变量,并且用括号将参数封闭起来。 语法:函数过程名([参数列表]) 由于函数过程名返回一个值,故函数过程不能作为的单独语句加以调用,必须作为表达式或表达式的一部分,然后再配以其他的语法成分构成语句。 在调用函数之前,应首先来定义一个函数,如定义一个myreplace(S,Olds,NewS)函数过程,即用News 子字符串替换在S 字符串中出现的OldS 字符串。 例如,下面的程序是对前面自定义的函数过程CalculateSquareRoot 的调用,其代码如下: Private Sub CommandButton1_Click() Dim a a = InputBox("请输入数字") '调用CalculateSquareRoot 函数 MsgBox "计算平方根:" & CalculateSquareRoot(CInt(a)) End Sub 返回工作表中,单击【计算平方根】按钮,在弹出的如图9-3所示的对话框中,输入数字 25。然后,单击【确定】按钮,即可弹出如图9-4所示的效果。 图9-3 输入数字 图9-4 显示结果 注 意 “参数列表”称为实参或实元,它必须与形参保持个数相同,位置与类型一一对应。其中,实参可以是同类型的常数、变量、数组元素或表达式。 另外,在Visual Basic 中,通过WorksheetFunction 对象可使用Excel 工作表函数。例如,以下Sub 过程使用Min 工作表函数来确定单元格区域中的最小值,其代码如下: Sub UseFunction() Dim myRange As Range Set myRange = Worksheets("Sheet1").Range("A1:C10") answer = Application.WorksheetFunction.Min(myRange) MsgBox answer End Sub 从上述的代码可以观察到,用户将变量myRange 声明为Range 对象,然后将其设置为Sheet1上的A1至C10单元格区域。指定另一个变量answer 为对myRange 应用Min 函数的结果。最后,answer 的值显示在消息框中,效果如图9-5所示。 输入 单击

用VBA编写Excel自定义的累加函数

用VBA编写Excel自定义的累加函数 郑云勇 云南楚雄思远投资有限公司 摘要:Excel是常用的数据统计分析软件,本文介绍了用VBA编写加载宏的方法来扩展、定制Excel,以适合工程统计专业的特殊需要。下面,讨论如何实现一个自定义的具有任意合计形如“30.2m/165.45m3”的“分子/分母”工程量统计功能的函数,由于Sum函数系统已经内置,我们要实现的函数不妨命名为uLSum和uRSum。 关键词:Excel,定制,加载宏 1引言 电子表格软件Microsoft Excel具有快捷方便的数据输入方式和强大的数据处理能力,是工程地质中常用的数据统计分析软件,为我们的工作带来了极大的方便。但Excel毕竟只是一个通用的办公软件,对于工程专业中的各种特殊需求,它自然不会有专门的功能支持。比如:采矿工程师在做每年的采掘生产计划时,通常遇到要累加掘进工程量的合计数,即“30.5/125.6”加“120.2/625.8”的合计,我们通常的做法是分步完成,先将分子之、分母之和求出来后,在填入单元格中。或者将分子、分母分别填入两列中,分别用sum函数求和。这样既劳神,又容易出错,特别是对大量数据进行复杂的公式计算。如果从头编写一个独立、专门的计算程序来处理,则似有小题大作之嫌,而且还不能与Excel无缝集成。那么有

没有更好的解决办法呢?答案是肯定的,那就是定制Excel,通过编程扩展它的功能。 事实上,Excel作为Microsoft最优秀的软件之一,很早就开始提供了二次开发的接口,4.0版以前有XLM,4.0版又发布了Excel C API,5.0版则内置了VBA。现在的Excel,除了人所共知的操作功能外,还是一个完善的软件开发平台。它拥有完备的ActiveX Automation服务器和客户机机制,可以通过编程对其进行全方位的扩展、定制,实现各种自定义功能。基于ActiveX Automation技术,使用C/C++等多种支持Automation的编程语言均可控制Excel,但我们最为熟悉和常用的还是内置于Excel中的VBA。 2VBA简介 Visual Basic for Application(VBA)是Microsoft面向最终用户的应用软件编程语言。它最早出现于Microsoft的Excel和Project中,如今VBA已成为VB和所有Office产品的组件。另外,越来越多的软件开发商购买了VBA语言的使用权,如常用的绘图软件AutoCAD等均已支持VBA作为二次开发工具。这意味着我们懂得VB,就已经懂得了VBA,反之亦然。 VBA的最大特点和最大优点是利用面向对象(OOP)的ActiveX Automation技术,使语言的引擎在技术上与开发环境分离,这可以从在任何VBA的IDE环境中都可以看到VBA单独的入口得到印证。因此,VBA的功能在很大程度上依赖于它的客户显露的Automation 接口,例如,VB与Office套件中的VBA,能完成的功能就大不一样。

原创—EXCEL VBA SPC自定义函数包括CPK PPK CP……

'################## stdevR=average(max-min)/R系数组内差 Function stdevR(ParamArray rng() As Variant) As Variant Dim rang As Range, rngi As Range, T As Single, F As Single, i As Integer, e As Integer Dim trr Dim arr() Dim brr() For Each r In rng If rang Is Nothing Then Set rang = r Else Set rang = Union(rang, r) For Each c In r Next Next n = rang.Cells.Count aa = rang.Columns.Count bb = rang.Rows.Count cc = Application.WorksheetFunction.Ceiling(n / 5, 1) If aa > 1 Then ReDim arr(1 To bb) For i = 1 To bb Set rngi = rang(i, 1).Resize(1, aa) arr(i) = Application.Max(rngi.Value) - Application.Min(rngi) Next F = Application.WorksheetFunction.Average(arr) trr = [{0,1.128,1.693,2.059,2.326,2.534,2.704,2.847,2.97,3.078,3.173,3.258,3.336,3.407,3.472,3.532,3.58 8,3.64,3.689,3.735,3.778,3.819,3.858}] T = trr(aa) stdevR = F / T Else e = 0 ReDim brr(1 To cc) For i = 1 To cc Set rngi = rang(1, 1).Resize(5, 1).Offset(e, 0) brr(i) = Application.Max(rngi.Value) - Application.Min(rngi) e = e + 5 Next F = Application.WorksheetFunction.Average(brr) T = 2.326 stdevR = F / T End If End Function '################## ppk=min(ppu,ppl)=(1-k)*pp 整体的过程能力指数带中心值的 Function ppk(USL As Variant, LSL As Variant, ParamArray rng() As Variant) As Variant Dim AV As Single, rang As Range, n As Integer, T As Single, SumN As Single, SE As Single, k As Single For Each r In rng If rang Is Nothing Then Set rang = r Else Set rang = Union(rang, r) For Each c In r

VBA自定义函数选合集(代码注释)

自定义函数选 附代码注释 By 蓝桥玄霜 前言 我们平时在工作表单元格的公式中常常使用函数,Excel自带的常用的函数多达300多个,功能强大,丰富多彩,博大精深。在Excel内置函数和扩展函数中有十多个应用领域的函数,如数学与三角函数、统计函数、文本和数据函数、查找和引用函数、数据库函数、财务函数、日期和时间函数、信息函数、工程函数和宏表函数等等。 但是我们每个人还可能有各种各样的问题而不能直接应用这些函数得到解决,于是Excel也提供了VBA可以让我们自己编一个自定义函数来解决自己特定的需求。以下挑选一些自定义函数,由简到繁,附以代码注释,供大家参考。 第1例折扣函数 一、题目: 要求编写一个当销售数量大于等于100时,售价打九折的计算折扣的自定义函数。二、代码: Function Zekou(sul, jiag) As Double If sul>=100 Then Zekou =sul*jiag*0.1 Else Zekou =0 EndIf Zekou =Application.Round(Zekou,2) End Function 三、代码详解 1、Function Zekou(sul, jiag) As Double :自定义函数的开始语句。 自定义函数总是以Function开头,以End Function语句结束。自定义函数的代码一定要放在标准模块里面。 Zekou是函数名,名字可取一个较短的描述信名称,这样容易记忆。如sul数量和jiag 价格,这里用的是拼音字母。函数后括号里的两个变量叫做函数的参数。两个参数都没有显式声明数据类型,都是可变型数据类型variant。AS Double 表示函数返回值的数据类型是双精度浮点型数据。 2、If sul>=100 Then 如果sul(数量)大于等于100,那么 这是标准的If…Then…Else判断语句,意思是如果第一个条件成立,或者说满足了第一个条件,那么执行Then以后的语句;否则执行Else以后的语句。

excel自定义函数编写方法

Excel自定义函数基础教程 1.总述、编写环境与设置 自定义函数功能是Excel中一个强大的扩展功能,它可以实现不同用户的特定计算要求。以使得Excel计算自主化、专业化,可以大大简化人工劳动(查表、专业公式计算、统计等)。所以编写与使用自定义函数应是每个工程计算人员必不可少的技能。本教程为零基础教程,特为呼和浩特职业技术学院编写,如需引用或咨询请联系526949738@https://www.360docs.net/doc/ad8424554.html,。 本教程以Excel2003为平台讲解,使用其他版本Excel的同学请参照学习。自定义函数需要应用宏编写,请进行如下设置。 工具—>宏—>安全性

写的宏了。 辑器,在弹出的窗口点击插入—>模块,即进入了编写环境。

选中相应的模块点击文件—>导出文件,就可以存储.bas的源文件。这样就可以方便存储整理,以便日后引用。 2.宏的概念与Visual Basic基础 有VB编程基础的同学可跳过此章。 宏实际上就是一段用以完成某些功能的源代码,Excel中的

宏以Visual Basic(以后简称VB)编写,存储后的.bas文件可以用记事本打开,里面记录的就是编写的代码。 VB是一门高级编程语言,其语法简单易于掌握,适合初学者学习。本教程中只对VB进行初步讲解,如果需要深入学习请参照VB相关的专门书籍(Visual Basic编辑器中的帮助也有详细介绍)。 顺序、选择、循环是编程的三种结构,合理组合嵌套这三种结构就可以解决所有编程问题。默认情况下,代码按照顺序结构执行,所以下面只介绍选择和循环结构的语句表达。 选择结构: 选择结构非常常见,它的作用是使程序根据条件的不同执行不同的语句。这里我们只介绍最简单的一种语句。 If condition Then [statements] [Else elsestatements] 或者 If condition Then [statements] [ElseIf condition-n Then [elseifstatements] ... [Else [elsestatements]] End If 注释:condition:条件表达式;statements:执行语句;[]中的内容为可选内容。

EXCEL-VBA自定义角度转换函数

'1、角度转换函数 '1.1---“度分秒”化“度”函数 '注:“度分秒”->“度”的角度单位转化 Public Function 度分秒_度(C2 As Double) Dim FuHao As Integer, C1 As Double Dim Du As Integer, Fen As Integer, Miao As Double FuHao = Sgn(C2) C1 = C2 + 0.0000000000001 * FuHao C1 = Abs(C1) Du = Int(C1) Fen = Int(C1 * 100) - Int(C1) * 100 Miao = (C1 * 100 - Int(C1 * 100)) * 100 If Fen >= 60 Or Miao >= 60 Then 度分秒_度 = "输入有误!" Exit Function End If 度分秒_度 = FuHao * (Du + Fen / 60 + Miao / 3600) End Function '1.2---“度.分秒”化“弧”函数 Public Function 度分秒_弧(度分秒 As Double) As Double Dim FuHao As Integer, C1 As Double Dim 度 As Integer, 分 As Integer, 秒 As Double FuHao = Sgn(度分秒) C1 = 度分秒 + 0.0000000000001 * FuHao C1 = Abs(C1) 度 = Int(C1) 分 = Int(C1 * 100) - Int(C1) * 100 秒 = (C1 * 100 - Int(C1 * 100)) * 100 If 分 >= 60 And 秒 >= 60 Then 度分秒_弧= "“分秒”输入有误!" Exit Function End If If 分 >= 60 Then 度分秒_弧= "“分”输入有误!" Exit Function

推荐-Excel中自定义函数实例剖析 精品

Excel中自定义函数实例剖析 稍有Excel使用经验的朋友,都知道Excel内置函数的快捷与方便,它大大增强了Excel数据计算与分析的能力。不过内置的函数并不一定总是能满足我们的需求,这时,就可以通过定义自己的函数来解决问题。 一、认识VBA 在介绍自定义函数的具体使用之前,不得不先介绍一下VBA,原因很简单,自定义函数就是用它创建的。VBA的全称是Visual Basic for Application,它是微软最好的通用应用程序脚本编程语言,它的特点是容易上手,而且功能非常强大。 在微软所有的Office组件中,如Word、Access、Powerpoint等等都包含VBA,如果你能在一种Office组件中熟练使用VBA,那么在其它组件中使用VBA的原理是相通的。 Excel中VBA主要有两个用途,一是使电子表格的任务自动化;二是可以用它创建用于工作表公式的自定义函数。 由此可见,使用Excel自定义函数的一个前提条件是对VBA基础知识有所了解,如果读者朋友有使用Visual Basic编程语言的经验,那么使用VBA 时会感觉有很多相似之处。如果读者朋友完全是一个新手,也不必太担心,因为实际的操作和运用是很简单的。 二、什么时候使用自定义函数? 有些初学Excel的朋友可能有这样疑问:Excel已经内置了这么多函数,我还有必要创建自己的函数吗?

回答是肯定的。原因有两个,它们也正好可以解释什么时候使用Excel自定义函数的问题。 第一,自定义函数可以简化我们的工作。 有些工作,我们的确可以在公式中组合使用Excel内置的函数来完成任务,但是这样做的一个明显缺点是,我们的公式可能太冗长、繁琐,可读性很差,不易于管理,除了自己之外别人可能很难理解。这时,我们可以通过使用自定义函数来简化自己的工作。 第二,自定义函数可以满足我们个性化的需要,可以使我们的公式具有更强大和灵活的功能。 实际工作的要求千变万化,仅使用Excel内置函数常常不能圆满地解决问题,这时,我们就可以使用自定义函数来满足实际工作中的个性化需求。 上面的讲述比较抽象,我们还是把重点放在实际例子的剖析上,请大家在实际例子中进一步体会,进而学会在Excel中创建和使用自定义函数。 三、自定义函数实例剖析 下面我们通过两个典型实例,学习自定义函数使用的全过程。这里实际上假设读者朋友都有一定的VBA基础。 假如你完全没有VBA基础也不要紧,当学习完实例后,若觉得自定义函数在自己以后的工作中可能用到,那么再去补充相应的VBA基础也不迟。 (一) 计算个人调节税的自定义函数 任务 假设个人调节税的收缴标准是:工资小于等于800元的免征调节税,工资800元以上至1500元的超过部分按5%的税率征收,1500元以上至2000元的超过部分按8%的税率征收,高于2000元的超过部分按20%的税率征收。 分析

vba自定义函数小结

小结: 函数参数前面标记byval,实现的是实参与形参之间的值传递,即形参具有了实参的值或者说建立了一个实参的副本给了形参,这样对形参的操作不会影响实参; 函数参数前面标记byref,实现的是实参与形参之间的引用传递,这样对形参的操作会影响实参,或者说对形参的操作等同于对实参的操作; 在函数内部使用“r=形参”,实现的是把形参的副本给r,在函数中对r操作不会影像形参,如果使用“set r=形参”,那么对r的操作会影响形参,这里实现的效果是r只是形参的一个别名而已,所以对r 的操作等同于对形参的操作。 在函数中形参前面不标记byref和byval,默认是引用传递byref,但是这种情况下如果实参是excel中worksheet的range区域,则默认是值传递。 有时调试结果不符合预期,比如值传递,对””r=形参”中的r操作,居然影响形参了,这可能是由于excel一时程序错乱导致,关闭重启就好了。 Public Function tjbcf(rng) r = rng 'Set r = rng'注意带着set是错误的 k = 0 If UBound(r, 1) > 1 And UBound(r, 2) = 1 Then For i = 1 To UBound(r, 1) f = 0 For j = 1 To i - 1 If r(i, 1) = r(j, 1) Then

f = 1 Exit For End If Next j If f = 0 And r(i, 1) <> "" Then k = k + 1 End If Next i End If If UBound(r, 1) = 1 And UBound(r, 2) > 1 Then For i = 1 To UBound(r, 2) f = 0 For j = 1 To i - 1 If r(1, i) = r(1, j) Then f = 1 Exit For End If Next j If f = 0 And r(1, i) <> "" Then k = k + 1 End If Next i End If If UBound(r, 1) > 1 And UBound(r, 2) > 1 Then For i = 1 To UBound(r, 1) For j = 1 To UBound(r, 2) If r(i, j) = "" Then f = 1 GoTo kk End If f = 0 For m = 1 To i - 1 For n = 1 To UBound(r, 2) If r(i, j) = r(m, n) Then f = 1 GoTo kk End If Next n Next m For n = 1 To j - 1

EXCEL自定义函数(反算正算角度化弧度)(精)

EXCEL自定义函数(反算、正算、角度化弧度)在Excel中建立自定义函数 一、建立自定义函数 ㈠、录制宏: ①、打开一个新的Excel工作薄 ②、选择“工具”菜单中的“宏”子菜单,从它的下级菜单中选择“录制新宏” ③、在“录制新宏”对话框的“宏名”中输入要建立的函数名,例:Rad ④、在“保存在”列表中选择“个人宏工作薄” ⑤、左击“确定” ⑥、在“停止录”对话框中左击蓝色的小方框 ㈡、写程序代码 ①、选择“工具”菜单中的“宏”子菜单,从它的下级菜单中选择“Visual Basic 编辑器”,双击模块* ②、将sub Rad()改写成Public Function Rad(y) ③、将下列程序代码写入(或拷贝)到 坐标反算代码 Public Function fsa(x1, y1, x2, y2) Dim aa, a, b, b1, b2, b3, a1, x, y, a0 Const pi = 3.14159265358979 x = x2 - x1: y = y2 - y1 a = Atn(y / x) If (x < 0 And y > 0) Or (x < 0 And y < 0) Then a = a + pi End If If x > 0 And y < 0 Then a = a + 2 * pi End If ab = a aa = Sgn(ab): If aa < 0 Then ab = Abs(ab) a0 = ab / pi * 180: b1 = Int(a0): a1 = (a0 - b1) * 60: b2 = Int(a1) / 100 b3 = (a1 - b2 * 100) * 60 / 10000 b = b1 + b2 + b3 fsa = b * aa '计算的角度为:°′″(12.3645---12°36′45″) End Function 将60进制角度化成弧度――2 Public Function rad(a)

在excel中如何自编函数并运用

在excel中如何自编函数并运用 工作中如果有大量的计算并很复杂,可以自编函数并保存下来,以后可以在相似的运算中套用工式,或在同一个表格中出现了反复的同格式运算时也可以用。 以下以做专业教学计划表时安排课程算课时为例说明。造计划表时要在八个学期安排各门课程,由于每学期周课时有限制,一开始安排时所放的课程可能会在八个学期间移来移去,具体安排多少课时或安排几个学期也是会变动。由于八个学期其实周数并不全是18周,所以一移动该门课总课时总会变。如果有一个公式能自动计算变动的周课时并算出该课程该学期的总课时,会减少很多麻烦。其它如总学分、全部总课时或实践课时等也可以依此做出相同的公式。 方法如下: 1.在“工具”菜单上,指向“宏”,然后单击“Visual Basic 编辑器”。 2.在“Microsoft Visual Basic”窗口中的“插入”菜单上,单击“模块”。 3.在“模块”窗口中,键入函数代码。例如,计算每门课“总学时”的函数可如下所示: (Function 总学时(MyNum1, MyNum2, MyNum3, MyNum4, MyNum5, MyNum6, MyNum7, MyNum8) 总学时 = MyNum1 * 15 + MyNum3 * 16 + (MyNum2 + MyNum4 + MyNum5 + MyNum6) * 18 + MyNum7 * 14 + MyNum8 * 6 End Function) 说明:由于每门课不知道移动时会出现在excel表格八个学期的列中的哪一列,但它安排在了某个学期,则其它学期的相应位置为空(值为0),这样,设计一个公式把把八个学期全算进去,则没有安排此课的学期不会有学时。上面的MyNum1至MyNum8是excel自定义函数的自定义变量,这里对应八个学期某门课所对应的八个单元格。第一学期为15周,第三学期为16周,第七学期为14周,第八为6周,其余为18周。因此该课的总学时可以用八学期算总数的方式得出。(注:第一行定义八个变量值,用英文逗号隔开,不需要空格。图上第二行数值之间的空格并不需要输入时敲入,函数按正常输入完成后系统自动分出空格。) 4.在“文件”菜单上,单击“关闭并返回到Microsoft Excel”。 5.在工作表上,在需要输入一门课程总学时的地方调用函数,就像使用任何工作表函数一样。点“插入——函数”,在其中找到自定义函数“总学时”并调用。

使用VBA编写自定义函数(修改版)

使用VBA编写自定义函数 前言 本教程仅适用于不懂或初学VBA的朋友。 万事开头难,VB的内容繁多庞杂,没接触过VB但想学习编程的朋友可能无所适从,然而,这也远不是一个小教程能说得明白的,所以,本教程没有讲过多的语法、函数,也没有摘录VBA帮助(可以算是主要的参考教程)里的内容,而是以口语的方式讲解编程的一个基本思路,再辅以讲解平常可能遇到情况,让学习者能基本上手编写一段简单的代码,我的目的就达到了,接下去,就是学习者自己去论坛找资料学习了。 一、VBA简介 Visual Basic for Applications(VBA)基于Visual Basic的一种宏语言,是微软用来扩展Windows的应用程序,特别是在Microsoft Office软件中执行通用的自动化(OLE)任务的编程语言。它与VB不同的是,VB的对象主要是可视化窗口,VBA的对象则主要是Microsoft Office应用程序,如EXCEL的单元格、工作表、工作薄等。由于对象不同,那么,对象的属性、方法、事件就会发生相应的变化,所以,学习VBA,或从VB转到VBA,就是要根据具体对象特性而进行不同的处理。 我们在使用EXCEL时,如果仅仅只限于简单的数据处理,那就完全没有发挥出EXCEL强大的功能,我们完全可以使用VBA让我们的工作效率大大提高。 一般情况下,我们通常编写三类程序: 1、自定义函数:它与工作表内置函数使用方法一样,使用简单,适用于固定几个参数得出结果这种类型; 2、表格处理,这种编程较为复杂,适用于对整表进行大批量量数据的处理,对表格进行美化处理等。 3、可视化窗口,可以通过窗口设置对表格数据进行处理。 以上三种并不是独立存在的,可以相互结合使用,更能发挥更大的效率。 本次讲解的主要自定义函数,从较为简单的独立的自定义函数开始,逐渐学习进行大数据处理的能力。

VBA之自定义函数及加载

VBA之自定义函数 这一贴说的是自定义函数。Excel本身已自带了很多函数,供我们使用,但有些问题用原有的函数解决起来很复杂,甚至是无能为力,但有了VBA,可能就可以现实。 怎样自定义一个函数?下面我们建一个名为RangeCount和函数,用来统计给定单元格数量。上贴说过怎么插入一个宏(子程序),其实细心的朋友就会发现,里面有一项函数的选项,就是用这个添加了!键入你需要的名称RangeCount,即会自动生成一个函数的头Public Function RangeCount()和尾End Function!这时大家可以知道,子程序都是以Sub关键字开头,而函数是以Function关键字开头。 怎样给自定义函数传递参数?用过Sum函数的朋友都知道Sum的用法,在单元格中键入=Sum(A1:A10)就能对A1:A10进行求和,那么怎么让我们的自定义函数也有此功能呢,其实很简单,只要在Function RangeCount()中的(与)之间加入即可,象现在我们要给这个自定义函数传递一个单元格的参数,即在()间加入XRan As Range即可。其中XRan就是我们给这个参数设定的名称,As 是关键字,而Range就是给定参当数的类型(单元格类型),更详细的说明可以参见VBA的帮助(上贴有说明怎么用帮助了吧:))。 怎么样自定义函数加入功能?其实也和子程序一样,在函数的头Public Function RangeCount()和尾End Function之间就可以加入代码,我们这个函数的代码只有一句:RangeCount = XRan.Count 怎么样让自定义函数返回值?从上面的例子看出,只要将函数的名称设定为需要返回的值即可。 怎么当前工作表中使用自定久函数?使用自定义函数的方法其实和一般函数的方法是一样的,在单元格中键入=RangeCount(A1:A10),即可以得到值(10)!当然,也可以通过菜单插入/函数,在类别中选择用户自定义里找到你自定义的函数。 怎么在工作表里使用别的工作表里的自定义函数?从菜单插入/函数,类别中的用户自定义里,可以看到,如果这个自定义函数不是在当前的工作表里的,函数会变成——文件名.xls!函数名了,这样我们使用上面的自定义函数就变成=Book1.xls!RangeCount(A1:A10)(设我们刚才保存文件为Book1)。 怎么样在任何工作表中使用自定义函数?自定义了函数后,每一次使用都要打开这个工作簿,不方便,那么怎么样让任何工作簿都能使用这个自定义函数呢?有两个方法,第一个就是把代码写在上面说到的个人宏工作簿中,因为个人宏工作簿都是随Excel自动打开的,那么我们就可以通过PERSONAL.XLS!函数名来使用这个自定义函数。第二个方法就是加载宏(关于加载宏的其它用法和具体说明以后还会有专门的一贴),将包含这个自定义函数的工作簿,去掉无关的内容(不去当然也行啦!)后另存为加载宏(不会不知道怎么另存吧,汗!后注!),这样在菜单工具/加载宏里,将相关项前打勾,即可使用该自定义函数,这时使用函数的方法只要直接用函数名即可,如=RangeCount(A1:A10)。 最后再说一点大家少遇到的现象:用过VBA后,大家知道在同一模块中是不能有相同名称的子程序与函数的,如果有,运行时会提示存在二义性!但在不同模块中,却能有相同甸称的函数存在,那么怎么使用这样的函数呢?从菜单插入/函数,类别中的用户自定义里,我们可以看出这样的函数变成模块名.函数名了,这样我们的使用方法就是=模块1.RangeCount(A1:A10)或=模块2.RangeCount(A1:A10)。 后注:详细的另存为加载宏的过程,点击菜单/文件/另存为,在文件类型里选择Microsoft Excel加载宏项,这时文件夹自动转到保存加载宏的AddIns,再保存即可。 附:上面RangeCount的完整代码: Function RangeCount(XRan As Range) RangeCount = XRan.Count

相关主题
相关文档
最新文档