Chapter 8 まとめ

8-1.MDBとの違いによる注意事項
     ・定義域集計関数の使用について
     ・マクロの使用について
     ・オプション設定の変更と復元について
8-2.ウィザードやビルダーの作り方
8-3.最後に


8-1.MDBとの違いによる注意事項

定義域集計関数の使用について

「定義域集計関数」とは、DLookup関数やDMax関数など、テーブルを直接的に検索して、単一フィールドの集計結果を返す関数です。これらの関数をアドインで使用する場合には、限定された事項があるので十分注意が必要です。限定事項とは、これらの関数を実行すると、アドインではなく常にユーザーが作成しているカレントデータベースのテーブルを検索するということです。アドインのプログラムの中から実行してもアドイン内のテーブルに対して適用することはできません。もしアドイン内にしかないテーブルがその対象として指定されていると、そのオブジェクトが見つからないためにエラーが発生します。もしどうしてもこのような機能を使いたいのであれば、次のようなVBAのカスタム代替関数を作って使うとよいでしょう。

Public Function cst_DMin(Expr As String, Domain As String, Optional Criteria As Variant) As Variant
'定義域集計関数 DMin の代替関数

  Dim dbsCd As Database
  Dim rst As Recordset
  Dim strSQL As String

  On Error GoTo Err_cst_DMin

  Set dbsCd = CodeDb
  strSQL = "SELECT MIN(" & Expr & ") AS RecValue FROM " & Domain
  If Not IsMissing(Criteria) Then
    strSQL = strSQL & " WHERE " & Criteria
  End If
  Set rst = dbsCd.OpenRecordset(strSQL)
  rst.MoveFirst
  cst_DMin = rst!RecValue

Exit_cst_DMin:
  On Error Resume Next
  rst.Close: Set rst = Nothing
  dbsCd.Close: Set dbsCd = Nothing
  Exit Function

Err_cst_DMin:
  With Err
    Select Case .Number
      Case 3075
        .Raise 3075, , "クエリー式 '" & Criteria & "' の構文エラー"
      Case 3078
        .Raise 64231, , "入力テーブルまたはクエリー '" & Domain & "' は見つかりませんでした。"
      Case 3265
        .Raise 64479, , "指定した式に含まれる名前 ' " & Expr & "' が見つかりません。"
    End Select
  End With
  cst_DMin = Null
  Resume Exit_cst_DMin:

End Function


Public Function cst_DSum(Expr As String, Domain As String, Optional Criteria As Variant) As Variant
'定義域集計関数 DSum の代替関数

  Dim dbsCd As Database
  Dim rst As Recordset
  Dim strSQL As String

  On Error GoTo Err_cst_DSum

  Set dbsCd = CodeDb
  strSQL = "SELECT SUM(" & Expr & ") AS RecValue FROM " & Domain
  If Not IsMissing(Criteria) Then
    strSQL = strSQL & " WHERE " & Criteria
  End If
  Set rst = dbsCd.OpenRecordset(strSQL)
  rst.MoveFirst
  cst_DSum = rst!RecValue

Exit_cst_DSum:
  On Error Resume Next
  rst.Close: Set rst = Nothing
  dbsCd.Close: Set dbsCd = Nothing
  Exit Function

Err_cst_DSum:
  With Err
    Select Case .Number
      Case 3075
        .Raise 3075, , "クエリー式 '" & Criteria & "' の構文エラー"
      Case 3078
        .Raise 64231, , "入力テーブルまたはクエリー '" & Domain & "' は見つかりませんでした。"
      Case 3265
        .Raise 64479, , "指定した式に含まれる名前 ' " & Expr & "' が見つかりません。"
    End Select
  End With
  cst_DSum = Null
  Resume Exit_cst_DSum:

End Function



<使用例>
使い方は通常のDMin関数やDSum関数と同じです。

  Debug.Print cst_DMin("得点", "成績テーブル")

  Debug.Print cst_DSum("得点", "成績テーブル", "学生コード='123456'")




マクロの使用について

