VBA技術解説
VBAの省略可能な記述について

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2018-08-11 最終更新日:2019-10-30

VBAの省略可能な記述について


VBAには、省略可能な記述が数多くあります。
省略可能な記述とは、書いても書かなくても動作に何の違いもないものになります。


VBAのこの記述の自由度は、慣れてしまえば楽なものですが、
初心者の方が覚え始める時には、多少混乱することもあると思います。

基本的な考え方としては、
・省略できるものはなるべく省略して書く
・省略しない方が読みやすい場合は省略しない
書くか書かない迷ったときは、このような判断をしてください。

マクロはVBAで書く手順書になります。
明瞭かつ簡潔で、わかり易く読みやすい方が良いに決まっています。

ただし、省略する場合は省略形を書いているという事を承知した上で書く方がより良いです。
省略していると承知した上で、省略しても何も問題が無い場合は省略するという考えになります。

以下では、VBAの省略可能な代表的な記述について取り上げます。
下記以外にもまだ有りますが、このくらいについて理解していれば十分でしょう。

変数の宣言

VBE→ツール→オプション→変数の宣言を強制する

VBA 参考画像

ここにチェックを入れている場合は、新規モジュール作成時にはモジュールの先頭に、
Option Explicit
この一文が自動挿入されます。

このOption Explicitがある状態であれば、変数は必ず宣言しなければなりません。
変数宣言をしない場合はエラーになります。
しかし、
Option Explicitが無ければ、変数は宣言しなくても問題なく動作します。

Option Explicitが無い状態での変数宣言は、
データ型指定においては意味をもちますが、勧められる使い方ではありません。
といいますか、
必ずOption Explicitを指定して、変数は必ず宣言するようにして下さい。

変数宣言のデータ型

Dim i
Dim i As Long
これらは、どちらでも動作にほとんど違いはありません。
「ほとんど」と書きましたが、100%同じ動作というわけではありません。
例としては、
Ifステートメントで比較する場合に違いが発生する場合があります。
Sub test1()
  Dim i
  Dim j
  i = 123
  j = "123"
  If i = j Then
    MsgBox "同じ"
  Else
    MsgBox "違う"
  End If
End Sub

この結果は、「違う」となります。
しかし、
変数iまたは変数jのどちらかでも、
Dim i As Long
このように宣言すると、「同じ」となります。

※このような動作になる理由は、Variantの説明をかなり詳細に説明しなければなりませんので、ここでは省略します。
変数の型を省略すると、Variantになります。
Dim i
これは、
Dim i As Variant
このように宣言したことと同じになります。

指定すべきデータ型が不明な場合は、省略またはVariant指定でも構いませんが、
可能な限り、分かる範囲内でデータ型を指定するようにしましょう。

固有オブジェクト型について
固有オブジェクト型とは、例えば、
Dim sht As Worksheet
このようにオブジェクトの型を指定するものの事です。
WorksheetやWorkbook程度は直ぐに分かりますが、
オブジェクトの中にはオブジェクトの型が直ぐには分からない場合もあります。
特に、オブジェクトのプロパティで参照されるオブジェクト(子供のようなオブジェクト)の場合、
必ずしもプロパティ名と一致していない場合もあるため、正しいオブジェクトの型が分からない場合が出てきます。
オブジェクトの型が不明な場合は型を省略してVariantで構いません。
【参考】
第12回.変数とデータ型(Dim)
・データ型 ・変数の使い方 ・変数名の規則 ・良く使われる変数名 ・自動型変換、暗黙の型変換 ・変数宣言の必要性 ・Dim変数宣言のまとめ

Application.ScreenUpdating = True : Application.DisplayAlerts = True

マクロ開始の先頭の方で、
Application.ScreenUpdating = False
Application.DisplayAlerts = False
これらで、画面描画とアラートを止める指定をしている場合が多いです。
そこで、これらをTrueに戻さなくて良いのか、戻し忘れたらどうなるか・・・
結論としては、マクロの一連の動作が終了した時点で、自動的にTrueに戻ります。
従って、Trueに戻さなくても問題はありません。
※エラーでマクロが停止した場合はScreenUpdatingが戻らない場合があります。

では、Trueに戻す記述を省略して良いかどうかという事ですが、
なるべくTrueに戻した方が良いでしょう。
ScreenUpdating、DisplayAlerts以外にも、Applicationのプロパティでマクロ開始時点で変更している場合も多々あります。
Applicationのプロパティの中には、マクロ終了時点で元に戻らないものが多数あります。
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
これらは、マクロが終了してももとには戻りません。

