エクセルVBAでFor each文でオブジェクトが必要なエラーが発生する問題の代替案はあるか

このQ&Aのポイント
  • エクセルVBAでFor each文を使用する際に、「オブジェクトが必要です」というエラーが発生してしまう場合、代替案があります。具体的なエラーの原因は不明ですが、以下のような方法で対処することができます。
  • まず、特定のシートのみで処理を行いたい場合は、処理したいワークシートのオブジェクトを明示的に指定する必要があります。つまり、For each文の前に特定のワークシートのオブジェクトを宣言し、それを使用して処理を行います。
  • 具体的なコードは以下のようになります。 dim ws as worksheet set ws = ThisWorkbook.Worksheets("シート名") 'ここに処理を書く このようにすることで特定のシートのみで処理を行うことができます。エラーが発生しないようになるはずです。エクセルのバージョンによって細かな書き方は異なる場合がありますので、ご注意ください。
回答を見る
  • ベストアンサー

エクセルVBAでFor each文

下記のようなコードを書きたいのですが「オブジェクトが必要です」というエラーが 出力されてしまいできないようです。何か代替案はありますでしょうか。 --- dim ws as worksheet with thisworkbook for each ws in array(.worksheets(1),.worksheets(2),.worksheets(3)) with ws 'ここに処理を書く end with next ws end with --- ちなみにこのbookにある全てワークシートで処理を回したいわけではなく 特定のシートのみで処理をしたいです。 エクセル2003です。 よろしくお願いします。

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

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

ArrayはVariant型であり、オブジェクトでは無いとされるからではないでしょうか。 素直に配列としてアクセスするか、 Sub test() Dim ws As Worksheet Dim buf As Variant Dim i As Long With ThisWorkbook buf = Array(.Worksheets(1), .Worksheets(2), .Worksheets(3)) For i = LBound(buf) To UBound(buf) With buf(i) Debug.Print .Name End With Next i End With End Sub どうしてもEachが使いたければ、Collectionに収納すれば良いかも。 下記shはObject型でなければダメかと思いましたが、Worksheet型でも大丈夫でした。インテリセンスが効くメリットはありそうですね。 Sub test2() Dim wsCollection As Collection Dim sh As Worksheet Set wsCollection = New Collection With ThisWorkbook wsCollection.Add .Worksheets(1) wsCollection.Add .Worksheets(2) wsCollection.Add .Worksheets(3) End With For Each sh In wsCollection Debug.Print sh.Name Next sh End Sub

lelion1000
質問者

お礼

前者はNo.4と大体同じですね。今回はこの方法でやることにしました。 後者はAddが1つずつしかできないのがデメリットですね。 ありがとうございました。

その他の回答 (3)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

#2です。 追加ですが、下記はエラーにならず動作します。あまり使いたく無いですが... Sub test() Dim ws As Variant '<- ここをVariant型で宣言 With ThisWorkbook For Each ws In Array(.Worksheets(1), .Worksheets(2), .Worksheets(3)) With ws Debug.Print ws.Name End With Next ws End With End Sub

lelion1000
質問者

お礼

なるほど。Variant型でいけるのですね。 ありがとうございました。

  • DreamyCat
  • ベストアンサー率56% (295/524)
回答No.3

sheetsでもworksheetsでもどちらで書いてもいいですが、 名前で指定すると、シートの順番も変えて処理できます。 For Each ws In .Sheets(Array(.Sheets(1).Name, .Sheets(4).Name, Sheets(2).Name))

lelion1000
質問者

お礼

質問の意図が伝わらなかったみたいです。 ありがとうございました。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.1

> 「オブジェクトが必要です」というエラーが どの行で出ます? withを書いたのだから、項目の前に.(ドット)が必要なのでは?

lelion1000
質問者

お礼

ドットはあると思います。 回答ありがとうございました。

