実行プロシージャの作成
では、作成したクラスclsTrans
のメソッドToExcel
を使ったプロシージャを作成しましょう。
プロジェクトに標準モジュール「Module1」を追加します。そして、プロシージャレコード全体をExcelに転送する
を宣言します。
Sub レコード全体をExcelに転送する() End Sub
まず、DimステートメントにNewキーワードを付けて、クラスからオブジェクトを作成します。
Dim Qex As New clsTrans
次に、プロパティQryName
にクエリ名を、SaveBookName
にブック名をフルパスでセットします。これらは、必ずメソッドToExcel
を実行する前にセットしてください。
With Qex .QryName = "商品区分別商品リスト" .SaveBookName = "c:\QryData.xls"
そして、メソッドToExcel
を実行します。Excelが起動し、クエリの結果セットがすべてワークシートに転送されます。
.ToExcel End With
最後に、使用したオブジェクト変数を開放します。
Set Qex = Nothing
レコード数を指定してデータを転送するメソッドの作成
もう1つメソッドを作成しておきましょう。このメソッドは、Excelに転送するレコード数を指定して実行するメソッドです。
オブジェクト変数の宣言
クラスの宣言セクションに、作成する新規ブックへの参照を格納するオブジェクト変数を宣言します。
Dim QryBook As Excel.Workbook
そして、SubプロシージャRecord_Trans
を作成します。
Public Sub Record_Trans() End Sub
プロシージャの先頭で、Excel
オブジェクトへの参照を格納する変数と、ループのカウンタ用変数を1つずつ宣言します。そして、このカウンタ用変数を「1」に初期化しておきます。
Dim RecExcel As Excel.Application Dim i As Integer i = 1
クエリを実行する
DoCmd
オブジェクトのRunCommand
メソッドを使用して、クエリを実行します。実行するクエリ名は、プロパティQryName
から取得し、読み出し専用で開きます。
DoCmd.OpenQuery QryName, , acReadOnly
そして、CreateObject
関数でExcel
のインスタンスを作成し、オブジェクト変数に格納して、Excel
を表示状態にします。
Set RecExcel = CreateObject("excel.Application") RecExcel.Visible = True
ここまでは、先ほど作成したメソッドToExcel
と同じですが、このメソッドではExcelに新しいブックを組み込んであげる必要があります。
先ほど使用した[Office Links]-[Excelに出力]機能は勝手にExcelに新しいブックを追加してくれましたが、ここで行う処理では自分でブックを追加しなくてはなりません。これは、Workbook
オブジェクトのAdd
メソッドが実行します。
Set QryBook = RecExcel.Workbooks.Add
メソッドを実行し新規ブックを追加すると、メソッドはWorkbook
オブジェクトを返してきますので、これをSet
ステートメントでオブジェクト変数に格納しておきます。なお、この変数は、あとで説明するグラフ作成のプロシージャでも使用しますので、モジュールレベルの変数で宣言しておきます。
クエリ結果をExcelに転送する
このクラスでは、クエリ結果のレコードを1件ずつ選択して、クリップボード経由でExcelのワークシートに転送します。
まず、クエリを実行した時点で、先頭のレコードがカレントレコードになっていますので、これをRunCommand
メソッドにacCmdSelectRecord
をセットして実行し選択状態にします。次に、RunCommand
メソッドにacCmdCopy
をセットしてコピーします。これらの操作は、Accessの[編集]メニューにある[レコードの選択][コピー]と同じ働きをします。
DoCmd.RunCommand acCmdSelectRecord DoCmd.RunCommand acCmdCopy
次に、Worksheet
オブジェクトのPaste
メソッドを使用して、先頭行のセルに貼り付けます。これで、クエリ結果のレコード1行分の、すべてのフィールドデータがコピーされます。
With QryBook.Worksheets("Sheet1") .Paste Destination:=.Cells(i, 1) End With
そして、ループのカウンタ用変数を1つ増やし、クエリ結果の2行目のコピーを行います。これは、While...Wend
ステートメントを使用し、16回この「コピー・貼り付け」操作を行います。
ただし、この一行単位のレコードコピーを実行すると、フィールド名が毎回いっしょにコピーされてしまいます。すなわち、クエリ結果では1行コピーしても、ワークシートには2行貼り付けられてしまいます。これでは一覧表が見づらくなってしまいますので、1回コピーしたらフィールド名の行を削除してあげるようにします。
i = i + 1 While i < 16 On Error GoTo FAIL DoCmd.RunCommand acCmdSelectRecord DoCmd.RunCommand acCmdCopy With QryBook.Worksheets("Sheet1") .Paste Destination:=.Cells(i, 1) .Rows(i).Delete End With
レコードを1行コピーしたら、カウンタ用変数の値を1つ増やし、RunCommand
メソッドにacCmdRecordsGoToNext
をセットして実行します。これで、カレントレコードが次のレコードに移動します。
i = i + 1 DoCmd.RunCommand acCmdRecordsGoToNext Wend
プロシージャの終了処理
もし、カレントレコードが最後のレコードなのに、次のレコードに移動しようとするとRunCommand
メソッドでエラーが発生します。そのため、On Error
ステートメントを組み込み、ラベルFAIL
に処理をジャンプさせます。
ラベルFAIL
では、開いたクエリを閉じ、グラフ作成のプロシージャを呼び出して、使用したオブジェクト変数を開放します。
プロシージャ内部で使用する公開しないメソッド(プロシージャ)を呼び出す場合は、Me
キーワードをつけてそのプロシージャ名を記述します。
ここでは、グラフ作成の処理を別ルーチンで実行させますので、内部で呼び出して使用するプロシージャCreateGraph
を作成しています。
FAIL: DoCmd.RunCommand acCmdClose Call Me.CreateGraph Set QryBook = Nothing Set RecExcel = Nothing End Sub
通常、クラスのメソッドは、Publicで宣言されたSubまたはFunctionプロシージャで作成されますが、クラスのメソッドとしてではなく、メソッド内で呼び出して使用するプロシージャが必要なことがあります。そうしないと、多くの処理を行うメソッドではプロシージャのコードがぐちゃぐちゃになってしまうからです。
Friend
キーワードを使用して、SubまたはFunctionプロシージャを宣言すると、内部処理用のプロシージャとして扱われ、クラスのメソッドとしては使用できなくなります。今回、グラフ作成の処理と、グラフ作成の元になるセル範囲を取得するプロシージャを、このFriendキーワードで宣言し、内部処理用のプロシージャとしています。Friend Sub CreateGraph() End Sub