[No.90 Access Form OpenArg引数でセット位置を渡す]
[No.91 Access ダイアログフォームって?何? acDialogとPublic変数を使用]
[No.92 Excel Sheets(X).Name シート名へのアプローチいろいろ]
[No.93 Access2000 ADOでクエリーのレコードを参照 Excelへ出力]
[No.94 Access Form_Open Form_Loadイベントの発生順]

www.ken3.org(サイト内)から Google を利用して、

三流君 VBAで楽しくプログラミング(Excel/Access VBAの解説/サンプルです)
[VBA系のバックナンバー] [VBA系 TOP] [三流君 TOP]



No.90 2003/06/22
Access Form OpenArg引数でセット位置を渡す
[ページTOPへ戻る]

<Access Form OpenArg引数でセット位置を渡す>

(検索フォームで選択した番号を使用する その2) どうも、三流プログラマーのKen3です。 今回は、 フォーム間のデータのやり取りで、 前回の続きで、開いた別フォームからデータを受け取りたい、 そんな感じの処理を書きたいと思います。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba090.lzh にdb090.mdb(Access2000版)が保存されています。

/* * 1.今回のキッカケ */

掲示板に下記の質問をもらいました。 --------------- In message "[BBS :142] Accessでのパラメータ引渡し方法", Yoshi さん wrote... >投稿時間:2003/06/18(Wed) 17:25 > >おなまえ:Yoshi >タイトル:Accessでのパラメータ引渡し方法 >URL : >コメント: > >こんにちは。はじめて書き込みます。 >現在「顧客画面」と「顧客番号検索画面」というものがあります。 >「顧客画面」は、KEYである顧客番号とその他情報を登録、修正、削 >除する画面です。 >「顧客番号検索画面」は、「顧客画面」の顧客番号の検索機能です >。 >つまり、「顧客画面」で登録されている顧客情報を変更する場合 >現在データベースに登録されている顧客番号を一覧(顧客番号検索画 >面)表示させ選択された顧客番号を「顧客画面」に戻すといった方法 >を教えてください。 >すいません、わかりずらいと思うので簡単な図を書きます。 > >1顧客画面 ← 顧客情報の一部の修正を行いたいためこの画面を >開く > >2顧客番号横の検索ボタンを押下 ← 顧客番号がすぐにわからな >いため検索画面を開く > >3顧客番号検索画面が開く ← リストボックスで作成した一覧を >表示 > >4リストボックスの対象行を選択 > >5顧客画面 ← 選択された顧客番号を表示させる --------------- そんな質問に対して、 前回の [No.89 Access 検索フォームで選択した番号を使用する その1] http://www.ken3.org/backno/backno_vba18.html#89 では、 顧客画面の該当レコードへデータを移動する。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 方法、
Private Sub btn選択_Click()

    Dim LNG顧客番号 As Long

    '番号選択のチェック
    If IsNull(Me![lst顧客番号]) Then '何も選択されていないか?チェック
        MsgBox "顧客番号を選択してください"
        Exit Sub '関数を抜ける
    End If
    
    '番号をローカル変数に保存する
    LNG顧客番号 = Me![lst顧客番号]
    Debug.Print LNG顧客番号  'テバックで表示
    
    'フォームを閉じる
    DoCmd.Close

    'レコードを移動する
    DoCmd.GoToControl "顧客番号"  '顧客番号フィールドにコントロールを移動
    DoCmd.FindRecord LNG顧客番号  '選択された番号のレコードに移動
    ' 
End Sub
と、 DoCmd.GoToControl "顧客番号" '顧客番号フィールドにコントロールを移動 で、コントロールを顧客番号にして、 DoCmd.FindRecord LNG顧客番号 '選択された番号のレコードに移動 で、レコードを探す(移動する) 代入はしていないのですが、レコードが移動しているので、 代入しているように見えます。 なんて、勝手に作ってました。

/* * 2.読者の心の声を代弁してみる(笑) */

読者が心の中で、下記のように言ったかどうかは不明ですが、 勝手な物語を少し読んでください。 読者の声を代弁(笑)※自分落としネタ ^^^^^^^^^^^^^^^^^^^^ へぇ〜、動いてるけど、それだと、顧客番号を使用する違う画面から、 顧客番号検索画面が使えないジャン。 例えば、印刷処理で、 顧客データ印刷画面 ^^^^^^^^^^^^^^^^^^ 顧客コード[ ______ ] 検索 と、印刷画面でも検索ボタンを作って、 顧客番号検索画面(共通)を呼びたいのに 顧客番号検索_印刷用とフォームをもう一つ作って、
Private Sub btn選択_Click()
    '番号選択のチェック
    If IsNull(Me![lst顧客番号]) Then '何も選択されていないか?チェック
        MsgBox "顧客番号を選択してください"
        Exit Sub '関数を抜ける
    End If
    
    '番号を親フォームに保存する
    Forms!顧客画面!顧客番号 = Me!lst顧客番号    
     '↑↑↑
    'ここを印刷画面に変えて
    Forms!顧客データ印刷!顧客番号 = Me!lst顧客番号    

    'フォームを閉じる
    DoCmd.Close
End Sub
と、 Forms!顧客画面!顧客番号 = Me!lst顧客番号      '↑↑↑ 'ここを印刷画面に変えて Forms!顧客データ印刷!顧客番号 = Me!lst顧客番号 だけ、違うフォームを作れって? 検索数分、同じ処理なのに、コピーしてフォームを作れ?って? フォームの数が多いほうがプログラム作った気になれるって? イヤ、そこまでは、考えてなくて、 ただ、検索できればいいのかなぁと思って・・・ だから三流作者とかクレームのメールたくさんもらうんだよ。 (※お礼メールの方が多くなるように努力しないとね)

/* * 3.フォームに引数を渡して逃げる OpenArg引数 */

さてと、 今の問題を少し整理すると、 ^^^^^^^^^^^^^^^^^^^^^^^^^^ 新たに開いた検索画面で データ選択後の処理で、 Forms!顧客画面!顧客番号 = Me!lst顧客番号      '↑↑↑ Forms!顧客データ印刷!顧客番号 = Me!lst顧客番号 だけ、違うフォームを作れって? なんて、言ってました。 下記のような、印刷開始番号〜印刷終了番号を入れる画面を例にして、 処理を考えて見ます。 顧客データ印刷画面 ^^^^^^^^^^^^^^^^^^ 顧客コード[ ______ ] 検索 〜 [ ______ ] 検索 (txtSTART) (txtEND) と、印刷開始コード、終了コードをそれぞれセットするサンプルを作ってみます。 ↑作成した画面 違うのは、 選択されたデータのセット位置(フォームと項目)なので、 顧客番号検索フォームに 選択された番号をセットするフォーム名と項目名を渡します。 フォームに渡す? ~~~~~~~~~~~~~~~~ なにそれ? えっと、 DoCmd.OpenForm に何かいいパラメータ無いかなぁ、、と探っていたら、 一番最後に、OpenArg引数なんて引数があるじゃないですか・・・ ↑パラメータヒントの画面 さっそく、ヘルプで調べてみると、 Forms!社員.OpenArgs me.OpenArgs など、 フォームオブジェクト.OpenArgs で、フォームを開くときに指定した引数を参照できる。 でも、1つしか渡せないのかぁ、/(スラッシュ)で区切って渡し、 分解してもらうか。 下記の2つの検索ボタンが押されたら、
Private Sub btn開始番号検索_Click()
    Dim stDocName As String
    Dim stLinkCriteria As String

    stDocName = "顧客番号検索画面"
    DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtSTART"
