![]() |
![]() |
||||
![]() |
![]() |
![]() |
![]() |
![]() |
|
Lotusnut >> Soft >> Visual Basic for Application >> VBA
前章「エクセル」の項で、標準関数(エクセルのセル上で利用できる予め用意された関数)の例を示しました。
セル範囲の合計を計算する関数 =sum(範囲)を例にとりましょう。例の「E列」のような記述によって、セルE2に表示される合計額は300点になり、平均は75点になります。
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | 国語 | 算数 | 理科 | 社会 | 合計 |
| 2 | 80 | 85 | 65 | 70 | =SUM(A2:D2) |
| 3 | 80 | 85 | 65 | 70 | =AVERAGE(A2:D2) |
標準関数はとっても便利で、標準関数の範囲内で作成できるプログラムなら、シート上にうまく配置したフォームで見栄えの良い作品ができるでしょう?そして、それを作者自身のみが使うというのであれば、とても魅力的で簡単な操作で思ったような仕事ができるとおもいます。また、とてもよくできた作品は、ぜひとも他人にも使ってもらって評価を得たいものです。また他人に使ってもらうことによって、勉強にもなり、プログラムの腕も上がるというものです。しかしながら、第三者に使ってもらうとなると、いろいろ問題が出てくることも確かです。その一つの例が上記の標準関数を消されない(上書き)ように守ってあげる必要性が出てくるということです。つまり、関数というものを知らない人が関数の入ったセルを侵す危険があるということです。確かにそのためにEXCELには、セルを保護する仕組みもちゃんと整っています。普通の人は、この保護の仕組みを利用して、大事な関数を守ってあげるシート上の標準関数を中心としたプログラムを作ることを心がけていけばよいと思います。
しかしながら、なぜそれでもVBAを使うプログラムの必要性や必然性があるのでしょうか?
一つは上記のような他人に使ってもらう時、未然にエラーを防ぎたい。一つは上級?の段階に進みプログラムを勉強したい。一つは関数を裏で(VBA)つくり、セルに値として返す有利さ。・・・などなど有利な点は、数多くあると思います。すこし、その辺のことを記述していきたいと思います。
皆さんは、マクロとVBAは何が違うと感じているでしょう?コードを見た上では、どちらも同じではないかと思われるでしょう?一言で言うと、マクロはあくまでエクセルの用意された標準的なロジック(コード)といえます。それに引き換えVBAを使うということは、コードを一から自分で考え、自分で作れる所に違いがあると思います。マクロは操作の記録によってエクセルが自動でコードを書いてくれ、それを理解しようがしまいが、動くのです。つまり、自分で作ったという感覚が薄れると感じるのです。
ここで、自作という意味で、上記の見本に出したSUM関数を自分なりにロジック(コード)で表わすと、別表・ロジックのようになります。標準のSUM関数とは、引数(=()で囲んだロジックに渡す値)の数に違いがありますが、VBAを勉強することで、標準関数の動き方が大体自分なりに理解できるようになります。(このことは、コンピュータという言う広域の意味を理解する上でもとても勉強になることです。) また、下段のロジックで示したとおり、シート上のセルを変化させた時のイベントのコードでは、もちろん、標準関数でセルに書き込んだ関数を他人に消されても、まったく問題のない裏(自分なりの表現では見えないところという意味)で動かし、結果を表に出すというVBAの行為は、明らかに有利なエクセルの設計になると思っています。
|
Private Sub Worksheet_Change(ByVal Target As Range) |
VBAを使う上で、二人三脚の役割を果たすのが、「ユーザーフォーム(form)」です。エクセルメニューの「ツール」「マクロ」「Visial Basic Editor」を開いて見てください。「挿入」「ユーザーフォーム」でフォームの基が表示されます。そして、下図のような「ツールボックス」内のコントロールを使って、フォームを設計します。

