【Excel VBA】Functionの使い方を解説(宣言・引数、戻り値の指定、応用法)

  • 2024.10.11
       
【Excel VBA】Functionの使い方を解説(宣言・引数、戻り値の指定、応用法)

Excelを使っていて、自分だけに必要な計算処理をしてくれる関数が欲しいと思ったことはありませんか? Excelで用意されている数多くの関数と同じような処理を自分で作成したいときは、Functionプロシージャを使います。

Functionプロシージャの使い方を解説

この記事では、Functionプロシージャについて基本的なところから解説をしていきます。

  • Functionとは?プロシージャって何?
  • Functionの定義
  • Functionを呼び出す方法
  • 引数のある関数について
  • 引数の参照渡しとは?

そして、実際にFunctionプロシージャを使うときに役立つ応用的な内容についても分かりやすく解説していきます。

  • 戻り値としてオブジェクトを指定する方法
  • 引数や戻り値として配列を指定する方法
  • PublicとPrivateの違い、使い分け

Functionとは?プロシージャって何?

Functionプロシージャとは、VBAで自前の関数を定義するときに使用するプロシージャです。

VBAでの関数とは、たとえばセルの範囲を指定してその中の値を足し算するSUM()などのように、値を入力すると計算結果が返ってくるような一連の手続きのことです。Functionを使用することで、Excelに最初から入っている関数以外にも自分で定義することができます。

VBAのプロシージャとは、様々な計算や処理を一つの塊にまとめたものです。たとえば、普段VBAでプログラムを書くときに使っているSub … End SubのかたまりはSubプロシージャです。

VBAで実行したい処理や計算の内容に応じてFunctionプロシージャを書くことで、特定の計算などの処理を一連の処理の中で簡単に呼び出すことができるようになり、きれいなコードで書くことができます。

Functionの定義と基本的な書き方

最初に、Functionプロシージャの定義について見ていきましょう。関数の中で計算式に入れる値を指定するために使う引数を使用するかどうか、関数の処理の結果として戻り値を返すかどうかで場合分けをして解説していきます。

引数・戻り値なし

最もシンプルな、引数と戻り値を使わない場合は以下のとおりです。

【基本構文】

Function FunctionName()   'FunctionNameは定義する関数の名前で置き換える
  ...    '関数内で行う計算や処理を書く
End Function

【サンプルコード】

Function Sample1()
  MsgBox "テックマニア編集部"
End Function

上のサンプルでは、Sample1という関数を定義しています。この関数が呼び出されたとき、値を返さずメッセージボックスにテキストを表示します。

戻り値あり

次に、戻り値がある場合について見ていきましょう。変数を定義するときのように、Functionの定義にデータ型を指定します。

Function FunctionName() As Type   'Typeにはデータ型を入力する
  ...
  FunctionName = ReturnValue   'ReturnValueには実際の戻り値となるデータや計算式が入る
End Function

戻り値ありの関数を定義するとき、最初に指定したデータ型と関数の戻り値の型が一致しているかをしっかり確認しながら書きましょう!
たとえば数値型で指定したのに戻り値に文字列を入れていた場合などは、「型が一致しません」というエラーが出てしまいます。

【サンプルコード】

Function Sample2() As String
    Sample2 = "テックマニア編集部"
End Function

Functionを呼び出す方法

Functionプロシージャは定義したものを単独で実行することができません。Functionプロシージャを実行するにはSubプロシージャの中で呼び出すか、ワークシート関数として呼び出す必要があります。

ここでは、SubプロシージャのなかでFunctionを呼び出す場合について解説していきます。

引数・戻り値なしの関数を呼び出す

引数と戻り値のない関数を呼び出す場合は、Subプロシージャや他のFunctionプロシージャの中に呼び出したいFunctionの名前を書くだけで処理が走ります。

【サンプルコード】

Sub CallFunc()
    Sample3
End Sub

Function Sample3()
    MsgBox "テックマニア編集部"
End Function

このほかに、関数名の前にCallステートメントを付けて呼び出す方法もあります。書き方はメッセージボックスを表示するMsgBox関数のように、Callのあとにスペースを空けて関数の名前を入力する形式です。

【Callを付ける場合のサンプルコード】

Sub CallFunc()
    Call Sample4
End Sub

Function Sample4()
    MsgBox "テックマニア編集部"
End Function

最初に紹介した書き方のようにCallステートメントは省略することができますが、関数を呼び出すときにCallステートメントを毎回つけるように記述すると、関数を呼び出していることを明確に表せるというメリットもあります。VBAを使う場面に応じて書き方を使い分けてみましょう!