End Sub
Private Sub btn終了番号検索_Click()
    Dim stDocName As String
    Dim stLinkCriteria As String

    stDocName = "顧客番号検索画面"
    DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtEND"
End Sub
と 顧客番号検索画面フォームに引数を渡し、 顧客番号検索画面で顧客番号が選択されたら、 結果を引数で受け取った場所にセットしてみますか。

/* * 4.検索画面、Me.OpenArgsを参照して、データをセットする */

顧客番号検索画面 ^^^^^^^^^^^^^^^^ のモジュールを下記のように修正しました。 キャンセルボタンの時は、何もしないで閉じてます(変更無し)
Private Sub btnキャンセル_Click()
    'フォームを閉じる
    DoCmd.Close
End Sub
選択ボタンの時、Me.OpenArgsを参照して、データをセットする
Private Sub btn選択_Click()

    '番号選択のチェック
    If IsNull(Me![lst顧客番号]) Then '何も選択されていないか?チェック
        MsgBox "顧客番号を選択してください"
        Exit Sub '関数を抜ける
    End If
    
    '変換場所の判断
    Dim n As Integer '/の位置判断
    Dim strSETFORM As String  'フォーム名
    Dim strSETCONTROL As String 'セットするコントロール名
    n = InStr(Me.OpenArgs, "/")
    If n <> 0 Then  'スラッシュの位置によって処理する
        strSETFORM = Left(Me.OpenArgs, n - 1)   '左から/の前まで
        strSETCONTROL = Mid(Me.OpenArgs, n + 1) '/の次から最後まで
        '顧客番号を指定フォームのコントロールにセット
        Forms(strSETFORM).Controls(strSETCONTROL) = Me![lst顧客番号]
    Else  '下記、普通は通らないエラー処理
        MsgBox "パラメータエラー、プログラム管理者にお伝えください"
    End If
   
    'フォームを閉じる
    DoCmd.Close

End Sub
ポイントは、 ~~~~~~~~~~~~ n = InStr(Me.OpenArgs, "/") If n <> 0 Then 'スラッシュの位置によって処理する strSETFORM = Left(Me.OpenArgs, n - 1) '左から/の前まで strSETCONTROL = Mid(Me.OpenArgs, n + 1) '/の次から最後まで で、/の位置を探し、 DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtSTART" で送られてきた、 "顧客データ印刷/txtSTART" のフォーム名とテキストボックスの名前を分解します。 '顧客番号を指定フォームのコントロールにセット Forms(strSETFORM).Controls(strSETCONTROL) = Me![lst顧客番号] で、 フォーム名とコントロール名を指定して、データをセットしています。 あまり見慣れない書き方かもしれませんが、 Forms(文字列).Controls(文字列) で、代入/参照することが出来ます。 おまけで、
Private Sub lst顧客番号_DblClick(Cancel As Integer)
    'リストボックスをダブルクリックしたら
    Call btn選択_Click    'と、選択ボタンの処理を呼ぶ
End Sub
と リストボックスをダブルクリックで、選択ボタンを押した処理を走らせてます。 Call btn選択_Click と、イベントの btn選択クリック処理を呼ぶ、みたいな書き方も出来ます。 ※操作になれた人だと、リストボックスダブルクリックで選択にしておくと、  便利だと思います。  (本題と関係ない、余談ですが、入れておくと便利ですよ) -【けんぞう!】--------------------------------------------------------- 参加無料:予想が当たれば一攫千金?今月はプロ野球のセパ勝敗とホームラン数 http://www.ken3.org/etc/500yen/5050.html ← 100万を当たった人数で山分け 『チッ、大穴横浜の勝利に賭けてるのに当たらない(笑)』(横浜ファン:30歳) ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

検索フォームで選択した番号を使用する その2 Access Form OpenArg引数でセット位置を渡す方法はどうでしたか? これなら、共通の番号選択処理を使うことができそうですね。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba090.lzh にdb090.mdb(Access2000版)が保存されています。 実は、検索フォームで選択した番号を使用する その3があるのですが、 続きは、次回のお楽しみで。 ※読者の心の声:その3はたぶんあの方法だな、読めたよ三流君。  と聞こえてきたところで。。。  (次回の展開を予想するのも一流読者の密かな楽しみみたいなので(笑)) 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。 ※評価は↓で投票してね。感想は掲示板かメールでくださいね。

No.91 2003/06/23
Access ダイアログフォームって?何? acDialogとPublic変数を使用
[ページTOPへ戻る]

<Access ダイアログフォームって?何? acDialogとPublic変数を使用>

(検索フォームで選択した番号を使用する その3) どうも、三流プログラマーのKen3です。 今回は、 フォーム間のデータのやり取りで、 グローバルにデータを置いて置き処理してみます。 ※前回の続きで、開いた別フォームからデータを受け取りたい、  そんな感じの処理を書きたいと思います。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba091.lzh にdb091.mdb(Access2000版)が保存されています。 何かの参考となれば、幸いです。

/* * 1.今回のキッカケ */

掲示板に下記の質問をもらいました。(三週連続、載せ過ぎだけど) --------------- In message "[BBS :142] Accessでのパラメータ引渡し方法", Yoshi さん wrote... >投稿時間:2003/06/18(Wed) 17:25 > >おなまえ:Yoshi >タイトル:Accessでのパラメータ引渡し方法 >URL : >コメント: > >こんにちは。はじめて書き込みます。 >現在「顧客画面」と「顧客番号検索画面」というものがあります。 >「顧客画面」は、KEYである顧客番号とその他情報を登録、修正、削 >除する画面です。 >「顧客番号検索画面」は、「顧客画面」の顧客番号の検索機能です >。 >つまり、「顧客画面」で登録されている顧客情報を変更する場合 >現在データベースに登録されている顧客番号を一覧(顧客番号検索画 >面)表示させ選択された顧客番号を「顧客画面」に戻すといった方法 >を教えてください。 >すいません、わかりずらいと思うので簡単な図を書きます。 > >1顧客画面 ← 顧客情報の一部の修正を行いたいためこの画面を >開く > >2顧客番号横の検索ボタンを押下 ← 顧客番号がすぐにわからな >いため検索画面を開く > >3顧客番号検索画面が開く ← リストボックスで作成した一覧を >表示 > >4リストボックスの対象行を選択 > >5顧客画面 ← 選択された顧客番号を表示させる --------------- そんな質問に対して、 [No.89 Access 検索フォームで選択した番号を使用する その1] http://www.ken3.org/backno/backno_vba18.html#89 では、 呼び出した検索画面から、呼び出し元画面の 'レコードを移動する DoCmd.GoToControl "顧客番号" '顧客番号フィールドにコントロールを移動 DoCmd.FindRecord LNG顧客番号 '選択された番号のレコードに移動 と、コントロール移動とレコード移動でかわし(逃げて) あまり意味の無い回答でした。 次の(前回の) [No.90 Access Form OpenArg引数でセット位置を渡す] http://www.ken3.org/backno/backno_vba19.html#90 では、 コントロールにアクセスする方法は、 Me.Controls!新規データ Me.Controls![新規データ] Me.Controls("新規データ") なんて、名前を指定する方法があるので、 OpenArg引数でフォーム名とコントロール名を検索フォームに渡し、 stDocName = "顧客番号検索画面" DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtSTART" DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtEND" (↑OpenArgパラメータを発見) 検索画面側で、 n = InStr(Me.OpenArgs, "/") If n <> 0 Then 'スラッシュの位置によって処理する strSETFORM = Left(Me.OpenArgs, n - 1) '左から/の前まで strSETCONTROL = Mid(Me.OpenArgs, n + 1) '/の次から最後まで '顧客番号を指定フォームのコントロールにセット Forms(strSETFORM).Controls(strSETCONTROL) = Me![lst顧客番号] と、 引数を分解、 Forms(フォーム名).Controls(コントロール名) へデータを代入してます。