具体的に、あるフォームを見て見ましょう。
![]() |
フレームの中に入れることによって、複数のオプションボタンが一つのみ選択可能になります。 基本的なコントロールで、数字・文字列・日付、なんでも入る変数の箱の役割を担います。 名称や番号記号等をリスト化し、ユーザーインターフェースを楽にさせます。 コンボボックスが表示部分が一行に対し、数行が見えるリスト構造になります。 実行やキャンセルのきっかけになるボタンコントロール チェック付のラベル判定に利用します。 タブインデックスを切り替えとして、数ページの項目を管理できます。 |
それでは、具体的にコントロールの利用の仕方を提示しましょう・・・
1) コンボボックスにリストを作り選択された項目をテキストに表示するフォームを作ってみます。
![]() |
まず各コントロールの説明と名前を付けます。 |
|
Private Sub UserForm_Initialize( ) |
|
フォームの起動前のイベントは’UserForm_Initialize( )’を使います。ここで、リストにジャンルを結びつけ初期表示のリストを決めます。 |
![]() |
今度は、リストで選択した項目をテキストボックスに表示します。
Private Sub cboGenre_Change() |
そして、最後にテキストに入力された項目をセルに出力するロジックとフォームを閉じるロジックを提示します。
|
Private Sub cmdOk_Click() ![]() Private Sub cmdCancel_Click() |
当然ながら、上記のような冗長なフォームの設計をするプログラマーはいないと思うのですが、リストの使い方。コントロールからコントロールに値を渡す流れ、セルに出力する方法等、初心者の方には、コードをなぞってみてほしいと思います。このような簡単な設計が基本となって複雑なロジックも生まれていくということを、感じてください。
VBA(VB)には、プロシージャという定義された二つの「かたち」がある。
ひとつは Private sub test(ByVal intCcount As Integer ) ・・・・・End Subでsubプロシージャと呼ぶ。
もひとつは、Public Function test(ByVal intCcount As Integer) As Boolean ・・・・・ End FunctionでFunctionプロシージャという。
ともに( )のなかは、引数と呼ばれ、値渡しや参照渡しで 〜Endまでのコードの中で、必要に応じて利用する。そして、この二つのプロシージャのなかでも、Functionプロシージャは (引数)の後に As ・・・(Booleanは型のひとつ) のかたちで、値を返すこともできる。つまり、Functionプロシージャのことを特に関数と呼んでいる。もうお気づきのことかと思いますが、標準関数の「関数」とは、引数を渡し、値を返す (たとえばSUM(範囲)の結果が合計)Functionプロシージャのことであるといえます。
二つのどちらのプロシージャも利用されるわけですが、自分で作るプロシージャは、できるだけ関数(Function)になるように作ることを心がけたいものです。しかも、特に何かの結果を返すものの他では、正常に関数が動いたかどうかの検証を伴った関数にすることによって、より強固なロジックができると思っています。それらの例をできるだけこの後で、示せたらなと思っています。
プロシージャ(自分は好んで「ロジック」という)を作成する上で、個人的に考えて作っていく信条がある。それは、汎用性があり後々再利用できるように、一つ一つのロジックを検証しながら積み上げていくということである。そのためにも引数をうまく利用することになる。そして、最初の解説の項でも述べてあるが、「安全なエラーコーディングの実践」である。エラーを未然に防ぎつつエラー箇所がわかり易くなるような書き方である。エラーが埋もれて表面のみが、なんとなく動くという作り方は、どうも自分のスタイルには合っていなし。以下の項では、大胆にも・・・恥ずかしくも・・・小生のロジックを提示したいと思うのだが、あくまでもプログラムロジックというものは、個人の趣味性が強く出るもので、個性が出るものです。その手の先輩諸氏には、なんか変でない?というようなロジックも度々目にしてしまうかも知れませんが、そこは、まさに大目に見て、通り過ぎてください。
というわけで、趣味的ロジックにお付き合いください。
下記のロジックを見てください。3行目でいきなりエラー処理の宣言をします。・・・以下にエラーが発生したらErrTrap(23行目)に飛ぶ。つまり予期しないロジック中のエラーはすべて、実行することなくエラーとして処理し、デバックの手伝いをします。もちろん実行途中で、ユーザーによる予期できるエラーをメッセージなどで、知らしめることは、懸命な処理ですが、実は、エラーの大敵は、予期できぬエラーであったり、予期できても、完璧なロジックへの道は険しいのが現実であることを考えると、少なくても、たとえばエラー処理に「On Error Resume Next(エラーが発生しても無視して次の処理に進む)」を使うようなロジック構成にすべきではないと思うのです。9行目と18行目の処理も重要です。自作のプロシージャは必ず関数を使っていただきたいことは、先に説明しました。False(偽)で初期化し、ロジックが正常に進めば、True(真)でロジックを完成させます。ロジックの終了(Exit Function)のすぐ前に書くことで、予期せぬエラー以外のエラーでの終了処理を受けて側の関数へ真偽を渡すことができます。
|
次にExcelで使うロジックをいくつか紹介したいと思います。
エクセルで、VBAを利用する要素に欠かせないのが、フォームの設計でしょう。前節までに少しさわりを述べてきましたが、ここでは具体的にフォームとエクセルの連携について述べて生きたいと思います。また、エクセルの頁でセル上のコントロールを説明しました。それらとは、動作的には似ているのですが、Visual Basic Editorで作成するフォーム設計は、もうほとんどVBやCの世界で、エクセルとの連携では、ボタンや右クリックをイベントとして表示させるもので、ここまでくれば、ローカルプログラムの設計となんら違いの無く引けをとらない「プログラム」になります。しかもEXCEL−VBAということですから、主要な表処理や表示はEXCELのセルや印刷機能に任せて、ただ、EXCELとのインターフェースプログラムに集中できるという利点が出てきます。皆さんも実際に作成を始められれば、それを実感できると思います。
十人十色とは言いますが、プログラムの設計もやはり、人の個性が出てきます。読者諸氏の皆さんには、気に入らない点等多々あることをご了解の上、お付き合いください。
|
ポイント:エクセルを理解されている方には、すぐお分かりになると思うのですが、通常右クリックは、使用頻度の高いエクセルのメニューが割り当てられています。右クリックの制御を強制的に自作フォームに割り込む形になるので、18行目でその辺との兼ね合いを取ってあります。(何を言っているかわからない方は、18行と21行をはずして、試しても理解できると思います。)
右に図のように、右クリックで、フォームを表示した後、必要なテキストボックスに項目を入れ、「セル出力」ボタンでセルに出力しています。見てのとおり、テキストボックス、スピンボタン(日付変更)、オプションボタン(収入・支出の別)、各種ボタン等適材適所に配置することが重要です。 |
上記のセルへの出力の例は、勿論あくまで一例であって、いろいろと出力の書き方はあります。36行〜40行目のコントロールの値を配列変数に格納し、セルに結び付けることです。この例でも一つずつコントロールの値をセルに出力しても、OKなのですが、セルに出力する時が一番速さに影響するので、出力するときは、一気に。その前準備として変数にできるだけ格納しておくことを心がけたいものです。