【入門編】ADOでストアドプロシージャを呼び出し、戻り値を取得する実装パターン – Access VBA解析バイブル

スポンサーリンク

こんにちは!現場でバリバリ使えるAccess VBAのテクニック、楽しく極めていきましょう。

「マクロの記録」や簡単なボタン操作から一歩抜け出して、本格的な業務システムを作ろうとしたとき、必ずぶ壁になるのが「SQL Serverなどの外部データベースとの連携」です。

特に、データベース側に複雑な計算やデータ処理を丸投げできる「ストアドプロシージャ」を使いこせるようになると、Accessのパフォーマンスと安定性は見違えるほど跳ね上がります。

今回は、ADO(ActiveX Data Objects)を使ってSQL Serverのストアドプロシージャを呼び出し、その実行結果(戻り値)をVBA側でスマートに受け取る「黄金の極限実装パターン」を伝授します。ここをクリアすれば、Access VBAのアーキテクチャの理解は一気にプロの領域に到達しますよ!

—

1. なぜDAOではなく「ADO」なのか?

Accessといえば標準の「DAO(Data Access Objects)」が親しまれていますが、SQL Server等の外部RDBが持つ「ストアドプロシージャの戻り値(Return Value)や出力パラメータ(Output Parameter)」を緻密にハンドリングするには、ADOのアーキテクチャが不可欠です。

ADOは、COMコンポーネントを通じてデータベースと対話します。その中でも、今回主役になるのが以下の3つのオブジェクトです。

  • `ADODB.Connection` :データベースへの「パイプライン(接続)」
  • `ADODB.Command` :SQLやストアドプロシージャを運ぶ「特急列車の車両」
  • `ADODB.Parameter` :ストアドに渡す「荷物(引数)」や、受け取る「お土産(戻り値)」

この役割分担を頭にイメージしながら、実際のコードを見ていきましょう。

—

2. 【実践】ストアドプロシージャ呼び出しの完全実装コード

それでは、現場でそのままコピペして使える、堅牢(ロバスト)なエラーハンドリング付きのサンプルコードを公開します。

今回は例として、「社員IDを渡すと、今年の売上合計を算出して返し、ついでにステータス(成功/失敗)を戻り値として返す」というシチュエーションを想定しています。

SQL Server側の準備(イメージ)

— SQL Server側でこんなストアドが用意されていると仮定します
CREATE PROCEDURE sp_GetYTDeseSales
@EmployeeID INT, — 入力パラメータ
@TotalSales DECIMAL(18,2) OUTPUT — 出力パラメータ
AS
BEGIN
— 何らかの計算処理
SELECT @TotalSales = ISNULL(SUM(SalesAmount), 0)
FROM Orders
WHERE EmployeeID = @EmployeeID AND YEAR(OrderDate) = YEAR(GETDATE());

— 正常終了の証として「0」を返す(戻り値)
RETURN 0;
END

Access VBA側の実装コード

Option Explicit

Public Sub CallStoredProcedureSample()
‘ — オブジェクト変数の宣言 —
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prmReturn As ADODB.Parameter
Dim prmEmpID As ADODB.Parameter
Dim prmSales As ADODB.Parameter

‘ — 制御用変数 —
Dim targetEmpID As Long
Dim resultSales As Currency
Dim returnValue As Long

‘ 接続文字列の定義 (環境に合わせて書き換えてください)
Dim connStr As String
connStr = “Provider=SQLOLEDB;Server=YOUR_SERVER_NAME;Database=YOUR_DB_NAME;Uid=YOUR_USER;Pwd=YOUR_PASSWORD;”

targetEmpID = 101 ‘ 対象の社員ID

On Error GoTo ErrorHandler

‘ ==========================================
‘ 1. コネクションの確立
‘ ==========================================
Set conn = New ADODB.Connection
conn.ConnectionString = connStr
conn.Open

‘ ==========================================
‘ 2. コマンドオブジェクトの構築
‘ ==========================================
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = conn