/* * 2.掲示板やMLでもよくある話? */

ふう、前回の駆け足説明が終わったところで、 掲示板やMLでもよくある話? 読者の声を代弁(笑) 下記は作り話なので、今回の質問者からクレームもらっていないので、 誤解しないでくださいね。 ※質問者の立場と回答者の作り話ですよ(本気にしないでね) 前回の方法は、呼ばれたフォーム側で処理をする方法で、 私がやりたいのは、フォームから値を受け取りたいんです。 ※そんな参照方法で逃げる別の案は聞きたくないし、  OpenArgで渡し、Forms(strSETFORM).Controls(strSETCONTROL)へ代入  は、知ってるし、できなかったらやろうと思ってました。  *なんて書いたらケンカになるなマズ(注意してね) Input Box関数みたいに、ダイアログフォームから値を受け取りたいんです。 そんな方法を知りたくて質問したんです。
Private Sub 検索ボタン_Click()
  Dim MyValue as String
    'オリジナルのINPUTBOXもどき(ダイアログフォーム)から顧客番号が帰ってきて
    MyValue = INPUT_顧客番号検索()

    If MyValue = "" Then
	'キャンセル処理を記述
  Else 
	'ここに検索実行や値を使用したを記述します
        '・
        '・
    End If
End Sub
と、処理したいんです。 まぁ、質問者と受け手の回答者のイメージがズレていると発生する、 そんなよくある話しかなぁ。 最悪は、回答者が、初めから情報を全て出せ、こんなの聞いてない。 オレ様の方法で動くんだ、そんな処理作るな(オイオイ、何様だ?) となったりするし、、、、 そんな現場を目にした初心者の人は、 全文ソースを載せてしまいます。 すると、今度は、 ソースの丸投げですか?困ったもんだサポートセンターと勘違いしているよこの子? こっちは無償でやってんだから・・・と回答者のお偉いさんは言う(オーバーだけど) もっとマズイのが、 テストデータで潰さないといけないのに、 顧客のデータ(実データ)をそのまま掲示板などに載せてしまう。 また、 私宛の質問に添付ファイルで送ってくれる。信用しているのか? どこの誰ともわからない三流プログラマーに、 大事な顧客データを流してくれる・・・ 私が流用したら or メールで送っているので途中でパクられたら? こんな感じで意識が低いんだよね、データの流出って。 そんな暗い、ブラックな話題を主に扱っているのが(オイオイ大丈夫?) 愚痴マガと言われているマニアックな読者?が読んでる http://www.ken3.org/guchi/ --- 三流プログラマー業務の愚痴 です。 No.148 公園デビューする気持ち?と掲示板の猛者達(笑) http://www.ken3.org/backno/backno_guchi29.html#148 No.155 回答者の行き場の無い気持ち(笑) http://www.ken3.org/backno/backno_guchi31.html#155 なんて、書いてます。よかったら見に来てください。 読者の声:宣伝は終わりでいいの?ハヤク次やってよ(笑) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/* * 3.話をやっと戻し、今回やりたいこと */

脱線した、いつものでも今回は長過ぎた前置き話は、置いといて、 話をやっと戻し、今回やりたいこと ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Dim MyValue as String 'オリジナルのINPUTBOXもどき(ダイアログフォーム)から顧客番号が帰ってきて MyValue = INPUT_顧客番号検索() If MyValue = "" Then たしかに、共通で番号検索フォームを使いたいなら、 DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtSTART" DoCmd.OpenForm stDocName, , , stLinkCriteria, , , "顧客データ印刷/txtEND" とセット位置をOpenArg引数で渡すよりは、 MyValue = INPUT_顧客番号検索() と、リターン値でもらえると、面白いよね。 顧客データ印刷画面 ^^^^^^^^^^^^^^^^^^ 顧客コード[ ______ ] 検索 〜 [ ______ ] 検索 (txtSTART) (txtEND) と、印刷開始コード、終了コードをそれぞれセットするサンプル だったら、
Private Sub btn開始番号検索_Click()
    Me!txtSTART = INPUT_顧客番号検索画面()
End Sub
Private Sub btn終了番号検索_Click()
    Me!txtEND = INPUT_顧客番号検索画面()
End Sub
なんて、してみたいよね。

/* * 4.フォームでリターン値を返せないので、 * 標準モジュールとPublic変数で対応してみた */

フォームでリターン値を返せない(もしかしたら返せる?) ので、 印刷指示画面から btn開始番号検索_Click()などの検索ボタンが押されたら、 Me!txtSTART = INPUT_顧客番号検索画面() と、Function INPUT_顧客番号検索画面 なんて、 標準モジュールに作成した、値を返す、Function関数を作成します。 値を返す、Function関数では、 グローバルの変数を初期化します。 顧客番号検索フォームをダイアログ指定で開きます。 ダイアログ指定でフォームを開くと、 開いたフォームを閉じるまで処理が止まっています。   顧客番号検索フォームの処理が走ります   キャンセルボタンが押されたらPublic変数に0をセット後閉じる。   顧客選択のボタンが押されたらPublic変数に顧客番号をセット後閉じる フォームが閉じると、処理が戻ってくるので。 単純に、Public変数をリターン値で返します。 INPUT_顧客番号検索画面 = Public変数みたいな感じで。 *なんだぁ、結局パブリック変数に頼るのね、期待して損したよ  そっ、そんなこと言わないでよ(笑) Access2000の画面だけど、 まずはモジュールを選択して、 新規のモジュールを追加します。 ※モジュールの新規作成 白紙のモジュール編集画面が表示されます。 Public 選択番号 As Long '選択された顧客番号(共通) と Public変数を定義します。 DoCmd.OpenForm stDocName, , , stLinkCriteria, , acDialog とフォームオープンのモードを変更します こんな感じで、フォームを開いて、値を返します。
Function INPUT_顧客番号検索() As Long

    Dim stDocName As String
    Dim stLinkCriteria As String

    stDocName = "顧客番号検索画面"
    'acDialog指定でフォームを開く
    DoCmd.OpenForm stDocName, , , stLinkCriteria, , acDialog
    
    INPUT_顧客番号検索 = 選択番号  '共通変数を代入しただけ

