• ベストアンサー

エクセル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/17068)
回答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

  • エクセル、ワークシートが保護されているかどうかを判断するVBAは?

    以下のように書いてもダメでした。 どう直せばよいでしょうか? Sub TEST2() Dim n As Integer n = ThisWorkbook.Worksheets.Count For i = 1 To n If Worksheets(i).Protect = False Then MsgBox Worksheets(i).Name End If Next End Sub

  • エクセルVBAで、作業対象を全ワークシートか選択シートかを切り替えたい

    エクセル2000です。 VBAで、作業対象を全部のワークシートか選択されたシートかを任意で切り替えたいのです。 ためしに無理とは思いながら以下のように作ってみましたが、当然のようにエラーになります。 どうかお知恵をお貸しくださいませ。 お願い致します<(_ _)> Sub test() sc = ThisWorkbook.Worksheets.Count ssc = ActiveWindow.SelectedSheets.Count If sc <> ssc Then ans2 = MsgBox(ssc & " 枚のシートだけでいいんですね?" _ & vbCr & "" _ & vbCr & "もし全部のシート(" & sc & "枚)を対象にするなら" _ & vbCr & "いいえを選択してください。", vbYesNo + vbQuestion, " o(^-^)o") ts = IIf(ans = vbNo, Worksheets, ActiveWindow.SelectedSheets)'ここでエラー End If For Each sh In ts sh.Activate sh.Cells(1, 1).Value = sh.Name Next sh End Sub

  • エクセルVBA シート名の部分一致検索について エクセル2007

    VBAでエクセルの全シート名を部分一致で検索したいと考えています。 そこで以下のコードを書いたのですが、 インプットボックスにどんな文字列を入力しても全てのシート名を 取得してしまって途方にくれています。 どなたかお助けください。 Sub test01() Dim name As String Dim ws As Worksheet shn = InputBox("検索文字列を入力") For Each ws In ThisWorkbook.Worksheets If ws.Name Like " * " & name & " * " Then ws.Activate MsgBox ws.Name End If Next ws End Sub

  • 最終シートからその手前まで5シートの選択したい

    最終シート名が「基本」、その前が「種別」、さらにその前が「一覧」と言うシート名になっています。 またその「一覧」の前2ケは、シート名をindexで指定したいです。 以下のコードを実行してもうまく、シートを除外してくれません。どうしたらよろしいでしょうか。 Sub 各シートに関数を入力() Dim EXCEPT_NAME As String EXCEPT_NAME = " 一覧  種別  基本" & Worksheets(Sheets.Count - 4).name & Worksheets(Sheets.Count - 5).name Application.ScreenUpdating = False ChDrive ThisWorkbook.Path ChDir ThisWorkbook.Path Dim list, sheetName For Each sheetName In ActiveWorkbook.Worksheets If InStr(EXCEPT_NAME, sheetName.name) = 0 Then Sheets(sheetName.name).Activate ActiveSheet.Unprotect Call 関数貼付 End If Next End Sub

  • VBAで初歩的な質問ですシートのコピーについて

    Sub SheetCopy() For i=1 to 31 WorkSheets.Add.Move after:=WorkSheets(workSheets.Count) シート名=i ActiveSheet.Name=シート名 Next End Sub と、シートをコピーするプロシージャを作りました。本当は、シート名を7月1日から、7月31日の31枚を作りたいのですが、どのように書けばよいのでしょうか? よろしくお願いします。

  • エクセルVBAで一番左の可視シート名を取得

    エクセルVBAで一番左側にあるシート名を取得する場合、通常は Sub test01()   MsgBox Sheets(1).Name End Sub で簡単にできますが、このSheets(1)が非表示になっている場合でもその名前が取得されるため、見た目での一番左側にあるシート名ではなくなってしまいます。 もちろん、非表示になっているシートを除外して Sub test02()   Dim n As Integer   For n = 1 To Sheets.Count     If Sheets(n).Visible Then       MsgBox Sheets(n).Name       Exit For     End If   Next End Sub とすれば取得できるのはわかりますが、こんなまだるっこい方法以外に簡単に一番左の可視シート名を取得する方法はないでしょうか? (^∇^)? ご教示くださいませ。

  • EXCELのシートを並べ替えすると・・・

    エクセルのシートを並べ替えようと思って こちらで調べてようやく並べ替えができるようになったのですが、幾つかあるデータの中で実行するとエラーが出るものがあります。 シートの名前は1日~31日&集計という構成なのですが、下記を実行すると実行エラー9:インデックスが有効範囲にありません!とでます…デバックを押すと Worksheets(CStr(Wwh.Cells(N, 1).Value)).Move After:=Sheets(N) のところが黄色になっています。 同じようなシートの構成があるデータで試してみると成功するものと失敗するものがありもう何がなにやら(;´Д`) 何か変更しないとだめなんでしょうか? 分かる人がいたらアドバイスお願いします。 Sub SortSheets() Dim Wwh As Worksheet Dim N As Integer Application.ScreenUpdating = False Sheets.Add Before:=Worksheets(1) Set Wwh = ActiveSheet For N = 2 To Worksheets.Count   Cells(N - 1, 1).Value = Worksheets(N).Name   Cells(N - 1, 2).Value = _   Application.GetPhonetic(Worksheets(N).Name) Next N Range("A1").CurrentRegion.Sort Key1:=Range("B1"), _   Order1:=xlAscending, Header:=xlNo, OrderCustom:=1 '昇順 'Range("A1").CurrentRegion.Sort Key1:=Range("B1"), _   Order1:=xlDescending, Header:=xlNo, OrderCustom:=1 '降順 For N = 1 To Range("A1").End(xlDown).Row   Worksheets(CStr(Wwh.Cells(N, 1).Value)).Move After:=Sheets(N) Next N For N = 2 To Worksheets.Count   If Worksheets(N).Visible = xlSheetVisible Then     Worksheets(N).Activate     Exit For   End If Next N Application.DisplayAlerts = False Wwh.Delete Application.DisplayAlerts = True Application.ScreenUpdating = True Set Wwh = Nothing End Sub

  • エクセルVBA シートがアクティブではないのに画面に表示される?

    下記のSub test01のマクロでは、画面は常に最初のシートのままで全シートに作業が行なわれます。 ところが、同じマクロですが単にシートを保護するという1行を追加すると(それがSub test02です。)、画面が各シートに切り替わるようになるのです。 しかし、保護されてないシートにSub test02をはしらせると、最初の一回は画面は常に最初のシートのままで全シートに作業が行なわれ、その結果全シートが保護された状態になってから再度実行すると、画面が切り替わるのです。同様に、保護されたシートにSub test01を実行しても画面が切り替わります。 しかし不思議な事に、アクティブなシート名を表示させるようにしたステータスバーには常に最初のシート名しか表示されません。つまりシートがアクティブではないのに画面に表示されるようです。 もちろんScreenUpdatingをFalseにすれば画面が切り替わらなくなるのは存じておりますが、疑問なのはなぜシートがアクティブではないのに画面に表示されるのか?(しかもシートを保護あるいは保護解除する場合に限って)ということです。 どうか、ご教示下さい。 Sub test01() For Each st In Worksheets Application.StatusBar = ActiveSheet.Name st.Unprotect With st.Range("E5") For i = 50000 To 1 Step -500 .Value = Int(i / 500) Next i End With Next st End Sub Sub test02() For Each st In Worksheets Application.StatusBar = ActiveSheet.Name st.Unprotect With st.Range("E5") For i = 50000 To 1 Step -500 .Value = Int(i / 500) Next i End With st.Protect Next st End Sub

  • 「 VBA の 宣言 」 がない場合の問題点は ?

    下記例で、 「 宣言 」 なしでも、現在のところ、問題は発生してませんが、 今後、「 宣言 」 がなかった場合の 「 問題点の例 」 を教えて下さいませ。 ------------------------------- Sub ブックA*の全シートをコピー() Dim Wb As Workbook '宣言 For Each Wb In Workbooks If Wb.Name Like "ブックA*.xls" Then With Workbooks("ブックB.xls") Wb.Worksheets _ .Copy after:=.Sheets(.Sheets.Count) End With End If Next Worksheets(Worksheets.Count).Activate MsgBox ActiveSheet.Index Worksheets("Sheet1").Select End Sub

  • VBAの書き方を教えてください 2

    以前にこちらで質問をさせて頂き、(http://okwave.jp/qa/q8451754.html)これに、VBAを追記していきたいのですが、移動したシートがアクティブする方法がわかりません。 移動したシートのA1000をアクティブにする場合、教えて頂いたVBAにどこに何を入れれば宜しいのでしょうか? よろしくお願いします。 Private Sub CommandButton1_Click() Dim k As Long, myFlg As Boolean For k = 1 To Worksheets.Count If Worksheets(k).Name = Range("A1") Then myFlg = True Exit For End If Next k If myFlg = True Then Worksheets(k).Activate Else MsgBox "該当シートなし" End If End Sub

このQ&Aのポイント
  • 重度知的障害を装った白痴が悪事を働く問題があります。彼らは警察に逮捕されることもありますが、再び同じことを繰り返します。このような悪人を懲らしめるためには、どのような手段が有効でしょうか?
  • 重度知的障害を装った白痴は、無銭飲食などの悪事を働き、障害者手帳を使って責任を逃れます。彼らは警察によって逮捕されることもありますが、再び同じことを繰り返します。このような悪人を懲らしめるためには、どのような方法が有効でしょうか?
  • 重度知的障害を装った白痴が悪事を繰り返しています。彼らは警察に逮捕されることもありますが、再び同じことを行います。このような犯罪行為を防ぐためには、どのような手段が必要でしょうか?
回答を見る

専門家に質問してみよう