百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

VBA正确使用过程和自定义函数

toyiye 2024-06-21 12:02 11 浏览 0 评论

过程是一个VBA语句块,包含在声明语句(Function、Sub、Get和Set)和匹配的End声明中。

VBA中的所有可执行语句都必须位于某个过程内。可以将整个应用程度编写为单个大的过程,但如果将它分解为多个较小的过程,代码就更容易阅读和理解。

1 VBA过程类型

1.1 VBA子过程:用于执行代码后不返回值的情况。它们以关键字Sub开头,并以关键字End Sub结束。在Excel中录制的宏就是这种过程。

1.2 Function函数过程:用于执行代码后返回计算结果的情况。它们以关键字Function开头,以关键字End Function结束。使用Function函数过程可创建Excel的扩展函数。

1.3 Property过程:用于自定义对象。使用属性过程可设置和获取对象属性的值,或者设置对另外一个对象的引用。

2 VBA子过程与Function函数过程的区别

2.1 Sub子过程不能返回值,而Function函数过程可以返回一个值,因此可以像Excel内部函数一样在表达式中使用Function函数。

2.2 Sub过程可作为Excel中的宏来调用,而Function函数不会出现在“选择宏”对话框中,如果要在工作表中调用Function函数,则可以像使用Excel内部函数一样使用该函数。

2.3 在VBA中,Sub过程可作为独立的基本语句调用,而Function函数通常作为表达式的一部分。

3 Sub过程结构

[Private | Public | Friend] [Static] Sub 过程名 [(参数列表)]

[语句序列1]

[Exit Sub]

[语句序列2]

End Sub

如:

Sub 手工创建Sub过程()

MsgBox "这是手工输入代码创建的Sub过程!"

End Sub

4 Function函数的语法结构

[Private | Public | Friend] [Static] Function 函数名 [(参数列表)] [As 返回类型]

[语句序列1]

[函数名=表达式1]

[Exit Function]

[语句序列2]

[函数名=表达式2]

End Sub

如:

Function fTest1(a As Integer, b As Integer) As Integer

Dim t As Integer

Randomize

If a > b Then

t = a

a = b

b = t

End If

fTest1 = Int(Rnd * (b - a)) + a

End Function

5 Sub子过程调用

5.1 用Call语句调用

Call 过程名(过程参数列表) ‘没有参数,可以写成:Call 过程名

5.2 将过程作为一个语句

Call Test(a,b)

Call Test a, b

6 调用Function函数过程

6.1 在工作表的公式中调用

“公式”选项卡→“插入函数”→在”或选择类别“选择框内选择”用户定义“,即可看到自定义的函数,如下:

6.2 在VBA代码中调用

在VBA代码中,可以像VBA内部函数一样调用这种用户自定义的Function函数。

Sub 生成随机数()

Dim R As Integer, l As Integer, u As Integer

l = Val(InputBox("请输入随机数的下限:", "设置下限", 1))

u = Val(InputBox("请输入随机数的上限:", "设置上限", 100))

R = fTest1(l, u)

MsgBox "生成的随机数为:" & R

End Sub

7 过程参数的形参与实参结合的方式

7.1 按位置结合

Function fTest1(a As Integer, b As Integer) As Integer

...

End Function

Call fTest1(1,100)

7.2 按命名参数方式结合

Call fTest1(a:=1,b:=100) '两个参数的位置可以随意

7.3 按位置和名称混合结合参数

Call fTest1(1,b:=100)

8 过程参数传递方式(传值或传地址)

在VBA中,实参可通过传值和传地址两种方式将数据传递给形参。

定义过程时,在形参的前面添加ByVal关键字,则该参数就按传值方式传递;否则就按传地址(默认)方式传递。

8.1 按传值方式传递参数

Sub 传值测试(ByVal a As Integer)

a = a + 1

Debug.Print "子过程中的变量A=" & a

End Sub

Sub 调用传值测试()

Dim b As Integer

b = 3

Debug.Print "主程序中变量B=" & b

传值测试 b

Debug.Print "主程序中变量B=" & b

End Sub

上述代码在“立即窗口”中的显示结果:

主程序中变量B=3

子过程中的变量A=4

主程序中变量B=3

由上面的结果可知,值并没有真正传递过去。

8.2 按传地址方式传递参数

Sub 传地址测试(ByRef a As Integer)

a = a + 1

Debug.Print "子过程中的变量A=" & a

End Sub

Sub 调用传地址过程()

Dim b As Integer

b = 3

Debug.Print "主程序中变量B=" & b

传地址测试 b

Debug.Print "主程序中变量B=" & b

End Sub

上述代码在“立即窗口”中的显示结果:

主程序中变量B=3

子过程中的变量A=4

主程序中变量B=4

9 数组作为参数

Sub 求最大数(a() As Integer)

Dim i As Integer, max As Integer

max = a(LBound(a))

For i = LBound(a) To UBound(a)

If a(i) > max Then max = a(i)

Next

Debug.Print "最大数:" & max

End Sub

Sub 测试求最大数()

Dim MyArray(5) As Integer, i As Integer

For i = 0 To 5

MyArray(i) = i * 2

Next

求最大数 MyArray()

End Sub

10 设置可选参数

“可选参数”在过程定义中由关键字Optional指示:

Sub 可选参数(strName As String, strSex As String, Optional ID)

With Worksheets("sheet3")

.Range("A2") = strName

.Range("B2") = strSex

If Not IsMissing(ID) Then

.Range("C2") = ID

End If

End With

End Sub

Public Sub 调用可选参数过程1()

可选参数 "wwu", "male"