End Function
________________ 顧客番号検索画面の選択フォーム側は、 ~~~~~~~~~~~~~~~~
Private Sub btnキャンセル_Click()
    '共通変数に選択データをセットする
    選択番号 = 0  'ここではキャンセル時の0をセットする
    'フォームを閉じる
    DoCmd.Close
End Sub
Private Sub btn選択_Click()

    '番号選択のチェック
    If IsNull(Me![lst顧客番号]) Then '何も選択されていないか?チェック
        MsgBox "顧客番号を選択してください"
        Exit Sub '関数を抜ける
    End If
    
    '共通変数に選択データをセットする
    選択番号 = Me![lst顧客番号]  'リストボックスの値をセットする

    'フォームを閉じる
    DoCmd.Close

End Sub
と、選択結果を選択番号に代入しただけです。(Publicで定義の変数に代入) さてと、テストは、 ? INPUT_顧客番号検索 とイミディエイト ウインドウでテストしてみました。 無事選択され、データが返りました。 'acDialog指定でフォームを開く DoCmd.OpenForm stDocName, , , stLinkCriteria, , acDialog これを、 DoCmd.OpenForm stDocName, , , stLinkCriteria とすると、どうなるか?違いを試してみてください。 すると、いきなり結果が返ってくると思います。 ※これで、acDialogの動作がわかると思います、 __________________ 顧客データ印刷画面 ^^^^^^^^^^^^^^^^^^ 顧客コード[ ______ ] 検索 〜 [ ______ ] 検索 (txtSTART) (txtEND) 実際に顧客番号を共通で使用する画面に組み込んでみます。
Private Sub btn開始番号検索_Click()
    Dim lngNO As Long
    
    lngNO = INPUT_顧客番号検索 '共通の検索ダイアログ
    If lngNO <> 0 Then  'キャンセル0以外なら
        Me!txtSTART = lngNO  '検索された番号をセット
    End If

End Sub
Private Sub btn終了番号検索_Click()
    Dim lngNO As Long

    lngNO = INPUT_顧客番号検索 '共通の検索ダイアログ
    If lngNO <> 0 Then  'キャンセル0以外なら
        Me!txtEND = lngNO  '検索された番号をセット
    End If
End Sub
lngNO = INPUT_顧客番号検索 と関数的にフォームを呼び出し、リターン値を受け取ります。 キャンセルのチェックをしたいので、 If lngNO <> 0 Then とIf文を入れてます。 ホントは直接、 Me!txtSTART = INPUT_顧客番号検索 が、かっこいいんだけどね。 -【けんぞう!】--------------------------------------------------------- 月500円、タバコなら2箱、120円缶コーヒーなら4缶分の謝礼をGetするなら http://www.ken3.org/etc/500yen/ ←無料アンケート系の広告です。 『チッ、がんばって回答して月500円かよ』(お馬鹿なプログラマー:31歳) ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

こんな感じで、 共通の顧客番号選択フォームをINPUT BOXもどきのように使用することができます。 って言っても、 Publicの共通変数とacDialogを使っただけの、 フォームを開く、中間で処理する関数を作っただけでした。 まぁ、人間関係も直接やり取りするのが難しかったら、 間に人を立てて(爆)なんて話は、愚痴マガネタでしたね。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba091.lzh にdb091.mdb(Access2000版)が保存されています。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。 ※評価は↓で投票してね。感想は掲示板かメールでくださいね。

No.92 2003/06/24
Excel Sheets(X).Name シート名へのアプローチいろいろ
[ページTOPへ戻る]

<Excel Sheets(X).Name シート名へのアプローチいろいろ>

どうも、三流プログラマーのKen3です。 今回は、 Excelのシート名で遊んでみたいと思います。 何かの参考となれば、幸いです。

/* * 1.今回のキッカケ */

掲示板に下記の質問をもらいました。 --------------- >投稿日 : 2003/06/23(Mon) 18:52 >投稿者 : sn >タイトル : EXCelへ出力 > > >ACCESS VBAはまったくのシロオトデス。 >クエリーでのレコードをレコード毎にEXCELにレコード名を取って >レコードの数だけ連続で出力するなんてことできる?、教えていた >だけるとうれしいのですが・・・・・!! --------------- そんな質問の前準備で、 今回は、事前調査でExcelのシート名について探ってみたいと思います。

/* * 2.いつものマクロ記録でプロパティを探る */

さてと、バカの一つ覚えのマクロ記録で、プロパティを探ってみたいと思います。 プロパティ、メソッドの探り方 マクロ記録とF1のHelpを使う http://www.ken3.org/vba/excel-help.html も、ヒマなとき、見に来てください。 マクロ記録でシートの追加、名前の変更を探ってみました。 記録結果は、
Sub Macro1()
    Sheets.Add
    Sheets("Sheet4").Select
    Sheets("Sheet4").Name = "名前の変更"
End Sub
でした。 .Nameプロパティを使用すれば出来そうですね。
Sub test1()
    MsgBox ActiveSheet.Name
End Sub
なんてやると、現在選択されているシートの名前を表示可能です。
Sub test2()
    MsgBox ThisWorkbook.Sheets(2).Name
End Sub
だと、左から2番目のシート名が表示されたと思います。 さらにバカっぽくヤルと、
Sub test3()
    MsgBox ThisWorkbook.Sheets(2).Name
    MsgBox ThisWorkbook.Sheets(3).Name
    MsgBox ThisWorkbook.Sheets(4).Name
    MsgBox ThisWorkbook.Sheets(5).Name
End Sub
'---- ThisWorkbook.Sheets(n番目) で左から2〜5のシートを参照し、 .Nameプロパティの値を使用してシート名を取得しています。 5番目のシートが無いのでインデックスが有効範囲に無いと MsgBox ThisWorkbook.Sheets(5).Name の場所でこけるけど。番号で参照可能ですね。 まぁ、.Countってプロパティがあって、 要素・コレクションの個数がわかるんで、
Sub test4()
    MsgBox "現在のシート数は、" & ThisWorkbook.Sheets.Count & "です"
End Sub
とやると、シートの個数が表示されると思います。 ループでまわして、
Sub test5()
    Dim n As Integer  'カウンター変数
    Dim strMSG As String 'メッセージ作成用のワーク
    
    '一番目のシートから個数分処理を行う
    For n = 1 To ThisWorkbook.Sheets.Count
        strMSG = n & "番目のシート名は" & ThisWorkbook.Sheets(n).Name
        MsgBox strMSG
    Next n
    