戻り値ありの関数を呼び出す

戻り値があると、先ほどとは少し書き方が異なります。

【基本構文】

Dim Object As Type   'Typeは関数の戻り値と同じデータ型にしてください
Object = FunctionName   'FunctionNameの代わりに呼び出す関数の名前を入れてください

変数にデータを代入するときのように、オブジェクトを作成して関数を代入することで関数を呼び出すことができます。

【サンプルコード】

Sub macro1()
    Dim str As String
    str = StrFn()
    MsgBox str
End Sub

Function StrFn() As String
    Sample1 = "テックマニア編集部"
End Function

ここでは、関数StrFnの戻り値として設定した文字列をmacro1というSubプロシージャのなかで呼び出しています。

文字列型の戻り値なので、関数の宣言をするときと呼び出す際に代入するオブジェクトの型をどちらもStringにしておく必要があります。型が一致しているかどうかを毎回確認することを心がけましょう。

関数を宣言する際に名前の横に付けている括弧は、引数がないときは呼び出す際に書く必要はありません。ただし、Callと同じように関数であることを明確にするために省略せずに書くことで、より分かりやすくきれいなコードになります。

引数のある関数について

ここまでに見てきた関数の書き方は、引数のないものでした。しかし、実際にVBAで関数を使うときは引数を持っている関数をよく使うことになります。引数を指定することで、関数を呼び出す際に値を入力して戻り値で計算結果を返す、といった処理が行えるようになるのでぜひ覚えましょう!

【基本構文】

Function FunctionName(ByVal 引数1 As データ型, ByVal 引数2 As データ型, ...) As 戻り値のデータ型
    FunctionName = 戻り値
End Function

引数は関数名の後ろにつく括弧の中にカンマ(,)で区切って並べていきます。引数が1つの場合はカンマを使いません。

引数の名前の前につくByVal修飾子といい、この引数が「値渡し」であることを示すために記述します。ByVal修飾子を省略した場合はByRef修飾子というものが付いている状態と見なされて、「参照渡し」という方式で引数が扱われます。ByRef修飾子についても後ほど解説していきます。

【サンプルコード】

Sub macro2()
    MsgBox func1(3) & vbCrLf & func2(4, 2)
End Sub

Function func1(ByVal num As Integer) As Integer
    func1 = num * 2
End Function

