三流君 VBAで楽しくプログラミング(Excel/Access VBAの解説/サンプルです)
[VBA系のバックナンバー]
[VBA系 TOP]
[三流君 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でした。
※評価は↓で投票してね。感想は掲示板かメールでくださいね。
<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でした。
※評価は↓で投票してね。感想は掲示板かメールでくださいね。
<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でした。
※評価は↓で投票してね。感想は掲示板かメールでくださいね。
<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でした。
※評価は↓で投票してね。感想は掲示板かメールでくださいね。
<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でした。
検索して目的の情報を探す。
目的の情報を探すには、最近はググれとよく聞きます。なので、検索ボックスを付けました。
いろいろなキーワードを入れて、検索してみてください。
ページフッター
ここまで、読んでいただきどうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。
質問や要望など メッセージを送る(三流君に連絡する)
質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
|
感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。
|
急ぎで連絡がほしい、そんな時は:[三流君連絡先]に連絡してください。
リンクや広告など
項目別に↓に人気の記事をまとめてみました。お探しのジャンルを選択してください。
人気記事(来場者が多い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系バックナンバー目次へ移動]