วิธีส่งคืนผลลัพธ์จากฟังก์ชัน VBA


277

ฉันจะส่งคืนผลลัพธ์จากฟังก์ชันได้อย่างไร

ตัวอย่างเช่น:

Public Function test() As Integer
    return 1
End Function

สิ่งนี้ทำให้เกิดข้อผิดพลาดในการคอมไพล์

ฉันจะทำให้ฟังก์ชันนี้คืนค่าเป็นจำนวนเต็มได้อย่างไร


10

คำตอบ:


429

สำหรับประเภทการส่งคืนที่ไม่ใช่วัตถุคุณจะต้องกำหนดค่าให้กับชื่อฟังก์ชั่นของคุณดังนี้:

Public Function test() As Integer
    test = 1
End Function

ตัวอย่างการใช้งาน:

Dim i As Integer
i = test()

หากฟังก์ชันส่งคืนประเภทวัตถุคุณต้องใช้Setคำหลักเช่นนี้:

Public Function testRange() As Range
    Set testRange = Range("A1")
End Function

ตัวอย่างการใช้งาน:

Dim r As Range
Set r = testRange()

โปรดทราบว่าการกำหนดค่าส่งคืนให้กับชื่อฟังก์ชั่นจะไม่ยุติการใช้งานฟังก์ชันของคุณ Exit Functionหากคุณต้องการที่จะออกจากฟังก์ชั่นแล้วคุณจะต้องพูดอย่างชัดเจน ตัวอย่างเช่น:

Function test(ByVal justReturnOne As Boolean) As Integer
    If justReturnOne Then
        test = 1
        Exit Function
    End If
    'more code...
    test = 2
End Function

เอกสารประกอบ: http://msdn.microsoft.com/en-us/library/office/gg264233%28v=office.14%29.aspx


32
เพื่อความสมบูรณ์ควรสังเกตว่าเมื่อคุณส่งคืนวัตถุ (เช่นRangeตัวอย่าง) คุณจะต้องใช้Setเช่นเดียวกับการตั้งค่าตัวแปรวัตถุในวิธีการปกติ ดังนั้นหากยกตัวอย่างเช่น "การทดสอบ" set test = Range("A1")เป็นฟังก์ชั่นที่กลับมาช่วงคำสั่งกลับจะมีลักษณะเช่นนี้
Jay Carr

ทำไม @JayCarr นั่น
PsychoData

4
@PsychoData - เพียงเพราะนั่นคือวิธีที่คุณตั้งค่าตัวแปรออบเจกต์โดยทั่วไปและการดำเนินการโดยไม่setทำให้เกิดปัญหา ฉันมีปัญหาในการทำ แต่ถ้าฉันใช้setฉันจะไม่ทำ :)
Jay Carr

1
ฉันคิดว่ามันเป็นสิ่งที่ควรค่าแก่การกล่าวถึงว่าพฤติกรรมของฟังก์ชั่นนั้นแตกต่างกันเมื่อคุณเรียกมันจากสเปรดชีตเปรียบเทียบกับการเรียกจากฟังก์ชัน VBA หรือย่อยอื่น
Doug Jenkins

2
เมื่อเรียกภายใน VBA ฟังก์ชันจะส่งคืนวัตถุช่วง แต่เมื่อถูกเรียกจากแผ่นงานจะส่งกลับเฉพาะค่าจึงset test = Range("A1")เท่ากับว่าtest = Range("A1").Valueโดยที่ "test" ถูกกำหนดเป็น Variant แทนที่จะเป็น Range
Doug Jenkins

86

ฟังก์ชั่น VBA ถือว่าชื่อฟังก์ชั่นของตัวเองเป็นประเภทของตัวแปร ดังนั้นแทนที่จะใช้returnคำสั่ง "" คุณจะพูดว่า:

test = 1

อย่างไรก็ตามขอให้สังเกตว่าสิ่งนี้ไม่ได้แยกออกจากฟังก์ชั่น รหัสใด ๆ หลังจากคำสั่งนี้จะถูกดำเนินการ ดังนั้นคุณสามารถมีคำสั่งมอบหมายจำนวนมากที่กำหนดค่าที่แตกต่างกันไปtestและสิ่งที่เป็นค่าเมื่อคุณถึงจุดสิ้นสุดของฟังก์ชั่นจะเป็นค่าที่ส่งกลับ


จริง ๆ แล้วคุณตอบคำถามให้ชัดเจนยิ่งขึ้นด้วยข้อมูลเพิ่มเติม (ซึ่งอาจนำไปสู่คำถามอื่นจากคนใหม่ไปถึง VBA guy) ติดตามการทำงานที่ดี
Adarsha

ขออภัยดูเหมือนคุณเพิ่งตอบสิ่งเดียวกับคำตอบของฉันซึ่งฉันมีก่อน แต่เพียงเพิ่มความจริงที่ว่ามันไม่ได้แยกออกจากฟังก์ชั่น มันเป็นการเพิ่มที่ดีฉันแค่คิดว่ามันจะเหมาะสมกว่าเป็นความคิดเห็น ฉันไม่แน่ใจว่ามารยาทที่เหมาะสมคืออะไรฉันคิดว่ามันค่อนข้างหยาบคายที่จะลดระดับลงเพราะนั่นเป็นคำตอบที่ดี แต่มันจะไม่ปล่อยให้ฉันเลิกทำ
ด่าน

41

