Q.VBAを覚えたいんですけど、どうやって覚えたらいいでしょう?


ほかのプログラミング言語をやっていた人なら、Helpの例を見ればそのHelpで説明している以外のことも解ってしまいますよね。IF文の書き方とか、関数の呼び方とか、変数の定義のしかたとか。
ところが、悲しいかな Access を使う人の多くはプログラミング経験がありません。そういう方々は高レベルな会議室などで質問をしても要領を得なかったり、常連のみなさんに「まずメールの書き方を覚えれ」とか冷たくあしらわれたりしますよね(^^;)(たしかに、質問する態度やメールの書き方などのマナーを覚えることはとても大事です、人としてダメな奴も多いですから)

 

なぼも昔は「冷たくあしらう派」でしたが、最近はそれじゃーダメだろう、と考えるようになりました。肝心の質問には一切答えず、「投稿のしかたを守れ」とだけしか言わないのって、あんまりにもタカビーあんたなに様じゃないですか?(でも、中にはほんとうにヒドイ投稿をする奴がいるのも確かです)
お偉い先生方は偉いんですからかまいませんが、なぼはまだまだライトユーザーの域を出ていませんから(^^;)そんなことはしたくないです。時々しちゃうけど。
コンピューターが一部のコンピューターの専門家、自分でCPUの設計までできちゃいそうな大学の研究室レベルの方々だけのものだった時代は終わったのです。知らないから覚えようとしている人の意欲をくじく真似は、この業界の先人として恥ずべき行為ですよね。
まぁ、中には親切にマナーまで教えてくれようとしている方に暴言を吐いたりする失礼な奴もいますが、(多分自分が誰だかわからないだろうと思っているんでしょうが、調べようと思えば住所までつきとめられるんですよ)そういう人には孤独を愛していただくことにして、このサイトでは「覚える気持ちがある」人を対象にしていきたいと思います。