End Sub
なんて感じで処理もできます。 サンプルはシート名をMsgboxで表示だけですが、 取得データを変数に入れて使ったり可能だと思います。 >なんでFor Each...Nextを使わないのですか? と、 何人の読者が心の中でつぶやいたかは、わかりませんが、 なんで使用しないのと言われてもなぁ、、 答えは、私の趣味・好みです。 おいおい、そりゃぁないでしょう。 だって、やせてる女性よりチョットふっくらしている女性が好みなんで、、、 じゃなくって、 そろそろ、真面目にいきます、 今回のシート名を取り出すのに、 For Each...Nextを使用すると、 ^^^^^^^^^^^^^^^
Sub test35()

    Dim MyObject As Object 'オブジェクト型にしたけどシート型でも
    Dim strMSG   As String 'メッセージ作成用のワーク

    '一番目のシートから個数分処理を行う
    For Each MyObject In ThisWorkbook.Sheets 'ブックからシートを取り出す
        strMSG = "今見ているシート名は" & MyObject.Name
        MsgBox strMSG
    Next

End Sub
となります。 こんな感じで処理すると、カウンターで回しているより、スマートです。 *まぁ、好みもありますが。。。 For Each MyObject In ThisWorkbook.Sheets など、書式は、書いていくうちになれるので、 複数のオブジェクトをまわす時は、 ぜひ使ってみてください。 少しふっくらがイイのになぁ、、 (まだ言ってるよ、だれかコイツを黙らせて、、、) オブジェクトのループはFor Each In でループさせる http://www.ken3.org/backno/backno_vba15.html#73 も、ヒマな時、のぞきに来てね。

/* * 3.シートの存在をチェックしてみる */

今回、シートの存在チェックはいらないんだけど、 ついでなので、やってみる。 関数の仕様は、いつものようにラフに、 ~~~~~~~~~~~~~~ シート名を受け取り、 判断結果をTrue,Falseで返す関数にします。(したいです) 関数名 :chkSHEET 入力値 :シート名文字列 戻り値 :シートの有無・結果 処理概要:シート名をパラメーターで受け取り、      アクティブなブック内に存在するかを確認し、      結果のTrue,Falseを戻り値で返す 自作のFunction関数で値の受け取りと戻り値の型を書きます。 ^^^^^^^^^^^^
Function chkSHEET(strSNAME As String) As Boolean
    ・
  ・
End Function
>Function chkSHEET(strSNAME As String) As Boolean ^^^^^^^^^^^^^^^↑関数名です、重複しないわかりやすい名前にしましょう。 >Function chkSHEET(strSNAME As String) As Boolean ^^^^^^^^^^^^^^^^^^ ここでは、変数名strSNAME、変数の型は文字列で受け取ることにします。 最後の、 >Function chkSHEET(strSNAME As String) As Boolean ^^^^^^^^^^^^ As Booleanですが、聞きなれない、見なれない人も居るかもしれませんが、 ブール型 (Boolean) 真 (True) または偽 (False)を格納可能な変数の型です。 なんだか、堅苦しい話だなぁ、もっとサクッといかないかなぁ? まぁまぁ、数作っているうちにわかるから。 *値の受け取り方や、型、関数の書式などは、  いろいろなプログラムを見てるうちにわかると思います。 シート名を表示するテストはできたから、 今度は、シート名の表示じゃなくって、 受け取ったシート名が存在するかのチェックをif文を使用して行います。
Function chkSHEET(strSNAME As String) As Boolean

     Dim MyObject As Object

     'ブック内のシート名の比較を行う
     For Each MyObject In ThisWorkbook.Sheets
         '.Nameプロパティのシート名と受け取ったstrSNAMEを比べる
         If MyObject.Name = strSNAME Then
            chkSHEET = True '名前が一致したのでTrueをセット
            Exit Function   'もうすること無いので関数を抜ける
         End If
     Next

     '一つも一致しなかったので、Falseをセット
     chkSHEET = False

End Function
Sub testmain()
    Dim strNAME As String     'INPUT BOX 値受け取り用
        'InputBoxでシート名を入力する
    strNAME = InputBox("シート名を入力してください")
    
        '作ったユーザ関数をテストしよう
    If chkSHEET(strNAME) = True Then
        MsgBox strNAME & "シートはブック内に存在します"
    Else
        MsgBox strNAME & "シートはブック内に存在しません"
    End If

End Sub
とやってみました。 三流君さぁ、なんか、しっくりこないんだよねぇ えっ、どこが?テストで動いてるジャン、 '---- 01: 'ブック内のシート名の比較を行う 02: For Each MyObject In ThisWorkbook.Sheets 03: '.Nameプロパティのシート名と受け取ったstrSNAMEを比べる 04: If MyObject.Name = strSNAME Then 05: chkSHEET = True '名前が一致したのでTrueをセット 06: Exit Function 'もうすること無いので関数を抜ける 07: End If 08: Next 09: 10: '一つも一致しなかったので、Falseをセット 11: chkSHEET = False '---- では、言うけど、ここの処理なんだげとさぁ、 05: chkSHEET = True '名前が一致したのでTrueをセット 06: Exit Function 'もうすること無いので関数を抜ける と 10: '一つも一致しなかったので、Falseをセット 11: chkSHEET = False で、結果をセットして関数抜けてるんだけど、 もうすること無いのでいきなりExit Functionでその下実行しないで抜けてるけど、 流れがなんかなぁ、、、 流れを少しスッキリさせる ~~~~~~~~~~~~~~~~~~~~~~~~ では、少し頭を使って、、、
Function chkSHEET(strSNAME As String) As Boolean

     Dim MyObject As Object
     Dim MyRET    As Boolean    'リターン値を保存
 
     'ブック内のシート名の比較を行う
     For Each MyObject In ThisWorkbook.Sheets
         '.Nameプロパティのシート名と受け取ったstrSNAMEを比べる
         If MyObject.Name = strSNAME Then
            MyRET = True '名前が一致したのでTrueをセット
            Exit For 'もう探す必要無いのでループを抜ける
         Else
             MyRET = False  '見つからないのFalseをセット
         End If
     Next
     
     'リターン値をセットして、関数を抜ける
     chkSHEET = MyRET
     
End Function
これは、どうでしょうか? Dim MyRET As Boolean を定義して、下記の判断で戻り値をセット、 If MyObject.Name = strSNAME Then MyRET = True '名前が一致したのでTrueをセット Exit For 'もう探す必要無いのでループを抜ける Else MyRET = False '見つからないのFalseをセット End If 見つかった時はExit For でループを抜けます。 三流君、なんかなぁ、、サクッといかないみたいね。 まぁ、書き方はいろいろ、女性の好みと一緒とかいつもいってるけど、 少しでもキレイでわかりやすいのにしたほうがいいよねぇ。 ギク、、パターンを読者に読まれているかも。。。 先にFalseで初期化しておくのも一つの手かなぁ? ~~~~~~~~~~~~~~~~~~~~~~
Function chkSHEET(strSNAME As String) As Boolean

     Dim MyObject As Object
     Dim MyRET    As Boolean    'リターン値を保存

     MyRET = False  '先に見つからないFalseを初期化代入

     'ブック内のシート名の比較を行う
     For Each MyObject In ThisWorkbook.Sheets
         '.Nameプロパティのシート名と受け取ったstrSNAMEを比べる
         If MyObject.Name = strSNAME Then
            MyRET = True '名前が一致したのでTrueをセット
            Exit For 'もう探す必要無いのでループを抜ける
         End If
     Next

     'リターン値をセットして、関数を抜ける
     chkSHEET = MyRET

