Visual Basic の概念

# [Visual Basic の概念](http://msdn.microsoft.com/en-us/library/aa240822(VS.60).aspx)

※[Visual Basic Coding Conventions](http://msdn.microsoft.com/en-us/library/aa240822(VS.60).aspx) の和訳です。

# Visual Basic のコーディング規則

この付録では、Visual Basic プログラムの推奨されるコーディング規則のセットを示します。

コーディング規則は、プログラムのロジックではなく、物理的な構造と外観に焦点を当てたプログラミングガイドラインです。コードを読みやすく、理解しやすく、保守しやすくします。コーディング規則には次のものが含まれます。

- オブジェクト、変数、およびプロシージャの命名規則。
- コードのラベル付けとコメントの標準化された形式。
- 間隔、フォーマット、およびインデントのガイドライン。

以下のセクションでは、これらの各領域について、適切な使用例とともに説明します。

# コーディング規約が必要な理由

一貫したコーディング規則のセットを使用する主な理由は、アプリケーションの構造とコーディングスタイルを標準化して、あなたと他の人がコードを簡単に読んで理解できるようにすることです。

適切なコーディング規則により、他の言語規則と一貫性があり、可能な限り直感的な、正確で読みやすく、明確なソースコードが得られます。

## 最小限のコーディング規約

汎用のコーディング規約では、上記の目的を達成するために必要な最小限の要件を定義し、プログラマーがプログラムのロジックと機能フローを自由に作成できるようにする必要があります。

その目的は、過度の制約と任意の制限によってプログラマの自然な創造性を狭めることなく、プログラムを読みやすく理解しやすくすることです。

この目的のために、この付録で提案されている規則は簡潔で示唆的なものです。可能なすべてのオブジェクトまたはコントロールをリストするわけではなく、価値のある情報コメントのすべてのタイプを指定するわけでもありません。

プロジェクトと組織の特定のニーズに応じて、これらのガイドラインを拡張して、次のような追加の要素を含めることができます。

- 社内で開発された、またはサードパーティベンダーから購入された特定のオブジェクトおよびコンポーネントの規則。
- 組織の事業活動または施設を説明する変数。
- プロジェクトまたは企業が明快さと読みやすさのために重要と考える他の要素。

### **詳細情報**

プロシージャ、変数、および定数の命名に関する制限については、[プログラミングの基礎](https://docs.microsoft.com/ja-jp/previous-versions/visualstudio/visual-basic-6/aa716286(v=vs.60)) の [コードの基本](https://docs.microsoft.com/ja-jp/previous-versions/visualstudio/visual-basic-6/aa240817(v=vs.60)) を参照してください。

# オブジェクトの命名規則

オブジェクトには、オブジェクトのタイプを簡単に識別できるように、一貫したプレフィックスを付けて名前を付ける必要があります。Visual Basic でサポートされるいくつかのオブジェクトの推奨規則を以下に示します。

## コントロールの推奨プレフィックス

| **制御タイプ**                               | **プレフィックス** | **例**           |
| -------------------------------------------- | ------------------ | ---------------- |
| 3D パネル                                    | pnl                | pnlGroup         |
| ADO データ                                   | ado                | adoBiblio        |
| アニメーションボタン                         | ani                | aniMailBox       |
| チェックボックス                             | chk                | chkReadOnly      |
| コンボボックス、ドロップダウンリストボックス | cbo                | cboEnglish       |
| コマンドボタン                               | cmd                | cmdExit          |
| 共通ダイアログ                               | dlg                | dlgFileOpen      |
| コミュニケーションズ                         | com                | comFax           |
| コントロール                                 | ctr                | ctrCurrent       |
| データ                                       | dat                | datBiblio        |
| データバインドコンボボックス                 | dbcbo              | dbcboLanguage    |
| データバインドグリッド                       | dbgrd              | dbgrdQueryResult |
| データバインドリストボックス                 | dblst              | dblstJobType     |
| データコンボ                                 | dbc                | dbcAuthor        |
| データグリッド                               | dgd                | dgdTitles        |
| データリスト                                 | dbl                | dblPublisher     |
| データリピーター                             | drp                | drpLocation      |
| 日付ピッカー                                 | dtp                | dtpPublished     |
| ディレクトリリストボックス                   | dir                | dirSource        |
| ドライブリストボックス                       | drv                | drvTarget        |
| ファイルリストボックス                       | fil                | filSource        |
| フラットスクロールバー                       | fsb                | fsbMove          |
| フォーム                                     | frm                | frmEntry         |
| フレーム                                     | fra                | fraLanguage      |
| ゲージ                                       | gau                | gauStatus        |
| グラフ                                       | gra                | graRevenue       |
| グリッド                                     | grd                | grdPrices        |
| 階層フレックスグリッド                       | flex               | flexOrders       |
| 水平スクロールバー                           | hsb                | hsbVolume        |
| 画像                                         | img                | imgIcon          |
| 画像コンボ                                   | imgcbo             | imgcboProduct    |
| イメージリスト                               | ils                | ilsAllIcons      |
| ラベル                                       | lbl                | lblHelpMessage   |
| 軽量チェックボックス                         | lwchk              | lwchkArchive     |
| 軽量コンボボックス                           | lwcbo              | lwcboGerman      |
| 軽量コマンドボタン                           | lwcmd              | lwcmdRemove      |
| 軽量フレーム                                 | lwfra              | lwfraSaveOptions |
| 軽量の水平スクロールバー                     | lwhsb              | lwhsbVolume      |
| 軽量リストボックス                           | lwlst              | lwlstCostCenters |
| 軽量オプションボタン                         | lwopt              | lwoptIncomeLevel |
| 軽量テキストボックス                         | lwtxt              | lwoptStreet      |
| 軽量の垂直スクロールバー                     | lwvsb              | lwvsbYear        |
| ライン                                       | lin                | linVertical      |
| リストボックス                               | lst                | lstPolicyCodes   |
| リストビュー                                 | lvw                | lvwHeadings      |
| MAPI メッセージ                              | mpm                | mpmSentMessage   |
| MAPI セッション                              | mps                | mpsSession       |
| MCI                                          | mci                | mciVideo         |
| メニュー                                     | mnu                | mnuFileOpen      |
| 月ビュー                                     | mvw                | mvwPeriod        |
| MS チャート                                  | ch                 | chSalesbyRegion  |
| MS Flex グリッド                             | msg                | msgClients       |
| MS タブ                                      | mst                | mstFirst         |
| OLE コンテナー                               | ole                | oleWorksheet     |
| オプションボタン                             | opt                | optGender        |
| 画像ボックス                                 | pic                | picVGA           |
| 画像クリップ                                 | clp                | clpToolbar       |
| プログレスバー                               | prg                | prgLoadFile      |
| リモートデータ                               | rd                 | rdTitles         |
| リッチテキストボックス                       | rtf                | rtfReport        |
| 形状                                         | shp                | shpCircle        |
| スライダー                                   | sld                | sldScale         |
| スピン                                       | spn                | spnPages         |
| ステータスバー                               | sta                | staDateTime      |
| システム情報                                 | sys                | sysMonitor       |
| タブストリップ                               | tab                | tabOptions       |
| テキストボックス                             | txt                | txtLastName      |
| タイマー                                     | tmr                | tmrAlarm         |
| ツールバー                                   | tlb                | tlbActions       |
| ツリー表示                                   | tre                | treOrganization  |
| 上下                                         | upd                | updDirection     |
| 垂直スクロールバー                           | vsb                | vsbRate          |

## データアクセスオブジェクト(DAO)の推奨プレフィックス

次のプレフィックスを使用して、データアクセスオブジェクトを示します。

| **データベースオブジェクト** | **プレフィックス** | **例**           |
| ---------------------------- | ------------------ | ---------------- |
| 容器                         | con                | conReports       |
| データベース                 | db                 | dbAccounts       |
| **DBEngine** オブジェクト    | dbe                | dbeJet           |
| 資料                         | doc                | docSalesReport   |
| フィールド                   | fld                | fldAddress       |
| グループ                     | grp                | grpFinance       |
| 索引                         | idx                | idxAge           |
| パラメータ                   | prm                | prmJobCode       |
| **QueryDef** オブジェクト    | qry                | qrySalesByRegion |
| レコードセット               | rec                | recForecast      |
| 関係                         | rel                | relEmployeeDept  |
| **TableDef** オブジェクト    | tbd                | tbdCustomers     |
| ユーザー                     | usr                | usrNew           |
| ワークスペース               | wsp                | wspMine          |

いくつかの例:

```vbscript
Dim dbBiblio As Database
Dim recPubsInNY As Recordset, strSQLStmt As String
Const DB_READONLY = 4            ' Set constant.
'Open database.
Set dbBiblio = OpenDatabase("BIBLIO.MDB")
' Set text for the SQL statement.
strSQLStmt = "SELECT * FROM Publishers WHERE & _
   State = 'NY'"
' Create the new Recordset object.
Set recPubsInNY = db.OpenRecordset(strSQLStmt, _
   dbReadOnly)
```

## メニューの推奨プレフィックス

アプリケーションは頻繁に多くのメニューコントロールを使用するため、これらのコントロールに固有の命名規則を設定すると便利です。

メニューコントロールのプレフィックスは、ネストの各レベルに追加のプレフィックスを追加して、最初の「mnu」ラベルを超えて拡張し、名前の文字列の最後に最後のメニューキャプションを追加する必要があります。

次の表にいくつかの例を示します。

| **メニューキャプションシーケンス** | **メニューハンドラー名** |
| ---------------------------------- | ------------------------ |
| ファイルを開く                     | mnuFileOpen              |
| ファイル送信メール                 | mnuFileSendEmail         |
| ファイル送信ファックス             | mnuFileSendFax           |
| フォーマット文字                   | mnuFormatCharacter       |
| ヘルプ目次                         | mnuHelpContents          |

この命名規則を使用すると、特定のメニューグループのすべてのメンバーが、Visual Basic の[プロパティ]ウィンドウに隣り合って一覧表示されます。

さらに、メニューコントロール名は、それらが接続されているメニュー項目を明確に文書化します。

## 他のコントロールのプレフィックスの選択

上記にリストされていないコントロールの場合、一貫性を保つために一意の2文字または3文字のプレフィックスを標準化する必要があります。明確にするために必要な場合にのみ、3文字以上を使用してください。

たとえば、派生コントロールまたは変更されたコントロールの場合、上記のプレフィックスを拡張して、どのコントロールが実際に使用されているかについて混乱しないようにします。サードパーティのコントロールの場合、製造元の小文字の略語をプレフィックスに追加できます。たとえば、Visual Basic Professional 3Dフレームから作成されたコントロールインスタンスは、fra3dのプレフィックスを使用して、実際に使用されているコントロールの混乱を回避できます。

# 定数および変数の命名規則

オブジェクトに加えて、定数と変数にも整形式の命名規則が必要です。このセクションでは、Visual Basic でサポートされる定数と変数の推奨規則をリストします。また、データの種類と範囲を識別する問題についても説明します。

変数は常に可能な限り最小のスコープで定義する必要があります。グローバル (**Public**) 変数は、非常に複雑なステートマシンを作成し、アプリケーションのロジックを非常に理解しにくくします。グローバル変数は、コードの再利用と保守をはるかに困難にします。

Visual Basic の変数のスコープは次のとおりです。

| **範囲**           | **宣言**                                                     | 有効範囲                                             |
| ------------------ | ------------------------------------------------------------ | ---------------------------------------------------- |
| プロシージャレベル | **Private** なプロシージャ、**Sub**、**Funcion**             | 宣言されているプロシージャ                           |
| モジュールレベル   | フォームまたはコードモジュール(.frm、.bas)の宣言セクションにある **Private** | フォームまたはコードモジュールのすべてのプロシージャ |
| グローバル         | コードモジュール(.bas)の宣言セクションの **Public**          | アプリケーションのどこでも                           |

Visual Basic アプリケーションでは、フォーム間でデータを共有する他の便利な方法がない場合にのみ、グローバル変数を使用する必要があります。グローバル変数を使用する必要がある場合、関数ごとにグループ化された単一のモジュールですべてを宣言することをお勧めします。モジュールに Public.bas などの目的を示す意味のある名前を付けます。

可能な場合は常に、モジュラーコードを記述することをお勧めします。たとえば、アプリケーションにダイアログボックスが表示される場合、ダイアログのタスクを実行するために必要なすべてのコントロールとコードを単一のフォームに配置します。これにより、アプリケーションのコードを便利なコンポーネントに整理し、実行時のオーバーヘッドを最小限に抑えることができます。

(渡されるべきではない)グローバル変数を除き、プロシージャと関数はそれらに渡されたオブジェクトに対してのみ動作する必要があります。プロシージャで使用されるグローバル変数は、プロシージャの冒頭の宣言セクションで特定する必要があります。さらに、渡された引数の値を明示的に変更する必要がない限り、ByValを使用してサブルーチンと関数に引数を渡す必要があります。

## 可変スコーププレフィックス

プロジェクトの規模が大きくなると、変数スコープをすばやく認識する価値も大きくなります。タイプ名の前にある1文字のスコーププレフィックスは、変数名のサイズを大幅に増やすことなく、これを提供します。

| **範囲**               | **プレフィックス** | **例**             |
| ---------------------- | ------------------ | ------------------ |
| グローバル             | g                  | gstrUserName       |
| モジュールレベル       | m                  | mblnCalcInProgress |
| プロシージャ内ローカル | 無し               | dblVelocity        |

変数は、標準モジュールまたはフォームモジュールで **Public** と宣言されている場合、グローバルスコープを持ちます。標準モジュールまたはフォームモジュールでそれぞれ **Private** と宣言されている場合、変数は*モジュールレベルの*スコープを持ち*ます*。

**注** この手法を生産的に使用するには、一貫性が不可欠です。Visual Basic の構文チェッカーは、「p」で始まるモジュールレベルの変数をキャッチしません。

## 定数

定数名の本体は、大文字と小文字を混ぜて、各単語を開始する必要があります。標準の Visual Basic 定数にはデータ型とスコープ情報は含まれていませんが、i、s、g、mなどのプレフィックスは、定数の値とスコープを理解するのに非常に役立ちます。定数名については、変数と同じ規則に従います。例えば:

コピー

```vbscript
mintUserListMax      'Max entry limit for User list
                  '(integer value,local to module)
gstrNewLine            'New Line character
                  '(string, global to application)
```

## 変数

すべての変数を宣言すると、タイプミス (aUserNameTmp vs. sUserNameTmp vs. sUserNameTemp など) によって引き起こされるバグの数が減るため、プログラミング時間が節約されます。[オプション] ダイアログの [エディター] タブで、[変数宣言が必要] オプションをオンにします。Option Explicitステートメントでは、Visual Basic プログラムですべての変数を宣言する必要があります。

変数には、データ型を示す接頭辞を付ける必要があります。オプションで、特に大規模なプログラムの場合は、変数のスコープを示すためにプレフィックスを拡張できます。

## 可変データ型

次のプレフィックスを使用して、変数のデータ型を示します。

| **データ・タイプ**   | **プレフィックス** | **例**        |
| -------------------- | ------------------ | ------------- |
| ブール値             | bln                | blnFound      |
| バイト               | byt                | bytRasterData |
| コレクション         | col                | colWidgets    |
| 通貨型               | cur                | curRevenue    |
| 日付時刻型           | dtm                | dtmStart      |
| 倍精度浮動小数点数型 | dbl                | dblTolerance  |
| エラー               | err                | errOrderNum   |
| 整数型               | int                | intQuantity   |
| 長整数型             | lng                | lngDistance   |
| オブジェクト型       | obj                | objCurrent    |
| 単精度浮動小数点数型 | sng                | sngAverage    |
| 文字列型             | str                | strFName      |
| ユーザー定義タイプ   | udt                | udtEmployee   |
| バリアント型 (暗黙)  | vnt                | vntCheckSum   |

## 記述変数とプロシージャ名

変数またはプロシージャ名の本体では、大文字と小文字が混在している必要があり、その目的を説明するために必要な長さである必要があります。さらに、関数名は、InitNameArray や CloseDialog などの動詞で始まる必要があります。

頻繁に使用される用語や長い用語については、名前の長さを適切に保つために標準の略語を使用することをお勧めします。一般に、VGA ディスプレイでは、32文字を超える変数名は読みにくい場合があります。

略語を使用する場合、それらがアプリケーション全体で一貫していることを確認してください。プロジェクト内で Cnt と Count をランダムに切り替えると、不必要な混乱が生じます。

## ユーザー定義型

多くのユーザー定義型を持つ大規模なプロジェクトでは、多くの場合、そのような各型に独自の3文字のプレフィックスを付けると便利です。これらの接頭辞が「u」で始まる場合、ユーザー定義型を使用しているときは、すぐに簡単に認識できます。たとえば、「ucli」は、ユーザー定義のクライアントタイプの変数のプレフィックスとして使用できます。

# 構造化コーディング規則

命名規則に加えて、コードのコメントや一貫したインデントなどの構造化されたコーディング規則により、コードの可読性が大幅に向上します。

## コードコメント規約

すべての手順と機能は、手順の機能特性(機能)を説明する簡単なコメントで始まる必要があります。この説明は実装の詳細(方法)を説明するべきではありません。これらはしばしば時間とともに変化し、不必要なコメント保守作業、またはさらに悪いことに誤ったコメントをもたらすためです。コード自体と必要なインラインコメントは、実装について説明します。

プロシージャに渡される引数は、それらの機能が明らかでない場合、およびプロシージャが引数が特定の範囲にあると予想する場合に説明する必要があります。プロシージャによって、特に参照引数を通じて変更される関数の戻り値とグローバル変数も、各プロシージャの冒頭に記述する必要があります。

プロシージャヘッダーのコメントブロックには、次のセクションの見出しを含める必要があります。例については、次のセクション「コードのフォーマット」を参照してください。

| **セクション見出し** | **コメントの説明**                                           |
| -------------------- | ------------------------------------------------------------ |
| 目的                 | プロシージャの実行内容(方法ではありません)。                 |
| 仮定                 | 各外部変数、コントロール、開いているファイル、または他の明らかでない要素のリスト。 |
| 効果                 | 影響を受ける各外部変数、コントロール、またはファイルと、それが持つ効果のリスト(これが明らかでない場合のみ)。 |
| インプット           | 明らかでない可能性のある各引数。引数はインラインコメント付きの別の行にあります。 |
| 返却値               | 関数によって返される値の説明。                               |

次の点に注意してください。

- すべての重要な変数宣言には、宣言されている変数の使用を説明するインラインコメントを含める必要があります。
- 変数、コントロール、およびプロシージャは、インラインコメントが複雑な実装の詳細にのみ必要となるように、十分に明確に名前を付ける必要があります。
- プロジェクトの Visual Basic ジェネリック定数宣言を含む .bas モジュールの最初に、アプリケーション、プライマリデータオブジェクト、プロシージャ、アルゴリズム、ダイアログ、データベース、およびシステムの依存関係を列挙する概要を含める必要があります。時には、アルゴリズムを説明する擬似コードが役立つ場合があります。

## コードのフォーマット

多くのプログラマーは依然として VGA ディスプレイを使用しているため、ロジックの構造とネストを反映したコードフォーマットを許可しながら、画面スペースをできるだけ節約する必要があります。以下にいくつかのポインタを示します。

- 標準のタブベースのネストされたブロックは、4つのスペースでインデントする必要があります (デフォルト)。
- プロシージャの機能概要コメントは、1スペースインデントする必要があります。概要コメントに続く最高レベルのステートメントは、1つのタブでインデントし、ネストされた各ブロックは追加のタブでインデントする必要があります。

###### 例:

```vbscript
'*****************************************************
' Purpose:   Locates the first occurrence of a
'            specified user in the UserList array.
' Inputs:
'   strUserList():   the list of users to be searched.
'   strTargetUser:   the name of the user to search for.
' Returns:   The index of the first occurrence of the
'            rsTargetUser in the rasUserList array.
'            If target user is not found, return -1.
'*****************************************************

Function intFindUser (strUserList() As String, strTargetUser As _
   String)As Integer
   Dim i As Integer            ' Loop counter.
   Dim blnFound As Integer      ' Target found flag.
   intFindUser = -1
   i = 0
   While i <= Ubound(strUserList) and Not blnFound
      If strUserList(i) = strTargetUser Then
         blnFound = True
         intFindUser = i
      End If
      i = i + 1
   Wend
End Function
```

### グループ化定数

変数と定義された定数は、隔離された領域や特殊ファイルに分割するのではなく、機能ごとにグループ化する必要があります。Visual Basic ジェネリック定数は、アプリケーション固有の宣言から分離するために、単一のモジュールにグループ化する必要があります。

### & および + 演算子

文字列を結合する場合は常に **&** 演算子を使用し、数値を操作する場合は **+** 演算子を使用します。**+** 演算子を使用して連結すると、2つのバリアントを操作するときに問題が発生する場合があります。

###### 例:

```vbscript
vntVar1 = "10.01"
vntVar2 = 11
vntResult = vntVar1 + vntVar2    'vntResult = 21.01
vntResult = vntVar1 & vntVar2   'vntResult = 10.0111
```

### MsgBox、InputBox、およびSQLクエリの文字列の作成

長い文字列を作成するときは、アンダースコア行継続文字を使用して複数行のコードを作成し、文字列を簡単に読み取ったりデバッグしたりできるようにします。この手法は、メッセージボックス(MsgBox)または入力ボックス(InputBox)を表示するとき、またはSQL文字列を作成するときに特に役立ちます。

###### 例:

```vbscript
Dim Msg As String
Msg = "This is a paragraph that will be " _
& "in a message box. The text is" _
& " broken into several lines of code" _
& " in the source code, making it easier" _
& " for the programmer to read and debug."
MsgBox Msg

Dim QRY As String
QRY = "SELECT *" _
& " FROM Titles" _
& " WHERE [Year Published] > 1988"
TitlesQry.SQL = QRY
```

# 参考サイト

- [Excel VBAコーディング ガイドライン案](https://qiita.com/mima_ita/items/8b0eec3b5a81f168822d)
- [エクセルVBAコーディングガイドライン](https://tonari-it.com/excel-vba-coding-guide-line/)
- [【ExcelVBA入門】クラスモジュールのメリット・使い方を徹底解説!](https://www.sejuku.net/blog/67476)
- [Excel VBA 標準モジュールとクラスモジュールの違い](https://kiyotatsu.com/excel-vba-mj/)
- [ExcelVBAのクラスモジュールって何?という人向けの使い方まとめ](https://ateitexe.com/how-to-use-class-module/)