おっと前置きが長いですね(^^;;)
まず、早めに覚えたほうがいいポイントをあげてみます。

  • IF・・・ELSE・・・ENDIF、変数の定義、値の代入
    VBAで記述する最大の目的は、「変数の利用と条件による分岐処理」だと思ってます。
    つまり、「ある項目の値が××のときAの処理、◎◎のときBの処理」と、状況によって行いたい処理が違う場合。
    処理の内容は関数を呼ぶだけとかフォームを開くだけとか簡単なものであっても、マクロでは対処しきれない場合があります。

    Dim Ret as Integer   ←1
    Ret = MsgBox("処理していいですか?",vbYesnoCancel)   ←2
    IF Ret = vbOK then   ←3
    Docmd.OpenForm("処理用フォーム")   ←4
    ELSE   ←5
    IF Ret = vbCancel then   ←6
    MsgBox("キャンセルしました")   ←7
    End If   ←8
    End If   ←9

    1. 「Ret」という名前の整数型の変数を定義している。MsgBox関数戻り値である、「どのボタンを押されたか」という情報をとっておくのに使う

    2. MsgBox関数を実行。「処理していいですか?」というメッセージを画面に出し、オペレータにOK、NO、キャンセルボタンのどれかを押してもらい、どれが押されたかを「Ret」という変数保存(値の代入)している

    3. もし、「Ret」の中身が「vbOK」だったら、という判断をしている。つまり、前のMsgBox関数を実行したとき、オペレータが押したのがOKボタンだったら、という意味。もしOKボタンを押した場合、4.の処理を実行することになる。

    4. 「処理用フォーム」というフォームを開いている。マクロのアクション「フォームを開く」と同じ処理を実行するためのDocmdオブジェクトを使っている。3.での判断結果が「正」のとき、つまりオペレータがOKボタンを押した時だけ実行される。

    5.  3.での判断結果「誤り」の場合、という意味。オペレータが押したボタンがOKボタンでない場合(キャンセル、NOのどっちか)4.の処理をせずにこっちに制御が移る。

    6. もし、「Ret」の中身が「vbCancel」だったら、という判断をしている。つまり、前のMsgBox関数を実行したとき、オペレータが押したのがキャンセルボタンだったら、という意味。もしキャンセルボタンを押した場合、3.での判断結果が「誤り」となり制御が5.に移ってきて、6.の判断が実行される。

    7. MsgBox関数を実行。オペレータにキャンセルしたことを確認通知するために、画面に「キャンセルしました」というメッセージを表示している。

    8. 6.のif文の終了。If文1つにつき1つ、必ずEnd Ifが必要になる。Elseは必要がなければ無くてもよい。

    9. 3.のif文の終了。

    どうでしょう?なんとなく、「処理の分岐」のイメージがつかめてきましたか?
    このように、If文を使えば、IIF関数ではできなかった複雑な判断ができるようになり、それだけ小回りのきく処理を行うことができるようになります。

    ここで注目してもらいたいのが「判断」「変数」です。
    「判断」の結果は、「正」「偽(誤り)」の2種類しかありません。(VBAではこれをTrue(正)False(偽)とあらわすことがありますので覚えておきましょう)
    では、分岐処理は2つにしか分岐できないのか?いいえ、そうではありません。
    この例のように、If文の中でさらにIf文を書くことができるので、判断結果がFalseだったとき別の判断をするようにすれば、いくつにでも分岐することができますね。もちろん、判断結果がTrueだったときにまったく別の判断をすることもできますから、AndとOrが複雑にからみあう条件を指定するときなど便利です。

    ここで、なぜ「Ret」という変数を使ったのかというと、MsgBox関数の結果を保存しておきたいからなのですが、今回の場合は「NO」ボタンを押されたときに何もしていませんから、分岐は2つで済むので結果を保存しておく必要は、実はありませんでした。
    が、「NO」ボタンを押されたときに別のフォームを開く必要があったときどうでしょう。MsgBox関数の結果を変数に代入しておかなければ、2つにしか分岐することができません。

    IF MsgBox("処理していいですか?",vbYesnoCancel) = vbOK then
    Docmd.OpenForm("処理用フォーム")
    ELSE
    MsgBox("キャンセルしました")
    End If

    結果を保存しないとすると、上記のようになるのですが(このページの下「関数の呼び出し方」参照)、この場合Elseに制御が移ったときには、もうMsgBox関数の結果はどこかへ行ってしまっています。NOボタンなのかキャンセルボタンなのか判断しようとしてもできないのです。

    このように変数は、あとでもういちど使いたい値を保存しておいたり、数を数えたり、四則演算をしたり、別のモジュールに値を渡したりといろいろなことに使えます。
    変数には本体のEXEが終了するまで(Accessの場合はMSACCESS.EXEの終了 またはMDBを閉じる)値が残っているものもあれば、定義したモジュールが終わってしまえばメモリ上から消えてなくなってしまうものもあります。用途によって使い分けましょう。

    変数に値を代入するには、= を使います。
    a = 1
    これで、「a」 という変数「1」という値が入りました。マクロの「値の代入」アクションよりも簡単ですね!
    上記の例では、MsbBox関数が返してきた「どのボタンが押されたか」という情報を = を使って「Ret」に代入しているわけですね。こうすることにより、このモジュールの中ではいつでもMsgBox関数の結果を見ることができるのです。

    *各関数の詳しい機能についてはHelpを参照してください


  • Docmdオブジェクトの使い方
    マクロは使ったことがありますか?フォームを開いたり、レポートを印刷したり。
    実は、VBAでもマクロは使います。正確にはマクロではなく、Docmdオブジェクトですが。
    フォームを開いたり、閉じたり、レポートを印刷したり、プレビューで開いたりといった動作は、VBAに対応する命令は用意されていないので、Docmdオブジェクトを利用して実行することになります。
    ただしVBAで利用するときには日本語名でアクションを指定できないので、(旧バージョンのAccessではできる場合があります)Helpを引いてVBAでの記述を調べる必要があります。
    また、DocmdオブジェクトにはないアクションVBAに対応する命令があるアクションもありますので、Helpで確認しながら利用するようにしましょう。
    (値の代入アクションやメッセージの表示アクションはDocmdオブジェクトにはありません。また、フォーカスの移動アクションや再描画アクションはVBAに対応する命令が用意されているのでVBAの命令を使いましょう)


  • 実行中オブジェクトのコントロールの値の参照
    実行中オブジェクト、というとなんだかわらりづらいですが、要するにフォームレポートのことです(^^;)
    みなさんがVBAを記述するとしたら、おそらくフォームやレポートの「イベントプロシージャ」内でしょう。
    だとすると、「フォームのこの項目に入ってる値が見たい!」とか「いま印刷してるデータで計算したい!」ってことになってきますよね。
    この場合よく見掛けるのが、

    Forms![フォーム名]![コントロール名]

    という文法ですね。クエリーなどでフォームに入力された値で抽出処理したい場合など、この書き方を勉強したのではないでしょうか?
    イベントプロシージャに限ってですが、自分のフォームやレポートのコントロールの値を参照する場合には、フォーム名やレポート名を省略することもできます。

    Me![コントロール名]

    と書けば、自オブジェクト内のコントロールだと判断してくれますので、いちいちフォーム名やレポート名から書かなくても大丈夫です。ただし、レポートから表示中のフォームの値を参照、って時には自オブジェクトじゃないですから、フォーム名から書かないとだめですよ。
    では、一番よくある(と、思われる 実際はそんなのないかな・・・)パターン、レポートの詳細セクションに、「数量」と「単価」から、「金額」を計算して求める処理をやってみましょう。

    Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    '詳細セクションのフォーマット時イベント

    Me![金額] = Me![数量] * Me![単価]

    End Sub

    [金額] は詳細セクション上の非連結コントロール、[数量]と[単価]は連結コントロールだとします。
    * は「掛け算を行う」という記号です。四則演算の記号についてはHelpで確認してください。


  • 関数の呼び出し方
    VBA内でも関数はもちろん使えます。上記の例でもMsgBox関数を使いましたよね。
    関数の呼び出し方にはいくつかの記述方法があります。DLookUp関数で説明しましょう。

    • Me![名称] = DLookUp("商品名","商品マスター","商品コード='" & me![商品コード]& "'")
      一番一般的な書き方ですね。DLookUp関数の結果を、「名称」という名前のコントロールに代入しています。
      こうすれば、変数などを利用せずに直接「名称」というコントロールに商品名を表示することができます。

    • If IsNull(DLookUp("商品名","商品マスター","商品コード='" & me![商品コード]& "'")) Then
      商品名をどこかで使うわけではないけど、関数の結果を一時的に判断したい時このようにIf文の中で呼んでしまうことがあります。この場合、判断処理が終わったら取得した名前は消えてしまいますから、商品名をどこかに表示する必要がでてきた時にはもう一度DLookUp関数を実行することになってしまいます。

    • Call DLookUp("商品名","商品マスター","商品コード='" & me![商品コード]& "'")
      ただ呼ぶだけ、結果を保存も判断もなにもしない場合、先頭に「Call」をつけて呼び出すことができます。
      DLookUp関数ではまったくなんの意味もない呼び出し方ですが、自分で作った標準モジュール等を呼び出す場合、モジュール内で処理さえしてくれればいい、結果の判断は必要ない、という時にこのような書き方をすることもあります。