すると、マクロ開始時点で、
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
このように記述しているとしたら、マクロ終了時の記述として、
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.Calculation = xxlCalculationAutomatic
このように記述することが自然であり、
あえてScreenUpdatingとDisplayAlertsだけを記述しない理由は見当たりません。

結論としては、
ScreenUpdatingとDisplayAlertsだけしか使っていないとしても、
マクロ終了時の記述としてもとに戻すくせを付けておいた方がより良いと思います。
ただし、これは必須と言うほどのものではなく、書いておくに越したことはないという程度のものです。

【参考】
第57回.Applicationのプロパティ
・Applicationの主要プロパティ ・ScreenUpdating(マクロVBAの高速化) ・DisplayAlerts(警告停止) ・Interactive(ユーザー操作の禁止) ・Calculation(計算方法) ・StatusBar ・Cursor ・その他
マクロの開始・終了(Applicationのプロパティ)
・マクロVBA開始時 ・マクロVBA終了時 ・Applicationのプロパティ解説 ・マクロが途中で終了した場合

Applicationのプロパティ

ActiveCell
ActiveSheet
ThisWorkbook
これらは詳しくは、Applicationのプロパティになります。
つまり、
Application.ActiveCell
Application.ActiveSheet
Application.ThisWorkbook
これらのApplicationが省略された状態です。
さすがに、これらにApplicationを付けて書いているのはほとんど見かけません。
これらのApplicationは省略して書くべきでしょう。

WorksheetFunctionもApplicationのプロパティです。
※WorksheetFunction自体はClassですが、
  ApplicationのWorksheetFunctionプロパティを経由して参照します。
このApplicationは省略できます。
書いても構いませんが、記述が長くなるので省略した方が見やすいと思います。

Applicationのプロパティでも、ScreenUpdatingやDisplayAlertsはApplicationを省略できません。
いきなり、ScreenUpdatingと書いてしまうとエラーとなります。

【参考】
第57回.Applicationのプロパティ
・Applicationの主要プロパティ ・ScreenUpdating(マクロVBAの高速化) ・DisplayAlerts(警告停止) ・Interactive(ユーザー操作の禁止) ・Calculation(計算方法) ・StatusBar ・Cursor ・その他

Applicationを省略できるプロパティと、省略できないプロパティについて
オブジェクトブラウザー(VBEでF2で起動)

VBA 参考画像

このグローバルに入っているものは、Applicationを省略できます。
Applicationのプロパティで、ここに無いものはApplicationを省略できません。

Applicationのメソッド

省略できるかどうかは、Applicationのプロパティと同様になります。
グローバルに入っているものは、Applicationを省略できます。
SendKeys
Intersect
Union
これらは、グローバルに入っているので省略可能です。
ただしプロパティと違って、省略できるメソッドは極めて稀です。

上記以外には、直ぐに思いつくものがありません。
上記の3つのメソッドについては良く使われるものですので、
Applicationを省略できることも結構知られているので省略して構わないでしょう。
少なくとも私は省略して書いています。

ただし、記述を見ただけでは関数との区別がつかないので、あえてApplicationを書くという考え方もあります。
初心者の方とVBAを共有する場合は、Applicationを書いておいた方が無難かもしれません。

【参考】
第102回.Intersectメソッド
・Intersectメソッド ・Intersectの使用例 ・Intersectメソッドの最後に
第103回.Unionメソッド
・Unionメソッド ・Areasプロパティ ・Unionメソッドで連結した結果のRangeオブジェクトの状態について ・Unionメソッドの使用例 ・Unionメソッドの実践例
第104回.GetPhoneticメソッドとSetPhoneticメソッド(フリガナ)
・GetPhoneticメソッド ・GetPhoneticメソッドの使用例 ・SetPhoneticメソッド ・SetPhoneticメソッドの使用例

Range.Value

このValueについては、
多くの場合は省略できるのですが、一部省略できない場合が存在します。
セルに値を入れるだけの記述なら、
Range("A1").Value = "abc"
Range("A1") = "abc"
これらに動作の違いはありませんので、
多くのセルに値を入れる場合は読みやすさを考えれば省略した方が良い場合も多いでしょう。
実際に私も、値を入れる場合は結構省略しています。

ただし、Valueプロパティとして考えたときには、前述のとおり省略できない場合もあるので気を付けて下さい。
以下の参考ページを是非お読みください。

