• ベストアンサー

エクセルVBAでSheet1.ActivateとSheet(n).Activate

エクセル2000です。 VBAでの疑問点を教えてください。 Sub test1() Sheet1.Activate MsgBox ActiveSheet.Name End Sub これは問題なく作動します。 Sub test2() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheet(n).Activate MsgBox ActiveSheet.Name Next End Sub これは「SubまたはFunctionがていぎされていません」というエラーになります。 もちろん、 Sub test3() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheets(n).Activate MsgBox ActiveSheet.Name Next End Sub のように書けばOKなのは存じておりますが、これではSheet名に係らず、左から順番となってしまいます。 Sub test4() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheets("Sheet" & n).Activate MsgBox ActiveSheet.Name Next End Sub のように明確にシート名として記述すればOKなのですが、それでは、Test1のSheet1.Activate が通って、Sheet(n).Activate が通らないのはなぜでしょう? しょうもない質問でごめんさない。

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

  • ベストアンサー
  • driverII
  • ベストアンサー率27% (248/913)
回答No.1

Sheet1 は Sheet1 という(Worksheet を継承した)オブジェクトなんです。 Sheets(n) や Sheets("Sheet" & n) は Sheets コレクションのなかの n 番目、"Sheet" & n というシートということです。Sheets(index)プロパティで Worksheet オブジェクトを返します。 Sheet(n) はそもそも Sheet というオブジェクトがないのでエラーになってしまうというわけです。

merlionXX
質問者

お礼

有難うございます。 勉強になりました。

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 >しょうもない質問でごめんさない。 私は、そんなことないと思います。merlionXXさんの質問や回答を、もう、2年近くを見てきているので、なんとなく何に引っかかっている分かるような気がします。実は、私も、こういう部分が分かったのは、VBAをはじめて3年目ぐらいの時だったと思います。 #3 のtaocat さんの内容と重複してしまいますが、私も同じように考えています。(書いた後に、そう思いました) >シート名を変更しても「オブジェクト名」Sheet1はそのままです。 のとおりなのですが、Sheet(n)というのは、ミスだとしても、Sheet1, Sheet2 というのは、オブジェクト名、またの名をCodeNameといいます。これがオブジェクトの本名なのですね。本名というのは、名指しすれば、それだけでオブジェクトを取得できるようになっています。そして、これらのオブジェクトは、複合的(別の名前、別の集まり=Collection)に出来ているのだと私は思っています。 想像の話で恐縮なのですが、通称名の、"Sheet1", "Sheet2" は、便宜的に、オブジェクト名と同じにしてしまったようなのです。VB6 には、このようなことは、なかったと思います。 それがVBAをややこしくさせているようです。私は、VBA入門当時は、どうして、こんな書き方に違いがあるのだろうか、ずっと引きずっていたわけです。ただ、今の私に言えることは、Sheet1, Sheet2 というオブジェクト名の使い方は、確かに、インテリセンスが出て見やすいのですが、通常、使わなくてよいものだと思います。ただし、実務では、オブジェクト名は、Sheet オブジェクトやVBAProject は、一意の名前を付けるようにしています。それは、ユーザーが名前を変えてしまう可能性があるのと、VBAProject は、呼び出しに混乱をさせるときがあるからです。 ワークシート側とVBA側は、それぞれ違う面を持っているのだと思います。だから、通称名は、おそらくは、何千分の一秒かで、そのオブジェクトを探しているのではないでしょうか?確かに、その分、使用範囲を割り引かれているような気がしますが、オブジェクト名の指定の方法は、変数が用いられないので、ループなどが利かずに、使いづらいのではないでしょうか?

merlionXX
質問者

お礼

Wendy02さま、いつも有難うございます。 いつまでたっても初心者から抜け出せないでおります・・・。

  • taocat
  • ベストアンサー率61% (191/310)
回答No.3

お師匠さん、こんにちは。 >しょうもない質問でごめんさない いやいやこれは「基本的なことではありますが非常に重要」なことだと思います。 こういった疑問が生じるということは、 「オブジェクト名とシート名」の区別がついてないからですね。 >Sheet(n).Activateが通らないのはなぜでしょう? これは単に文法ミスです。 Sheetという名前のコレクションがないのに使ってるからです。 (n)とかのINDEXが使えるのはコレクション(同じものの集まり)の場合です。 WorkBooks(n) とか Sheets(n) 等々。。 ●ここから本題● >Test1のSheet1.Activate (1)Sheet1.Activate (2)Sheets("Sheet1").Activate (3)Sheets(1).Activate (1)のSheet1は、「オブジェクト名」 (2)のSheet1は、「シート名」 (3)は、シートコレクション(シートの集まり)をIndexで表わす ここで新しいブックを開き VBE画面でプロジェクトエクスプローラを見てください   Sheet1(Sheet1)   Sheet2(Sheet2)   Sheet3(Sheet3) と同じ名前になっていますよね。 左が「オブジェクト名」で( )内が「シート名」です。 Sheet1のプロパティ画面を表示して Nameプロパティ(シート名)の値を "売上" に変更して 再度エクスプロラー画面を見てください、   Sheet1(売上) となってるはずです シート名を変更しても「オブジェクト名」Sheet1はそのままです。 で、上記(1)の、Sheet1.ActivateのSheet1はこの「オブジェクト名」を使っていることになりOKなのです。 もちろん、売上.Activate(シート名.Activate)はダメですよ。 このように新しいブックでは「オブジェクト名」と「シート名」が同じなのでそこらあたりをちゃんと理解しておかないとこんがらがってしまいます。 もちろん、オブジェクト名も変更はできますが、Sheetに関しては変更しないのが普通だと思います。 CommandButtonとかは、PrintBtnとかCmdBtn1とか変更したりはしますが。。。 以上です。

merlionXX
質問者

お礼

道士さま、よくわかりました。 不勉強で申し訳ありません。

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

Sub test2() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheet(n).Activate MsgBox ActiveSheet.Name Next End Sub は何をしたいのでしょうか。 どういう順番にシート名を出したいのでしょうか。 やっていることはうまくいっても、シートタブの言えている順番にシート名しか出ない内容でしょう。しかしSheet(n)という表現が許されていないからエラーになる。Index値で()で表せるのは、コレクションオブジェクトですが、コレクションオブジェクトは末尾にsがつきます。 自分の思う順序にシートをアクチブにしたいなら シート名がSheet2、Sheet1,Sheet3のようであるとき Sub test3() Dim s As Variant s = Array("Sheet2", "Sheet3", "Sheet1") x = ThisWorkbook.Worksheets.Count For n = 0 To x - 1 Worksheets(s(n)).Activate MsgBox ActiveSheet.Name Next End Sub これ自身は意味のないプログラムですが。シートを名前で指定してます。

merlionXX
質問者

お礼

有難うございます。勉強になりました。

関連するQ&A