はじめてのExcelVBA~基本~

こんにちは。クニ吉です。
年明け早々、胃腸炎に風邪のダブルパンチで大変でした。。。
遊びにいくどころか読書も進まないし、レイトン教授vs逆転裁判(ゲーム)もなかなか進まず、ちょっとストレス溜まりました;
とりあえず、ほぼ復活&クリアです(^^)v次はシュタインズゲートだっ

最近Accessのブログばっかりだったので、ちょっと違う内容を書きたいなーということで、今回はVBAをネタに。
プログラミングを全くといっていいほどわからなかったので(今もマスターしてません)、わからなかった時のことを思い出しながら書いていきます。

なぜVBAを使うのか

様々な言語がある中どうしてVBAなのかというと、私は事務職のためExcelやAccessを使うからです。
VBAも様々な処理をボタンひとつ、アクションひとつで実行できます。
例えばボタンクリックで集計をしたり、文字入力後に書式を変更したり、メッセージを表示させたり。
とにかく面倒くさがりなので自分でやらなくてもできることはプログラムにやらせたい!(自分が作れる範囲で)と、たいへん個人的な理由から始めましたが、実際普段の作業時間はだいぶ短縮され、短縮された分他の仕事をできるようになったり急ぎの作業もささっと対応できるようになりました。
人間は思考することや自由に体を動かすことができますので、プログラムに任せて空いた時間を「人」にしかできない仕事にあてた方がいいですよね(^^)

コードはどこで書くの?~モジュールについて~

何らかの処理を実行させたい場合にはコードを記述していくわけですが、コードを書く場所のことを「モジュール」と言います。
モジュールは4種類あり、その特徴は下記の通りになります。

  • Microsoft Excel Object
    ブックやシートのオブジェクトに対するコードを記述します。
    ワークシートモジュールはシート毎に用意されています。
  • 標準モジュール
    共通して利用できるような汎用性のあるコードを記述します。
    すべてのモジュールから呼び出すことができます。
  • クラスモジュール
    独自のクラスを定義する際に記述します。
  • ユーザーフォーム
    フォームを作成した場合、フォームやフォーム上のコントロールに対するコードを記述します。

モジュールはVBEを起動すると表示され、記述できるようになります。

VBE起動

コードの基本~プロシージャについて~

プロシージャとは、複数の処理をまとめたプログラムのことです。
例えば、下記のような塊をひとつのプロシージャとします。
これはワークシートがアクティブになった時に現在の日付を画面に表示するものです。

Private Sub Worksheet_Activate() ←ここから始まり
 Dim dtmHiduke As Date
 dtmHiduke = Date        間に処理を記述
 MsgBox dtmHiduke
End Sub              ←ここで終わる

プロシージャには下記のような種類があります。

  • Subプロシージャ
    操作を実行することができます。値を返すことはできません。
    【構文】 Sub [プロシージャ名]([引数])・・・処理記述・・・End Sub
  • Functionプロシージャ
    関数と呼ばれ、計算結果などの値を返します。
    例えば受け取ったinteger型の引数(仮に「売上金額」)に対して、その値によりstring型の結果(「達成」などの文字列)を返すことができます。
    【構文】 Function [プロシージャ名]([引数] As [引数のデータ型])As [戻り値のデータ型]・・・処理記述・・・End Function
    ※データ型については、後ほど書きます。
  • イベントプロシージャ
    特定の動作によって実行することができます。 
    例えば「ワークシートがアクティブになった時」、「ボタンが押された時」等です。
    【構文】 Sub [プロシージャ名]_[イベント]・・・処理記述・・・End Sub
    この[イベント]というのは、すでに用意されています。詳細についてはまた別の機会に書きたいと思います。

また、プロシージャは別のプロシージャを呼び出すことができます。

プロシージャの呼び出し

このように分割するメリットとして、例えば汎用性の高いプロシージャを分割すれば同じコードを何度も書かなくて済むようになります。
何か変更があった場合に修正箇所が少なくなるため、メンテもしやすくなります。
【呼び出し】 Call  [プロシージャ名] 
呼び出しはプロシージャ名だけでも呼び出すことはできますが、プログラムを見やすくするためにCallと書くことをお勧めします。