【参考】
Rangeオブジェクト.Valueの省略について
エクセルVBAを教えていて、これほど多く聞かれる質問はないでしょう、RangeやCellsの.Valueは省略したほうが良いか、書いた方が良いか、当然、省略出来ない場合もあれば、オブジェクトとして扱うために.Valueは書けない場合もあります。ですので、結論から言えば、書きたければ書けば良いし、書きたくなければ書か…

プロシージャーのCall

SubプロシージャーやFunctionプロシージャーを呼ぶ時に、
Call Subプロシージャー名
Call Functionプロシージャー名
これらは、Callを省略して、
Subプロシージャー名
Functionプロシージャー名
このように記述しても、動作に何らの違いもありません。

ですが、これらのCallはなるべく書いた方が好ましいと考えます。
VBAを書いている人は、SubプロシージャーやFunctionプロシージャーの存在が分かっているので、
Callを書いても書かなくても、読んでいて違和感を感じないのですが、
他人がCallが省略されたVBAを読むと、一瞬「これは何?」というような感覚になる場合があります。
特に英語のプロシージャー名だと、ぱっと見た目では何者なのかが分かりづらい場合があるという事です。

【参考】
第105回.Callステートメント
・Callステートメント ・Callステートメントの使用例 ・同じことは2度書かない ・プロシージャーの分割について
VBAにおける括弧()の使い方
・基本文型 ・VBAにおける括弧() ・VBAにおける半角空白の意味 ・戻り値を他の用途に使う時 ・括弧()の使い方の基本文型 ・Callを省略しなければ全て括弧が必要になる ・最後に一言

メソッドのCall

ここのでメソッドとは、VBAに用意された(Range等の)メソッドの事になります。

メソッドの戻り値を使用しない場合は、いきなりメソッドから書き始める場合が多くあります。
例えば、
Range.AutoFilter Field:=1, Criteria1:="a"
これは、Callを付けて書くことが出来ます。
Call Range.AutoFilter(Field:=1, Criteria1:="a")

世の中のVBAコードのほとんどは、この場合のCallは省略されて書かれています。
慣例には従った方が無難なので、このCallは省略して書いた方が良いでしょう。

ただし、メソッドの戻り値を使う場合は、括弧()が必要になるので、混乱しないようにして下さい。

【参考】
VBAにおける括弧()の使い方
・基本文型 ・VBAにおける括弧() ・VBAにおける半角空白の意味 ・戻り値を他の用途に使う時 ・括弧()の使い方の基本文型 ・Callを省略しなければ全て括弧が必要になる ・最後に一言

Let

変数への代入の際には、
オブジェクト変数なら、
Set 変数 = オブジェクト
と書きますが、通常データの変数の場合は、
変数 = 値
と記述します。

変数 = 値
これを省略せずに全て書くなら、
Let 変数 = 値
と書くことになります。

しかし、このLetが書かれているVBAコードは/Zqi見ることがありません。
さすがにこれは書書ないほうが良いでしょう。

ヘルプにも、
「Letを明示的に使用するかどうかは表記上の問題であり、通常は省略します。」
このように書かれています。

Next 変数

For i = 1 To 10
  ・・・
Next i
この
Next i のiは省略できます。
つまり、
For i = 1 To 10
  ・・・
Next
これでよいという事です。
この場合、Nextの後ろに書くとしたらi以外は書くことが出来ません。
つまり、iと書くか、iを省略するかという選択になります。

VB(Visual Basic)の後継にあたる、Visual Studio の Visual Basicでは、
For i = 1 To 10ここまで書いてEnterすると、Nextが自動挿入されます。
Next iではなくNextが自動挿入されます。
つまりこれは、Microsoftがこのiは不要だといっていると判断して構わないはずです。

Forをネストした時に、どのForに対するNextかが分かるように、Nextの後ろに変数名を書いた方が良いという意見もあるようですが、
ネストの読みやすさを議論するなら、ただしくインデントすべきであって、これ以上の読みやすさ対策はありえません。

むしろコピペでVBAコードを使い回す時に、このiを書き換える手間が発生する事を考えれば、
むしろ省略した方が良いと考えます。

【参考】
第16回.繰り返し処理(For Next)
・For Next ステートメント ・For Next 例文 ・For Next をステップ イン実行で目で見て確認しましょう。 ・1行置きに処理する場合 ・Exit For ・For~Nextのネスト(入れ子) ・最後に一言
第59回.コレクション処理(For Each)
・For Each の構文 ・Exit For ・For Each の使用例 ・RangeオブジェクトのFor Each ・For Each サイト内の参考ページ

Step 1

