2025澳门开彩结果历史记录-2025澳门开彩结果-2025澳门开彩查询记录-2025澳门聚宝盆-2025澳门九点半一肖一码-2025澳门精准资料免费全览

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

VBA函數(shù)中ByVal和ByRef的區(qū)別與應(yīng)用技巧

admin
2025年1月23日 21:31 本文熱度 152

一、ByVal和ByRef基礎(chǔ)



ByVal和ByRef是用于限定VBA函數(shù)(Function)或子過程(Sub)(以下統(tǒng)稱為函數(shù))參數(shù)傳遞方式的關(guān)鍵字。它們決定了在調(diào)用函數(shù)時(shí),參數(shù)是按值傳遞還是按引用傳遞。形如:

Function GetName(ByVal a As Integer , ByRef b As Integer) As String

    '代碼區(qū)

End Function

ByVal(By Value)限定參數(shù)a按值傳遞數(shù)據(jù)。

ByRef(ByReference)限定參數(shù)b按引用傳遞數(shù)據(jù)。

在VBA中,ByRef為默認(rèn)(省略關(guān)鍵字時(shí)的)值。如果僅看上面這些一板一眼的說明,對于沒有編程基礎(chǔ)的人,是非常難理解的。

以下這個(gè)test函數(shù)使用了ByVal參數(shù)和ByRef參數(shù),通過示例mExample過程來展示使用這兩個(gè)參數(shù)傳遞數(shù)據(jù)以后發(fā)生的變化:

'測試用test函數(shù):

Function test(ByVal myval As Integer, ByRef myref As Integer)

    myval = myval + 10

    myref = myref + 10

End Function

'示例子過程:

Sub mExample()

    Dim a As Integer, b As Integer

    a = 10: b = 10

    

    Debug.Print "test前: a=" & a & ",b=" & b

    test a, b

    Debug.Print "test后: a=" & a & ",b=" & b

End Sub

示例運(yùn)行后的結(jié)果:

test前: a=10,b=10

test后: a=10,b=20

通過示例,再次理解一下:

ByVal傳遞的只是值,相當(dāng)于將變量a的副本傳入函數(shù),無論函數(shù)中怎樣改變a的值,在函數(shù)外部,都不會(huì)影響變量a原始的值;

ByRef傳遞的卻是引用(即:變量的內(nèi)存地址,可以理解為變量自身),在函數(shù)中對變量b的重新計(jì)算、賦值,都會(huì)改變實(shí)體變量b的值,所以經(jīng)過函數(shù)的洗禮,這個(gè)b變量的值已是物是人非,也不再是它的初始值了。



二、ByVal和ByRef進(jìn)階



以上的基礎(chǔ)不足以滿足我們對ByVal和ByRef的好奇心。

1、我們注意到,以上示例向函數(shù)中傳遞的都是變量,所以才存在這種區(qū)別。換句話說,ByVal和ByRef只是對變量參數(shù)產(chǎn)生影響,如果函數(shù)接收的是兩個(gè)常量值:

test 100, 150

那么使用ByVal、ByRef的結(jié)果是一樣的,VBA也不會(huì)報(bào)錯(cuò)。只是這樣做會(huì)失去函數(shù)設(shè)置ByRef限定的意義而已。

ByVal參數(shù)設(shè)計(jì)的初衷,是要接收一個(gè)變量或一個(gè)具體的常量值。而ByRef參數(shù)設(shè)計(jì)的初衷,是要接收一個(gè)變量。

2、既然能讓ByVal、ByRef發(fā)揮作用的是傳遞變量,那么又要看這個(gè)變量屬于什么類型。下面對普通變量(如上述示例)、數(shù)組變量、對象變量分別說明:

(1)普通變量,最常使用的一種變量,它的變化情況如上述示例。

(2)數(shù)組變量,如果函數(shù)的參數(shù)是一個(gè)數(shù)組,則必須傳遞ByRef。

(3)對象變量,同樣只能傳遞ByRef,不能使用ByVal來按值傳遞,VBA不支持對象按值傳遞。

3、對于函數(shù)中使用的ByRef傳遞方式,目的可以有兩個(gè):一是要使用這個(gè)參數(shù)值;二是要改變這個(gè)參數(shù)值。在實(shí)際運(yùn)用中,這兩項(xiàng)目的并不是每次都想要達(dá)成的。

例如,函數(shù)設(shè)計(jì)中使用了ByRef,但是在使用時(shí)偶爾又需要只傳遞變量的值,而不要改變參數(shù)原始的變量值。

一種方法是使用一個(gè)第三方變量,其實(shí)就是設(shè)置一個(gè)變量副本,從而間接保護(hù)原來的變量:

'示例子過程:

Sub mExample2()

    Dim a As Integer, b As Integer, c As Integer

    a = 10: b = 10: c = b

    

    Debug.Print "test前: a=" & a & ",b=" & b

    test a, c

    Debug.Print "test后: a=" & a & ",b=" & b

End Sub

這個(gè)方法看似笨拙,但很有效。

第二種方法是變量作為參數(shù)時(shí),使用小括號(看著要高級一些)括起來:

'示例子過程:

Sub mExample3()

    Dim a As Integer, b As Integer

    a = 10: b = 10

    

    Debug.Print "test前: a=" & a & ",b=" & b

    test a, (b)

    Debug.Print "test后: a=" & a & ",b=" & b