‘ 実行するストアドプロシージャの名前を指定
cmd.CommandText = “sp_GetYTDeseSales”
‘ コマンドの種類が「ストアドプロシージャ」であることを明示(パフォーマンス向上)
cmd.CommandType = adCmdStoredProc

‘ ==========================================
‘ 3. パラメータの定義と追加(※ここが最重要!)
‘ ==========================================

‘ ① 戻り値 (Return Value) の受け皿作成
‘ ※ADOでは、戻り値は必ず【最初(先頭)】に追加する必要があります。
Set prmReturn = cmd.CreateParameter(“ReturnValue”, adInteger, adParamReturnValue)
cmd.Parameters.Append prmReturn

‘ ② 入力パラメータ (@EmployeeID) の作成
Set prmEmpID = cmd.CreateParameter(“@EmployeeID”, adInteger, adParamInput, , targetEmpID)
cmd.Parameters.Append prmEmpID

‘ ③ 出力パラメータ (@TotalSales) の作成
Set prmSales = cmd.CreateParameter(“@TotalSales”, adCurrency, adParamOutput)
cmd.Parameters.Append prmSales

‘ ==========================================
‘ 4. ストアドプロシージャの実行
‘ ==========================================
‘ レコードセットを返さない(UPDATEや計算処理主体)ため、第1引数は省略可
cmd.Execute

‘ ==========================================
‘ 5. 結果(戻り値と出力パラメータ)の回収
‘ ==========================================
returnValue = prmReturn.Value
resultSales = prmSales.Value

‘ 判定処理
If returnValue = 0 Then
MsgBox “処理が正常終了しました!” & vbCrLf & _
“今年の売上合計: ” & Format(resultSales, “Standard”), vbInformation, “成功”
Else
MsgBox “ストアド内で異常終了コードが検出されました: ” & returnValue, vbExclamation, “警告”
End If

CleanUp:
‘ ==========================================
‘ 6. リソースの確実な解放(メモリリーク防止)
‘ ==========================================
On Error Resume Next
If Not cmd Is Nothing Then Set cmd = Nothing
If Not conn Is Nothing Then
If conn.State = adStateOpen Then conn.Close
Set conn = Nothing
End If
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanUp
End Sub

—

3. 現場で絶対にハマる「3大トラップ」と回避策

このパターンを実装する際、多くのエンジニアが同じ罠にハマります。先回りして回避策を押さえておきましょう。

トラップ1:パラメータの「順番」を間違える

ADOの `Command.Parameters.Append` を使うとき、「戻り値(adParamReturnValue)」は、SQL側の定義順に関わらず、必ず一番最初にAppend(追加)しなければなりません。
順番を間違えると、SQL Server側で型不一致エラーや「パラメータが見つからない」という謎のエラーに悩まされることになります。

トラップ2:接続の解放漏れによるメモリリーク

VBAはガベージコレクションが優秀ではないため、エラーが発生した際などに `Connection` や `Command` がメモリ上に残り続け、Accessがフリーズする原因になります。
上記のコードのように、必ず `CleanUp` ラベルを用意し、`On Error Resume Next` を挟んで確実に `Nothing` を代入する習慣をつけましょう。

トラップ3:参照設定のし忘れ

このコードを動かすには、VBAの画面([ツール] > [参照設定])から、「Microsoft ActiveX Data Objects x.x Library」 にチェックを入れる必要があります。
これを忘れると、`New ADODB.Connection` の記述で「ユーザー定義型は定義されていません」というエラーが即座に飛んできます。

—

まとめ:ここをクリアすれば怖くない!

今回解説したADOによるストアドプロシージャの呼び出しは、Accessを「単なるローカルファイルデータベース」から「本格的なクライアント・サーバーシステムのフロントエンド」へと昇華させるための強力な武器です。

  • Connectionで繋がり、
  • Commandで運び、
  • Parameterで往来する。

この美しいオブジェクトの連携さえマスターすれば、どんなに複雑なビジネスロジックが裏で待ち受けていても、Accessから自由自在にコントロールできるようになります。

ぜひご自身の開発環境で試して、ワンランク上のAccess VBAプログラミングを楽しんでくださいね!

タイトルとURLをコピーしました