★独学者が1年後にExcelVBAを爆発的に伸ばすための最低限の基礎知識メモ(ダイジェスト):Vol0029:ついでに、ウォッチウィンドウの「一般的に、普通に使う使い方」も少し-12。(エラー回避の基礎13)★ ウォッチウィンドウで「ActiveSheet.UsedRange」のセル範囲やオブジェクト変数「rrr」のセル範囲、マウスで選択したセル範囲を調べる方法と、それによって「何がわかるか?」「わかること」。
バックナンバー目次ページは→こちらです。
まぐまぐのページは以下です。
https://www.mag2.com/m/0001691660.html
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■独学者が1年後にExcelVBAを爆発的に上達させるための最低限の基礎知識メモ(ダイジェスト)
Vol.0029
タイトル:ついでに、ウォッチウィンドウの「一般的に、普通に使う使い方」も少し-12。(エラー回避の基礎13)
★ ウォッチウィンドウで「ActiveSheet.UsedRange」のセル範囲やオブジェクト変数「rrr」のセル範囲、マウスで選択したセル範囲を調べる方法と、それによって「何がわかるか?」「わかること」。
バックナンバー目次とサンプル号
https://euc-access-excel-db.com/tips/ct07_se/ct075012_xls2k_vba_tips/mag2-01
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
あけましておめでとうございます。
本年もよろしくお願い致します。
今回も前回の続きです。
https://euc-access-excel-db.com/tips/ct07_se/ct075012_xls2k_vba_tips/mag2-01-26
における、下図の状態にしておいてください。
「Let ggg = ActiveSheet.UsedRange」と、
「Set rrr = ActiveSheet.UsedRange」の2行が
追記された状態となります。
もちろん、
「Sheet1」には、AとBの列に、
下図のようにセルに値が入っているようにしておいてください。
そして、F5キーを押して、
Stop
の行が黄色くなった状態にしておいてください。
前回は「ggg」の行の、「型の列の Variant/Variant(1 to 4, 1 to 2) の意味」について、を少し詳しくやりました。
それは
▼ 「Activesheet.UsedRangeを直接、(Setではなく)”Let”を使って、”単一の ”Variant型の変数にいきなりムリヤリ代入したモノ」であったので、
▼ それによって「変数が、(オブジェクトにはならず)単一のモノから ”配列変数 ”に自動変化するので(=モトからそういう仕様になっているので)」、
▼ ウォッチウィンドウにてその配列変数の「+」マークを展開していけば、
▼ その各値たちが、実際のシート上のセル範囲の入力値たちと同じ並びだ・・・とわかり・・・、
▼ 配列変数の「添え字(位置を決めるモノ)」についても、「×××.Cells」プロパティでのセル指定と、「行と列の位置を」「同じ意味の数字で指定できる」・・・、
▼ つまり、配列の中身の各値の位置と実際の表の各値の位置を「いわばリンク」させられる・・・
▼「Variant/Variant(1 to 4, 1 to 2) 」の「1 to 4」は縦に4行、「1 to 2」はヨコに2列、の意味で、「そういう構造を持った表のようなかたちに自動変化した」という意味・・・
▼逆に、「Let」ではなくて「Set」で代入すると、配列には自動変化せず、普通に「オブジェクト」として代入され、 変数も「オブジェクト変数」の意味合いとなる(同じ「+」マークは付くけど、中身はまったく違ったモノになる)・・・。
ということが「実際に目で」「ひとつひとつの値」を「見ながら」確認できました。(下図のように)
今回、以降ではすこし・・・・、
「Activesheet.UsedRange」を配列に代入しなくても、
また、
オブジェクト変数に代入してもしなくても、
「Activesheet.UsedRange」という「式」のまま、
セル範囲の実際の「セルの入力値」を、
ウォッチウィンドウ(ローカルウィンドウも同じ)で確認できる(その他諸々も確認)・・・
あるいは、
「Activesheet.UsedRange」をオブジェクト変数に代入したり、
逆に、何もしなかったりでも、
「Activesheet.UsedRange」という「式」のまま、
セル範囲のセル番地(アドレス)をイミディエイトウィンドウで確認できる(その他諸々も確認)・・・
ということを実験してみたいと思います。
これは今回の「Activesheet.UsedRange」(つまりは「Worksheet.UsedRangeプロパティ」)以外にも・・・、
・単純に「Worksheet.Range」プロパティや
(例:Worksheets("Sheet1").Range("A1")、など)
・「Worksheet.Cells 」プロパティ、
(例:Worksheets("Sheet1").Cells(3,5)、など)
・「Range.Cells 」プロパティ、
(例:Worksheets("Sheet1").Range("A1").Cells(10,2)、など)
・「Range.CurrentRegion」プロパティ、
(例:Worksheets("Sheet1").Range("A1").CurrentRegion、など)
・「Application.Selection」プロパティ、
(例:Application.Selection、Selection、など)
・「Window.Selection」プロパティ、
(例:Workbooks("Book1.xlsx").Windows("Book1.xlsx").Selection、など)
・・・などを使ってセル範囲をゲットしたときも、
同じ「見方」「チェック方法」が使えますので、ぜひ覚えておいてほしいと思います。
(初心者の方にはいきなりこんなにたくさん、書いてしまってすみません。初心者の方には、今回ぼ紹介する操作が「いろいろな場面で応用できるんだな」程度に理解て頂ければそれでOKです。ことあるごとに、今回と同じ操作を何度も繰り返せば、上述のことがわかってくるようになれるとも思います。がんばってください。)
※参考
以下の図も参考にしてみてください。
例えば Rangeオブジェクトの取得の場合、どういったプロパティなどが使われるか、の「イメージ」の図です。
あくまでも「イメージ」ですが、下図の「正規ルート」と「ワープルート」の違いなどを良く見てみてください。
「正規ルート」では普通の原則的なセル範囲(A1形式のセル範囲)が取得でき、
「ワープルート」では、「少し便利なかたち(性格が異なったかたち。R1C1形式や使用された部分のみ、数個ずらした、等々)でのセル範囲が取得できます。
(※「ワープルート」=下の図で言うと、オレンジの点線矢印でのRangeオブジェクトのゲット=アクセスのルートのことです。)
※各コレクションオブジェクトの「Item」という名前のプロパティやメソッドは基本、省略されることがほとんどです。(後述)
ただ、「VBAは省略しない方が上達します」。
あと、一口に、例えば「Cells」プロパティと言っても、Application.Cellsもあれば、Worksheet.CellsやRange.Cellsもあって、「それぞれに「微妙に動きが異なる」ので、「親となるオブジェクトとセットで」、「どのCells」オブジェクトなのか、を明確に指定する必要があります。それは「Cells」に限らず、他のプロパティでも同じことが言えます。
(例えば上図だと「Application.Selection」や「Window.Selection」、各種「Item」がそれにあたります。)
なので上図では、その意味で、「親となるオブジェクト」の名前もくっつけた状態で説明してあります。
「ヘルプ(特に2007以降)」や「オブジェクトブラウザ」もこの形式を守っていますので、逆に、このことを知らないと、「ヘルプ」や「オブジェクトブラウザ」が読めません。
ご注意ください。
ではまずはチェックが簡単なイミディエイトウィンドウで、セル範囲のセル番地を確認する事例をお話しさせていただきます。
結論から言いますと、
「ある1つのオブジェクトについて、その何かをイミディエイトウィンドウで調べる際は」、
おおまかには、
以下の(01)~(03)のような方法で、調べることができます。
(01)代入コードの右辺の一部・または全部(今回だと「ActiveSheet.UsedRang」)を使って、調べられる。
(02)そのオブジェクトが、もしシート上で「マウスで選択」できるモノであれば、「×××.Selection.×××」を使って調べられる。
(※「オブジェクト」→いきなりオブジェクトなんて書いてすみません。
今回の実験で言うと、「セル範囲(Rangeオブジェクト)」のことを指しています。
「オブジェクト」にはそのほかにも「ブック(Workbook)」や
「シート(Worksheet)」など、様々な「オブジェクト」があります。)
(03)もしオブジェクト変数に代入した場合なら、そのあとは(プログラムが終了するまでの間なら・F8キー実行中の間なら)、「オブジェクト変数.×××」でも調べられる。
※なお、セル範囲の何かを調べる場合、イミディエイトウィンドウでは、例えば「セル番地」を調べるのには便利です。
ローカルウィンドウやウォッチウィンドウではセル番地は調べられないのですが、イミディエイトはラクに調べられます。
総じてVBEの画面で「何かを調べるとき」には、、イミディエイト、ローカル、ウォッチ、のどれがいいかは、調べるモノによって替わります。
例えばセル番地を調べる場合はイミディエイトが便利ですが、セルの入力値を調べるには、これまでにお示ししてきたような感じで、ローカル、ウォッチ、のほうがわかりやすいです
(イミディエイトでも一応調べられますがかなり手間・面倒くさいです。)
では、まずは、「Activesheet.UsedRange」を使ってのセル番地の調査から。
まず、セル番地を調べるには、
「Range.Address プロパティ」という命令を使います。
上記の「Range」の部分は、「Rangeオブジェクトを表す式」という意味なのですが、「Activesheet.UsedRange」も「Rangeオブジェクトを表す式」のひとつです。
で、その「式」の内容は、状況・目的によって長かったり短かったり、使う単語も異なったりで、色々に異なってきす。変化します。
※ちなみにですが、2007、2010のヘルプが、こういう「オブジェクト.プロパティ名」といった形式の、「優しい書き方」をしてくれてます。
これだとオブジェクトブラウザともリンクさせて理解しやすいです。
2013以降のヘルプはこういう優しい書き方じゃなくなりました。
「オブジェクト」の部分がなくなって、「プロパティ名」だけになりました。
オブジェクトブラウザともリンクして理解しにくいです。
いちいちWebに繋がないと見れないし、表示が遅いし。
そして、最悪なのは、機械翻訳で訳がメチャクチャだったり、まったく間違ったプロパティやメソッドのヘルプページが出てきてしまったりします。
なぜヘルプを退化させるのか、その意味がわかりません。
マイクロソフトは本当に不親切です。
顧客第一なんて20年前からいつもウソばっかり。
では早速ですが、
イミディエイトウィンドウにて、
? Activesheet.UsedRange.Address
と書いて、Enterしてみます。
すると、
$A$1:$B$4
と表示されます(=返ってきます)。
これはどんな意味かといいますと、
Activesheet.UsedRange.Address
つまり、
今現在の、Activesheet.UsedRangeのセル範囲は、
「$A$1:$B$4」ですよ~
ということを言っています。
「$A$1:$B$4」は絶対参照 での記述方式ですので、
これを普通の相対参照の記述方式に直すと
(「$」記号を取るだけなので)
「A1:B4」
となります。
で、実際に「Sheet1」というシートを確認してみますと、下図のようになっていますので・・・
確かに、
「A1:B4」
に値が埋まっており、「UsedRange」を使った場合のセルアドレス(セル番地)は、
「A1:B4」
であるな・・・とわかります。
実感できます。確信・確認できます。
そして
? Activesheet.UsedRange.Address
のほかには、以下の書き方でもOKです。
? Application.Workbooks.Item("ブック名").WorkSheets.Item("シート名").UsedRange.Address
これが一番省略の少ない書き方です。
下図ので言うと「ワープルート」ではありますけど、
『 面倒くさがって「 Activesheet 」だけしか書かない 』ということではなくて、
『 ちゃんと、「 Application.Workbooks.Item("ブック名").WorkSheets.Item("シート名") 」を省略せずにちゃんと書く 』、
という意味で、です。
もちろん「 Application.Workbooks.Item("ブック名").WorkSheets.Item("シート名") 」の部分までは、「正規のルート」を辿ってもいます。
以下の図の「正規のルート」と「ワープルート」の違いを参考にしてみてください。オレンジの点線が「ワープルート」です。
※図を見るときの補足情報
「WorkSheet.UsedRangeプロパティ」や「Range.CurrentRegionプロパティ」は、「オブジェクトを返す自作関数のようなもの」で、かつ、しかも、「 ”ワープルート ”を使える」、「オブジェクトを返す自作関数のようなもの」というイメージでいいと思います。
同様に「Application.Cellsプロパティ」や「Application.Selectionプロパティ」「Window.Selectionプロパティ」も、「正規ルート」ではなく「ワープルート使用可能なタイプのモノ」です。
そのほかに、以降のような書き方もあります。
? Application.Workbooks("ブック名").WorkSheets("シート名").UsedRange.Address
? ActiveWorkbook.Activesheet.UsedRange.Address
? ActiveWorkbook.WorkSheets("シート名").UsedRange.Address
? WorkSheets("シート名").UsedRange.Address
? VBAProject.Sheet1.UsedRange.Address
? Sheet1.UsedRange.Address(上記の省略形)
などなど。(ほかにもあります。)
(※上記の全行の末尾の「Address」という単語たちよりも前に記述されているモノはすべて、前述しました「Rangeオブジェクトを表す式」というモノです。長いモノも短いモノもありますが、このように、「Rangeオブジェクトを表す式」は状況・目的によって色々に異なってきす。変化します。逆に言うと、状況によって、目的を一番達成できる書き方に、「使い分け・書き分け」をします。
なお、「Address」の前は「長かろうが短かろうが、ドットが多かろうが少なかろうが、」、どんな書き方だろうが、「ぜんぶ、」、「”1個の ” Rangeオブジェクトを表す式だ」、「”1つの ” Rangeオブジェクトを特定する式だ」ということも覚えておいてください。)
これらは全部、省略したり、別の角度から見て書いたりしたものです。
全部「Range.UsedRange」を使っていますが、その「UsedRange」を含めたソコより前(左)の部分は、(前述もしましたとおり)「Range」の部分を表しており、色々に異なっています。
また、どれも「.(ドット)」が複数付いていますが、どれも、「1つだけ」の「オブジェクト」を表しています。
『 「.(ドット)」が複数付いていても、実は、1つのオブジェクトを選択している状態。 』というイメージです。
(詳しくはどこかでまた説明します。https://euc-access-excel-db.com/00000WPIMG/2020-12-29---16-52-17.jpg の「正規ルート」や「ワープルード」の図を見て分かる方がいらっしゃったらうれしいですが・・・)
ExcelVBAでは、
・2つ以上の複数のxlsx(xlsm)を同時に扱ったり、
・1つだけのブックの扱いであってもそのブックやシートの名前が分からない時・特定できない時があったり、
・シートの位置が入れ変わっても常に同じシートを指定したい時があったり、
などなど、
「いろんなシーンがある」のですが、
この「Range」に相当する部分の書き方の変化は(=書き分けは)、そのようなシーン・目的に合わせて、書き方を変えている・・・・というわけです。
で、結果は以下のようになります。
(以下は全部、「シート名」を「Sheet1」でやった場合です。「"ブック名"」は皆さんの状況にあてはめて書き換えてください。シートのウィンドウタイトルに表示されたブック名です。拡張子が無い場=まだ最初保存が終わってない場合は、拡張子無しのまま指定します。なお、「"ブック名"」や「"Sheet1"」をインデックス番号でやってもOKです。)
? Application.Workbooks.Item("ブック名").WorkSheets.Item("Sheet1").UsedRange.Address
$A$1:$B$4
? Application.Workbooks("ブック名").WorkSheets("Sheet1").UsedRange.Address
$A$1:$B$4
? ActiveWorkbook.Activesheet.UsedRange.Address
$A$1:$B$4
? ActiveWorkbook.WorkSheets("Sheet1").UsedRange.Address
$A$1:$B$4
? WorkSheets("Sheet1").UsedRange.Address
$A$1:$B$4
? VBAProject.Sheet1.UsedRange.Address
$A$1:$C$4
? Sheet1.UsedRange.Address
$A$1:$C$4
ちなみにですが、
「Range.CurrentRegion」プロパティを使った場合でも、「今回の実験(今回のシートの入力値・表構成)に限っては」全く同じです。
「Range.CurrentRegionプロパティ」は、
「Range」の部分で指定した「単一のセル」を起点として、
そのタテヨコの上下左右の端っこの、
ぐるっと空白行と空白列で囲まれたセル範囲、
をゲットすることができるプロパティです。
今回はシートに書いたサンプルの表が、「表の上と左には空白行や空白列が無い」ため、そのために、「たまたま」、セル番地を調べた結果(答え)が、「Worksheet.UsedaRangeプロパティ」の場合と同じになります。
(※今回の実験以外の場合は、表の作り方によっては返ってくる結果内容は同じにならない=異なることが結構あります。今回はたまたま同じなっただけです。ただ、『 セル範囲のアドレスを確認をするためにイミディエイトウィンドウを使う 』という『 目的・手段 』に関してだけは、まったく同じです。)
「Range.CurrentRegion」プロパティを使う場合は、以下のような式でイミディエイトウィンドウで確認します。
? Application.Workbooks.Item("ブック名").WorkSheets.Item("シート名").Range("A1").CurrentRegion.Address
「CurrentRegion」を使う場合に限っては、これが一番省略の少ない基本形です。
これも、以下の図の「正規のルート」と「ワープルート」を参考にしてみてください。オレンジの点線は「ワープルート」です。
「ワープルート」は上からはもちろん下からも(=上の階層からはもちろん下の階層からも)あることがイメージできると思います。特にRangeオブジェクト以外の他のオブジェクトでは下の階層からのワープルートも実際にあります。(×××.Parentプロパティや×××.Applicaionプロパティを使う場合など)
今のこの図では「下の階層から」、というワープルートは描いていませんが、「CurrentRegion」からアクセスする場合は、なんとなく「下からっぽく見える」と思いますが、少なくとも「ワープルートは上からばかりではない」ということがこれで「なんとなく想像もつく」と思います。(Rangeオブジェクトの場合、Range.Hyperlinkオブジェクトが保持・保有する「Rangeプロパティ」が「下からのワープルート」になるかもしれません。ちょっと自信ないですが・・・。でも一応、オブジェクトモデルの一覧図にはRangeオブジェクトの下の階層にもHyperlinkオブジェクトがあるので多分そう・・・。)
※「WorkSheet.UsedRangeプロパティ」や「Range.CurrentRegionプロパティ」は、「オブジェクトを返す自作関数のようなもの」で、かつ、しかも、「 ”ワープルート ”を使える」、「オブジェクトを返す自作関数のようなもの」というイメージでいいと思います。
同様に「Application.Cellsプロパティ」や「Application.Selectionプロパティ」「Window.Selectionプロパティ」も「ワープルート使用可能なタイプのモノ」です。
以降は、
? Application.Workbooks.Item("ブック名").WorkSheets.Item("シート名").Range("A1").CurrentRegion.Address
という書き方を省略したり、別の角度から見て書いたりした調べ方です。
? Application.Workbooks("ブック名").WorkSheets("シート名").Range("A1").CurrentRegion.Address
? ActiveWorkbook.Activesheet.Range("A1").CurrentRegion.Address
? ActiveWorkbook.WorkSheets("シート名").Range("A1").CurrentRegion.Address
? WorkSheets("シート名").Range("A1").CurrentRegion.Address
? Activesheet.Range("A1").CurrentRegion.Address
? VBAProject.Sheet1.Range("A1").CurrentRegion.Address
? Sheet1.Range("A1").CurrentRegion.Address(上記の省略形)
などなど。(ほかにもあります。)
(※上記の全行も、最末尾の「Address」という単語よりも前に記述されているモノはすべて、前述しました「Rangeオブジェクトを表す式」というモノです。長いモノも短いモノもありますが、このように、「Rangeオブジェクトを表す式」は状況・目的によって色々に異なってきす。変化します。逆に言うと、状況によって、目的を一番達成できる書き方に、「使い分け・書き分け」をします。
「Range.CurrentRegion」を使うと、少しややこしくなるので混乱してしまうかもしれませんが、ここでは深く考えずに、「Address」の前は「長かろうが短かろうが、ドットが多かろうが少なかろうが、」、「ぜんぶ、」「”1個の ” Rangeオブジェクトを表す式だ」、「”1個の ” Rangeオブジェクトを特定する式だ」ということだけでも覚えておいてください。)
結果は以下のようになります。
(「シート名」を「Sheet1」でやった場合。)
? Application.Workbooks.Item("ブック名").WorkSheets.Item("Sheet1").Range("A1").CurrentRegion.Address
$A$1:$B$4
? ActiveWorkbook.Activesheet.Range("A1").CurrentRegion.Address
$A$1:$B$4
? ActiveWorkbook.WorkSheets("Sheet1").Range("A1").CurrentRegion.Address
$A$1:$B$4
? WorkSheets("Sheet1").Range("A1").CurrentRegion.Address
$A$1:$B$4
? Activesheet.Range("A1").CurrentRegion.Address
$A$1:$B$4
? VBAProject.Sheet1.Range("A1").CurrentRegion.Address
$A$1:$C$4
? Sheet1.Range("A1").CurrentRegion.Address
$A$1:$C$4
以上のどれを使ってもいいといえばいいですが、
? WorkSheets("シート名").Range("A1").CurrentRegion.Address
? Activesheet.Range("A1").CurrentRegion.Address
などは、ブックの部分を省略してしまっているので、あまりよろしくありません。
単一のブックしか扱わないプログラムならこれでもいいですが、
複数のブックを扱う場合はエラーや誤作動を起こすことがあります。
実務のプログラムでは、注意して使ってください。
? Range("A1").CurrentRegion.Address
などは、エラーだらけになって最悪ですので、絶対に実務で使わないようにしてください。
(やむをえない場合以外は。)
ちょっと脱線しますが、
ラスト2行の、
? VBAProject.Sheet1.Range("A1").CurrentRegion.Address
? Sheet1.Range("A1").CurrentRegion.Address
という書き方は(「Range.UsedRange」の場合も同じだったんですが)・・・・、
「単一のブックしか扱わない場合に限ってであれば」、
シート名やシートの位置が変わっても、プログラム側は書き換える必要が無いやり方なので、便利と言えば便利です。
が、ただし、これも「複数のブックを同時に扱うとき」は、ヤバくなるときがありますので、「複数のブックを同時に扱うとき」は積極的には使わないほうがいい書き方です。
例えば、「Personal.xlsb」(=個人用マクロブック)を使っている時がヤバいです。
「Personal.xlsb」(=個人用マクロブック)を使っている時にこの2つの書き方を使ってしまうと、今アクティブなブックではなくて、「Personal.xlsb」がらみの値が返ってきてしまう(=答えが違ってきてしまう)ことがあります。
それはつまり、プログラムが誤作動する可能性がある、ということです。
そして、今自分が「Personal.xlsb」(=個人用マクロブック)を使っているかいないかは、VBAに慣れてないと「気づけません」。
また、職場で他人に配布するプログラムを作る場合、「Personal.xlsb」(=個人用マクロブック)を使っていない人も多いです。そこでも、プログラムが誤作動する可能性が上がってしまいます。
一部の市販書籍では、この書き方を「一番よい」としていることがありますが、そんなことはまったくない=誤りですので注意が必要です。
本来、応急処置などの場合に「一時的な逃げ」として使う書き方のように思います。
なので、いきなり「VBAProject.Sheet1」とか「Sheet1」から書き出す書き方については、「注意が必要」です。むやみに使用しないでください。
そもそも「VBAProject」というもの自体の扱いが少し面倒です。
複数の「VBAProject」が存在できますし、逆に個別に名前を変えることもできてしまいますし、また、『 参照設定やPersonal.xlsb、xlsa=アドインファイルなど 』のからみで複数の「VBAProject」が存在する場合は、例えば、ある「VBAProject」から別の「VBAProject」のSheet1を直接指定・操作することができません。基本、現在アクティブな「VBAProject」=例えば点滅カーソルが在る「VBAProject」しか、Excelは「アクティブなVBAProjectとして」認めてくれません。
一応、ある「VBAProject」から、別の「VBAProject」に自動的にアクティブにするには、
以下のようなコードを使えばできるっぽいのですが・・・、
Application.VBE.VBProjects(1).VBComponents(1).Activate あるいは
Application.VBE.VBProjects(1).VBComponents(1).CodeModule.CodePane.Show など。
(個人用マクロブック=Personal.xlsbがある場合は、それをアクティブにする。
無い場合は、最初に読み込まれたブックのVBAProjectをアクティブにする。)
Application.VBE.VBProjects(2).VBComponents(1).Activate あるいは
Application.VBE.VBProjects(2).VBComponents(1).CodeModule.CodePane.Show など。
(それ以外のVBAProjectをアクティブにする。)
・・・でもこれができたとしても、
『 複数の異なるVBAProjectのあいだ 』では、切り替わった瞬間に
一旦コントロール(制御)を「ブチ切られる」ので、
そのあと、『 複数の異なるVBAProjectのあいだの中 』で、
『 どのようにコントロールを「つなげて」行けばいいか 』、
が、分かりません。
これは「VBAProject」という名前を、自分の好きな任意の名前に変更してもダメみたいです。色々試しましたがダメでした。
(Accessはこういう煩わしさがなくて便利です。他のAccessファイル=mdbファイルのプログラムを動かす場合も、参照設定するだけでプロジェクトがどうこうなく、色々、間違わずに、やれます。Excelが「少し大き目な機能拡張のしやすいシステムを作るのには向かない」というのは、こういう部分のこともあります。意外と「致命的」。です。色々に機能拡張したいときに、Accessと同じようにはできなくて、ムチャクチャ腹が立ちます。)
結局、いきなり「VBAProject.Sheet1」とか「Sheet1」から書き出す書き方は、
「単一のブックしか扱わず、かつ、個人用マクロブック(Personal.xlsb)も存在しない」ときだけ、
しか有効活用できなさそうです。
あるいは、個人用マクロブック(Personal.xlsb)が存在していてもいいのですが、気を付けないと誤作動を招くので、注意しながらプログラムを作ることが必要です。
(※↑間違いかもしれないのでご自分でも調べてみてください。ただ、僕も結構色々調べましたけど、意外と使い勝手が悪かったです・・・。結局、この書き方を使わずに・ブックの保護などが必要になる気がする・・・・、と感じました。)
脱線すみませんでした。
というわけで、ゴチャゴチャとこまごま説明してしまってすみませんが、
前述のテスト結果どおり・・・・、
? Application.Workbooks.Item("ブック名").WorkSheets.Item("Sheet1").UsedRange.Address
? Application.Workbooks("ブック名").WorkSheets("シート名").UsedRange.Address
? ActiveWorkbook.Activesheet.UsedRange.Address
? ActiveWorkbook.WorkSheets("シート名").UsedRange.Address
? WorkSheets("シート名").UsedRange.Address
? VBAProject.Sheet1.UsedRange.Address
? Sheet1.UsedRange.Address
? Application.Workbooks.Item("ブック名").WorkSheets.Item("Sheet1").Range("A1").CurrentRegion.Address
? Application.Workbooks("ブック名").WorkSheets("シート名").Range("A1").CurrentRegion.Address
? ActiveWorkbook.Activesheet.Range("A1").CurrentRegion.Address
? ActiveWorkbook.WorkSheets("シート名").Range("A1").CurrentRegion.Address
? WorkSheets("シート名").Range("A1").CurrentRegion.Address
? Activesheet.Range("A1").CurrentRegion.Address
? VBAProject.Sheet1.Range("A1").CurrentRegion.Address
? Sheet1.Range("A1").CurrentRegion.Address(上記の省略形)
・・・・といった、どの記述方法でも、
今回のテストの場合に限っては、返ってくるセル範囲のアドレスは、
「$A$1:$B$4」
が答えとして返ってきます。
つまり、
「全部」、
「A1:B4」だ、
ということになります。
まずはこのような調査方法が「1つ目」、です。
そのほか、「2つ目」として、
セル範囲の「A1~B4」を「ドラッグで選択しておいてから」、
「Application.Selection」プロパティ、や
「Window.Selection」プロパティ、
を使って調べるのも同じです。
「Application.Selection」プロパティ、の場合なら、
? Application.Selection
あるいは(「Application」を省略して)、
? Selection
とイミディエイトウィンドウに書いてEnterすると、
「$A$1:$B$4」と返ってきますし、
「Window.Selection」プロパティ、の場合なら、
? ActiveWindow.Selection
あるいは
? Workbooks("ブック名").Windows("ブック名").Selection
とイミディエイトウィンドウに書いてEnterすると、
「$A$1:$B$4」と返ってきます。
あと、「3つ目」として、
これも大事な確認方法ですが、「データを代入済み」の「変数」を使う方法です。
例えば今回のサンプル(実験)では、
「Set rrr = ActiveSheet.UsedRange」
というコードによって
オブジェクト変数の「rrr」に「ActiveSheet.UsedRange」を代入しました。
ですので、
変数「rrr」を使っても、(この例においては)
イミディエイトウィンドウで「ActiveSheet.UsedRange」のセル範囲を確認することができます。
もちろんこれも、今までと同じように、
『 F8キーでのステップ実行中でしか 』
確認ができません。
が、とりあえずイミディエイトウィンドウにて
? rrr.Address
と書いて、Enterします。
すると、これまでのテストと同様、
「$A$1:$B$4」と返ってきます。
これで、
『 あ! オブジェクト変数の「rrr」は ホントに「ActiveSheet.UsedRange」と同じになったんだね! 』
と分かります。
実感、確信、できます。
なお、ここまでの流れでもうお分かりかとは思いますが、以降のような「代入のコード」を書いたときも、「? rrr.Address 」と書いてEnterすると、これまでのテストと同様、「$A$1:$B$4」と返ってきます。
(もちろん、今回の実験・限定です。)
Set rrr = Application.Workbooks.Item("ブック名").WorkSheets.Item("Sheet1").UsedRange
Set rrr = Application.Workbooks("ブック名").WorkSheets("シート名").UsedRange
Set rrr = ActiveWorkbook.Activesheet.UsedRange
Set rrr = ActiveWorkbook.WorkSheets("シート名").UsedRange
Set rrr = WorkSheets("シート名").UsedRange
Set rrr = VBAProject.Sheet1.UsedRange
Set rrr = Sheet1.UsedRange
Set rrr = Application.Workbooks.Item("ブック名").WorkSheets.Item("Sheet1").Range("A1").CurrentRegion
Set rrr = Application.Workbooks("ブック名").WorkSheets("シート名").Range("A1").CurrentRegion
Set rrr = ActiveWorkbook.Activesheet.Range("A1").CurrentRegion
Set rrr = ActiveWorkbook.WorkSheets("シート名").Range("A1").CurrentRegion
Set rrr = WorkSheets("シート名").Range("A1").CurrentRegion
Set rrr = Activesheet.Range("A1").CurrentRegion
Set rrr = VBAProject.Sheet1.Range("A1").CurrentRegion
Set rrr = Sheet1.Range("A1").CurrentRegion
以上のように、
「ある1つのオブジェクトについて、その何かをイミディエイトウィンドウで調べる際は」、
以下の(01)~(03)のような方法で、調べることができます。
(※「オブジェクト」→いきなりオブジェクトなんて書いてすみません。
今回の実験で言うと、「セル範囲(Rangeオブジェクト)」のことを指しています。
「オブジェクト」にはそのほかにも「ブック(Workbook)」や
「シート(Worksheet)」など、様々な「オブジェクト」があります。)
(01)代入コードの右辺の一部・または全部(今回だと「ActiveSheet.UsedRang」)を使って、調べられる。
(02)もしシート上で「選択」できるモノであれば、「×××.Selection.×××」を使って調べられる。
(03)オブジェクト変数に代入したあとは、「オブジェクト変数.×××」でも調べられる。
そして、今回の調査でわかったことは以下のような事です。
『 あ! オブジェクト変数の「rrr」は 代入のコードを実行した後に、ホントに「ActiveSheet.UsedRange」と同じになったんだね!! だってセル番地調査の答えがどっちも「$A$1:$B$4」だもんね! 』
『 変数に代入しなくても、式のままでも、あるいは「シート上でセルを選択しただけ」でも、セル番地って調べられるんだね!だって、「ActiveSheet.UsedRange.Address」のままでも「×××.Range("A1").CurrentRegion.Address」のままでも、「×××.Selection.Address」でも、全部、「$A$1:$B$4」って同じ答えが出てきたもんね! 』
『 あ! 「ActiveSheet.UsedRange」と「×××.Range("A1").CurrentRegion」は、今回たまたまだけど、確かに同じセル範囲だ!ってわかった!! だってセル番地調査の答えがどっちも「$A$1:$B$4」だもんね! 』
『 「どの書き方とどの書き方が同じ意味か」、とか、「どのオブジェクト変数とどの”式 ”が同じ意味か」、などが、このようにイミディエイトウィンドウを使うやり方でわかる場合もあるんだね!! 』
『 目的によって、いろんな異なる書き分けで、でも、同じモノや異なるモノ、色々と調べられるんだね! 』
『 ローカルウィンドウやウォッチウィンドウで調べられない時は、イミディエイトウィンドウで調べるられるケースも少なくないんだね!(その逆も!) 』
『 https://euc-access-excel-db.com/00000WPIMG/2020-12-29---16-52-17.jpg の図から、Rangeオブジェクトをゲット=取得する=返してもらうには、正規ルートとワープルートがあるんだね!』
『 使うプロパティによって、ゲットできるRangeオブジェクトの「状態・状況」が、いろいろに異なるんだね!(今回たまたま 「ActiveSheet.UsedRange.Address」のままでも「×××.Range("A1").CurrentRegion.Address」と結果は同じだったけど・・・。』
『 シート上で「選択」できるモノは、「×××.Selection.×××」で色々と調べられるんだね! 』
『 ひとつの同じセル範囲、たとえば「$A$1:$B$4」を表す・ゲットするにしても、シーンによって・目的によって、(短かったり長かったり)いろんな書き方・書き分けの方法があるんだね! だって全部、同じ、「$A$1:$B$4」って答えが返ってきてるもんね!』
今回は以上です。
==========================================================================
バックナンバー目次とサンプル号
----------------------------------------------------------------------
■独学者が1年後にExcelVBAを爆発的に上達させるための最低限の基礎知識メモ(ダイジェスト)
発行システム:『まぐまぐ!』 http://www.mag2.com/
配信中止はこちら https://www.mag2.com/m/0001691660.html
----------------------------------------------------------------------