End Sub

重點(diǎn)是這個(gè)(b),即在傳遞b變量時(shí),使用小括號括起來,這時(shí)就會(huì)臨時(shí)性只傳遞變量b的值(使其變成了ByVal參數(shù)),而不會(huì)對原實(shí)體變量b造成傷害。

使用小括號的方法,同樣適用于數(shù)組變量參數(shù)。如果要獲取函數(shù)的返回值,就需要兩層括號了,類似這種形式:test(a, (b))。

ByRef總結(jié):如果函數(shù)的參數(shù)使用了ByRef關(guān)鍵字,就傳遞一個(gè)變量的引用(地址,會(huì)改變原變量的值),如果對這個(gè)關(guān)鍵字參數(shù)只想傳遞值,可以將變量單獨(dú)用小括號括起來,這樣就只傳遞變量的值,不會(huì)修改變量的原始值,也可以直接使用一個(gè)實(shí)體的變量副本。



三、ByRef應(yīng)用技巧



當(dāng)我們了解了ByVal和ByRef的原理后,在編寫VBA代碼時(shí),就需要加以注意了。因?yàn)閰?shù)的限定關(guān)鍵字被省略時(shí),默認(rèn)是ByRef傳遞。

通常我們只是使用這個(gè)參數(shù)傳遞的值,而不會(huì)在函數(shù)中對參數(shù)進(jìn)行運(yùn)算、賦值等動(dòng)作,所以使用ByVal或ByRef可能感覺不到有什么區(qū)別。如果一個(gè)函數(shù)中傳遞的變量在該函數(shù)運(yùn)行后,仍需要調(diào)用它,就需要注意是否是ByRef傳遞。

其實(shí),利用ByRef傳遞,在函數(shù)中對傳遞的變量進(jìn)行賦值等操作,有時(shí)候會(huì)收到奇特的效果,如下示例函數(shù)(根據(jù)身份證號獲取生日,同時(shí)根據(jù)需要獲取性別信息):

Function GetBirthDate(ByVal idCard As String, Optional ByRef gender As String) As Date

    Dim birthDate As Date    

    birthDate = DateSerial(CInt(Mid(idCard, 7, 4)), CInt(Mid(idCard, 11, 2)), CInt(Mid(idCard, 13, 2)))

    ' 提取性別

    If Val(Mid(idCard, 17, 1)) Mod 2 = 0 Then

        gender = "女"

    Else

        gender = "男"

    End If    

    GetBirthDate = birthDate

End Function

調(diào)用該函數(shù)時(shí):

Sub 測試GetBirthDate()

    Dim idCard As String

    Dim gender As String

    

    idCard = "420624199610030080"

    

    '僅獲取生日:

    Debug.Print GetBirthDate(idCard)

    

    '獲取生日及性別:

    Debug.Print GetBirthDate(idCard, gender)

    Debug.Print gender

    

    '僅獲取性別:

    GetBirthDate idCard, gender

    Debug.Print gender

End Sub

不知道你看清這個(gè)操作沒有,通過將ByRef參數(shù)設(shè)置一個(gè)可選參數(shù),在函數(shù)中對該參數(shù)賦值。

使用時(shí),如果沒有特別的要求,只想得到函數(shù)的返回值,就省略該參數(shù),也不會(huì)影響函數(shù)正常發(fā)揮。如果想得到這個(gè)經(jīng)過函數(shù)洗禮后的變量的值,就如上述示例中所做,這樣,就能夠通過一個(gè)函數(shù),同時(shí)獲取到多個(gè)返回值的奇特效果。

我們在使用一些API函數(shù)時(shí)也會(huì)遇到這些情形,非常實(shí)際的技巧。


閱讀原文:原文鏈接


該文章在 2025/1/24 9:26:18 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 2025今晚澳门开特马 | 二四六天好彩944cc246天天 | 香港118图库宝典 | 2025年正版资料大全 | 管家婆三期开一期2025 | 2025年澳门一肖一特一码一中—— | 今日香港澳门资料 | 澳门最准一肖一码100精准 | 澳门特马好网站1877 | 246天天彩944cc二四六天天彩 | 2025澳门精准正版资料76期 | 澳门精准铁算算盘4905 | 王中王1王中王资料大全 | 2025管家婆一码一肖资料 | 红姐统一彩图库 | 三码中一码精准方法 | 香港正版资料免费大全下载安 | 2025澳门天天开彩资料大全 | 管家婆精准三肖必中一期 | 2025年管家婆的马资料 | 澳门正版资料免费大全2025年原创精华 | 今期管家婆资料图 | 香港马会免费资枓大全 | 管家婆一肖一码最准资料公开预包装食品 | 澳门精准免费资料大全1 | 新澳门全年 | 澳门精准免费资料大全1 | 2025澳门正版全年资料下载 | 易计算彩库宝典的密码是什么 | 2025澳门资料正版大全 | 2025年最旺的生肖 | 澳门2025精准一肖一码 | 2025澳门新媒体与社会调查报告发布 | 香港最新最准确资料二四六a | 天下水果奶奶免费资料 | 2025资料大全正版资料 | 天下彩了(9944cc)天下图 | 澳门三肖三码精准管家婆 | 今晚上澳门特马开几号 | 今晚上澳门特马开几号 | 天空彩天下彩福彩资料大全2025下载 |