はじめに

メインプログラム
関数
サブルーチン
計算処理
データ取得
表示処理
更新処理

本記事では、VBAで使われる「関数」と「サブルーチン」について、初心者の方でも理解できるように、基礎から実践的な活用方法まで詳しく解説します。コードの再利用や処理の効率化に役立つこれらのツールを習得することで、プログラムの品質と保守性を大幅に向上させることができます。

関数とサブルーチンの基本概念

Function
+入力値
+処理
+戻り値
Subroutine
+入力値
+処理

関数とは

関数は、特定の処理を行い、その結果を返すコードのまとまりです。例えば、数値の計算や文字列の操作など、何らかの入力を受け取り、処理を行って結果を出力します。

関数の基本構造

Function 関数名(引数 As) As 戻り値の型
    ' 関数の中で行う処理を書く
    関数名 = 結果
End Function
  • Functionキーワード
    これから関数を定義することを宣言します。
  • 関数名
    関数の名前で、何をするのかが分かるように命名します。
  • 引数リスト
    関数に渡すデータ(入力)です。複数の引数をカンマで区切って指定できます。
  • As 戻り値の型
    関数が返す結果のデータ型を指定します。
  • 関数の本体
    実際の処理を記述します。
  • 戻り値の設定
    関数名に結果を代入することで、戻り値を設定します。
  • End Function
    関数の終わりを示します。

関数の例

例 長方形の面積を計算する関数

Function CalculateArea(length As Double, width As Double) As Double
    ' 面積を計算して返します
    CalculateArea = length * width
End Function

この関数では、length(長さ)とwidth(幅)を引数として受け取り、その積を計算して面積を返します。

サブルーチンとは

サブルーチンは、特定の処理を行うコードのまとまりですが、関数と異なり結果を返しません。主に、何かの動作を実行するために使われます。

サブルーチンの基本構造

Sub サブルーチン名()
    ' サブルーチンの中で行う処理を書く
End Sub
  • Subキーワード
    これからサブルーチンを定義することを宣言します。
  • サブルーチン名
    サブルーチンの名前で、何をするのかが分かるように命名します。
  • サブルーチンの本体
    実際の処理を記述します。
  • End Sub
    サブルーチンの終わりを示します。

サブルーチンの例

例 メッセージを表示するサブルーチン

Sub DisplayMessage()
    MsgBox "こんにちは!"
End Sub

このサブルーチンは、メッセージボックスに「こんにちは!」と表示します。

関数とサブルーチンの違い

  • 戻り値があるかないか
    関数は結果を返しますが、サブルーチンは返しません。
  • 使用目的
    関数は計算結果や処理結果を得るために使われ、サブルーチンは特定の動作を実行するために使われます。

変数の宣言と使用(Dimについて)

変数の種類数値型IntegerLongDoubleCurrency文字列型StringChar論理型Booleanその他VariantObjectDate

プログラム内でデータを一時的に保存するためには、変数を使用します。変数は、情報を保存するための「箱」のようなものです。Dimキーワードを使って変数を宣言します。

変数の宣言の基本構造

Dim 変数名 As データ型
  • 変数名
    変数の名前で、何を保存するのかが分かるように命名します。
  • データ型
    変数が保存するデータの種類を指定します。

主なデータ型

  • Integer
    整数(-32,768 ~ 32,767)
  • Long
    大きな整数(-2,147,483,648 ~ 2,147,483,647)
  • Double
    倍精度浮動小数点数(小数点を含む数値)
  • String
    文字列
  • Boolean
    真(True)または偽(False)

変数の使用例

Dim length As Double
Dim width As Double
Dim area As Double

length = 5.0
width = 3.0
area = length * width

この例では、lengthwidthareaという3つの変数を宣言し、それぞれに値を代入しています。

  • length
    長さを保存
  • width
    幅を保存
  • area
    面積を保存

変数を使うメリット

  • データの一時保存
    計算結果やユーザー入力を保存できます。
  • コードの可読性向上
    意味のある名前を使うことで、コードが分かりやすくなります。
  • プログラムの柔軟性
    変数の値を変更することで、同じコードを再利用できます。

関数とサブルーチンを組み合わせた例

サブルーチン関数メイン処理サブルーチン関数メイン処理関数呼び出しサブルーチン呼び出し内部で処理実行計算用データ送信計算結果を返却処理用データ送信処理完了通知

実際に、関数とサブルーチンを組み合わせてプログラムを作ってみましょう。

例 長方形の面積を計算して表示するプログラム

Function CalculateArea(length As Double, width As Double) As Double
    ' 面積を計算して返します
    CalculateArea = length * width
End Function

Sub ShowArea()
    ' ユーザーから長さと幅を入力し、面積を計算して表示します
    Dim length As Double
    Dim width As Double
    Dim area As Double

    length = InputBox("長さを入力してください:")
    width = InputBox("幅を入力してください:")

    area = CalculateArea(length, width)

    MsgBox "面積は " & area & " 平方単位です。"
