Excel VBAにLeft関数、Mid関数、Replace関数などの自身で処理を記入しなくても、VBA側で設定されている関数を呼び出せば毎回同じ処理が実行されます。
これと似たように、Functionを使用することによって自身で関数を作成出来ます。それを呼び出すことによって自身が作成した処理を毎回実行出来ます。
SubとFunctionの違い
簡単に言いますと戻り値が設定出来るか出来ないかの違いです。
Subは戻り値が設定出来ません。
Functionは戻り値も設定できます。
Functionの使用例
・引数なし、戻り値なしの場合
・引数あり、戻り値なしの場合
・渡す引数と受け取る引数の型が不一致の時に発生するエラー
・引数なし、戻り値ありの場合
・戻り値の型が不一致の時に発生するエラー
・引数あり、戻り値ありの場合
・引数複数、戻り値配列の場合
・ByValとByRefの違いについて
の内容で説明をしていきます。
引数なし、戻り値なしの場合
引数なし、戻り値なしの場合のFunctionの定義
Function 適当な名前()
処理内容
End Function
メイン側がCallで呼び出しをします。
Sub メイン1()
Call 引数と戻り値なし1()
End Sub
Function 引数と戻り値なし1()
MsgBox "引数と戻り値なし1"
End Function

メイン側でCallを記入しないで呼び出しをします。
Sub メイン2()
引数と戻り値なし2
End Sub
Function 引数と戻り値なし2()
MsgBox "引数と戻り値なし2"
End Function

プログラマーによって記入方法が変わるので注意してください。
メイン側でFunctionではなくSubを使用した関数を呼び出します。
Sub メイン3()
Call 引数と戻り値なし3()
End Sub
Sub 引数と戻り値なし3()
MsgBox "引数と戻り値なし3"
End Sub

この様に戻り値がなければ、FunctionかSubのどちらでも問題ありません。
開発元のコーディングルールに基づいて開発を行って下さい。
引数あり、戻り値なしの場合
引数あり、戻り値なしの場合のFunctionの定義
Function 適当な名前(ByVal Or ByRef(省略可) 変数名 as データの型)
処理内容
End Function
引数はByRefとByValの2つの記入方法があり、省略した場合はByRefが設定されます。
ByRefとByValは後程説明します。
メイン側がCallで呼び出しをします。
Sub メイン4()
Dim text As String
text = "引数あり戻り値なし4"
Call 引数あり戻り値なし(text)
End Sub
()の中にString型を設定しています。
Function 引数あり戻り値なし(ByVal text As String)
MsgBox text
End Function

引数を渡してそのまま表示しました。
メイン側でCallを記入しないで呼び出しをします。
Sub メイン5()
Dim text As String
text = "引数あり戻り値なし5"
引数あり戻り値なし text
End Sub
引数あり戻り値なし関数の後に” “とtextを記入します。
Functionは変更していません。
Function 引数あり戻り値なし(ByVal text As String)
MsgBox text
End Function

この様に引数に渡す内容を変更すれば結果が変わります。
メイン側でFunctionではなくSubを使用した関数を呼び出します。
Sub メイン6()
Dim text As String
text = "引数あり戻り値なし6"
Call 引数あり戻り値なし6(text)
End Sub
FunctionをSubに変更しただけです。
Sub 引数あり戻り値なし6(ByVal text As String)
MsgBox text
End Sub

渡す引数と受け取る引数の型が不一致の時に発生するエラー
エラーが発生する場合は大体コピペで中身を変更した時に発生します。
コピペをする時は注意して下さい。
ByValの場合
Sub メイン7()
Dim text As String
text = "あいう"
Call ByValを利用(text)
End Sub
渡す引数はString型に設定しています。
Function ByValを利用(ByVal text As Integer)
MsgBox text
End Function
受け取る側はInteger型に設定しています。
この時に処理を実行した場合に発生するエラーの内容です。

ByRefの場合
Sub メイン8()
Dim text As Integer
text = 4
Call ByRefを利用(text)
End Sub
渡す引数はInteger型に設定しています。
Function ByRefを利用(ByRef text As String)
MsgBox text
End Function
受け取る側はString型に設定しています。
この時に処理を実行した場合に発生するエラーの内容です。