コード記述のお作法~変数とデータ型~

では、プロシージャをおさえたところで、中身を見ていきましょう。
先ほどのコードが何をしているのかを書いています。

Private Sub Worksheet_Activate() 
 Dim dtmHiduke As Date ←変数宣言
 dtmHiduke = Date ←Date関数を使い、変数に現在の日付を代入
 MsgBox dtmHiduke ←MsgBOX関数を使い、変数内の値を画面に表示
End Sub

記述していく上で重要なのが「変数」と「データ型」というものです。
「Dim strHiduke As Date」という部分ですね。
「strHiduke」が変数、「Date」がデータ型となり、上の文は変数宣言と言って、「Date」型の「strHiduke」という変数を使うよーと宣言しています。
では変数とデータ型について詳しく書いていきます。

~変数ついて~

変数とは、データを一時的に格納する入れ物です。大抵の人が「データを入れる箱」という説明をします。
しかし、当時の私はそれだけではあまりピンとこなくて、コードを擬人化して説明してもらってやっとわかりましたw
というわけで、擬人化して説明します。
Aさんは製造メーカーさんで、「Date(日付)」という製品を作っています。
Bさんは小売店さんでお店で展示するために「Date」という製品が必要です。(MsgBox dtmHiduke の部分)
AさんはBさんに製品を宅急便で送るためにダンボールへ入れました。
変数とは、この「日付」という製品を入れるダンボール(箱)のようなものです。
「dtmHiduke(箱) = Date(日付という品物)」
こうして箱に詰めて運んであげないと次のコードは値を扱えないというわけです。

変数のイメージ

~データ型について~

 さて、お次はデータ型についてです。
Excelには日付や通貨、文字列といったいろんな表示形式があると思いますが、そのイメージで考えてもらえば理解しやすいと思います。
データ型とは変数に格納できるデータの種類(形式)のことを言います。
例えば文字列は「string型」、数値は「Integer型」や「long型」等さまざまな種類があります。
先ほどの変数宣言「Dim strHiduke As Date」では、「strHiduke」変数はDate型(日付型)を扱いますよと書いてあるわけです。
この場合、日付型の変数「strHiduke」には「合格」などといった文字列を入れることはできません。

データ型のイメージ

~なぜ、わざわざ変数を宣言するのか?~

実は、わざわざ変数宣言をしなくても変数を使うことはできます。
その場合、その変数は自動的にどんなデータ型も格納できるVariant型という特殊なデータ型となります。
それならそっちの方が便利じゃーん!と思うのですが、変数を宣言しないと色々面倒なことが起こります。

  • 可読性の低下
    変数宣言せずに急にコード上に変数が出てくると、どんなデータを扱うものなのか、そもそも変数なのか、などコードの可読性が低下します。
    自分で作っていても「あれ?」と思うことがありました。
    他の人がメンテする必要が出てくる可能性もありますので、コードがどんな処理をしているのかが分かるようにしましょう。
  • 実行速度が遅くなる
    体感としてそこまでの差は出ないようですが、メモリ領域のサイズが大きくなってくると処理時間は大きく変わってくるようです。
  • 誤動作を招く可能性がある
    Variant型はすべてのデータを格納することができますが、それゆえに自分の想定する結果が返ってこない場合があります。
    例えば2つの入力欄に入力された数値を足して、その結果を表示する場合、入力項目にそれぞれ「50」と入力すれば想定する結果は「100」ですが、作りによっては入力された値を文字列と判断し、「5050」という結果が返ってしまう場合があります。

Variant型の誤動作例

こうした誤動作を避けるためにも、きちんとデータ型まで宣言する必要があります。

データ型の説明1

~変数の有効範囲について~

変数とデータ型が終わった所で、先ほどの「Dim strHiduke As Date」を見てみると、「Dim」というのがあります。
これはステートメントと言って、変数の有効範囲を示しています。また、宣言する場所によっても有効範囲は変わります。

変数の有効範囲

変数の有効範囲図

 

というわけで長くなりましたが、コードの記述に関する基本的なことについてでした。
ExcelVBAとAccessVBAは多少記述の仕方が異なりますが、変数とデータ型についての考え方は同じです。
ではまた(^^)ノシ