アクションの実行エラーダイアログ アドインの場合にはマクロは使わない方がよいでしょう。なぜなら、マクロの処理対象となるオブジェクトは、まずアドイン内で検索され、もしそこになければユーザーが作っているカレントデータベースを探すという手順で実行されるため、もし問題があった場合、原因となっている箇所を見つけるのが難しくなる場合があるからです。そして特にマクロの場合、エラーが発生すると「アクションの実行エラー」のダイアログが表示されますので、ユーザーを当惑させることになるかもしれません。

やはり、エラーをトラップしてその後のフローを制御したり、エラーメッセージの表示内容をアドイン側で組み立てられるVBAだけでプログラミングするのがよいでしょう。


オプション設定の変更と復元について

オプション設定ダイアログアドインにおけるオプション設定の変更と復元についての話を始める前に、まずオプション設定がプログラムにどんな影響を与えるかを確認しておきましょう。ここでは、オプション設定の中の「エラートラップ」の例について説明します。

オプションダイアログの[全般]タブには[エラートラップ]というオプションがあり、3つの項目の中から1つを選択するようになっています。デフォルトでは「クラスモジュールで中断」になっていて、そのまま使っている限りは特に気にすることもないでしょう。しかし、「クラスモジュールで中断」の設定で開発・動作確認したアドインを、もしも「エラー発生時に中断」の設定になっているユーザーのAccessで動作させたらどうなるでしょう?。ここでは簡単なエラー処理ルーチンを含んだ次のようなコードで試してみましょう。

Sub test1()

  On Error GoTo Err_Handler
  
  Debug.Print GetSum(2000030000)

Exit_sub:
  Exit Sub

Err_Handler:
  MsgBox Err.Description
  Resume Exit_sub:

End Sub

Function GetSum(value1, value2) As Integer

  GetSum = value1 + value2

End Function



まず、「クラスモジュールで中断」の設定で走らせてみます。test1プロシージャを実行するとGetSumプロシージャが呼び出されます。このプロシージャは単純に2つの引数の和を返す関数です。返り値のデータ型はIntegerです。ところがtest1プロシージャは20000+30000を要求していますので、計算結果の50000はデータ型の値範囲をオーバーしてしまい、GetSumプロシージャ内で「オーバーフロー」エラーが発生します。このプロシージャ内ではエラー処理がないため、そのエラーは呼び出し元のtest1プロシージャでハンドリングされ、"Err_Handler"のエラー処理ルーチンでメッセージ表示されます
MsgBox関数によるエラーメッセージ

開発者はこのような動きを意図してコーディングしているわけですが、もしオプションで「エラー発生時に中断」が選択されていたらどうなるでしょう。オプション設定を変更してtest1プロシージャからステップ実行してみます。すると「GetSum = value1 + value2」の行でエラーが発生し、呼び出し元のtest1プロシージャに返る前にプログラムがストップしてしまいます。もちろんそれによってtest1プロシージャのエラートラップも完全に無視された状態になってしまいます。
Accessからのエラーメッセージ


実際のところこのオプション設定がAccessのユーザーごとにどの程度変更されるかは分かりません。事実個人的にはこの設定を変更したことは一度もありません。しかし、より精巧なアドイン(私の作ったアドインでこれに当てはまるものはありませんが)を作ろうとするならこの問題を無視するわけにはいきません。そこで採るべき対処方法が「オプション設定の変更と復元」です。つまり、アドインの本来の処理を実行し始める前に、ユーザーが設定しているオプションの内容を保存し、アドイン実行中はその開発者が想定している設定で動作させ、すべての処理が完了した時点で元の状態に戻すのです。これらの処理はApplicationオブジェクトのGetOptionメソッドSetOptionメソッドで実現することができます。実際の例としては、次のようなコードをスタートアッププロシージャに記述します。なお、"Error Trapping"は「エラートラップ」オプションを表す定型句です。もしこれ以外のオプションを保存・復元する場合にはそれに対応した文字列を指定します。また、GetOptionメソッドなどの前にある"Application."は省略可能です。

