こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

エクセル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 が通らないのはなぜでしょう?
しょうもない質問でごめんさない。

投稿日時 - 2007-02-28 15:41:20

QNo.2791223

暇なときに回答ください

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

Sheet1 は Sheet1 という(Worksheet を継承した)オブジェクトなんです。

Sheets(n) や Sheets("Sheet" & n) は

Sheets コレクションのなかの n 番目、"Sheet" & n というシートということです。Sheets(index)プロパティで Worksheet オブジェクトを返します。

Sheet(n) はそもそも Sheet というオブジェクトがないのでエラーになってしまうというわけです。

投稿日時 - 2007-02-28 15:54:02

お礼

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

投稿日時 - 2007-03-01 11:32:23

このQ&Aは役に立ちましたか?

6人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.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側は、それぞれ違う面を持っているのだと思います。だから、通称名は、おそらくは、何千分の一秒かで、そのオブジェクトを探しているのではないでしょうか?確かに、その分、使用範囲を割り引かれているような気がしますが、オブジェクト名の指定の方法は、変数が用いられないので、ループなどが利かずに、使いづらいのではないでしょうか?

投稿日時 - 2007-03-01 00:14:30

お礼

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

投稿日時 - 2007-03-01 11:37:40

ANo.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とか変更したりはしますが。。。

以上です。

投稿日時 - 2007-02-28 18:24:09

お礼

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

投稿日時 - 2007-03-01 11:35:27

ANo.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
これ自身は意味のないプログラムですが。シートを名前で指定してます。

投稿日時 - 2007-02-28 17:10:39

お礼

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

投稿日時 - 2007-03-01 11:33:33

あなたにオススメの質問