For i = 1 To 10
For i = 1 To 10 Step 1
これらは全く同一のものになります。
ForのStepをし省略した場合は、Step 1となります。

Step 1を書くことに何の不都合もありませんが、
このStep 1をわざわざ書く人は稀でしょう。

【参考】
第16回.繰り返し処理(For Next)
・For Next ステートメント ・For Next 例文 ・For Next をステップ イン実行で目で見て確認しましょう。 ・1行置きに処理する場合 ・Exit For ・For~Nextのネスト(入れ子) ・最後に一言

引数が無い場合の()

変数 = Now
変数 = Now()
どちらでも構いません。
この括弧を書くかどうかは、個人の好みでしょう。

変数 = Dir(パス)
Do While 変数 <> ""
  ・・・
  変数 = Dir()
Loop
この、
変数 = Dir()
これは、
変数 = Dir
このように()を省略することが出来ます。
しかし、Dirの引数を省略した場合は次のファイル名を取得するという仕様を考えたとき、
引数が省略されていることを見た目でわかり易いように伝えるとすれば、括弧を書いた方が良いでしょう。

【参考】
VBAにおける括弧()の使い方
・基本文型 ・VBAにおける括弧() ・VBAにおける半角空白の意味 ・戻り値を他の用途に使う時 ・括弧()の使い方の基本文型 ・Callを省略しなければ全て括弧が必要になる ・最後に一言

名前付き引数

Range("A1:C10").AutoFilter Field:=1, Criteria1:="a"
この、Field:=やCriteria1:=を名前付き引数と呼びます。
これらの名前付き引数を省略して、
Range("A1:C10").AutoFilter 1, "a"
このように書いても、動作に何の支障もありません。

VBA 参考画像

しかし、名前付き引数を省略する場合は、引数の指定順を厳密に守らなければなりません。
また、後でVBAコードを読んだときに、引数の意味が分からなくなってしまう事にもなりかねません。

一般的なVBAの慣習として、
VBA関数の引数には、名前付き引数を省略して書く
メソッドの引数には、名前付き引数を指定して書く
このような使われ方をしている場合が多いので、それに従っておいた方が無難でしょう。

VBA関数は引数が少なく、引数を覚えている人が多いが、
メソッドの引数は数が多い場合があり、引数を覚えていない人の方が多いという事が最大の理由でしょう。

【参考】
第25回.名前付き引数について
・仮引数と実引数 ・メソッドとは ・名前付き引数について ・名前付き引数の例文 ・名前付き引数の必要性

メソッドの規定値

Range("A1:C10").Sort Key1:=Range("A1"), Order1:=xlAscending
これは、
Range("A1:C10").Sort Key1:=Range("A1")
このように、ソート順を指定しなくても動作に問題はありません。
Order1の規定値が、xlAscendingなので省略しても良いという事になります。

VBA 参考画像

しかし、
このOrder1の規定値がxlAscendingだと知っている人ばかりではないという事を考えれば、
ここは引数を省略せずに、Order1:=xlAscendingと書いておいた方が良いでしょう。

【参考】
第88回.並べ替え(Sort)
・Range.Sortメソッド・・・Excel2003までのソート ・2007以降の並べ替え ・Excel2003までのSortとExcel2007以降のSortの使い分け
第98回.Findメソッド(Find,FindNext,FindPrevious)
・Findメソッド ・FindNext メソッド ・FindPrevioust メソッド ・Application.FindFormatメソッド ・FindメソッドとFindNextメソッドの実戦例
第99回.Replaceメソッド(置換)
・Replaceメソッド の構文 ・Replaceメソッドの注意点 ・Replaceメソッドの使用例 ・ReplaceメソッドとReplace関数の使い分け
第100回.InputBoxメソッド(インプットボックス)
・InputBoxメソッド ・InputBoxメソッドの使用例 ・最後に
VBAのFindメソッドの使い方には注意が必要です
・1.処理速度が遅い ・2.指定オプションがシート操作とリンクしている ・「値」で検索した場合は、表示形式に依存した検索になる ・最後に

組み込み列挙

Range("A1").Borders.LineStyle = xlContinuous
この、xlContinuousの列挙を省略せずに書くと、
Range("A1").Borders.LineStyle = XlLineStyle.xlContinuous
このようになります。

VBAで、Xl○○と言うものは列挙になります。
列挙の記述では、省略しない場合は、
列挙.メンバー
と記述することになります。

VBA 参考画像