渡す引数はInteger型で受け取る引数はString型なのでコンパイルエラーが発生します。
この様にByValとByRefでエラーの内容が変わりますので注意して下さい。
引数なし、戻り値ありの場合
引数なし、戻り値ありの場合のFunctionの定義
Function 適当な名前() As データの型
処理内容
適当な名前 = データの型
End Function
戻り値がある場合はFunctionで設定した名前に戻り値のデータを=で設定します。
Sub メイン9()
Dim text As String
text = 引数なし戻り値あり() '()を省略する事も可能です。
MsgBox text
End Sub
Function側で戻り値を設定している場合はCallを使用しません。
メイン側でFunctioの戻り値を受け取ります。
Function 引数なし戻り値あり() As String
Dim text As String
text = "String型が戻り値です"
引数なし戻り値あり = text
End Function
Function側の戻り値は=で設定します。

Function側の戻り値が表示されました。
戻り値の型が不一致の時に発生するエラー
エラーが発生する場合は大体コピペで中身を変更した時に発生します。
コピペをする時は注意して下さい。
Sub メイン10()
Dim i As Integer
i = 引数なし戻り値あり()
MsgBox i
End Sub
受け取り側がIntegerで受け取っています。
Function 引数なし戻り値あり() As String
Dim text As String
text = "String型が戻り値です"
引数なし戻り値あり = text
End Function
戻り値はString型で戻しています。

処理の実行時に実行時エラー’13’が発生します。
引数あり、戻り値ありの場合
引数あり、戻り値ありの場合のFunctionの定義
Function 適当な名前(ByVal Or ByRef(省略可) 変数名 as データの型) As データの型
処理内容
適当な名前 = データの型
End Function
メイン側でFunction側の戻り値を”=”で受け取ります。
Sub メイン11()
Dim text As String
text = "あいう"
text = 引数あり戻り値あり(text)
MsgBox text
End Sub
メイン側でtextの内容を”あいう”で設定します。
Function 引数あり戻り値あり(ByVal text As String) As String
text = "えおか"
引数あり戻り値あり = text
End Function
Function側で戻り値を”えおか”に設定します。

メイン側で”えおか”が表示されました。
引数複数、戻り値配列の場合
引数複数、戻り値配列の場合のFunctionの定義
Function プロシージャ名(ByVal 引数名1 As データ型, ByVal 引数名2 As データ型, ・・・) As 戻り値のデータ型()
処理内容
プロシージャ名 = 戻り値()
End Function
メイン側で配列を受け取れるように配列の変数を設定します。
Sub メイン12()
Dim text1, text2, text3 As String
Dim textList() As String
text1 = "あいう"
text2 = "aiu"
text3 = "アイウ"
textList = リスト作成(text1, text2, text3)
MsgBox textList(0) + "," + textList(1) + "," + textList(2)
End Sub
text1,2,3に”あいう”,”aiu”,”アイウ”を設定してFunction側を呼び出します。
Function側の戻り値はString型の配列なのでString型の配列で受け取ります。
Function リスト作成(ByVal text1 As String, ByVal text2 As String, ByVal text3 As String) As String()
Dim list(2) As String
list(0) = text1
list(1) = text2
list(2) = text3
リスト作成 = list()
End Function
Function側でlistの配列の要素数をlist(2)と設定しています。
配列は0番目から設定するので3つのデータを設定したい場合は要素数を2に設定しました。

textListが設定されて表示出来ました。
ByValとByRefの違いについて
ByValは引数をFunction側に値を渡すだけです。
ByValを使った引数渡しを値渡しといいます。
ByRefは引数をFunction側に値を渡すだけではなく、Function側で引数が変更されても呼び出し側でも変更後の値を取得します。
ByRef句を使った引数渡しを参照渡しといいます。
ByValの場合
Sub メイン13()
Dim text As String
text = "あいう"
Call ByVal使用(text)
MsgBox text
End Sub
Function ByVal使用(ByVal text As String)
'あいうからabcに変更
text = "abc"
End Function
メイン側でtextに”あいう”を設定してFunction側を呼び出しています。
Function側は”あいう”を”abc”に変更しています。

結果は”あいう”が表示されました。
ByRefの場合
Sub メイン14()
Dim text As String
text = "あいう"
Call ByRef使用(text)
MsgBox text
End Sub
Function ByRef使用(ByRef text As String)
'あいうからabcに変更
text = "abc"
End Function
ByValをByRefに変更しました。
他の処理内容は先ほどと変わりません。

結果が”abc”に変更されました。
この様にByRefを使用すると引き渡された変数の内容が変更後の値に設定されます。
戻り値を設定しなくても値が変更出来ます。複数の引数の値を変更したい時に便利です。
注意点として色々な所でByRefを使用すると処理内容を変更する時に処理を追うのが大変になるので気を付けて下さい。
今回はFunctionについて説明をさせて頂きました。
皆様の参考になれば幸いです。