VBA入門
オブジェクト変数とSetステートメント

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
最終更新日:2021-09-13

第52回.オブジェクト変数とSetステートメント


変数のデータ型の説明において、
Object ・・・ オブジェクト型
というのがあった事を覚えているでしょうか。


数値や文字ではなく、オブジェクトを入れる変数がオブジェクト変数です。
オブジェクトと言っても、いろいろなものがあります。
ブックシートセルも、これらは全てオブジェクトです。
これらを入れることができる変数がオブシェクト変数になります。

そして、オブジェクト変数にオブジェクトを入れる時には、
単なる=の代入ではなく、Setステートメントを使った=代入を使用します。


オブジェクト変数

Object型変数は、オブジェクトなら何でも入れられるデータ型になります。
総称オブジェクト型とも言います。

しかし、さらに固有のオブジェクトに対応したデータ型もあります。

Workbook
Worksheet
Range

これらは、それぞれ、

Workbookオブジェクト
Worksheetオブジェクト
Rangeオブジェクト


これらのデータ型になります。
その他にも、
Font
これは、Fontオブジェクトのデータ型になります。
このようにオブジェクト型は沢山ありますが、良く使うものはそんなに多くありません。
とりあえず最低限として、Workbook、Worksheet、Range、この3つだけは覚えておいてください。

データ型については、

Variant(バリアント型) > Object(総称オブジェクト型) > 固有オブジェクト型

このようになります、つまり、

Variantは、何でも入る
Objectは、オブジェクトなら何でも入る
個別のオブジェクト型は、そのオブジェクトのみ

出来れば、個別のオブジェクト型を使用して欲しいとは思いますが、
型指定が難しければObjectでも、まあ、Variantでも良いと思います。
ただし、
上記の3つ(Workbook、Worksheet、Range)これくらいは、正しく指定するようにして下さい。

以下のページで、さらに詳しい解説をしています。
オブジェクト変数とは何か|VBA技術解説
・そもそも変数とは何か ・変数の入れ物としての大きさは ・オブジェクト変数にオブジェクトは入っていない ・オブジェクト変数のメモリアドレス ・Is演算子によるオブジェクトの比較 ・TypeOf演算子 ・オブジェクト変数を使う時の注意点 ・オブジェクト変数の最後に


個有のオブジェクト型とは

個有のオブジェクト型という言い方は、正式な言い方なのかははっきりしません。
Microsoftのサイトでは、
「固有のデータ型を使用してオブジェクト変数を宣言」
このような文章がほとんどです。
しかし、一般的な呼び方として定着しているので、ここでも使用しています。

オブジェクトの型について難しい事を書けば、オブジェクトのクラス名になるのですが、
これはまだ知る必要が無いでしょう、おいおい説明していきます。


Setステートメント

オブジェクト変数を使うには、Setステートメントが必要になります
オブジェクトへの参照を変数に代入します。
この参照を変数に代入というのが解りづらいでしょう。

オブジェクトへの参照、それはつまり、オブジェクトのアドレスを変数に入れるのです。
オブジェクトは単なる値ではなく、プロパティやメソッドを複数含んだ集合体になります。
オブジェクトの実態を変数に入れていたのでは大変です。
そこで、オブジェクトのある場所(アドレス)を変数に入れておくという事です。
アドレスの入った変数を見ればオブジェクトのある場所が分かり、
結果としてオブジェクトにアクセスできるという仕組みです。

難しく感じる場合は、
「こう書けばこう動く」
まずは、そのまま覚えてしまいましょう。

Set オブジェクト変数 = オブジェクト


Setステートメントの使用例

Dim ws As Worksheet
Set ws = Worksheets("シート名")
ws.Cells(1, 1) = 1

これは、

Worksheets("シート名").Cells(1, 1) = 1

これと同じ事になります。
つまり、
Set ws = Worksheets("シート名")
これ以降は、
Worksheets("シート名")別名として、wsという名称を使えると考えてもらって結構です。
上記では、1行で済むものを3行で書いているので、かえって面倒な感じもしてしまいますが、
wsはその後何回でも使えますので、結果として記述は楽になります。

Worksheets("シート名").Range("A1").Font.Bold = True
Worksheets("シート名").Range("A1").Font.Color = vbRed
Worksheets("シート名").Range("A1").Font.Size = 12


これは、

Dim MyRange as Range
Set MyRange = Worksheets("シート名").Range("A1")
MyRange.Font.Bold = True
MyRange.Font.Color = vbRed
MyRange.Font.Size = 12

このように書き直す事が出来ます。


WithとSetの使い分け方

Setステートメントは、使い方としてはWithステートメントと似ている部分があります。
どちらも、記述の簡略化になります、
そして、なにより、処理速度も速くなるのです。
ワークシートは、プロシージャーの先頭でオブジェクト変数に入れてから使う事をお勧めします。
さらに、Withと組み合わせることで、可読性・保守性の高いマクロVBAにすることができます。