先の、Applicationのプロパティで書いたとおり、
グローバルに入っているものは、列挙のメンバーをいきなり書くことが出来ます。
一般的には、列挙のメンバーをいきなり書いている方が多いでしょう。
列挙のメンバーを調べる手段として、自動記録かネット検索になると思いますが、
どちらも、列挙のメンバーをいきなり書いている場合がほとんどになるからです。
つまり、省略した書き方しか知らない人が多数だという事です。

ただし、
XlLineStyle.xlContinuous
このように書いておくと、後々線種を変更したい時にはインテリセンスが使えるので記述が楽になります。

【参考】
VBA Excel 列挙体の一覧
VisualBasicのExcel列挙体の一覧です。全てではありません、よく使いそうなもののみ抜粋です。全てのVBA定数は、以下で参照できます。MSDNVisualBasic言語リファレンス定数(VisualBasicforApplications) 名前 値 説明 XlBordersIndex 設定する罫線を指定…

関数のモジュール名

VBA関数は、VBAが用意したモジュールに入っているものになります。
文字列系関数(Mid,Right等々)は、
Stringsと言うモジュールに含まれています。
つまり、
Strings.Mid
省略しなければ、このように書くという事になります。
VBA 参考画像

日付時刻系(Date,DateSerial等々)は、
DateTimeモジュールに含まれています。
VBA 参考画像

VBA関数は、グローバルに入っているので、いきなり関数から書き始められます。
関数のモジュール名については、むしろ知っている人の方が少ないので、
モジュール名が書かれているVBAコードにお目にかかることはかなり稀になると思います。

ただし、モジュール名で就職した書き方と、省略した書き方で動作が若干違ってくる関数が存在します。

【参考】
VBAにおける配列やコレクションの起点について
・配列の起点について ・コレクション ・Collectionオブジェクト ・その他:文字列関数 ・配列の起点の原則

コレクションのItem

Worksheets(1)
Worksheets.Item(1)
後者の書き方を見かけることは滅多にありませんが、
この二つは、全く同じものになります。
Workbooks等、他のコレクションでも同じ書き方が存在します。

Worksheetsはコレクションです。
VBAで扱うコレクションの多くでは、既定のプロパティとしてItemプロパティを持っています。
既定のプロパティとは、プロパティを省略した場合に適用されるプロパティという事になります。
従って、Itemを省略してもItemが指定されているものとされるという事になります。

Itemプロパティが既定のプロパティとなっているコレクションの場合は、Itemは省略して書かれることがほとんどです。

Rangeオブジェクトもコレクションです
Rangeオブジェクトもコレクションですが、他のコレクションとは少々異質のものになりますので注意してください。

MsgBox Range("A1:C10").Item(5).Address
MsgBox Range("A1:C10")(5).Address
この二つは同じ動作となり、結果は「$B$2」となります。

MsgBox ActiveSheet.UsedRange.Item(5).Address
MsgBox ActiveSheet.UsedRange(5).Address
前者は正しく動作しますが、後者は「不正なプロパティ」となります。
しかし、
Dim rng As Range
Set rng = ActiveSheet.UsedRange
MsgBox rng.Item(5).Address
MsgBox rng(5).Address
これなら、どちらも正しく動作します。

このようにRangeオブジェクトがコレクションだからと言って、
無条件かつ単純にItemを省略できるわけではありませんので、
Rangeオブジェクトの場合はItemを省略しない方が良いでしょう。

VBAの省略可能な記述の最後に

ステートメントと変数以外は、Applicationまたはモジュールに含まれているものになります。
従って、省略せずに全てを書くとすれば、
ステートメントと変数以外はApplicationまたはモジュール名から書き始めることになります。
しかし、これでは記述が長くなってしまい読みづらいコードになってしまいます。

まずは、あなたが読みやすいと感じる書き方から初めて、
ゆくゆくは、他人にも読みやすいVBAコードを書くようにすると良いでしょう。



同じテーマ「マクロVBA技術解説」の記事

VBAの小数以下の演算誤差について
スピルでVBAの何が変わったか
CharactersプロパティとCharactersオブジェクト
ユーザーに絶対に停止させたくない場合のVBA設定
印刷範囲の設定・印刷範囲のクリア
VBAの省略可能な記述について
VBAのVariant型について
VBAのインデントについて
VBAの演算子まとめ(演算子の優先順位)
列幅不足による###表示や指数表示を判定する
VBA10大躓きポイント(初心者が躓きやすいポイント)


新着記事NEW ・・・新着記事一覧を見る

VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)
スピらない スピル数式 スピらせる|エクセル雑感(2023-12-06)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