End Function
エラー値で初期化じゃないけど、初期値で見つからないをセットしておく。 見つかれば、リターン値MyRET = Trueとして、 最後にリターン値を返す。 ※こんなフラグとループの作り方もありかなぁ。 枠外解説余談 - ActiveWorkbook と ThisWorkbookの違い ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ActiveWorkbook プロパティは、 現在のアクティブ ブックを返します。 ThisWorkbook プロパティは、 実行されている Visual Basic コードが記述されているブックを返します。 なんだ、同じジャンと私も思いましたが、 今回のサンプルや1つのブックしか使用しない場合は一緒ですが、 2つのブックを切り替えながら行うと違います。

/* * 4.On Error Goto でチェック */

目的を達成するには、いろいろな方法があって、 まぁ、彼女へのアプローチ方法も人それぞれ、得意な形と不得意系とあるんだけど。 私があまり使わない方法なんだけど、 On Error Goto ^^^^^^^^^^^^^ を使用して、エラーを発生させて処理する方法を書きます。 アプローチの内容は、シンプルで、 Sheets(シート名).Cells(1, 1) を参照し、参照エラーが発生したらシート無し、 無事参照できたらシート有りと判断。 へぇ〜、そんな手もあったんですね。 合コンで、目の前の女性の集団を左から名前を見ていかないで、 いきなり、 チエちゃん今日は楽しく飲もうね?と声をかけるんですね。 で、グループ内に居ればいいけど、居なかったらブーブーとエラーだよね。 ※チョット表現にキレがないけど、ゆるしてね。  順番に調べないで、いきなり参照に行くって話しです。 下記のサンプルを見てください。
Function chkSHEET(strSNAME As String) As Boolean

    Dim work As Variant

'エラーが発生したら、ラベルERR_NOSheetsへ飛ぶ
On Error GoTo ERR_NOSheets

    'シートの値を取り出す。ここでエラーならシート無しと判断するため
    work = Sheets(strSNAME).Cells(1, 1) 'ダミーで左上を参照
     
    'エラーが発生しなかったら、リターン値をセットして、関数を抜ける
    chkSHEET = True
    Exit Function

'エラーの時、ここに飛んでくる
ERR_NOSheets:
    chkSHEET = False   'シートの値が取れない=シートが無い

End Function
ポイントは ~~~~~~~~~~ 'エラーが発生したら、ラベルERR_NOSheetsへ飛ぶ On Error GoTo ERR_NOSheets とエラーが発生したら、ERR_NOSheets:へ飛ぶ設定をします。 で、在るか無いかわからないのに、 work = Sheets(strSNAME).Cells(1, 1) 'ダミーで左上を参照 と参照(声がけ)をします。 無事に目的の子(Sheet)にアクセスできたらそのまま処理が流れて、 'エラーが発生しなかったら、リターン値をセットして、関数を抜ける chkSHEET = True Exit Function となり、 エラー発生時は、(目的の子が居なかった時) 'エラーの時、ここに飛んでくる ERR_NOSheets: chkSHEET = False 'シートの値が取れない=シートが無い って、感じのエラーを使用して(利用した)処理方法も存在します。 事前に合コンのメンバーチェックなんて面倒だ、 参加して居なかったら(エラーだったら)、 何もしないで帰ろうって感じの処理、 慣れてくると、事前にイロイロと根回しチェックするよりも、 簡単だったりする。 ※心理的には、エラーが発生しないように、  用意周到に合コンセッティング時みたいに、  いろいろとチェックするんだけど。。。 予断ですが、エラー処理で Resume 'エラーが発生した行から処理を再開します(フラレても再度告白) Resume Next 'エラーが発生した次の行から処理を再開します(エラーの次の子に行く) なんてのもあります。 機会を作って解説したいと思うけど。 -【けんぞう!】--------------------------------------------------------- 三流君の、小金稼ぎ、お小遣い稼ぎシリーズ第3弾(稼げないだろコラ!!) 参加無料:予想が当たれば一攫千金?今月はプロ野球のセパ勝敗とホームラン数 http://www.ken3.org/etc/500yen/5050.html ← 100万を当たった人数で山分け 『チッ、大穴横浜の勝利に賭けてるのに当たらない(笑)』(横浜ファン:31歳) ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

ヤバ、くだらないこと書いてたら、ボリュームが増え過ぎた。 Sheetオブジェクト.Name = "名前の変更" とかで、シート名の変更可能なので(もしかして、2行でよかったの説明?) 次回に、 クエリーからデータ別にシート名をAccessから操作して出力、 そんなんで、遊んでみたいと思います。 同じ処理でも、いろいろと工夫できて、 プログラムは面白い・・そんな風に感じてくれれば・・・ ※彼女を落とした時みたいに、プログラムも創意工夫ですよキット。  (↑それは、成功者が言う言葉だよ、連敗中の私が言う台詞じゃないね(爆)) 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。 ※評価は↓で投票してね。感想は掲示板かメールでくださいね。

No.93 2003/06/25
Access2000 ADOでクエリーのレコードを参照 Excelへ出力
[ページTOPへ戻る]

<Access2000 ADOでクエリーのレコードを参照 Excelへ出力>

どうも、三流プログラマーのKen3です。 今回は、 Access2000 ADOでクエリーのレコードを参照してみたいと思います。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba093.lzh にdb093.mdb(Access2000版)が保存されています。 何かの参考となれば、幸いです。

/* * 1.今回のキッカケ */

掲示板に下記の質問をもらいました。 --------------- >投稿日 : 2003/06/23(Mon) 18:52 >投稿者 : sn >タイトル : EXCelへ出力 > >ACCESS VBAはまったくのシロオトデス。 >クエリーでのレコードをレコード毎にEXCELにレコード名を取って >レコードの数だけ連続で出力するなんてことできる?、教えていた >だけるとうれしいのですが・・・・・!! --------------- そんな質問をいただいたので、 レコード単位で処理してみたいと思います。

/* * 2.クエリーをExcelのシートに書き出すだけなら */

クエリーをExcelのシートに書き出すだけなら ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ まぁ、いろいろな方法あるんだけど、 勝手な作り話を書くと、 テーブル名:顧客 顧客番号 point 住所 氏名 電話番号 記号 100 120 名古屋 ドラキチ あ 200 15 北海道 どさんこ い 310 20 東京 ヤクルト う 320 5 神奈川 横浜 え 400 20 福岡 ダイエー お から クエリー:Q_顧客情報 で、ポイントが20以上のデータを絞りました、ついでに電話番号の項目を削除 顧客番号 point 住所 氏名 記号 100 120 名古屋 ドラキチ あ 310 20 東京 ヤクルト う 400 20 福岡 ダイエー お なんてQ_顧客情報ってクエリーがありました。 クエリーからExcelのシートを作成するのは、 手作業でやってもいいし、 ( ) 定期処理ならマクロを作成 ( ) フォームのボタンに組み込みたかったら(VBAの命令を調べたかったら)、 上記作成マクロを名前を付けて保存で、 保存をモジュールにすると、マクロを変換してモジュールを作ってくれる。 ※Excelのマクロ記録とは違うけど、  アクションを指定したマクロをDoCmd系のVBAに変換してくれるので、  命令を探るときは便利かなぁ。 DoCmd.TransferSpreadsheet acExport, 5, "Q_顧客情報", "e:\work\POINT20.xls", True, "" と命令を調べることが出来ます。 変換方法は下記の画像を見て、簡単なので読者自身もやってみてください