End Sub

Public Sub 调用可选参数过程1()

可选参数 "wwu", "male", "2012"

End Sub

11 设置可变参数

“可变参数”在过程定义中由关键字ParamArray和一个Variant数组定义:

Sub MySum(intTotal As Integer, ParamArray intNum())

Dim i As Integer, j As Integer

For i = LBound(intNum) To UBound(intNum)

intTotal = intTotal + intNum(i)

Next

End Sub

Sub 调用可变参数()

Dim i As Integer

MySum i, 1, 2, 3, 4, 5, 6, 7, 8

Debug.Print i

End Sub

12 过程的递归调用

“递归”过程是指调用自身的过程。在递归调用中,一个过程执行的某一步要用到它自身的上一步(或上几步)的结果。

Function fact(ByVal n As Integer) As Long

If n <= 1 Then

fact = 1

Else

fact = fact(n - 1) * n

End If

End Function

Sub test()

Debug.Print fact(8)

End Sub

13 常用过程实例

13.1 计算个人所得税


个人所得税税率表(3500起征)





级数全月应纳税所得额税率速算扣除数(元)
1全月应纳税额不超过1500元3%0
2全月应纳税额超过1500元至4500元10%105
3全月应纳税额超过4500元至9000元20%555
4全月应纳税额超过9000元至35000元25%1005
5全月应纳税额超过35000元至55000元30%2755
6全月应纳税额超过55000元至80000元35%5505
7全月应纳税额超过80000元45%13505

Public Function taxes(curP As Currency, Optional dep As Integer = 3500)

Dim curT As Currency

curP = curP - dep '3500为扣除数

If curP > 0 Then

Select Case curP

Case Is <= 1500

curT = curP * 0.03

Case Is <= 4500

curT = curP * 0.1 - 105

Case Is <= 9000

curT = curP * 0.2 - 555

Case Is <= 35000

curT = curP * 0.25 - 1005

Case Is <= 55000

curT = curP * 0.3 - 2755

Case Is < 80000

curT = curP * 0.35 - 5505

Case Else

curT = curP * 0.45 - 13505

End Select

taxes = curT

Else

taxes = 0

End If

End Function

公式对应值
=taxes(4000)15
=taxes(7000)245
=taxes(4000,5000)0
=taxes(7000,5000)95

13.2 将数值转换为表格的列号

Public Function NumtoCol(Numbers As Integer) As String

Dim i1 As Integer, i2 As Integer, i3 As Integer

Dim s1 As String, s2 As String, s3 As String

i2 = Numbers \ 26

i3 = i2 \ 26 '第3位

i2 = i2 Mod 26 '第2位

i1 = Numbers Mod 26 '第1位

If i2 > 0 And i1 = 0 Then

i1 = 26

i2 = i2 - 1

End If

If i3 > 0 And i2 = 0 Then

i2 = 26

i3 = i3 - 1

End If

s3 = Chr(i3 + 64)

s2 = Chr(i2 + 64)

s1 = Chr(i1 + 64)

If s3 = "@" Then

If s2 = "@" Then

NumtoCol = s1

Else

NumtoCol = s2 & s1

End If

Else

NumtoCol = s3 & s2 & s1

End If

End Function

Sub 显示列号()

With Worksheets("sheet1")

.Activate

.Range("AZ1").Select

End With

MsgBox Selection.Column

End Sub

Sub 测试显示列号()

Dim intCol As Integer

intCol = Val(InputBox("请输入列号(1~16384):"))

If intCol < 1 Or intCol > 16384 Then

MsgBox "输入的数据超过范围,请重新输入!"

Exit Sub

End If

MsgBox "列号:" & intCol & ",对应的字母为:" & NumtoCol(intCol)

End Sub

13.3 大写金额转换函数

Function CapsMoney(curMoney As Currency) As String '转换中文大写金额函数

Dim curMoney1 As Long

Dim i1 As Long '保存整数部分(元部分)

Dim i2 As Integer '保存十分位(角部分)

Dim i3 As Integer '保存百分位(分部分)

Dim s1 As String, s2 As String, s3 As String '保存转换后的字符串

curMoney1 = Round(curMoney * 100) '将金额扩大100倍,并进行四舍五入

i1 = Int(curMoney1 / 100) '获取元部分

i2 = Int(curMoney1 / 10) - i1 * 10 '获取角部分

i3 = curMoney1 - i1 * 100 - i2 * 10 '获取分部分

s1 = Application.WorksheetFunction.Text(i1, "[dbnum2]")

'将元部分转为中文大写

s2 = Application.WorksheetFunction.Text(i2, "[dbnum2]")

'将角部分转为中文大写

s3 = Application.WorksheetFunction.Text(i3, "[dbnum2]")

'将分部分转为中文大写

s1 = s1 & "元" '整数部分

If i3 <> 0 And i2 <> 0 Then '分和角都不为0

s1 = s1 & s2 & "角" & s3 & "分"

If i1 = 0 Then '元部分为0

s1 = s2 & "角" & s3 & "分"

End If

End If

If i3 = 0 And i2 <> 0 Then '分为0,角不为0

s1 = s1 & s2 & "角整"

If i1 = 0 Then '元部分为0

s1 = s2 & "角整"

End If

End If

If i3 <> 0 And i2 = 0 Then '分不为0,角为0

s1 = s1 & s2 & s3 & "分"

If i1 = 0 Then '元为0

s1 = s3 & "分"

End If

End If

If Right(s1, 1) = "元" Then s1 = s1 & "整" '为"元"后加上一个"整"字

CapsMoney = s1

End Function

-End-

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码