Cara mengembalikan hasil dari fungsi VBA

277

Bagaimana cara mengembalikan hasil dari suatu fungsi?

Sebagai contoh:

Public Function test() As Integer
    return 1
End Function

Ini memberikan kesalahan kompilasi.

Bagaimana cara membuat fungsi ini mengembalikan bilangan bulat?

Mike
sumber
10
Dokumentasi: msdn.microsoft.com/en-us/library/office/…
Jean-François Corbett

Jawaban:

430

Untuk jenis pengembalian non-objek, Anda harus menetapkan nilai ke nama fungsi Anda, seperti ini:

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

Contoh penggunaan:

Dim i As Integer
i = test()

Jika fungsi mengembalikan tipe objek, maka Anda harus menggunakan Setkata kunci seperti ini:

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

Contoh penggunaan:

Dim r As Range
Set r = testRange()

Perhatikan bahwa menetapkan nilai kembali ke nama fungsi tidak menghentikan eksekusi fungsi Anda. Jika Anda ingin keluar dari fungsi, maka Anda perlu mengatakannya secara eksplisit Exit Function. Sebagai contoh:

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

Dokumentasi: http://msdn.microsoft.com/en-us/library/office/gg264233%28v=office.14%29.aspx

Dan
sumber
32
Untuk kelengkapan harus dicatat bahwa ketika Anda mengembalikan objek (seperti Rangemisalnya), Anda perlu menggunakan Setseperti yang Anda lakukan jika mengatur variabel objek dalam metode biasa. Jadi jika, misalnya, "test" adalah fungsi yang mengembalikan Range, pernyataan pengembalian akan terlihat seperti ini set test = Range("A1").
Jay Carr
Kenapa itu @JayCarr?
PsychoData
4
@ PsychoData - Hanya karena itulah cara Anda mengatur variabel objek secara umum, dan melakukannya tanpa setdapat menyebabkan masalah. Saya pernah mengalami masalah tanpa melakukannya, tetapi jika saya menggunakannya setsaya tidak :).
Jay Carr
1
Saya pikir perlu juga disebutkan bahwa perilaku fungsi berbeda ketika Anda memanggilnya dari spreadsheet, dibandingkan dengan memanggilnya dari fungsi atau Sub VBA lain.
Doug Jenkins
2
Ketika dipanggil dalam VBA, fungsi akan mengembalikan objek rentang, tetapi ketika dipanggil dari lembar kerja, ia akan mengembalikan nilai saja, jadi set test = Range("A1")persis sama dengan test = Range("A1").Value, di mana "tes" didefinisikan sebagai Varian, bukan Rentang.
Doug Jenkins
86

Fungsi VBA memperlakukan nama fungsi itu sendiri sebagai semacam variabel. Jadi alih-alih menggunakan returnpernyataan " ", Anda hanya akan mengatakan:

test = 1

Namun, perhatikan bahwa ini tidak keluar dari fungsinya. Kode apa pun setelah pernyataan ini juga akan dieksekusi. Dengan demikian, Anda dapat memiliki banyak pernyataan penugasan yang menetapkan nilai berbeda test, dan apa pun nilainya ketika Anda mencapai akhir fungsi akan menjadi nilai yang dikembalikan.

froadie
sumber
Sebenarnya Anda menjawab pertanyaan lebih jelas dengan informasi tambahan (yang berpotensi dapat mengarah ke pertanyaan lain dari baru ke VBA guy). Terus bekerja dengan baik
Adarsha
Maaf, sepertinya Anda baru saja menjawab hal yang sama dengan jawaban saya, yang saya miliki pertama kali, tetapi hanya menambahkan fakta bahwa itu tidak keluar dari fungsinya. Ini adalah tambahan yang bagus, saya hanya berpikir itu akan lebih tepat sebagai komentar. Saya tidak yakin apa etiket yang tepat, saya kira itu agak kasar untuk mengundurkan diri hanya untuk itu, karena itu adalah jawaban yang baik, tetapi tidak akan membiarkan saya membatalkannya.
Dan
41