/* * 3.レコード単位で処理したいので、レコード処理を探る */

今回は、そんな単純な話じゃなくて、 クエリーのレコード単位で(1行単位で)、 処理を行いたいです。 う〜ん、何か無いかなぁ。。。 チョット無さそうなので、VBAで作ることにします。 AccessからExcelを作成するのは、少し前にもやりました。 これは、まず置いといて、 クエリーの中身をレコード単位で取り出す方法を調べてみたいと思います。 >> PS.Accessは97or2000どれでしょうか? > >ACCESS2000ですよろしくおねがいします。 ヤバ、Access2000かぁ・・・ADOでやるか。 ※一昔前のDAOは少しやったことあるんだけど。 DAOとADO移行を調べてみると(これから始める人は過去の関係なんて聞かなくても) ※DAO から ADO への移植 http://www.microsoft.com/japan/msdn/data/techmat/ado/dao2ado.asp 上記の情報もみるといいかも。 ざっとみてみると、いろいろあるんだけど、 Recordset を開く場合 ^^^^^^^^^^^^^^^^^^^^^ DAOだと、 Dim db as Database Dim rs as DAO.Recordset Set db = CurrentDB() Set rs = db.OpenRecordset("Employees") ADOだと、 Dim rs as New ADODB.Recordset rs.Open "社員", CurrentProject.Connection, adOpenKeySet, adLockOptimistic へぇ、そんな感じなんだぁ。
Private Sub btnTEST01_Click()
    Dim rs As New ADODB.Recordset
    rs.Open "Q_顧客情報", CurrentProject.Connection, _
                                adOpenKeyset, adLockOptimistic
    MsgBox "テストでレコードカウント表示" & rs.RecordCount
End Sub
と、テストしてみると。 おっ、レコード数持ってこれたね。 なんか、違和感あるけど、まぁそのうちなれるかな。 じゃ、いつものEOFまでループさせますか。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Private Sub btnTEST01_Click()
    
    Dim rs As New ADODB.Recordset  'ADOのレコードセット
    
    'レコードセットを開く(Q_顧客情報)
    rs.Open "Q_顧客情報", CurrentProject.Connection, _
                           adOpenKeyset, adLockOptimistic

    'ループ処理
    While rs.EOF = False  'いつものEOFが偽の間
        MsgBox "氏名は" & rs.Fields("氏名")  '氏名をテストで表示する
        rs.MoveNext  '次のレコードに移動しないと、とんでもないことに(笑)
    Wend

    rs.Close   '開いたら閉じろ、ドアを開けたら閉めるってしつけられたでしょ(笑)
    Set rs = Nothing  '変数も後始末しますか。使った器はキレイにしろって?

End Sub
ポイントは、 ^^^^^^^^^^^^ .Open でレコードセットを開き、 .EOF でレコードセットの終わりを判断、 .Fields("氏名") で、氏名のフィールドにアクセス(値の参照) .MoveNext で、次のレコードに進む .Close で、レコードセットを閉じて、 Set rs = Nothing 変数もお行儀良く開放 まぁ、私も育ちが悪いから、使ったもの使いっぱなしが多いけど、 開けたら閉める、使わなくなったものは開放する、、、キチントしましょうか。

/* * 4.Excelブックを作成、シート作成、データ転記する */

レコードのループができたので、 Excelのブックを作成 Workbooks.Add シートを作成 Sheets.Add , Sheets("Sheet4").Name = "AAA" データを転記する Range("A1") = "xxxx", Cells(2,2) = 999 そんな処理を組み込んでみます
Private Sub btnTEST_TO_Excel_Click()
    
    Dim rs As New ADODB.Recordset  'ADOのレコードセット
    Dim objEXCEL As Object  'Excel参照用

    'Excelを起動する
    Set objEXCEL = CreateObject("Excel.Application") 'オブジェクトの作成
    objEXCEL.Visible = True  'Excelを見えるようにする
    objEXCEL.Workbooks.Add   'Excelのブックを作成

    'レコードセットを開く(Q_顧客情報)
    rs.Open "Q_顧客情報", CurrentProject.Connection, _
                    adOpenKeyset, adLockOptimistic

    'ループ処理
    While rs.EOF = False  'いつものEOFが偽の間
        'Excelのシートを追加、シート名を氏名に変更する
        objEXCEL.Sheets.Add  'シートを追加する
        objEXCEL.ActiveSheet.Name = rs.Fields("氏名") '現在のシート名を変更
        'データをセットする(Accessから転記)
        objEXCEL.Range("A1") = "番号は"
        objEXCEL.Range("B1") = rs.Fields("顧客番号")
        objEXCEL.Range("A2") = "ポイントは"
        objEXCEL.Range("B2") = rs.Fields("point") 
        objEXCEL.Range("A3") = "氏名/住所"
        objEXCEL.Range("B3") = rs.Fields("氏名")  
        objEXCEL.Range("B4") = rs.Fields("住所")  
        
        rs.MoveNext  '次のレコードに移動しないと、とんでもないことに(笑)
    Wend
    '通常は、ここでExcelを保存するんだけど、今回は開きっぱなしの手抜き

    rs.Close   '開いたら閉じろ、ドアを開けたら閉めるってしつけられたでしょ(笑)
    Set rs = Nothing  '変数も後始末しますか。使った器はキレイにしろって?
    
End Sub
ポイントは、 ^^^^^^^^^^^^ Excelのオブジェクトを Dim objEXCEL As Object 'Excel参照用 'Excelを起動する Set objEXCEL = CreateObject("Excel.Application") 'オブジェクトの作成 objEXCEL.Visible = True 'Excelを見えるようにする で、作成。 objEXCEL.Workbooks.Add 'Excelのブックを作成 で、ブックを新規に追加。 あとは、ループの中で、 'ループ処理 While rs.EOF = False 'いつものEOFが偽の間 'Excelのシートを追加、シート名を氏名に変更する objEXCEL.Sheets.Add 'シートを追加する objEXCEL.ActiveSheet.Name = rs.Fields("氏名") '現在のシート名を変更 'データをセットする(Accessから転記) objEXCEL.Range("A1") = "番号は" objEXCEL.Range("B1") = rs.Fields("顧客番号") objEXCEL.Range("A2") = "ポイントは" objEXCEL.Range("B2") = rs.Fields("point") みたいに、 objEXCEL.Sheets.Add 'シートを追加する シートを追加後、現在のシート名を objEXCEL.ActiveSheet.Name = rs.Fields("氏名") '現在のシート名を変更 で、氏名に変更してます。 あとは、好きな位置にデータをセットしてます。 'データをセットする(Accessから転記) objEXCEL.Range("A1") = "番号は" objEXCEL.Range("B1") = rs.Fields("顧客番号") と、A1,B1などセルの位置を指定してセットしてます。 が実行結果の画面です。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba093.lzh にdb093.mdb(Access2000版)が保存されています。 イタズラしてみてください。 -【けんぞう!】--------------------------------------------------------- 三流君の、小金稼ぎ、お小遣い稼ぎシリーズ第3弾(稼げないだろコラ!!) 参加無料:予想が当たれば一攫千金?今月はプロ野球のセパ勝敗とホームラン数 http://www.ken3.org/etc/500yen/5050.html ← 100万を当たった人数で山分け 『チッ、大穴横浜の勝利に賭けてるのに当たらない(笑)』(横浜ファン:31歳) ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