เพียงแค่ตั้งค่าส่งคืนเป็นชื่อฟังก์ชั่นยังคงไม่เหมือนกันกับคำสั่ง Java (หรืออื่น ๆ ) returnเพราะใน java returnออกจากฟังก์ชั่นดังนี้:

public int test(int x) {
    if (x == 1) {
        return 1; // exits immediately
    }

    // still here? return 0 as default.
    return 0;
}

ใน VB ที่แน่นอนเทียบเท่าใช้เวลาสองเส้นถ้าคุณไม่ได้ตั้งค่าค่าตอบแทนในตอนท้ายของฟังก์ชั่นของคุณ ดังนั้นใน VB ข้อพิสูจน์ที่แน่นอนจะมีลักษณะเช่นนี้:

Public Function test(ByVal x As Integer) As Integer
    If x = 1 Then
        test = 1 ' does not exit immediately. You must manually terminate...
        Exit Function ' to exit
    End If

    ' Still here? return 0 as default.
    test = 0
    ' no need for an Exit Function because we're about to exit anyway.
End Function 

เนื่องจากเป็นกรณีนี้คุณควรใช้ตัวแปร return เช่นเดียวกับตัวแปรอื่น ๆ ในเมธอด แบบนี้:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test <> 1 Then ' Test the currently set return value
        test = 0 ' Reset the return value to a *new* value
    End If

End Function 

หรือตัวอย่างที่ดีที่สุดของการทำงานของตัวแปรส่งคืน(แต่ไม่จำเป็นต้องเป็นตัวอย่างที่ดีของวิธีที่คุณควรเขียนโค้ด) - สิ่งที่จะทำให้คุณตื่นขึ้นมาในตอนกลางคืน:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test > 0 Then

        ' RECURSIVE CALL...WITH THE RETURN VALUE AS AN ARGUMENT,
        ' AND THE RESULT RESETTING THE RETURN VALUE.
        test = test(test - 1)

    End If

End Function

2
"มันก็ดีที่รู้ว่าคุณสามารถใช้ตัวแปร return เช่นตัวแปรอื่น ๆ ในวิธีการ" ส่วนใหญ่เป็นจริง - แต่เช่นถ้าชนิด return เป็นVariantและเป้าหมายของคุณคือคืน array ดังนั้นสิ่งที่คล้ายReDim test(1 to 100)จะทำให้เกิดข้อผิดพลาด ยิ่งไปกว่านั้นแม้ว่ามันจะเป็นไปได้ที่จะรักษาแบบพื้นฐานIntegersเช่นนั้นก็ถือว่าเป็นเรื่องที่ไม่มีความรู้สึก ทำให้โค้ดอ่านยากขึ้น โปรแกรมเมอร์ VBA สแกนหาบรรทัดที่กำหนดให้กับชื่อฟังก์ชั่นเพื่อทำความเข้าใจว่าฟังก์ชั่นทำอะไร การใช้ชื่อฟังก์ชันเป็นตัวแปรปกติไม่จำเป็นต้องปิดบังสิ่งนี้
John Coleman

@ JohnColeman เห็นด้วยกับทั้งสองประเด็น ตัวอย่างสุดท้ายไม่ควรเป็นหนึ่งในวิธีการที่แนะนำ แต่คำถามในหัวข้อนั้นเกี่ยวกับวิธีคืนตัวแปรและนี่เป็นเพียงความพยายามในการอธิบายอย่างเต็มรูปแบบของผลตอบแทนของ VB และโดยการขยายการทำงานของมัน แน่นอนกรณีสุดท้ายไม่ใช่คำแนะนำ (แน่นอนฉันจะไม่เขียนโค้ดที่เป็นมากกว่าตัวอย่าง) ดังนั้นคะแนนของคุณก็ถูกนำไปใช้อย่างดีและการเพิ่มเติมที่ดี ขอบคุณ.
LimaNightHawk

มันมีประโยชน์สำหรับฟังก์ชั่นขนาดเล็กและเป็นสิ่งที่โปรแกรมเมอร์ VBA ควรรู้เกี่ยวกับดังนั้นฉันไม่มีปัญหากับคุณพูดถึงมัน ฉันแค่คิดว่าควรมีการเตือน
John Coleman

ขอบคุณที่อธิบายว่าExit Functionเกี่ยวข้องกับอย่างไรreturn
Austin D

@JohnColeman เห็นได้ชัดว่าคุณไม่สามารถReDim test(1 to 100)เรียกใช้ข้อผิดพลาดเพียงเพราะ 'test' ไม่ได้ถูกประกาศเป็น array! และไม่มีเหตุผลอื่นเลย! คุณไม่สามารถประกาศฟังก์ชันเป็นอาร์เรย์ได้ ประกาศเป็น a Variantจากนั้นเพียงแค่สร้างอาร์เรย์เอาต์พุตของคุณ (สามารถเป็นแบบไดนามิกหรือแบบคงที่) ภายในฟังก์ชั่นนี้testแล้วกำหนด ("=") อาร์เรย์นี้testเป็นค่าที่ส่งคืน หากต้องการจัดการเพิ่มเติมเช่นReDimคุณต้องกำหนดค่าที่ส่งคืนให้กับตัวแปรเช่นDim x as Variantและการโทรx = testหลังจากนั้นxคือสิ่งที่คุณทำtestเพื่อเป็น!
ยีน

-6

รหัสด้านล่างเก็บค่าส่งคืนในตัวแปรretValแล้วMsgBoxสามารถใช้เพื่อแสดงค่า:

Dim retVal As Integer
retVal = test()
Msgbox retVal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.