Hanya mengatur nilai kembali ke nama fungsi masih tidak persis sama dengan pernyataan Java (atau lainnya) return, karena di java, returnkeluar dari fungsi, seperti ini:

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

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

Dalam VB, ekuivalen yang tepat mengambil dua baris jika Anda tidak menetapkan nilai balik di akhir fungsi Anda . Jadi, dalam VB konsekuensi wajar yang tepat akan terlihat seperti ini:

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 

Karena ini adalah kasusnya, itu juga bagus untuk mengetahui bahwa Anda dapat menggunakan variabel kembali seperti variabel lain dalam metode ini. Seperti ini:

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 

Atau, contoh ekstrem tentang bagaimana variabel pengembalian bekerja (tetapi tidak harus contoh yang baik tentang bagaimana Anda seharusnya kode) - contoh yang akan membuat Anda terjaga di malam hari:

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
LimaNightHawk
sumber
2
"Senang juga mengetahui bahwa Anda dapat menggunakan variabel kembali seperti variabel lain dalam metode" sebagian besar benar - tetapi misalnya jika jenis kembali adalah Variantdan tujuan Anda adalah mengembalikan array maka sesuatu seperti ReDim test(1 to 100)akan memicu kesalahan. Juga, meskipun adalah mungkin untuk mengobati jenis dasar seperti Integersseperti itu dianggap agak unidiomatic. Itu membuat kode lebih sulit dibaca. Pemrogram VBA memindai baris yang menetapkan nama fungsi untuk memahami apa fungsi itu. Menggunakan nama fungsi sebagai variabel reguler tidak perlu mengaburkan ini.
John Coleman
@ JohnColeman, setuju sepenuhnya pada kedua poin. Bukan berarti seharusnya contoh terakhir menjadi salah satu metodologi yang direkomendasikan. Tapi, pertanyaan topiknya adalah tentang Bagaimana mengembalikan variabel, dan jadi ini hanya upaya penjelasan lengkap tentang hasil pengembalian VB, dan dengan perluasan bagaimana mereka bekerja. Tentunya kasus terakhir bukan merupakan rekomendasi. (Saya tentu tidak akan mengkode itu sebagai lebih dari contoh.) Jadi, poin Anda diambil dengan baik, dan penambahan yang baik. Terima kasih.
LimaNightHawk
Hal ini berguna untuk fungsi bertubuh kecil, dan adalah sesuatu yang setiap programmer VBA harus tahu tentang, jadi saya tidak punya masalah dengan Anda menyebutkan itu. Saya hanya berpikir bahwa peringatan harus dimasukkan.
John Coleman
Terima kasih menjelaskan bagaimana Exit Functionhubungannya denganreturn
Austin D
@ JohnColeman, Jelas, Anda tidak dapat ReDim test(1 to 100)tanpa memicu kesalahan hanya karena 'test' tidak dinyatakan sebagai sebuah array! dan tanpa alasan lain sama sekali! Anda tidak dapat mendeklarasikan fungsi sebagai array. Deklarasikan sebagai Variant, kemudian bangun array output Anda (bisa Dinamis atau Statis) di dalam fungsi ini testdan kemudian tetapkan ("=") array ini testsebagai nilai pengembalian. Untuk memanipulasi lebih lanjut, seperti ReDimitu, Anda perlu menetapkan nilai yang dikembalikan ke variabel, misalnya Dim x as Variantdan memanggil x = test, setelah xitu Anda testmenjadi apa!
Gene
-6

Kode di bawah ini menyimpan nilai kembali ke variabel retValdan kemudian MsgBoxdapat digunakan untuk menampilkan nilai:

Dim retVal As Integer
retVal = test()
Msgbox retVal
Biju John
sumber