実は、バグがあるんだよね。 どんな? シート名に使えない文字が入っていた時とか(/:\など) 同じ名称のデータを吐き出した時に、シート名がかぶってしまう。 と、 要望あまり聞いてないけど、処理方法が違うような気がする。 ※今回みたいに1レコード1シートにしてもあまり意味無いような。  在るとすれば、  ・クエリーのデータを地域別のシートに転記する(東京・名古屋など地区別シート)   顧客別にシートを作成して、請求明細を複数転記するなどの   1顧客1シート別に転送処理かなぁ。  ・あとは、固定の罫線付きのフォーマットに当てはめる  なんて感じもするけど。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。 ※評価は↓で投票してね。感想は掲示板かメールでくださいね。

No.94 2003/06/26
Access Form_Open Form_Loadイベントの発生順
[ページTOPへ戻る]

<Access Form_Open Form_Loadイベントの発生順>

どうも、三流プログラマーのKen3です。 今回は、 カレンダーコントロール を使用してみます。 (フォームのオープン時に初期化したいと思います) 何かの参考となれば、幸いです。

/* * 1.今回のキッカケ */

掲示板に下記の質問をもらいました。 --------------- >カレンダーコントロールを使用して、 >日付を入力することにしました。 >しかし、今日の日付をクリックしても入力できません。 --------------- そんな質問をいただいたので、 カレンダーコントロールを使ってみます。

/* * 2.カレンダーコントロールって何? */

カレンダーコントロールで遊んでみたいと思います。 標準のコントロールじゃないのですが、 拡張されたコントロールで、フォームに貼って使用可能です (セットアップ時に、カレンダーコントロールを選択しておくと使用できます) Access97の例ですが、 フォームの新規作成後、 挿入・ActiveXコントロール・カレンダーコントロール8.0を選択します。 ( ) おっ、それらしいのが表示されましたね。 プロパティを見ると、 イベントもあるし、いろいろと操作できそうですね。

/* * 3.カレンダーコントロールを使用してみる */

まずは、名前を変えますか。 OLE_Calendar と名称を変更してみました。 ( ) さてと、名前も変更したし、プロパティを参照してみますか。
Private Sub コマンド1_Click()
    MsgBox ".valueの値は" & Me!OLE_Calendar.Value
End Sub
普通のフォームに配置したコントロールと同様に、簡単に使えました。 ※.Valueで値を参照できました。 ( ) .Valueの他にプロパティで、 .Year .Month .Day が存在します。 テストを兼ねて、フォームを開いた時、 当月の1日を選択してみます。
Private Sub Form_Open(Cancel As Integer)
    'フォームオープン時、カレンダーを当月の1日にする
    Me!OLE_Calendar.Year = Year(Date)   'システム日付から
    Me!OLE_Calendar.Month = Month(Date) 'システム日付から
    Me!OLE_Calendar.Day = 1 '1日を固定代入
End Sub
としてみた。 あれ、、、変わらないよ、おかしいなぁ。。。

/* * 4.フォームのイベント発生順に注意 */

ヘルプを調べてみると、 Openイベントは、フォームが開くときに、最初のレコードが表示される前に発生 レポートの場合、レポートがプレビューされるか印刷される前に発生します。 Open イベントは、Load イベントよりも前に発生します。 Load イベントは、フォームが開くか、またはフォームのレコードが表示されたときに発生します。 最初にフォームを開くと、 次の順序でイベントが発生します。 Open --> Load --> Resize --> Activate --> Current ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ そんな順番なんだぁ、気にしてなかった。 コントロールへフォームのロード前に代入しているからか? それで代入しても無視されているのか。 まぁ、Resize Activate Current のイベントで、 コントロールを初期化するとマズそうだから (アクティブやサイズ変更と触っただけで、初期化すると処理的に怒られそう) Loadに入れてテストしてみます。
Private Sub Form_Load()
    'カレンダーを当月の1日にする
    Me!OLE_Calendar.Year = Year(Date)   'システム日付から
    Me!OLE_Calendar.Month = Month(Date) 'システム日付から
    Me!OLE_Calendar.Day = 1 '1日を固定代入
End Sub
無事にうまく行きました。 ※システム日付の月初が選択されました。 -- 余談 -- ~~~~~~~~~~ アトアト考えてみると、 フォームのオープンを下記のようにキャンセルできるってのは、
Private Sub Form_Open(Cancel As Integer)
    'データチェック
    If XXXX = XXXX Then
        Cancel = True  'フォームのオープンをキャンセルする
    End If
End Sub
イベントの発生順が Open --> Load --> Resize --> Activate --> Current ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ だから、 頭のOpenで表示Load前にキャンセルって感じなんでしょうね。 う〜ん、初期化処理って、 Open(開く時)のイベントに書きそうだけど、 物によっては、注意が必要ですね。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -【けんぞう!】--------------------------------------------------------- 転職関係、在宅プログラマー、SOHOの広告まとめました http://www.ken3.org/etc/500yen/zaitaku.html いろいろとあるので転機の人はぜひ 『だだ、広告料稼ぎたいだけだろ、紹介料300円〜1500円の小金稼ぎ』 ギクっ、、、バレた(笑)登録料無料、匿名で探せるので在宅で小金稼ぎの人も見てね ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

ヤバ、質問のクリックしたら日付の代入までいかなかった・・・ 今回は、カレンダーコントロールの紹介とイベントの発生順でした。 実際の使用方法は次回に、、、 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。


検索して目的の情報を探す。

目的の情報を探すには、最近はググれとよく聞きます。なので、検索ボックスを付けました。
いろいろなキーワードを入れて、検索してみてください。

カスタム検索
三流君(site:www.ken3.org) 内を Googleを利用してキーワード する

ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。

質問や要望など メッセージを送る(三流君に連絡する)

質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。
あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



(感想や質問・要望 メッセージはHPで記事に載せることがあります。)

急ぎで連絡がほしい、そんな時は:[三流君連絡先]に連絡してください。

リンクや広告など

項目別に↓に人気の記事をまとめてみました。お探しのジャンルを選択してください。
人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]

仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]

Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です

Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます

Blog:[三流君の作業日記]/ [サンプルコードのゴミ箱]/ 広告-[通販人気商品の足跡]



[三流君(TOP ken3.org へ戻る)] / [VBA系TOPへ] / [VBA系バックナンバー目次へ移動]