Public Function smp_Main()

  Dim intErrTrap as Integer

  'オプションの現在のエラートラップの設定を保存
  intErrTrap = Application.GetOption("Error Trapping")
  'アドイン実行中はエラートラップの設定を「クラスモジュールで中断」にする
  Application.SetOption "Error Trapping", 1

  '***********************************************
  ' ここでアドイン本来の処理を実行
  '***********************************************

  'オプションのエラートラップの設定を復元
  Application.SetOption "Error Trapping", intErrTrap

End Function


ページのトップへ



8-2.ウィザードやビルダーの作り方

すでに『1-2.アドインの種類』で説明したように、アドインには3つの種類があります。今回サンプルとして作成したアドインはその中の「メニューアドイン」だけに過ぎません。それではその他のアドイン、「ウィザード」や「ビルダー」はどのように作ればよいのでしょうか?。もちろん、同じデータベースアプリケーションであっても受発注データベースと蔵書管理データベースがまったく違うように、アドインの処理内容はメニューアドインとウィザードではまったく異なります。しかしこの違いは今回の説明でいえば"MDBとして作る"内容が異なるだけです。それぞれの用途に応じたアドインを作成した後は、アドインの種類によって実行するタイミングや起動方法を変えるだけなのです。

では具体的にどうすればよいかというと、システムテーブル「USysRegInfo」への登録内容をアドインの種類に応じて変えるだけなのです。

例えば、フォームのデザインビューでツールボックスの[コントロールウィザード]ボタンが押された状態でコントロールを挿入しようとしたときに起動するウィザードでは、USysRegInfoテーブルの[Subkey]フィールドを次のようにします。これはテキストボックス("TextBox")用のウィザードの例です。

  HKEY_CURRENT_ACCESS_PROFILE\Wizards\Control Wizards\TextBox\サンプルウィザード


また、テーブルを新規作成するときに使うウィザードの場合は次のようにします。

  HKEY_CURRENT_ACCESS_PROFILE\Wizards\Table Wizards\サンプルウィザード


これはほんの一例で、実際にはこの他にもUSysRegInfoテーブルのレコード数や[ValName]フィールド・[Value]フィールドの内容を変えたりしなければなりませんが、基本的にこれらのレコードの内容を指定のものに変えればよいことに変わりはありません。それらの具体的な値についてはマニュアルの丸写しになってしまうのでここでは説明しませんが、ぜひ一度、Accessの「アプリケーション開発ガイド」を参照してみるとよいと思います。

ページのトップへ



8-3.最後に

実際にアドインを作ろうと思うとやはりある程度はAccessの内部的なことも知らなければなりません。また、ふだんは使っていないメソッドや関数もいろいろ使わなければなりません。今回のサンプルアドインでは一切使いませんでしたが、ほとんどのウィザードではオブジェクトを作成するという操作を行います。テーブルを作成したり、フォームを作成したり、あるいはコントロールを挿入して各プロパティを設定したりといった操作です。しかし、そこまではAccess既存のものでも間に合うので要らないとしても、日頃データベースの開発を行っていて、1つ1つは単純だけれど同じようなことを何度も繰り返さなければならなかったり、「こんなことができたらもっと作業が楽になるのに」と思うことはいろいろあるはずです。そのようなアイデアをアドインとしてまとめ、ボタン1つで実行できるようにしておくことによって、開発の効率化が図れることもきっとたくさんあるはずです。"アドイン"というと自分で作るにはちょっと難しそうなイメージもあるかもしれませんが、今回のシリーズで「実はMDBを作るのとそんなには違いはない」ということを分かってもらえたのではないでしょうか?。それを知ってもらいたかったのがこのシリーズの目的でもあるのです。このシリーズで説明したアドイン作成に関する情報は、アドインを作る上でのほんの一部のテクニック、入り口に過ぎません。Office2000(Developer)ではCOMアドインも作れるようになり、その可能性はさらに拡大してきています。ぜひオリジナルのアドイン作りにトライして、その可能性をご自分のデータベース開発にお役立てください。

ページのトップへ

| Index | Prev | Next |

 

Copyright © T'sWare All rights reserved