Visual Basic 初級講座 |
Visual Basic 中学校 > 初級講座 >
プログラムの質を高める方法をプログラム自体の視点から説明します。特にメンテナンス性、可読性に関する話題を中心に紹介します。
概要 ・メンテナンス性を考慮しないプログラマは非常識。 ・ハードコードを行うとメンテナンス性が低下する。 ・変数の適用範囲を無駄に広く取るとメンテナンス性が低下する。 ・変数やクラスの名前を適切につけないとメンテナンス性が低下する。 ・XMLコメントを使うとVBの開発環境で自作メソッド等のヒントを表示することができる。 |
構文通りに書いていけばVBのプログラムは動きますし、それをうまく組み合わせれば望みどおりの機能を記述することができます。ところが、そうしてできあがったプログラムを優秀なプログラマに見てもらうと次のようなことを言われる場合があります。
「グローバル変数が多すぎてメンテできないよ。」
「この、Messageっていう変数はなんでクラスレベルで宣言してるの?え、プロシージャごとに書くのが手間だから?」
「ここ、フォルダ名をハードコードしちゃってるじゃん。」
「この『11』って何の値?」
「このVisible = Falseのラベルは…、あ、フォーム間で値をやり取りするときに使っているのか、うーむむ…」
何のことを言っているのかわからないかもしれませんが、なにやら良くない言われ方をしているという雰囲気はわかると思います。プログラム自体は立派に正常に動いているのにこのように評価されてしまう場合は珍しくありません。特に独学でVBを勉強している方にはありがちです。
というのもプログラムの書き方には暗黙の了解と言うものがあって、動けばよいというものではないのです。この暗黙の了解をあまりにも無視してプログラムを書いてしまうと「非常識なプログラマ」という烙印を押されてしまいます。
このように書くと理不尽に思われるかもしれませんが、一般的にはプログラムには次の点が求められているのです。
正確な動作 | 常に予期した結果が得られること。たとえば、電卓プログラムで時々計算結果が間違って表示されるようだと「正確な動作」をするとは言えない。 |
素早い動作 | ユーザーの要求に瞬時に応答すること。たとえば、電卓プログラムでは1つの計算に何秒もかかるようだと「素早い動作」をするとは言えない。 |
快適な操作性 | ユーザーが作業するために効率的な操作が可能であること。たとえば、電卓プログラムではマウスでしか操作できないようだと「快適な操作性」があるとは言えない。→電卓ならやはりテンキーを使って操作したくなりますよね。 |
メンテナンス性 | プログラムの修正・機能追加が容易であること。どんなによくできたアプリケーションでも、誰も修正・機能追加できないような難解・複雑なプログラムであるのならば「メンテナンス性」があるとは言えない。 |
■表1:プログラムに求められているもの
「暗黙の了解」とはこれらを達成するために標準的なプログラマが行っていることです。特にメンテナンス性に関連したものが多いです。今回はメンテナンス性を中心に、あなたのプログラムの質を高めるためのいくつかのトピックを説明します。
メンテナンス性についてもう少し詳しく説明します。 表に簡単に書きましたが、メンテナンス性とはプログラムの修正や機能の追加が容易であることを指しています。
たいていのプログラムは一度完成したらそれで終わりと言うことはなく、バグを発見したら修正しなければなりませんし、後になって機能を追加することも珍しくありません。バグもなく機能も十分なように思えても、たとえば新しいVisual BasicやWindowsが発売された場合に新しい環境でも快適に動作するように部分的に手を加えた方が良いような場合もあります。
また、重要な点としてはこのようなプログラムの修正・機能追加を行うのはプログラムを作ったあなたではないかもしれないということです。1人で黙々と開発を行っているのなら話は別ですが、学校の部活や会社の仕事などでは他の人と連携して作業することも少なくなりませんから、あなたにとっては修正しやすいプログラムでも他人にとって修正が難しいプログラムでは問題があります。
それに、ずっと1人で作っていても何ヶ月かぶりに機能を追加しようと思ったら何がなんだかわからなくなっていたりもするものです。
ですからメンテナンス性とは常に他人を基準とすべきなのです。
メンテナンス性を高めるために一般的には次の手段が有効であるとされています。
プログラム構造のスリム化 | 後で詳しく説明します。要するにわかりにくいプログラムをしないということです。 |
適切なコメント | プログラム中にコメントをつけること、どこでどんな処理をなんのためにやっているか、またどんな注意事項があるのか誰にでもわかるようにできます。 |
一般的な方法の採用 | 同じくらい効率的な別のやり方があるのなら、みんなと同じやり方でプログラムすることです。あなた独自の方法でプログラムすると他の人には読みにくいプログラムとなり、インターネットや書籍でも調べることが難しくなってしまいます。 |
ドキュメント作成 | プログラムの構造や、動作、注意点などを文書として保存しておきます。特にクラスを作成した場合にはクラスの使い方をヘルプのような形式でまとめておくことが重要です。→プログラムの動作を構造的に記述したものを「プログラム仕様書」と呼びます。 |
■表2:メンテナンス性を高めるために必要なもの
この中でドキュメントの作成以外はすべてコードの可読性の向上に寄与します。「可読性」とは「プログラムを読める」ということです。難しいプログラムや複雑なプログラムを見ると何をやっているのかさっぱり分からない場合がありますが、このようなプログラムは可読性が低いことになります。可読性が低いプログラムは当然メンテナンス性も低くなります。
次からは具体的な事例を挙げてメンテナンス性を中心にプログラムの質を向上させる方法を紹介していきます。
博士のワンポイントレッスン
|
ハードコードとはプログラム中に直接値を書き込むことを指しています。
次のプログラムを見てください。
Dim
i As
Integer Dim Message As String = "" 'ListBoxに表示されている項目を1つの文字列にまとめる For i = 0 To 11 Message &= ListBox1.Items(i) & " " Next TextBox1.Text = Message |
■リスト1
このプログラムでは11という部分がハードコードされている部分です。このプログラムを見ても11って何のことだかよくわかりませんよね?とりあえずListBoxの項目の数と関係あるようではありますが。
しかも、こういうプログラムに限ってあっちこっちに11という数字が出てきたりするものです。一体11って何なのでしょうか?プログラム中に埋め込まれているこういった謎の数値のことを揶揄して「マジックナンバー」(直訳すると『魔法の数』)とも呼びます。
動いているならいいような気がしますか?いいえ、この部分には問題があります。
たとえば、他の関係ない部分を何かの事情で修正したとしましょう。そのとき、はたして、この11という数字は変更しなくて良いのでしょうか?全然わからないですよね。
ということは、プログラムを修正する人はこの部分を修正する必要があるのかないのか調べるところから始めなければならないのです。これは明らかにメンテナンス性が低いと言わざるを得ません。
ListBoxの項目の数が12個であることが前提になっているのであれば次のように記述すべきです。
Dim i
As
Integer Dim Message As String = "" 'ListBoxに表示されている項目を1つの文字列にまとめる For i = 0 To ListBox1.Items.Count - 1 Message &= ListBox1.Items(i) & " " Next TextBox1.Text = Message |
■リスト2
これだと、プログラムを見ただけでListBoxの全項目を対象にループしているのだと言うことがわかりますし、ListBoxの項目数が変った場合でもプログラムを修正する必要がありません。
それでは、このケースで11という数がListBoxの項目の数ではない場合はどうやって書いたら良いでしょうか?つまり、ListBoxには12個以上の項目があって、そのうち最初の12個を1つの文字列にまとめようとしている場合です。
この場合は、定数を使って次のような記述をします。
Const
MESSAGE_ITEM_COUNT As Integer = 12 Dim i As Integer Dim Message As String = "" 'ListBoxに表示されている項目を1つの文字列にまとめる For i = 0 To MESSAGE_ITEM_COUNT - 1 Message &= ListBox1.Items(i) & " " Next TextBox1.Text = Message |
■リスト3
このように書くことで11と書いた場合に比べて意味がはっきりします。可読性の向上です。また、同じように「11」と書いている個所が複数あっても定数で設定している値を一ヶ所直すだけでプログラム全体を修正できることになりメンテナンス性も高まります。
定数はすべて大文字で単語と単語の間にはアンダースコア(_)を入れるのが普通が別にVBで決められているわけではないので普通の変数のような名前をつけても大丈夫です。ただし、プロのプログラマは大文字とアンダースコアで構成されている名前をみると反射的に「定数だな」と感じます。とは言え、最近は普通の変数のような名前をつけるケースも増えてきているように感じます。
博士のワンポイントレッスン
|
グラフィックスを扱うプログラムでは座標に関連してたくさんの数値が登場するのでマジックナンバーが使われているケースが多いです。次のプログラムは3×3の正方形を描くプログラムです。
Dim
X As
Integer Dim Y As Integer Dim g As Graphics = Me.CreateGraphics '・左上の正方形は座標(10, 10)から描画される。 '・正方形の一辺の長さは50 '・正方形と正方形の間隔は2 For X = 0 To 2 For Y = 0 To 2 g.FillRectangle(Brushes.Blue, X * 52 + 10, Y * 52 + 10, 50, 50) Next Next |
■リスト4
これだけのプログラムならこのままで良いという場合もありますが、大きなプログラムの一部としてこのようなコードが書かれているとしたらたくさんのマジックナンバーがプログラムの可読性を低下させていることは一目瞭然です。
この例ではコメントが書いてあるのでまだわかりやすい方ですがマジックナンバーを使わないように書き換えてみたらどうなるでしょうか。次のようになります。
Dim
X As
Integer Dim Y As Integer Dim g As Graphics = Me.CreateGraphics Const X_COUNT As Integer = 3 '横方向の正方形の数 Const Y_COUNT As Integer = 3 '縦方向の正方形の数 Const EDGE As Integer = 10 '一番端の正方形とフォームとの距離 Const SPACE As Integer = 2 '正方形と正方形の間隔 Const BOX_LENGTH As Integer = 50 '正方形の一辺の長さ For X = 0 To X_COUNT - 1 For Y = 0 To Y_COUNT - 1 g.FillRectangle(Brushes.Blue, X * (BOX_LENGTH + SPACE) + EDGE, Y * (BOX_LENGTH + SPACE) + EDGE, BOX_LENGTH, BOX_LENGTH) Next Next |
■リスト5
なんだかコードが長くなって逆に可読性が低下したと思いますか?そういう見方もあります。けれど、メンテナンス性という基本に立ち返って見るとこちらの方が優れています。何ヵ月後にもう一度このプログラムを見たときのことを考えてください。正方形の大きさをもう少し小さくするように修正する場合のことを考えてみてください。下の例の方が 容易であることに気が付くはずです。
博士のワンポイントレッスン
|
ハードコードの最も悪い例はフォルダ名やファイル名などの記述です。
次の例はフォームに画像を表示する例です。
Me.BackgroundImage = Image.FromFile("C:\Visual Basic 中学校\BackImage.bmp") |
■リスト6
この例ではファイル名がハードコードされています。実のところこの例では可読性はかなり高いです。この部分を見ただけてどの画像を表示しようとしているか簡単にわかるからです。
とはいえ、この例では明らかに可読性以前のところで問題があります。この場所にこのファイルが存在しない場合このコードは正常に実行されません。
プログラム中でファイルを指定する必要がある場合にハードコードを行うと言うことはそれだけで「非常識」に当たります。
この場合は、たとえば次のような記述が考えられます。
Const
FILE_BACKIMAGE As String =
"BackImage.bmp" Me.BackgroundImage = Image.FromFile(Application.StartupPath & "\" & FILE_BACKIMAGE) |
■リスト7
これでもファイル名は固定でBackImage.bmpになっていますが、フォルダの位置はexeファイルと同じ位置と言う指定になりましたから前の例よりはましです。前の例ではユーザーがフォルダの位置を指定できない点で大いに問題があります。
それにexeファイルと同じフォルダという指定であれば、フォルダを1つまるごとコピーするだけで動作するように構成することも可能なのです。なにか事情がない限り、このようにフォルダを丸ごとコピーすればアプリケーションが動作するようにプログラム上で配慮することは重要です。そうでなければ、アプリケーションを使おうとするユーザーにどこにどのようなフォルダが必要なのか調べながら自分で配置する面倒な手間をかけさせることにもなってしまいます。
このようなアプリケーションは意外と多いのです。Cドライブの○○フォルダにexeファイルを置かないと動作しないとか、Cドライブの××フォルダに設定ファイルを置かないと動作しないとか、本当に嫌になってしまいます。フォルダくらい好きに選ばせて欲しいです。
「フォルダを丸ごとコピーすれば動く」ということを「XCOPYによる配置」と呼ぶことがあり、VB(やC#などの.NET言語)の大きなセールスポイントともなっています。
なお、ファイル名も含めて完全にハードコピーをなくすには、app.configやini、レジストリ、あるいはリソースファイルなどの外部の設定を使用することになります。
変数の適用範囲を無駄に広く設定するとメンテナンス性が低下します。特に俗に「グローバル変数」と呼ばれるプログラム上のどの位置からでも使用できる変数の存在はメンテナンス性を著しく損ないます。
大量のグローバル変数を使用しているプログラムを見ると私はもうそれだけで怒りがこみ上げてきます。(特にAccessで作ったシステムにこの傾向が多く見られます。)
次の例を見てください。
Dim
Reader As
New
IO.StringReader(FileName) Dim Header As String Header = Reader.ReadLine Reader.Close() |
■リスト8
この例はテキストファイルの1行目を読み込む例ですが、対象のファイルが存在しない場合には当然エラーになります。
ここで対象のファイルが存在しなくてエラーになった場合のことを考えましょう。エラーの原因を調べるには変数FileNameに値をセットしているコードはどこで、どんな値を設定しているのかを調べることになります。
このとき、変数FileNameがプロシージャレベルで宣言されていればあなたはそのプロシージャの中だけを調べれば問題を解決できます。そうではなくフォームレベル(クラスレベル)で宣言されていればあなたはそのフォーム全体を調べないと問題を解決できません。さらに、もしこの変数がアプリケーションレベルで宣言されているならばあなたはこの問題を解決するためにアプリケーション全体を調べなければならなくなります。
発展学習 - アプリケーションレベルの変数 発展学習では意欲的な方のために現段階では特に理解する必要はない項目を解説します。 アプリケーション内のどこからでも使用できる変数を宣言するには、クラス内でPublic Sharedを使って変数を宣言します。または標準モジュールを使ってPublicで変数を宣言しても同じです。 ただし、本文で触れられているようにこのような変数はメンテナンス性を低下させますのでできるだけ使用しないようにしてください。 |
変数の適用範囲がメンテナンス性と大きく関わっていることが理解いただけるでしょう。変数の適用範囲はできるだけ狭い方がメンテナンス性に優れているのです。
この点を誤解しているプログラマは次のように考えています。「できるだけ少ない変数でプログラムを作った方が効率的だし、たくさんの小さな変数があっちこっちにあるより統一性があるんじゃないか」と。
このような考えのもとでよく見かけるプログラムは次のようなものです。
'これは悪い例です。 Dim Message As String |
Private
Sub Button1_Click(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles Button1.Click 'TextBox1に何も入力されていない場合のメッセージをセット If Len(TextBox1.Text) = 0 Then Message = "TextBox1に値を入力してください。" End If 'TextBox2に数値が入力されていない場合のメッセージをセット If Not IsNumeric(TextBox2.Text) Then Message = "TextBox2には数値を入力してください。" End If '何かメッセージがセットされている場合は表示する。 If Len(Message) > 0 Then ShowMessage() End If End Sub |
Private
Sub
Button2_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
Button2.Click Message = "提供:Visual Basic 中学校" & vbNewLine Message &= "(これは悪い例です)" MsgBox(Message) End Sub |
'■ShowMessage |
■リスト9
このプログラムではいろいろな場所でメッセージをセットしたり表示したりするのでフォームレベルでメッセージのための変数Messageを宣言しています。この考え方自体が既に悪いのですがプログラム自体にもバグがあります。
たとえば、最初にButton1をクリックすると警告メッセージが表示されますよね。ここまではいいのですが次にTextBox1とTextBox2に何か数値を入力してからButton1をクリックしても相変わらず警告メッセージが表示されます。
それに、TextBox1とTextBox2に数値を入れた後で、Button2をクリックしてメッセージを表示させ、その後にButton1をクリックするとおかしなことになってしまいます。
いろいろな場所で共通の変数Messageを使っているのでMessageをクリアする処理が必要になるのです。Messageをクリアする処理は別に難しいことはありませんが、私がいいたいことはプログラム中で気をつけなければいけないことが増えるということです。これはその分プログラムが複雑になるということでもあり、メンテナンス性が低下すると言っていいでしょう。
ちなみに、この例は次のようにすると良いプログラムになります。
Private Sub
Button1_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
Button1.Click Dim Message As String 'TextBox1に何も入力されていない場合のメッセージをセット If Len(TextBox1.Text) = 0 Then Message = "TextBox1に値を入力してください。" End If 'TextBox2に数値が入力されていない場合のメッセージをセット If Not IsNumeric(TextBox2.Text) Then Message = "TextBox2には数値を入力してください。" End If '何かメッセージがセットされている場合は表示する。 If Len(Message) > 0 Then ShowMessage(Message) End If End Sub |
Private
Sub
Button2_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
Button2.Click Dim Message As String Message = "提供:Visual Basic 中学校" MsgBox(Message) End Sub |
'■ShowMessage ''' <summary>警告メッセージを表示する</summary> ''' <param name="Message">メッセージの内容</param> ''' <remarks>これは悪い例です。</remarks> Private Sub ShowMessage(ByVal Message As String) MsgBox(Message, MsgBoxStyle.Exclamation) End Sub |
■リスト10
この例では2個所(引数も含めれば3箇所)でMessageという変数を宣言していますが、適用範囲はプロシージャレベルになるのでメンテナンス性は向上します。
メッセージの内容がハードコードされているのは問題ですが、ここは例をシンプルにするためと思ってご容赦ください。
この例のようにプロシージャ間での情報共有が必要な場合は共通変数ではなく引数を使用するのが一般的です。またフォーム間、クラス間での情報共有にはプロパティを使用することが推奨されます。
変数やクラスの名前も重要です。プログラムは名前1つで好印象にも悪印象にもなります。
私がいままでに出会った最悪の関数を紹介しましょう。この関数はVB6で記述されていました。
はっきりとは覚えていませんが、次のようなものでした。
'******************************************* 'ID:URIPG001_FUNC001 'CRT:K.Yamada 1998/2/28 'UPD:K.Yamada 1998/3/1 ' K.Yamada 1998/3/3 ' A.Suzuki 1998/3/10 'COMMENT:元号を変換します。 'ARG1:URIPG001_FUNC001_ARG001 和暦 'ARG2:URIPG001_FUNC001_ARG001 西暦 'ARG3:URIPG001_FUNC001_ARG001 年 'ARG4:URIPG001_FUNC001_ARG001 月 '******************************************* Public Sub URIPG001_FUNC001(ByRef URIPG001_FUNC001_ARG001, ByRef URIPG001_FUNC001_ARG002, ByRef URIPG001_FUNC001_ARG003, ByRef URIPG001_FUNC001_ARG004) If Len(URIPG001_FUNC001_ARG001) > 0 Then If Len(URIPG001_FUNC001_ARG001) = 6 Then '中略 End If End If '(読む気になれないコードが延々と続く… 省略) End Sub |
■リスト11
この関数、とうも和暦と西暦を変換してくれるらしいのですがどのように使うのかさっぱりわかりません。しょうがないからプログラムを読んでどういう動きをするのか調べようと思ったのですが、またなにやらごちゃごちゃ書いてあってとても読めたものではありませんでした。
どうもこのアプリケーションを作っていた人たちは管理するのが大好きでなんでもかんでもURIPG001のような独自のコードをつけて管理していたようです。フォームの名前も関数の名前も変数の名前もです。それとなく理由を聞いてみたらExcelで管理するのが便利だし、フォームがいくつあって、関数がいくつあるのかわかりやすいということでした。
そういうこともあるでしょうが、管理はアプリケーション作成を助けるためのものであって、管理するためにアプリケーションを作るのではないのですからこれは行き過ぎという物でしょう。
この問題と先ほどの変数の適用範囲の問題が重なるともう手に負えません。悪い例ばかり紹介しても仕方ないので具体例は割愛します。
プログラムの構造をすっきりとわかりやすくするということは慣れの問題もありますが、変数にわかりやすい名前をつけるくらいのことは誰でもできますからいつも意識していてください。
では、わかりやすい名前とはどのようなものなのでしょうか?
もちろんその変数や関数の機能が表現されている名前が良いのですが具体的なところは議論が分かれるものです。現在のところ名前付けに関してはいくつかの流派がありますので代表的なものを紹介しておきます。
マイクロソフト流 - できるだけ省略しない。 |
RegisterStartupScript |
DataGridViewColumnCollection |
新システム屋流 - あまり名前が長くなるようならば略語を使用する。 |
RegStrScript |
DgvColCollection |
旧システム屋流 - 適用範囲や型も名前として明示する。現在ではあまり使われない。 |
g_strRegStrScript |
m_colDgvColomun |
■表3:変数の名前付けに関する代表的な流派
○○流という名前は私が勝手につけたものですが、だいたいここにある3流派でプロのプログラマの90%をカバーしていると言えます。
どの流派も「わかりやすくする」という目的では共通していますので、みなさんはお好みの流派を採用すれば良いでしょう。
なお、私は基本的にはマイクロソフト流です。
名前付けに関してはCamel規約だのPascal規約だのハンガリアン記法だの意外と議論が深く、定数や変数、同じ変数でもPrivateかPublicかなどによっても異なる場合があります。ここでは深入りはしませんが、とにかく「わかりやすい名前」という点はいつでも共通です。
最後にXMLコメント(読み方:XMLコメント = エックスエムエルコメント)を紹介しておきます。XMLコメントとはVB2005から新しく導入された機能でコメントの一種です。
XMLコメントを使うと開発環境でインテリセンスとして自分で指定した情報を表示させることができるのでなかなか便利です。
たとえば、次のようにAddNumberメソッドを定義した場合で説明します。
'
←ここに ' を3つ入力する Private Function AddNumber(ByVal X As Integer, ByVal Y As Integer) As Integer Return X + Y End Function |
■リスト12
このメソッドの1行上のところにコメントを表すシングルクォーテーション( ' )を3つ続けて入力するとたちまち次のようなコメントが自動的に挿入されます。
'''
<summary> ''' ''' </summary> ''' <param name="X"></param> ''' <param name="Y"></param> ''' <returns></returns> ''' <remarks></remarks> Private Function AddNumber(ByVal X As Integer, ByVal Y As Integer) As Integer Return X + Y End Function |
■リスト13
後はこれらの項目に自分でコメントを書き込んでいくだけです。それぞれの項目は次のような意味です。
XMLコメント | 読み方 | 意味 |
summary | サマリー | 概要 |
param | パラム | 引数 |
returns | リターンズ | 戻り値 |
remarks | リマークス | 備考 |
■表4:XMLコメント
たとえば、次のようになります。
'''
<summary>2つの数値を合計します。</summary> ''' <param name="X">1つ目の数値を指定します。</param> ''' <param name="Y">2つ目の数値を指定します。</param> ''' <returns>合計の結果</returns> ''' <remarks>計算結果がIntegerの範囲を超えるとエラーになります。</remarks> Private Function AddNumber(ByVal X As Integer, ByVal Y As Integer) As Integer Return X + Y End Function |
■リスト14
ここで指定した記述がこのメソッドを使用するときにヒントとして表示されるわけです。
■画像1
今回はプログラムの質を向上させる方法をプログラム自体の視点からいくつか紹介しました。この話題は説明しだすと細かい話もいろいろあって大変なので私が特に重要と思う点を中心に扱いました。
みなさんにはこれらの点を気をつけていれば良いということではなく、これらの点を中心として常にプログラムのメンテナンス性、質を高めていくような方向でプログラムしていくと言うことを理解していただきたいです。
現在のところ、「こうすれば良いプログラムになる」というはっきりした方法はありません。こういう方向性で行けばよいという指針がある程度です。こんな状況ですから気をつけて書いているつもりでもなかなか良くないプログラムになってしまったりもします。
はっきりした方法が発見されていない以上、数をこなして慣れていくしかありません。
最後にもう1つ注意をします。「短いプログラムが優れている」と考えている方が時々いらっしゃいますがこれは間違いです。他の機能・性能がまったく同等ならメンテナンス性(≒可読性)の高いプログラムが優れているのです。
多くの場合は短いプログラムはメンテナンス性にも優れていますが、コードを短くするために変数を無理に共通化したりコメントを惜しんだりしないで下さい。それから、行継続文字(:)を使ってまで無理に1行にまとめないで下さい。このVB世界を読みやすい質の良いプログラムでいっぱいにしましょう。