End Sub
  • CalculateArea関数
    長さと幅を受け取り、面積を計算して返します。
  • ShowAreaサブルーチン
    ユーザーから入力を受け取り、CalculateArea関数を使って面積を計算し、結果を表示します。

このプログラムのポイント

  • コードの再利用
    面積を計算する処理を関数にまとめることで、他の場所でも簡単に利用できます。
  • 可読性の向上
    関数とサブルーチンに分けることで、コードが整理され、理解しやすくなります。
  • 柔軟性
    異なる長さや幅でも同じプログラムで対応できます。

Callステートメントと引数の渡し方

Callステートメントとは

Callステートメントは、サブルーチンや関数を呼び出すときに使います。引数がある場合や、コードの可読性を高めるために使用します。

Call サブルーチン名(引数)

引数の渡し方

引数をサブルーチンや関数に渡すとき、2つの方法があります。

  • 値渡し(ByVal
    引数の値をコピーして渡します。元の変数は変更されません。
  • 参照渡し(ByRef
    引数そのものを渡します。サブルーチン内で変更すると、元の変数も変わります。

値渡しの例

Sub IncrementValue(ByVal number As Integer)
    number = number + 1
End Sub

参照渡しの例

Sub IncrementValue(ByRef number As Integer)
    number = number + 1
End Sub

値渡しと参照渡しの違いを確認する

Sub TestPassing()
    Dim num As Integer
    num = 10

    Call IncrementValueByVal(num)
    MsgBox "値渡し後の値: " & num  ' 結果は10

    Call IncrementValueByRef(num)
    MsgBox "参照渡し後の値: " & num  ' 結果は11
End Sub

Sub IncrementValueByVal(ByVal number As Integer)
    number = number + 1
End Sub

Sub IncrementValueByRef(ByRef number As Integer)
    number = number + 1
End Sub
  • 値渡し(ByVal
    numの値は変わりません。
  • 参照渡し(ByRef
    numの値が変更されます。

実践的なプログラム例

在庫管理システムの例

データ操作
GetCurrentStock関数: 現在庫取得
GetProductRow関数
UpdateInventory: 在庫更新
開始: InventoryManagement
商品コード入力
DisplayStockInfo: 在庫情報表示
ProcessOrder: 発注数入力
新在庫数表示
終了

関数とサブルーチンを活用して、簡単な在庫管理システムを作成してみましょう。

プログラム全体

Sub InventoryManagement()
    Dim productID As String
    Dim currentStock As Long
    Dim orderAmount As Long

    productID = InputBox("商品コードを入力してください:")
    currentStock = GetCurrentStock(productID)

    Call DisplayStockInfo(productID, currentStock)
    Call ProcessOrder(orderAmount)
    Call UpdateInventory(productID, currentStock, orderAmount)
End Sub

Function GetCurrentStock(productID As String) As Long
    ' 在庫シートから現在の在庫数を取得
    GetCurrentStock = Worksheets("在庫").Range("B" & GetProductRow(productID)).Value
End Function

Sub DisplayStockInfo(productID As String, currentStock As Long)
    ' 在庫情報を表示
    MsgBox "商品コード: " & productID & vbCrLf & "現在の在庫数: " & currentStock
End Sub

Sub ProcessOrder(ByRef orderAmount As Long)
    ' 発注数を入力
    orderAmount = InputBox("発注数を入力してください:")
End Sub

Sub UpdateInventory(productID As String, currentStock As Long, orderAmount As Long)
    ' 在庫を更新
    Dim newStock As Long
    newStock = currentStock + orderAmount
    Worksheets("在庫").Range("B" & GetProductRow(productID)).Value = newStock
    MsgBox "在庫を更新しました。新しい在庫数: " & newStock
End Sub

Function GetProductRow(productID As String) As Long
    ' 商品コードから行番号を取得
    GetProductRow = WorksheetFunction.Match(productID, Worksheets("在庫").Range("A:A"), 0)
End Function

このプログラムのポイント

  • 関数とサブルーチンの組み合わせ
    各機能を分割して、コードの再利用性と可読性を高めています。
  • ユーザー入力の活用
    InputBoxでユーザーからの入力を受け取ります。
  • Excelシートとの連携
    Worksheetsオブジェクトを使ってシートのデータを操作します。

売上データ分析システムの例

次に、売上データを分析するプログラムを作成してみましょう。

プログラム全体

Sub SalesAnalysis()
    Dim targetMonth As String
    Dim salesData As Range
    Dim totalSales As Currency

    targetMonth = InputBox("対象月を入力してください(例  
    2024-01):")
    Set salesData = GetSalesData(targetMonth)

    Call CalculateTotalSales(salesData, totalSales)
    Call GenerateSalesReport(salesData, totalSales)
    Call FormatReport
End Sub

Function GetSalesData(targetMonth As String) As Range
    ' 売上データシートから対象月のデータを取得
    Dim dataRange As Range
    Set dataRange = Worksheets("売上データ").Range("A1").CurrentRegion
    Set GetSalesData = dataRange.Columns(1).Find(targetMonth).EntireRow
End Function

Sub CalculateTotalSales(salesData As Range, ByRef totalSales As Currency)
    ' 売上の合計を計算
    totalSales = WorksheetFunction.Sum(salesData.Offset(0, 1).Resize(1, 12))
End Sub

Sub GenerateSalesReport(salesData As Range, totalSales As Currency)
    ' 売上レポートを作成
    With Worksheets("レポート")
        .Range("A1").Value = "売上レポート"
        .Range("A2").Value = "対象月  
    "
        .Range("B2").Value = salesData.Cells(1, 1).Value
        .Range("A3").Value = "総売上  
    "
        .Range("B3").Value = totalSales
    End With
End Sub

Sub FormatReport()
    ' レポートの書式設定
    With Worksheets("レポート").Range("A1:B3")
        .Font.Bold = True
        .Borders.LineStyle = xlContinuous
        .Interior.Color = RGB(220, 230, 241)
    End With
End Sub

このプログラムのポイント

  • データの取得と分析
    指定した月の売上データを取得し、合計を計算します。
  • レポートの自動生成
    計算結果をExcelシートに出力し、書式設定も行います。
  • 機能ごとの明確な分割
    各処理をサブルーチンや関数に分けて整理しています。

開発現場でのベストプラクティス

コーディング
規約
命名規則
エラー処理
コメント
Pascal形式
Camel形式
On Error
エラーログ
行コメント
ブロック
コメント

命名規則

  • わかりやすい名前を付ける
    変数やサブルーチン、関数の名前は、その役割が一目で分かるようにします。
  • 一貫性を保つ
    プロジェクト全体で命名規則を統一します。
  • 略語の使用に注意
    一般的でない略語は避け、混乱を防ぎます。

エラー処理の実装

予期しないエラーが発生した場合でも、プログラムが適切に対応できるようにします。

Sub SafeProcessing()
    On Error GoTo ErrorHandler

    ' 通常の処理
    ' ...

    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description
End Sub

コメントの活用

コードにコメントを追加して、何をしているのか、なぜそうしているのかを説明します。

' ==============================
' 機能  
    顧客情報を取得する関数
' 引数  
    customerID - 顧客のID
' 戻り値  
    顧客情報のレコードセット
' ==============================
Function GetCustomerInfo(customerID As String) As Recordset
    ' 処理内容
End Function

パフォーマンスの最適化

パフォーマンス
最適化ポイント
画面更新
イベント制御
計算方法
メモリ管理
ScreenUpdating
EnableEvents
Calculation
変数の解放

大量のデータを処理する場合や、処理速度を向上させたい場合には、Excelの設定を一時的に変更します。

Sub OptimizedProcess()
    Application.ScreenUpdating = False  ' 画面の更新を停止
    Application.EnableEvents = False    ' イベントを無効化
    Application.Calculation = xlCalculationManual  ' 自動計算を停止

    ' 大量のデータ処理
    ' ...

    Application.Calculation = xlCalculationAutomatic  ' 自動計算を再開
    Application.EnableEvents = True    ' イベントを有効化
    Application.ScreenUpdating = True  ' 画面の更新を再開
End Sub

注意点

  • 処理終了後には、必ず設定を元に戻します。さもないと、Excelの他の機能に影響を及ぼす可能性があります。

応用テクニック

値の計算
再帰呼び出し
3 × 2 = 6
2 × 1 = 2
1
Factorial(1)
Factorial(2)
Factorial(3)

再帰的な呼び出し

関数やサブルーチンが自分自身を呼び出すことで、再帰的な処理を行うことができます。

例 階乗を計算する関数

Function Factorial(n As Integer) As Long
    If n <= 1 Then
        Factorial = 1
    Else
        Factorial = n * Factorial(n - 1)
    End If
End Function

  • Factorial(5)を呼び出すと、5 * Factorial(4)となり、再帰的に計算が進みます。

動的なサブルーチンの選択

ユーザーの入力や条件に応じて、異なるサブルーチンを呼び出します。

Sub DynamicProcess()
    Dim actionType As String
    actionType = InputBox("実行する処理を選択してください(登録/更新/削除):")

    Select Case actionType
        Case "登録"
            Call RegisterData
        Case "更新"
            Call UpdateData
        Case "削除"
            Call DeleteData
        Case Else
            MsgBox "無効な入力です。"
    End Select
End Sub

まとめ

関数とサブルーチンを適切に活用することで、VBAプログラミングの効率と品質を大幅に向上させることができます。プログラミングを始めたばかりの方でも、基本をしっかりと理解すれば、複雑な処理を簡単に実装できます。