Function func2(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
    func2 = num1 * num2
End Function

【実行結果】

ここでは、2つの計算結果を表示しています。

func1では1つの引数をとり、入力した数値を2倍した結果を返す関数を定義しています。func2は数値型の引数を2つ取り、それぞれの引数を掛け算した結果を戻り値として返しています。

引数のデータ型は全て同じである必要はありません。実際にコードを書いていくと、文字列型と数値型が混じっていたりと、複数のデータ型を扱う形で引数の指定をすることが多くなります。

引数の参照渡しとは?

先ほど、引数には「値渡し」「参照渡し」の二種類があるとご説明しました。「値渡し」は引数に代入した値が値としてそのまま渡され、「参照渡し」はオブジェクトの参照として値が渡されます。と言っても分かりづらいかと思いますので、実際にコードでご説明します。

【サンプルコード】

Sub Main()
    Dim num As Integer
    num = 5
    Call DoubleValue(num)
    MsgBox "Doubled value: " & num
End Sub

'引数に入れた値を二倍にして結果を返す
Function DoubleValue(ByRef number As Integer) As Integer
    number = number * 2
    DoubleValue = number
End Function

こちらは、DoubleValue()関数の引数をByRefで指定することで、メッセージボックスに正しい計算結果が表示されるコードになっています。

【ByRefで引数を参照渡しした場合】

【ByValで引数を値渡しした場合】

結果を見ると一目瞭然ですが、値渡しをした場合は引数に代入した変数numがもとの5という数値のままなのに対し、参照渡しをするとnumがDoubleValue()関数の計算結果である10に変化しています。

参照というのはこのように、いくつもの変数や引数が同じ値にアクセスできる状態を指していて、参照を何らかの処理で変化させると、同じ参照にアクセスしている変数は全てその変化に従います。

そのため、参照渡しを使うと関数に値を渡すだけでなく、関数の計算結果で値が変更されたあとの変数を利用することもできます。

関数を使用していて、引数に代入する変数の値を変えたくない!という場合は、ByVal修飾子を付けて値渡しで設定しましょう。

ちなみに、ByRefやByValを省略した場合も参照渡しになります。どちらの形式を使うべきかはよく注意してください。

戻り値としてオブジェクト型を返す

Functionの戻り値として、これまでは数値型や文字列型のみ扱ってきましたが、オブジェクト型を返すことも可能です。

オブジェクト型で戻り値を返す場合は、オブジェクトに値を代入する場合と同じくSetステートメントを付けます。

【基本構文】

Function 関数名(ByVal 引数名 As 引数の型) As 戻り値のオブジェクト型
    Set 関数名 = 戻り値
End Function

【サンプルコード】

Sub Main()
    Dim rng As Range
    Set rng = GetRange("A1:A5")
    
    If Not rng Is Nothing Then
        rng.Value = "Hello, VBA!"
    Else
        MsgBox "Range not found."
    End If
End Sub

Function GetRange(ByVal address As String) As Range
    Set GetRange = Range(address)
End Function

【実行結果】

ここではRangeオブジェクトを戻り値の型として設定することでオブジェクト型を扱っています。

戻り値を設定するだけでなく関数の戻り値を変数に代入する際にも、オブジェクト型なのでSetステートメントが必要になります。

関数の引数・戻り値に配列を指定する

引数や戻り値として配列を使いたい場合は、それぞれ引数名や戻り値のデータ型の後ろに括弧 () を付けます。

なお、引数に配列を指定すると常に参照渡しに設定されます。これは配列というデータ型の仕様上、値渡しを行うことができないからです。

【基本構文】

Function 関数名(引数名() As データ型) As 戻り値のデータ型()
    関数名 = 戻り値
End Function

【サンプルコード】

Sub Main()
    Dim inputArray() As Integer
    Dim outputArray() As Integer
    Dim i As Integer
    
    ' 入力配列を初期化
    ReDim inputArray(1 To 5)
    For i = 1 To 5
        inputArray(i) = i
    Next i
    
    ' 関数を呼び出して出力配列を取得
    outputArray = ProcessArray(inputArray)
    
    ' 出力配列の内容を表示
    For i = LBound(outputArray) To UBound(outputArray)
        MsgBox "Element " & i & ": " & outputArray(i)
    Next i
End Sub

Function ProcessArray(ByRef arr() As Integer) As Integer()
    Dim tempArray() As Integer
    Dim i As Integer
    
    ' 出力配列を入力配列と同じサイズに設定
    ReDim tempArray(LBound(arr) To UBound(arr))
    
    ' 各要素を2倍にする
    For i = LBound(arr) To UBound(arr)
        tempArray(i) = arr(i) * 2
    Next i
    
    ProcessArray = tempArray
End Function

こちらのサンプルコードを実行すると、メッセージボックスが5回表示されます。

配列が常に参照渡しであることから、メッセージボックスに表示される文字列が参照によって値が変化していくことが分かります。

FunctionプロシージャのPublicとPrivateの違い、使い分け

Functionプロシージャを定義するときに、Functionステートメントの前にPublicPrivateといったキーワードを付ける場合があります。

このキーワードを付けることによって、定義した関数がどこから呼び出すことができるかが変わります。

大きな違いは以下のとおりです。

Public Function

Functionの前にPublicを付けた場合は、VBAプロジェクト内のどこからでもその関数を呼び出すことができます。また、他のモジュールやフォームからもアクセスすることが可能で、ワークシート関数としても使えます

Functionの前に何もキーワードを付けない場合はPublicを設定している状態になります。定義した関数が全てPublicなら付ける必要はありませんが、次に説明するPrivateが混じっている場合は、違いを明らかにするためにPublicを付けておくと良いでしょう。

Private Function

Privateキーワードを付けた場合は、その関数が宣言されたモジュールの中でしか呼び出すことができません。他のモジュールからはアクセスできず、ワークシート関数として使うこともできなくなります

PrivateとPublicのどちらを使うべき?

Publicは広範囲で使用可能ですが、Privateは狭い範囲で関数を使用するためのキーワードです。どちらを使うべきかは、関数を使う範囲と目的に応じて選びましょう!

まとめ

VBAを使いこなすには、Functionプロシージャで関数を扱うことは必須になります。Functionを使いこなせるようになるまで、ぜひこの記事を何度も読んで活用してください!

Functionを使いこなして、業務の効率化を目指しましょう!

関連記事

VBAの勉強方法は?

書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。

ただ、VBAに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。

プログラミングスクールならテックマニアがおすすめ!

ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。

<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~

このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。

     

Otherカテゴリの最新記事