関連するQ&A

  • For Each でシートのループ

    簡潔に質問する為に以下のマクロを見て頂きたいのですが、 この場合sheet1,sheet2,sheet3のそれぞれの(1,1)に2が発生せず 現在目でみているシートにのみ有効なのですが、全シートに有効に するには何が足りないのでしょうか Sub aaa() Dim ws As Worksheet For Each ws In Worksheets  Cells(1,1)=2 Next End Sub

  • VBAですべてのワークシートを処理したい

    ブック内の全ワークシートに対して同じ処理をするために、 For each ワークシート in Worksheets ~処理~ Next ワークシート を使ってみたのですが、その時にアクティブになっているシートしか処理されません。たとえば次のようなシンプルなコードでも、同様です。何が抜けているのでしょうか。 Sub allworksheets() Dim WS As Worksheet For Each WS In Worksheets Range("a1") = "123" Next WS End Sub マクロの勉強を始めたばかりで、基本的なことでつまづいてます。よろしくお願い致します。

  • VBAで複数のシート名を置換する処理

    Dim ws As Worksheet Dim i As Long For i = 1 To ThisWorkbook.Sheets.Count For Each ws In ThisWorkbook.Sheets If ws.name Like "*T*" Then ws.name = Replace(ws.name, "T", "S") End If Next Next End Sub この処理をするとnameメソッド失敗worksheetオブジェクト 処理できるようにするにはどうすればいいんでしょうか

  • [VBA] For文の使い分けについての疑問

    こちらの識者の方々にはいつもお世話になっています。 VBAの質問です。 環境は下記になります。 OS=windows7 pro 64bit Office=Excel2010(14.0.7128.5000) ・疑問点 For each nextもFor nextも、最下行まで処理をしたいときに使用することが多いのですが、 単列の場合はFor each next、複数列の場合はFor nextというような使い方をしています。 例:For each next Sub test()  Dim ws As Worksheet  Dim r As Range  Dim endRow As Long  Set ws = ThisWorkbook.Sheets(1)  endRow = ws.Cells(Rows.Count, 1).End(xlUp).Row  For Each r In ws.Range("A1:A" & endRow)   If r.Value Mod 2 = 0 Then r.Font.Bold = True  Next r End Sub 例:For next Sub test2()  Dim ws As Worksheet  Dim i As Long  Dim endRow As Long  Set ws = ThisWorkbook.Sheets(1)  endRow = ws.Cells(Rows.Count, 1).End(xlUp).Row  For i = 1 To endRow   If ws.Cells(i, 1).Value Mod 2 = 0 Then ws.Cells(i, 1).Font.Bold = True   If ws.Cells(i, 2).Value Mod 3 = 0 Then ws.Cells(i, 2).Font.Bold = True  Next i End Sub 単純に、複数列での処理をする場合にはFor each next文を2つ書かないといけないと思い(込み)、 上記のような運用にしていますが、そもそもこの考え方は合っていますでしょうか? 単列の処理であってももちろんFor next文で問題なく使用できますし、 複数列の処理の場合もFor each next文で処理することはできます(冗長ですが)が、 VBA的に正しいというか、合理的な考えであるのかどうかが疑問です。 みなさんはFor each nextとFor nextをどのように使い分けていますか? 質問に不備不足等ございましたらご指摘ください。 ご面倒お掛けしますがよろしくお願いします。

  • セルに対してFor Each~In~Nextを使う

    セルに対してFor Each~In~Nextを使う事は出来ない? シートやブックに対してループする時は Sub aaa() Dim w As Worksheet For Each w In Worksheets MsgBox w.Name Next End Sub 等を使いますが、 A1に「あ」 A2に「い」 A3に「う」 が入っている場合、 Sub bbb() Dim i As Long For i = 1 To Range("a65536").End(xlUp).Row MsgBox Cells(i, 1) Next End Sub で、全ての値を取得できますが、 For~to~nextではなく セルに対してFor Each~In~Nextを使う方法があれば教えてください。 上記のように Dim w As Worksheetは宣言できますが Dim c As Workcellとはできませんでした。 なぜわざわざFor~to~nextでできる事をFor Each~In~Nextでやりたいかと言うと、 シートやブックはFor~to~nextでできるのに、セルはFor~to~nextができない理由を知りたいからです。 ご回答よろしくお願いします。

  • エクセル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

  • エクセルVBAで保護したシート内の書式設定を可能にしたい

    お世話になります。 『記入可能セルに記入させ、「送信」フォームを押すと、1箇所文字の色が変わり、添付されてメールで送られる。』というマクロを組みました。 その後、 シートがたくさんあるので、VBAを使って、一度にシートの保護、非保護を行いました。 以下はその記述文です。 Sub 保護() Dim Ws As Worksheet For Each Ws In Worksheets Ws.Protect Password:=111 Next End Sub Sub 保護解除() Dim Ws As Worksheet For Each Ws In Worksheets Ws.Unprotect Password:=111 Next End Sub この保護のマクロを使うと、記入可能なセルは、セルの書式設定の保護タブからチェックをはずしており全く問題ないのですが、 「色が変わる」という設定がエラーになります。 どのようにしたら、色が変わるのも許可されるマクロになるのでしょうか。 ご教示お願いいたします。

  • エクセルのVBAの記述について

    VBAの記述についてなのですが、 Sub filter() Dim gyo As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim ws3 As Worksheet Set ws1 = Worksheets("データ") Set ws2 = Worksheets("チーム") Application.ScreenUpdating = False ws2.Range("A4:BH30").Clear gyo = ws1.Range("A65536").End(xlUp).Row ws1.Activate With ws1.Range(Cells(4, 1), Cells(gyo, 6)) .AutoFilter Field:=1, Criteria1:="A" .SpecialCells(xlCellTypeVisible).Copy ws2.Range("A4") Selection.AutoFilter End With Application.ScreenUpdating = True End Sub ならプログラムははしるのですが、 14行目を .SpecialCells(xlCellTypeVisible).Copy ws2.Range(Cells(4, 1)) だと 「実行時エラー 1004 Rangeメソッドは失敗しました Worksheet オブジェクト」 とでるのですが、出来ないのでしょうか? Cells(4, 1)の1のところを変数にして変えていきたいのですが、よい方法はありますか。 よろしくお願いいたします。

  • 複数のエクセルシートをまとめるマクロ

    下は複数のエクセルファイルを一つにするマクロですが、100万件を超えるためcsvで保存するようにするにはどこを変更したらよいでしょうか。 よろしくお願いします。 Sub Sample() Dim t As Single Dim strPath As String Dim strFileName As String Dim WB1 As Workbook Dim WS1 As Worksheet Dim WS2 As Worksheet Dim lngRowCount As Long 'A列に値が入っているデータ数 t = Timer 'まとめたいシート Set WS2 = ThisWorkbook.Worksheets(1) strPath = ThisWorkbook.Path strFileName = Dir(strPath & "\*.xls*") Do While strFileName <> "" If strFileName <> ThisWorkbook.Name Then Set WB1 = Workbooks.Open(strPath & "\" & strFileName) Set WS1 = WB1.Worksheets(1) With WS1.Range("A1") lngRowCount = .Worksheet.Cells(.Worksheet.Rows.Count, .Column).End(xlUp).Row - .Row If lngRowCount >= 1 Then With .Resize(lngRowCount, 14).Offset(1) .Copy WS2.Range("A" & WS2.Rows.Count).End(xlUp).Offset(1) End With End If End With WB1.Close False End If strFileName = Dir Loop MsgBox "まとめ処理をしました。処理時間 " & Format((Timer - t) / 60 / 60 / 24, "h:mm:ss") End Sub

  • エクセルVBA フォルダ内のどんなシート名であっても読み込みたい

    フォルダ内の別ブック(D3で指定)の「情報」シートを読み込んで対象年月日に該当するデータを抽出して別ブックに貼り付けるものなんですが、下のコードではSet ws = wb.Worksheets("情報")と、なっていて、限定しているのですが、これをD3のファイルのどんなシート名であっても読み込みたいのですが、どのようにコードにしたらいいでしょうか?D3で指定するブックには必ずひとつのシートしかありません。 よろしくお願いします。 Sub test_1() Dim wb As Workbook Dim ws As Worksheet Dim ms As Worksheet Dim nb As Workbook Dim r As Long Set ms = ThisWorkbook.Worksheets("メニュー") Set wb = Workbooks.Open(ms.Parent.Path & "\" & ms.Range("D3").Value) Set ws = wb.Worksheets("情報") Set nb = Workbooks.Add With ws .Range("Q1").AutoFilter _ Field:=17, _ Criteria1:=">=" & ms.Range("D5").Text, _ Operator:=xlAnd, _ Criteria2:="<=" & ms.Range("F5").Text With .AutoFilter.Range r = .Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count If r = 1 Then MsgBox "抽出対象データ無し。" wb.Close False nb.Close False Set wb = Nothing: Set ws = Nothing Set ms = Nothing: Set nb = Nothing Exit Sub End If .Copy End With End With With nb.Worksheets(1) .Paste With .Range("A1:AG1") .Interior.ColorIndex = 6 .HorizontalAlignment = xlCenter .VerticalAlignment = xlCenter End With End sub

専門家に質問してみよう