Visual Basic 初級講座 |
Visual Basic 中学校 > 初級講座 >
第13回 取りこぼした重要なトピック
今回はいくつかの小さなテーマを説明します。これらは基本的で重要なことですがテーマとしては小さいため今までの説明には登場しなかったものです。
この回の要約 ・With 〜 End With を使うとプログラムを簡略化できる。 ・記号「 := 」を使って、引数を名前で指定することができる。 ・記号「 = 」には代入の他に、比較の機能もある。 ・定数や読み取り専用変数を使うことによりプログラムを構造化して将来の修正や変更を容易にできる。 ・プログラムを終了させるには Me.Close を使う。 |
Withブロック(読み方:With = ウィズ)を使うと、オブジェクト名を省略して記述することができるようになります。同じオブジェクトのメンバに続けざまにアクセスするときに重宝します。たとえば、次のような記述が可能です。
With
Button1 .Text = "Withですか?" .BackColor = Color.LightBlue .TextAlign = ContentAlignment.MiddleRight End With |
■リスト1:Withの使用例
このコードと次のコードはまったく同じ意味です。
Button1.Text = "Withですか?" Button1.BackColor = Color.LightBlue Button1.TextAlign = ContentAlignment.MiddleRight |
■リスト2
上記の2つのコードではWithを使ったコードの方がほんの少しだけ実行速度が速くなります。内部でのButton1への参照回数が減るからです。といってもこのくらいの差はまったく気にする必要がないと言って良いほどです。Withを使うか使わないかはまったくの好み次第です。よく With Meとして使っているコードを見かけますが、MeはWithを使わなくても省略可能です。ただ、With Meとしておくと「.」を打つだけでメンバの一覧が表示されるので利点はあります。
メソッドを呼び出すときに引数を引数の名前で渡すことができます。文章で書くとよくわからないと思うのですが、例を見てください。
Me.BackColor = Color.FromName(Name:="Red") |
■リスト3:名前を指定して引数に値をセットする例
この例ではColor構造体のFromNameメソッドを呼び出すときに引数Nameに"Red"を渡しています。通常は、引数に値を渡すときは単に値だけを記述すればよいのですが、この例のように記号「:=」を使って名前を指定して値を渡すこともできるのです。
このコードは次のコードとまったく同じ意味です。
Me.BackColor = Color.FromName("Red") |
■リスト4:順番に引数に値をセットする例
これがなんの役に立つかというと、まず省略可能引数が対象にある場合に名前で自分がセットしたい引数を指定できるということがあげられますが、私が思うになんと言っても最大のメリットはプログラムが読みやすくなることです。
ただ、この機能はほとんど使いません。この機能自体知らない人が多いように思えます。ここで取り上げたのは、他のサイトや雑誌などでこの書き方に出会ったときに意味が理解できるようにと思ってのことです。
記号「=」には2つの意味があります。1つは「代入」です。これは分かりやすいですよね。たとえば、次のコードでは変数Xに値7を代入します。
X = 7 |
■リスト5:「代入」の意味での = の使用例
もう、一つは「比較」です。これはわかっているようで分かりにくいものです。
比較の意味でよく使うのはIf文です。次のコードは理解できるでしょう。
If X =
7 Then MsgBox("7です") End If |
■リスト6:「比較」の意味での = の使用例
この場合の = はTrueかFalseを返します。たとえば、 + は合計を、 - は差を返しますよね? それと同じように = は比較の結果が同じなら True、異なっていれば False を返すのです。
従って、 X=7のとき、上記のコードは次のコードと同じ意味になります。
If
True
Then MsgBox("7です") End If |
■リスト7:Ifの条件節に直接結論(True)を指定する
Xが7でない場合は、次のコードと同じ意味になります。
If
False Then MsgBox("7です") End If |
■リスト8:Ifの条件節に直接結論(False)を指定する
If文以外でも使われる場合があります。たとえば、次のコードは理解できますか?
Dim
IsSeven As Boolean IsSeven = X = 7 |
■リスト9: = の応用事例
このコードでは、X=7の場合に、IsSevenはTrueになり、そうでない場合はIsSevenはFalseになります。
はじめの「=」は代入、2番目の「=」は比較の機能を持つわけです。
以上を踏まえれると、次のコードは冗長(読み方:冗長 = じょうちょう、意味:冗長 = 無駄が多い)です。
If X =
7 Then Return True ElseReturn False End If |
■リスト10:よくある冗長なIf文
このコードは次のように書くべきです。
Return X = 7 |
■リスト11
この2つはまったく同じ意味です。
プログラムの中でずっと変わらない値を扱う場合は「定数」を利用します。たとえば、随所に会社名を表示するプログラムを作る場合、コードの随所に会社名を書くのは非常に良くないやり方です。
次の例は非常に良くない例です。プロは絶対にこのようなコードを書きません。
Private Sub Form1_Load(ByVal
sender As
Object,
ByVal e
As System.EventArgs) Handles
MyBase.Load
'試用期間の警告 End Sub |
Private
Sub
Button1_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
Button1.Click
'バージョン表示 |
■リスト12:よくない例
何が良くないかというと、どこかで誤字を脱字の危険がありますし、あとで会社名の表示法が変わった場合にすべての個所を訂正しなくてはなりません。
このような場合は「定数」という機能を使って次のように書きます。
Private Const
COMPANY_NAME As String = "Visual
Basic 中学校" Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load '試用期間の警告 End Sub |
Private
Sub
Button1_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
Button1.Click
'バージョン表示 End Sub |
■リスト13:定数を使ったプログラム
この例ではCOMPANY_NAMEという名前の定数と宣言しています。宣言さえしてしまえば、後は必要なところで変数と同じように使うことができます。ただし、変数と違って値を変更することはできません。
定数を宣言するにはキーワードConst(読み方:Const = コンスト)を使用します。それ以外は変数と同じですが、宣言するときに必ず値を設定します。
また、定数の名前はすべて英語の大文字で、単語と単語の区切りには「_」(アンダーバー)を使う慣習があります。これは単なる慣習なので必ずしも従う必要はありませんが、特に理由がなければ従っておいてください。
ところで、会社名を定数にしたことにより、誤字・脱字の危険はかなり低くなり、後で修正が生じた場合にも一箇所直せばすべて直るような構図ができあがりました。
しかし、良くなったとはいえこの構造では会社名を修正するにはプログラムを修正する必要があります。
読み取り専用変数を使うと、定数と同じことができてしかもコンストラクタではその変数に値をセットすることができるようになります。コンストラクタで外部から値を読み込んでそれを読み取り専用変数にセットすればさらに柔軟なプログラムができます。
コンストラクタについては別の機会に正面から説明する予定ですが、簡単にいってしまうとNewという名前のプロシージャのことです。フォームにも必ずNewという名前のプロシージャが自動的に生成されています。必要なら、「Windows フォーム デザイナで生成されたコード」として折りたたまれている部分の中を探してみてください。
読み取り専用変数を宣言するにはReadOnly(読み方:ReadOnly = リードオンリー)を使用します。次のようになります。
Private ReadOnly COMPANY_NAME As String = "Visual Basic 中学校" |
■リスト14:読み取り専用変数の宣言
ユーザーがフォームの右上にある[閉じる]ボタンをクリックすればフォームが閉じてプログラムが終了しますが、プログラムから命令してプログラムの実行を終了させることもできます。
ここでは1つのフォームからなるWindowsアプリケーションを前提に説明しますが、基本が分かっていれば他の場合でも応用が利きます。
プログラムからプログラムの終了を命令するには次のどれかの命令を使います。
命令 | 読み方 |
Me.Close | クローズ |
Me.Dispose | ディスポーズ |
End | エンド |
Environment.Exit(0) | エンバイロメント.エグジット |
■表1:終了命令
これらは同じではありません。
特に理由がなければMe.Closeを使ってプログラムを終了させてください。このメソッドには引数がないので次のように手軽に使えます。
Me.Close() |
■リスト15:最も一般的なプログラムの終了方法
このメソッドを呼び出すと、順番にClosingイベント(読み方:Closing = クロージング)、Closedイベント(読み方:Closed = クローズド)、Disposedイベント(読み方:Disposed = ディスポーズド)が発生します。この中でもClosingイベントは特別で、このイベント内では終了をキャンセルすることができます。市販されているアプリケーションで編集中のファイルを保存するかどうかの確認などを行っているのもこのタイミングです。
たとえば、次のプログラムでは終了確認を行い、ユーザーが「いいえ」を選択した場合には終了をキャンセルします。
Private
Sub Button1_Click(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles Button1.Click Me.Close() End Sub |
Private Sub
Form1_Closing(ByVal sender
As Object,
ByVal e As
System.ComponentModel.CancelEventArgs) Handles
MyBase.Closing Dim Answer As MsgBoxResult Answer = MsgBox("終了しますか?", MsgBoxStyle.YesNo) If
Answer = MsgBoxResult.No
Then |
■リスト16:ユーザーに終了確認を行う例
Close以外の方法でプログラムを終了させようとした場合は、ClosingイベントやClosedイベントが発生しません。他にも終了するまでの流れに違いがあります。これらの違いを図にすると次のようになります。
■画像1:終了方法による動作の違い
この図には今の説明に登場しなかったイベント等も記載されていますが、現在のところそれらには特に気を使う必要はありません。なお、Endは内部でEnvironment.Exitを呼び出します。Environment.Exitは強制終了のようなものです。
終了命令については以上なのですが、最後になぜ終了のさせかたがいろいろあるのか簡単に説明します。
終了させるときに必要なのはなんといっても「終了処理」です。終了処理とはさきほども例にあげたように編集中のファイルを保存するかどうかユーザーに確認したりする処理ですがそれだけではありません。内部ではさまざまな処理を行っているのです。よくあるのはメモリの開放です。また使用しているファイルやネットワーク接続などのリソースを開放する必要がある場合もあります。
それらの終了処理を効率的に行うために「プログラムを終了させる」という口で言ってしまえば単純な動作のために複雑な構造が提供されているのです。