みなさん、こんにちはケンケンです。
今回は、変数についてお話ししていきます。
今までも変数を使ってコードを書いてきましたが、説明はサラっと流していました。
その理由は、
- まず自動化の手順を慣れてほしかった
- 変数は深入りしすぎるとハマる
からです。
1はともかく、2についてはなぜかというと、VBA変数にはデータの型というものがあります。
この型を変数の宣言をするタイミングで指定しておくことができるのですが、
これは、両刃の剣な感じがあります。
つまり、便利であり不便でもあるのです。
なので、今までこの説明を避けて簡素化した状態で解説してきました。
しかし、データの型を知っておくこと自体にデメリットはないと考えますので、今回解説していくことにしました。
この記事については暗記しようとしないでください。
コラムのような感覚でさらっと読み流すくらいがちょうどいいと思います。
変数の宣言を強制する
変数の重要性を理解していただくために、データの型の話をする前に、変数の宣言の強制についてお話しします。
モジュールを作成すると以下のように表示されていましたよね。
これは、変数を宣言するのを強制するおまじないのようなものです。
宣言なしで変数を使おうとするとエラーがでます。
上記のようにhensuを宣言なしに使うとエクセルに怒られます。
逆に、変数の宣言をしなくても変数を使える設定があります。
上記のように設定を変更して、改めてモジュールを追加すると
変数の宣言を強制するおまじないが消えて、変数なしでも実行できるようになりました。
便利と言えば便利ですが、これでは、何を目的として作られた変数か分かりませんね。
また、変数の数が増えると内容を追うだけでも一苦労です。
ですので、変数の宣言は強制する設定にして、きっちり管理した方がコードの書きやすさと可読性は増します。
なぜ、わざわざ変数の宣言を強制しないやり方をご紹介したかと言うと、強制なしでコードを書いているものが一定数あるからです。
きちんと勉強していない人が書く場合に多くあらわれ、そういう人はとりあえず動くものを作りたいという考えのもと、変数を適当に扱う傾向があります。
そうなると当然、メンテナンスする際に多大な労力がかかり、ミスも多くなりVBAで処理する意味が半減してしまいます。
可読性がなくメンテナンスも難しい適当なコードを書かないためにも、変数の宣言は強制にしておくことをおススメします。
データの型には種類がある
今まで使ってきたデータには型があります。
型とはそのデータが「数値」なのか「日付」なのか「文字列」なのかといった種類の判別ができるものです。
そのデータ型を変数で宣言するときに使うおまじないがあります。
例えば、
- Dim cnt as Long →長整数型(数値)
- DIm sName as String →文字列型
こんな感じです。
型の種類がどういうものがあるのか以下をご覧ください。
大きく分けて「通常の型」と「オブジェクト型」に分けることができ、2つの型を合わせた全体的な概念を「Variant型」と言います。
ひとつずつ解説していきます。
■通常の型
通常の型と表現していますが、専門用語ではありません。僕が勝手にオブジェクト型ではないもの、としてカテゴライズしているものの表現です。
データの型についてはこれ以上詳しく触れるつもりはないので、興味のある方はご自身で調べてください。
先ほども少し触れましたが、通常の型に属したものはどういうものかと言うと、今まで使ってきたものと考えて良いです。
今まで使ってきたものとは、
- あるセルの値
- ある列の最終行の値
- 繰り返すための値
などのことで、値や数値などを変数に格納する箱を作って格納していましたね。
ただ、この値にもいろいろな特徴がありますね。
数値だったり文字列だったり日付だったりします。
その値の特徴、つまり型に合わせて変数を宣言することができるのです。
long は長整数型、stringは文字列型といったように種類を分けることができます。
型を分けることによるメリットとしては、予期せぬミスを防げたりします。
例えば、以下のようなコードがあるとします。
実行するとA1セルに適正な文字列と数字が入りますね。
そこで、変数scoreに文字列を入れて実行してみてください。
変数scoreには点数を格納しなくてはいけないのですが、文字列を格納してもエラーにはなりません。
そこで、2つの変数にそれぞれ型を指定するとどうでしょうか。
scoreには得点を格納したいので長整数型のLongを、
sNameには人の名前を格納したいので文字列型のStringを宣言します。
この状態でコードを実行すると、
型が一致しませんというエラーが発生します。
score変数は数値しか格納できないように型を指定しているのでエラーがでるんですね。
このエラーが発生したら、変数とそれに格納する値に相違があることが分かるので、凡ミスがなくなります。
プログラミングをしていて一番やっかいなのが、実行してエラーにならないけど、結果が間違っているときです。
むしろ、今回のようにエラーになった方が何倍もマシです。
ひとつ前の例では、おかしな結果でも実行できていました。ミスを誰も気づかないなんていう結果になりかねないので、そういうミスを減らすためにも型を指定することは有効です。
■オブジェクト型
通常の型とは別にオブジェクト型というものがあります。
これは、通常の型とは違い、オブジェクトそのものを変数の中に格納するというものです。
オブジェクトとは
- セル
- ワークシート
- ファイル
- 図形
などのことです。
通常の型と何が違うのかというと、この場合は、既存のオブジェクトにあだ名をつけるような感覚でしょうか。
僕の名前はケンジなのでケンケンというあだ名をつけてブログを書いていますが、それと似たような感じです。
ではなぜオブジェクトにあだ名をつける必要があるのかというと、
コードが見やすくなるからです。
例えとして、次のようにワークシート(オブジェクト)を格納する変数wsに、data_typeを格納してみましょう。
Sub data_type2() Dim ws As Worksheet Set ws = Worksheets("data_type") ws.Range("A1").Value = "こんにちは" End Sub
コードを解説していきます。
変数を宣言する際に、Asの後にオブジェクト名を入力します。
今回は、Worksheetですが、他にWorkbook、Range、Shapeなどがあります。
オブジェクト変数の場合は、使えるようにするためにもう一段回あります。
変数にオブジェクトを格納するためにSetを使います。
使い方は「Set 変数名= オブジェクト名」というようにします。
上記コード「Set ws = Worksheets(“data_type”)」では、変数wsにdata_typeシートを格納していることになります。
格納後はwsでシートを指定することができます。
「ws.Range(“A1”).Value = “こんにちは”」では、Rangeの前に変数wsを指定することで「data_type」シートを指定することが出来るようになります。
これで、他のシートで実行しても「data_type」シートで実行されます。
オブジェクト型を使うことのメリットとして、コードが見やすくなると言いました。
以下をご覧ください。
2つのプロシージャがありますが、下がオブジェクト変数を用いたコードです。
両方とも実行結果は一緒ですがどちらが見やすいですか。
下の方が見やすいと思います。
一度オブジェクト変数を宣言してSetを使って格納しておくと、あとのコードが書きやすく可読性もあがります。
なお、おまけとしてオブジェクト変数を使うと良いことがあります。
自動メンバ表示が利用可能になります。
上記のように変数名のあとに「.」を打つと自動でプロパティやメソッドが出てきます。
■指定しないとVariant型
なにも指定しない、つまり前回までの方法で変数を宣言するとすべてVariant型として認識されます。
最初にお見せした図を見てもらえばわかりますが、Variant型はすべてを網羅しますので、普段コードを書いているときに意識する必要はありません。
ただ、Variant型で宣言した場合は、オブジェクト変数で説明したようなメンバ表示が出てこないという点もあります。
そういった面もあるので、利便性を上げるために型を指定することもあっていいと思います。
まとめ&個人的感想
ここからは、僕個人の感想ですが、あまりデータの型にこだわらないほうがよいと思います。
型を宣言しないでコードを書いてもほとんど困ったことはありません。
上記のように型を宣言したほうがミスの防止にもつながり、良いこともあるので否定はしませんが、型を意識しすぎないほうがよいかと思います。
僕自身、学習していた時の癖で型を指定することもけっこうあります。
型を理解して使っていると頭がすっきりして、自然とこれから書こうとするコードが漠然と見えてくることもあるので、あえて型を宣言することもあります。
ちゃんと頭の中を整理して使えるのであれば、型を宣言して損はないと思います。
また、他人が書いたコードを読み解くための知識として覚えておく分には有用です。
しかし、型よりも変数のネーミングをきちっと考え、法則性を持たせたほうが、あとあと見直すときに便利です。
変数のネーミングのコツもご紹介する機会があれば、発信していこうと思います。
いかがでしたか。
型を指定するかしないかは、個人の好みで良いと思います。
必要性という面では、特に突き詰めていくこともないでしょう。
それより、条件分岐と繰り返しの構造を理解することが圧倒的に重要です。
そこは、お間違えないようにお願いします。
これからもあまり細かいところは突っ込まずに重要で実務に使える部分にフォーカスして情報発信していこうと思います。
今回は以上です。お疲れ様でした。
VBAの基礎を学習したい方へおすすめ
【エクセルVBA入門編②】めんどうな仕事はForNext構文で解決
【エクセルVBA入門編③】繰り返し作業はFor Next構文で完全自動化!
【エクセルVBA入門編⑤】If Then構文で条件分岐をマスター
【エクセルVBA入門編⑥】手順に沿って請求書を作成してみよう【請求書作成自動化】