ここまで覚えれば、もうVBAは大丈夫。恐いことはありません。
Helpに載っている例だって、参考書のサンプルモジュールだって、以前とは比べ物にならないぐらい「見えてくる」はずです。
え?DAOの説明がない?だって、DAOとVBAは別物なんですよ。
DAOは、VB等他言語からも使えるJetエンジンとのインターフェースです。SQLエンジンの特性、レコードセットの性質など覚える事柄も多く、習得は簡単ではありません。いきなりDAOを使おうと無理をするから、VBAへの敷居が高くなってしまうんですよ。

・・・そうは言っても、「VBAを覚えたい」理由のダントツNO.1は「DAO、ADO を使いこなしたい」でしょう。(^^;)
ここで説明すると長くなりますので、また別の機会に・・・・

*そんなあなたにお勧め書籍*

Access VBAプログラミング開発工房 入門・基礎編

Access VBAプログラミング開発工房 データベース構築実践編

まずは上の↑1冊でもいいと思うんだけど、Access前提ならデータベース使うの前提なわけで、セットで読んだほうが実務に近くていいかも。
使いもしないメソッドをソラで覚えたっていいことないんで。

ちまたでは矢尻かおり氏の本が人気らしいけど、私は緒方典子さん派です。

トラックバック(0)

トラックバックURL: http://www.naboki.net/movabletype/mt-tb.cgi/31