VBAの個々の場所において、
SetとWithのどちらを使ったほうが良いかというような基準も決まりもありません。
WithはEnd Withの間でのみ有効なものであり、
Setで代入したオブジェクト変数は、変数の有効範囲そのものになります。
具体的には、以下のような使い方が良いでしょう。


Setステートメントの実践的な使い方

Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
Set ws3 = Worksheets("Sheet3")

With ws1
  .Cells(1, 1) = ws2.Cells(1, 1)
  ・・・
  .Cells(1, 2) = ws3.Cells(1, 1)
  ・・・
End With

上記の考え方は、
扱うワークシートは、とりあえず全てオブジェクト変数に入れる
主なワークシートは、Withにする
この辺の使い方は、人により個性が出るところではありますが、
このような使い方を念頭に置いておけば、マクロVBAがとても書きやすくなるはずです。


Is演算子によるオブジェクトの比較

Is演算子は、2つのオブジェクト参照変数を比較するために使用されます。

If オブジェクト1 Is オブジェクト2 Then

Object1とobject2の両方が同じオブジェクトを参照する場合はTrueになります。
それ以外はFalseになります。
オブジェクト変数(As Object または、As 固有オブジェクト型)の初期値はNothingです。

Dim 変数A As Worksheet
Debug.Print 変数A Is Nothing '→ True
Set 変数A = Worksheets(1)

Dim 変数B As Worksheet
Set 変数B = 変数A

Dim 変数C As Worksheet
Set 変数C = Worksheets(1)

Debug.Print 変数A Is 変数B '→ True
Debug.Print 変数A Is 変数C '→ True

Set 変数C = Worksheets(2)
Debug.Print 変数A Is 変数C '→ False

Rangeブジェクトの場合は注意が必要です。
Dim 変数A As Range
Set 変数A = Range("A1")

Dim 変数B As Range
Set 変数B = 変数A

Dim 変数C As Range
Set 変数C = Range("A1")

Debug.Print 変数A Is 変数B '→ True
Debug.Print 変数A Is 変数C '→ False

Rangeオブジェクトでは、上記VBAの最後がFalse判定になる点に注意してください。
したがって、同じセルを参照しているかの判定には、
.Address(External:=True)
この値(文字列)を比較するようにしてください。
第84回.RangeのAddressプロパティ
Addressプロパティは、セル範囲(Rangeオブジェクト)の参照範囲を表す文字列の値を返します。引数により、参照方法($の付いた絶対参照)や形式(R1C1形式)を指定できます。Addressは、マクロVBAの中で処理の一環として使う事はあまり多くないかもしれませんが、VBA作成過程ではRangeオブジェクト変数…


最後に

オブジェクト変数とSetステートメント、そしてWithステートメントを上手く組み合わせることで、
マクロVBAの記述が書きやすく、そして読みやすくなります。
Worksheets("シート名")
この記述は、プロシージャー内では、何度も同じ事を書かないようにします。
シート名が変更になった時には、変更がとても大変ですから。
前回のWithステートメントと合わせて、しかっりと使えるようになってください。
・Withの構文 ・Withを使った時と使わない時の比較 ・Withの使用例 ・Withのネスト ・Withを使ったときに気を付けるべき書き方 ・Withの使いどころ ・サイト内の参考ページ




同じテーマ「マクロVBA入門」の記事

第50回.総合練習問題6
第87回.WorksheetFunction(ワークシート関数を使う)
第51回.Withステートメント
第52回.オブジェクト変数とSetステートメント
第53回.Workbookオブジェクト
第54回.Windowsオブジェクト
第55回.Worksheetオブジェクト
第56回.Rangeオブジェクト(RangeとCells)
第57回.Applicationのプロパティ(マクロ高速化と警告停止等)
第58回.コレクションとは(Collection)
第59回.コレクション処理(For Each)


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

TOROW関数(配列を横1行の配列にして返す)|エクセル入門(2022-10-31)
TOCOL関数(配列を縦1列の配列にして返す)|エクセル入門(2022-10-31)
CHOOSECOLS関数(配列から複数の指定された列を返す)|エクセル入門(2022-10-29)
CHOOSEROWS関数(配列から複数の指定された行を返す)|エクセル入門(2022-10-29)
WorksheetFunctionの効率的な使い方とスピル新関数の利用|VBA入門(2022-10-27)
VSTACK関数(配列を縦方向に順に追加・結合)|エクセル入門(2022-10-25)
HSTACK関数(配列を横方向に順に追加・結合)|エクセル入門(2022-10-25)
LAMBDA以降の新関数の問題と解説(配列操作関数編)|エクセル入門(2022-10-24)
LAMBDA以降の新関数の問題と解説(ヘルパー関数編)|エクセル入門(2022-10-24)
LAMBDA以降の新関数の問題集|エクセル入門(2022-10-24)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.並べ替え(Sort)|VBA入門
8.マクロって何?VBAって何?|VBA入門
9.エクセルVBAでのシート指定方法|VBA技術解説
10.ExcelマクロVBAの基礎を学習する方法|エクセルの神髄




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


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



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