• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Range("Sheet2!A1")が何故通る?)

Range関数で不思議な挙動が起こる理由とは?

このQ&Aのポイント
  • Excel VBAでRange関数を使用すると、アクティブなシートに依存しない範囲指定が可能です。
  • 例えば、ActiveSheet.Range("Sheet2!A1")とするとエラーが発生しますが、Range("Sheet2!A1")とすると問題なく指定したセルを取得できます。
  • これはRangeオブジェクトの仕様によるもので、Microsoft Docsには詳細な説明はなかったです。

質問者が選んだベストアンサー

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率66% (1725/2595)
回答No.3

こちらの説明が見つかりました。 Range("Sheet2!A1")の場合 Application.RangeのApplicationが略されているという感じです。 Rangeオブジェクトの使い方(1) の中の外部参照の使用 http://hp.vector.co.jp/authors/VA016119/range1.html

Mathmi
質問者

お礼

答ありがとうございます。 (回答者が同一であると気付かず、回答No.2のお礼が変になってしまいました。申し訳ありません) 紹介していただいたサイト、疑問にそのままずばりな内容でした。 >対象オブジェクトは省略するか Application を指定します。 ・オブジェクト修飾子(ピリオドの左側に記述するオブジェクト)を指定しない場合、エクセル全体(Excel.Application)が省略されている ・シートが指定されない場合、デフォルトシートが選択される。 ・オブジェクト修飾子であろうが範囲の名前であろうが、シートが指定された場合そのシートが選択される。 ・引数が一つの場合、Rangeプロパティには範囲の名前を現す文字列しか渡せない(Rangeオブジェクトは渡せない)。 と、理解してしまえば当たり前の事でした。 ですが、普段Applicationを使わないので、全く思い浮かびませんでした。 また一つエクセルに詳しくなる事ができました。どうもありがとうございます。 ただ、MicrosoftDocsのApplication. Range プロパティ (Excel)では >オブジェクト修飾子を指定せずにこのプロパティを使用すると、ActiveSheet.Range のショートカットとなります。 とあります。 もしかして、Microsoftの公式資料でも仕様通りではない……?

その他の回答 (4)

  • kkkkkm
  • ベストアンサー率66% (1725/2595)
回答No.5

> もしかして、Microsoftの公式資料でも仕様通りではない……? そうですね。資料が多すぎて手が回らない感じかもしれません。 ただ、Rangeあたりを説明するとかなりややこしくなるというのをかなり前にどこかで見た気がします。

Mathmi
質問者

お礼

回答ありがとうございます。

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.4

正面からの、理由の回答でないのが残念ですが、 エクセル関数のINDIRECT関数のような処理(文字列指定なのだが、セル範囲を指定しての扱いで、取り込む処理)をRangeの引数に対し事前に行うのではないでしょうか。ワークシート関数の引数のような(下記例)書き方は通り、WorkSheets(”Sheet1")のように、VBA的な指定が通らないのは、何か内部処理のやり方に起因するのでは。VBAでフルパス指定文字列でも似たようなことだあると思いませんか。 ーー 小生がやってみると、質問の例に加え、下記の例がOKでした。 Sub test05() x = "Sheet4!B5" Range(x) = "AAvv" End Sub Sub test06() x = "[Book1]Sheet3!B7" Range(x) = "AApp" End Sub ーー もう一つ、Shitキーを押しながら、エクセルのアイコンをクリックして Book2を起動して(名前を付けて保存する前に) Sub test07() x = "[Book2]Sheet2!B2" Range(x) = "AAFFF" End Sub もOKでした。

Mathmi
質問者

お礼

回答ありがとうございます。 >WorkSheets(”Sheet1")のように、VBA的な指定が通らないのは、何か内部処理のやり方に起因するのでは。 真に申し訳ありません。これは私のミスです。 自分は[Range(Range("A1"), Range("B2"))]のように、引数にRangeオブジェクトを指定したつもりでした。 ですが[Range(Worksheets("Sheet2").Range("A1"))]だと、実は[Range(Worksheets("Sheet2").Range("A1").Value]、つまりセルの文字列を引数に指定する事になる事に、質問を投稿してから気付きました。 何も指定しなかった場合、Rangeオブジェクトを返す場合とValueプロパティを返す場合の二通りがあるのを忘れていました。 色々なパターンを試していただき、ありがとうございました。 保存前だと、ブックを指定するブック名に拡張子が付かないんですね。

  • kkkkkm
  • ベストアンサー率66% (1725/2595)
回答No.2

> 「今の知識ではエラーになる筈なのにエラーにならない理由」なんです。 単にRangeがActiveSheet.Range略ではないという事なのではないでしょうか。 標準モジュールにおいてRangeの親は既定ではActiveSheetだけど中で明示されたらそれが優先するとか。 Range("Sheet2!A1").Address は Sheets("Sheet2").Range("A1").Address と書いたとみなされると思いこんでみるとか。 Range("A1") が Range("A1").Value とみなされると同じかなくらいで。ちょっと違うけど。 どこかにそのような説明がないか知りたいということだとしたら、わかりません。

Mathmi
質問者

お礼

回答ありがとうございます。 >単にRangeがActiveSheet.Range略ではないという事なのではないでしょうか。 別のエクセルの解説ページで >Range("A1").Value >というオブジェクト式は、実は、 >Application.ActiveWorkbook.ActiveSheet.Range("A1").Value >と同じことを意味しています。 とあったので、Rangeプロパティ(でいいのか不安ですが)は、Worksheetオブジェクトのプロパティだとばかり思い込んでいました。 実際はNo.3の方に回答頂いた通り、WorksheetではなくApplicationのプロパティっぽいです。 なお、オブジェクトの構造としてはWorksheetの下にRangeがあるので、 Application.Range("A1").ParentはApplicationオブジェクトではなくWorksheetオブジェクトを返しました。

  • kkkkkm
  • ベストアンサー率66% (1725/2595)
回答No.1

> [Range]は、実際には[ActiveSheet.Range]の省略という認識でした。 よくわかりませんが、そうなんですか。 Sheet1のシートモジュールで Sheets("Sheet2").Activate Range("a1").Value = 111 と Sheets("Sheet2").Activate ActiveSheet.Range("a1").Value = 111 は同じ結果ではないのですが…。 また 標準モジュールでしたら Sheets("Sheet2").Activate Debug.Print ActiveSheet.Range("Sheet2!A1").Address や Debug.Print Sheet2.Range("Sheet2!A1").Address でエラーにはならないと思います。

Mathmi
質問者

お礼

回答ありがとうございます。 >Sheet1のシートモジュールで 自分は基本的にシートモジュールを使わないので、その視点は抜けていました。 作業は全て標準モジュールで行っていました。 >エラーにはならないと思います。 いえ、質問したいのは「エラーにならないコード」ではなく「今の知識ではエラーになる筈なのにエラーにならない理由」なんです。

関連するQ&A