• ベストアンサー

EXCEL2000 VBA でエラートラップできません。

次のスクリプトで”Select Case Workbooks(saki).Worksheets(z).Name”のところで変数zに存在しないワークシートのインデックスが入った時にはエラーが出るので、On Erroe Goto で回避しようと思うのですができません(そのままマクロが止まってしまう)。 なぜ回避できないのか教えてください。 また回避するいい方法があれば教えてください。 Private Sub UserForm_Activate() moto = Cells(2, 5) saki = Cells(1, 5) For z = 1 To 50 On Error GoTo e0 Select Case Workbooks(moto).Worksheets(z).Name Case "検索" Case "結果" Case "エフ" Case "ツール" Case "記憶" Case Else On Error GoTo e0 UserForm3.ComboBox1.AddItem Workbooks(moto).Worksheets(z).Name End Select Next e0: For z = 1 To 50 On Error GoTo e1 Select Case Workbooks(saki).Worksheets(z).Name    ’ここでエラーが出る(実行時エラー'9' インデックスが有効範囲にありません) Case "検索" Case "結果" Case "エフ" Case "ツール" Case "記憶" Case Else On Error GoTo e1 UserForm3.ComboBox2.AddItem Workbooks(saki).Worksheets(z).Name End Select Next e1: End Sub

  • vvat2
  • お礼率38% (13/34)

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

  • ベストアンサー
  • ki-aaa
  • ベストアンサー率49% (105/213)
回答No.1

zの値が、有効範囲を超えないようにすれば良いと思います。 >For z = 1 To 50 ↓ For z = 1 To Workbooks(moto).Worksheets.Count にしたらどうですか。

vvat2
質問者

補足

早速やってみたらうまくいきました。Countプロパティと言うものがあったとは、気づきませんでした。 今までエラーが出そうなところは大体 On Errorで処理しようとしていましたが、言われるとおりエラーを回避する前にエラーを出さないようにすると言う手もありますね。 またひとつ勉強になりました。ありがとうございます。 問題は解決しましたが、なぜエラートラップできないのか疑問なので、引き続き質問を受付けます。

その他の回答 (3)

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.4

#3 さんの回答で全てOKだと思いますが、せっかく書いたので、、、(^^; ループ部分の処理は殆んど同じようなので、こんな書き方もありかな? Private Sub UserForm_Initialize() Dim wb1 As Workbook, wb2 As Workbook  On Error Resume Next  Set wb1 = Workbooks(ActiveSheet.Cells(2, 5).Value)  If Not wb1 Is Nothing Then AddCombo wb1, Me.ComboBox1  Set wb2 = Workbooks(ActiveSheet.Cells(1, 5).Value)  If Not wb2 Is Nothing Then AddCombo wb2, Me.ComboBox2 End Sub Private Sub AddCombo(wb As Workbook, cmb As ComboBox) Dim ws As Worksheet  For Each ws In wb.Worksheets   Select Case ws.Name   Case "検索", "結果", "エフ", "ツール", "記憶"   Case Else      cmb.AddItem ws.Name   End Select  Next ws End Sub > エラーを出さないようにすると言う手もありますね。 こちらの考えを優先するべきだと思います。

vvat2
質問者

補足

こちらはちょっと高度なやり方ですか。 私のあまり使うことのないコードがあったりしますね。 VBA初心者の私ではいろいろと調べないと理解できないです。すみません。 回答ありがとうございました。

  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.3

>On Erroe Goto で回避しようと思うのですができません 質問のコードでは『e0』に飛んでいるだけですね。いわゆる『goto』の意味合いです。 ヘルプには、On Erroe Goto line は『引数 line に指定した行から始まるエラー処理ルーチンを有効にします』とあります。e0から始まるエラー処理ルーチンでエラーに対する処理を行わず、再度エラーが発生しトラップできなくなってます。 エラー処理としては、代表的にはResumeステートメントでしょうか。 ●エラーが出なくなるように書き換えてみました。(重複部分を少し訂正しています) Private Sub UserForm_Activate()   Dim moto As String, saki As String   Dim z As Integer   moto = Cells(2, 5)   saki = Cells(1, 5)   On Error GoTo e0   For z = 1 To 50     Select Case Workbooks(moto).Worksheets(z).Name       Case "検索", "結果", "エフ", "ツール", "記憶"       Case Else       UserForm3.ComboBox1.AddItem Workbooks(moto).Worksheets(z).Name     End Select   Next e0_re:   On Error GoTo e1   For z = 1 To 50     Select Case Workbooks(saki).Worksheets(z).Name       Case "検索", "結果", "エフ", "ツール", "記憶"       Case Else       UserForm3.ComboBox2.AddItem Workbooks(saki).Worksheets(z).Name     End Select   Next   Exit Sub e0:   Resume e0_re e1: End Sub ●このような処理の場合、『On Error Resume Next』の方が分かりやすいでしょう。 Private Sub UserForm_Activate()   Dim moto As String, saki As String   Dim z As Integer   moto = Cells(2, 5)   saki = Cells(1, 5)   On Error Resume Next   For z = 1 To 50     Select Case Workbooks(moto).Worksheets(z).Name       Case "検索", "結果", "エフ", "ツール", "記憶"       Case Else         UserForm3.ComboBox1.AddItem Workbooks(moto).Worksheets(z).Name     End Select   Next   For z = 1 To 50     Select Case Workbooks(saki).Worksheets(z).Name       Case "検索", "結果", "エフ", "ツール", "記憶"       Case Else         UserForm3.ComboBox2.AddItem Workbooks(saki).Worksheets(z).Name     End Select   Next End Sub ●エラー処理ルーチンは不要ですね。  #1さんの Worksheets.Count や下のようにFor Each で書けます。  個人的には UserForm_Activate よりは UserForm_Initialize を使っています。   Private Sub UserForm_Initialize()   Dim moto As String, saki As String     moto = Cells(2, 5)     saki = Cells(1, 5)        Dim ws As Worksheet   For Each ws In Workbooks(moto).Worksheets     Select Case ws.Name       Case "検索", "結果", "エフ", "ツール", "記憶"       Case Else         UserForm3.ComboBox1.AddItem ws.Name     End Select   Next   For Each ws In Workbooks(saki).Worksheets     Select Case ws.Name       Case "検索", "結果", "エフ", "ツール", "記憶"       Case Else         UserForm3.ComboBox2.AddItem ws.Name     End Select   Next End Sub コピーですむので長くなりました。

vvat2
質問者

補足

いろいろなやり方ありがとうございます。 VAB入門とかいうような本では On Error GoTo でエラー処理するように書いてありますが、こういう場合は On Error Resume Next のほうがいいようですね(ヘルプを見てもそう載っていました)

noname#240783
noname#240783
回答No.2

「エラー処理ルーチンの中で発生した実行時エラーは 当該のプロシージャでは救済されません。」 ご質問のコードでは、 上段のForループの中でエラーが発生した場合、 ラベルe0:の「エラー処理ルーチン」に飛んで下段のForループが 実行されますが、ここでいくら「On GoTo e1」を宣言しても 上記の理由で、e1:ラベルには飛んでくれません。 このプロシージャを抜けて呼び出し元で「実行時エラー」になります。 ちなみに上段のForループをすべてコメントアウトして実行すると e1:ラベルがエラー処理してくれます。 ご質問のコードのままで対処するならば、#1さんの方法は正解だと思います。 (以後の文は私見ですので読み流してください) ただ、このプロシージャの目的が2つのブックのシートを「必ず一度は検査する」 ことにあるようなので、そういったメインの処理をエラールーチンにいれるのは 問題があると思います。万一、別の事由のエラーが発生した場合も下段のForループが 実行されてしまい、そこでまたエラーが発生すればもう救済されませんし、 エラーが起こらなかったとしても、処理内容の整合性が疑われるかもしれません。 #1さんの方法を使えば、エラー処理を使わなくてもスッキリ記述できると思います。

vvat2
質問者

補足

なるほど・・・ラベルへ飛んだ先ではその後すべてがエラー処理ルーチンとみなされてしまうのですね。それで2重にエラー処理はできないよという考え方ですね。分かりやすい回答でしたありがとうございます。

関連するQ&A

  • VBA エラートラップができない

    <連番の付いた複数のFileを順に呼び出すプログラム> ForループでFileナンバーをインクリメントして行く方法で作成。 もしFileが存在しない場合、ラベルで警告して継続させたい。 この時、On Error GoTo をループ内で使って処理をしたのですが、 1回目は上手く行き、2回目がトラップできませんでした。何故?? Sub FileOpen() Dim N As Variant  For N=1 To 100   On Error GoTo ErrorRtn:   Workbooks.OpenText Filename:= N & ".csv" ErrorRtn: MsgBox  "Fileが有りません"  Next End sub

  • EXCEL VBAで教えてください。 ユーザーフォームに開始日、終了日

    EXCEL VBAで教えてください。 ユーザーフォームに開始日、終了日を入れ、コマンドボタンを押し、sheet1の開始日から終了日に該当するセルをコピーし、sheet2に貼り付けたいのですが、うまくいきません。 今は、メッセージボックスで範囲指定し、コピー&ペーストしているのですが、ユーザーフォームで開始日終了日を指定して、コピーしSheet2へ貼り付けたいのです。 -------------------- Sub 届() Dim myPath As String Dim myFName As String Dim ファイル名 As String Workbooks("処理.xls").Activate Range("B10:K80").Select Selection.ClearContents myPath = ActiveWorkbook.Path ChDir myPath myFName = Dir("m.txt") Dim データ形式 As Variant Dim 区切りタブ As Variant ファイル名 = "m.txt" データ形式 = xlDelimited 区切りタブ = True Workbooks.OpenText Filename:="m.txt", DataType:=xlDelimited, Tab:=True Selection.AutoFilter Selection.AutoFilter Field:=3, Criteria1:="<>" Columns("C:E").EntireColumn.AutoFit Range("C2").Sort key1:=Columns("C"), Order1:=xlAscending, Header:= _ xlGuess Worksheets.Add Worksheets("m").Select Dim moto As Range, saki As Range On Error Resume Next Set moto = Application.InputBox("どの範囲をコピーしますか?" & Chr(13) & "開始日、終了日を確認してください" & Chr(13) & "A列からE列まで選択してください", Type:=8) If moto Is Nothing Then Exit Sub If moto.Parent.Name <> "m" Then MsgBox "m から選択してください" Exit Sub End If Worksheets("Sheet1").Select Set saki = Application.InputBox("どこに貼り付けますか?" & Chr(13) & "A4", Type:=8).Cells(1, 1) If saki Is Nothing Then Exit Sub If saki.Parent.Name <> "Sheet1" Then MsgBox "Sheet1 から選択してください" Exit Sub End If On Error GoTo 0 moto.Copy saki ActiveWorkbook.SaveAs Filename:="届.xls", FileFormat:=xlWorkbookNormal MsgBox "対象者をコピーしました" End Sub ------------------ 下記でやってみたのですがうまくいきません。 Private Sub CommandButton1_Click() With Worksheets("sheet1") 開始日 = ">=" & TextBox1.Text 終了日 = "<=" & TextBox2.Text ActiveSheet.Range("A1:N200").AutoFilter , Field:=3, _ Criteria1:=開始日, Operator:=xlAnd, _ Criteria2:=終了日 Unload UserForm1 End With End Sub

  • エクセルVBAで名前の決まっているシートの倍率変更

    早速ですが名前の決まっているそれぞれのシートがあります実際にはA,B,C、D7月、E6月と今月と先月の数字が入っています。 それぞれのシートはいつもあるとは限らない為エラー処理をしましたが、なぜかうまくいきません。 下記の例ではsheet7、sheet5、sheet3。とありそれぞれの倍率に合わせた後に最後にsheet7のシートに戻るようにしましたがe2:のラインで止まってしまいます。 練習ではなく実際に必要なマクロなので、助言して頂ければ幸いです。 よろしくお願いします。 Sub bairitu() Worksheets("sheet" & Month(now())).Select '7 ActiveWindow.Zoom = 60 On Error GoTo e1 Worksheets("sheet" & Month(now()) - 1).Select '6 ActiveWindow.Zoom = 70 e1: On Error GoTo e2 Worksheets("sheet" & Month(now()) - 2).Select '5 ActiveWindow.Zoom = 80 e2: On Error GoTo e3 Worksheets("sheet" & Month(now()) - 3).Select '4 ActiveWindow.Zoom = 50 e3: Worksheets("sheet" & Month(now())).Select End Sub

  • シートを増やすVBA

    フィルタで隠れている場合もある列の値を シート名として増やしていくVBAで以下のようなものをつくりました (値は重複している場合もある) 雛型シートがありそれをシート名だけ増やしていくというものです Sub シートを増やす() Dim target As Range Dim h As Range On Error Resume Next Set target = Worksheets("一覧シート").Range("E10:E" & Worksheets("一覧シート").Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeVisible) If target Is Nothing Then Exit Sub 'シートを増やしていく For Each h In target On Error GoTo errhandle Worksheets(h.Value).Select On Error GoTo 0 Next Sheets("一覧シート").Select Exit Sub errhandle: Worksheets("雛型").Copy after:=Worksheets(Worksheets.Count) ActiveSheet.Name = h.Value Resume End Sub そうすると、実行エラー1004 ”シートの名前をほかのシート、Visual Basicで参照されるオブジェクトライブラリまたはワークシートと同じ名前に変更することはできません。” というエラーがたまにおきます(シート名が数字の場合におきるようです) 解決方法及び理由をご教授ください

  • VBA セルの名前検索でエラー回避

    セルに名前を付けてrange("test1").selectとしたとき、test1という名前がないとエラーになります。 test1というセル名があるかないか確認する方法はないですか? on error goto~で回避するしかないですか?

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

    何度も申し訳ございません。 以前にもこちらで質問させて頂いている者です。 Sheet1のrange("A1")をVLOOKUPで検索後の文字を取得し、同じ名前のシートを検索し、さらにrange("A1000")をアクティブにしてここからコードをつなげて処理しています。 range("A1")の処理が終わったら、range("A2")の処理に入り、range("A3") range("A4")を続けて処理を行っているのですが、range("A4")でVLOOKUPの検索が空白の場合、On Error GoTo myErrorで次のrange("A5")の処理に入りますが、On Error Gotoは1回のみの処理しかできないみたいで、range("A5")が空白の場合、実行時エラー9が発生してしまいます。 教えて頂いたコードを解読し、On Error Resume Nextなどを使おうとしているのですが、上手くできません。 1から10まで質問しっぱなしなのですが、どなたかご協力を頂けないでしょうか。 とりあえず自分の必要なコードはある程度省いて、2つ分のみ記載します。 本来この後、10回同じ処理を行います。 よろしくお願い致します。 Private Sub 記帳_Click()  On Error GoTo myError1  Dim i As Long  Dim myFlg As Boolean    For i = 1 To worksheets.Count If worksheets(i).Name = Range("A1").Value Then myFlg = True Exit For End If Next i If myFlg = True Then With worksheets(i) .Activate .Range("A1000").End(xlUp).Select    ActiveCell.Offset(1, 0).Select   ActiveCell = Range("J1") ActiveCell.Offset(0, 1).Select ActiveCell = Range("K1") End With Else MsgBox "該当シートなし" End If myError1: On Error GoTo myError2 For i = 1 To worksheets.Count If worksheets(i).Name = Range("A2").Value Then myFlg = True Exit For End If Next i If myFlg = True Then With worksheets(i) .Activate .Range("A1000").End(xlUp).Select ActiveCell.Offset(1, 0).Select   ActiveCell = Range("J1") ActiveCell.Offset(0, 1).Select ActiveCell = Range("K1") End With Else MsgBox "該当シートなし" End If End sub

  • Excel2007 VBA Copyメッソド

    Excel2003で開発されたVBAをExcel2007で動くように修正しているのですが、 次のコードがExcel2007ではエラーになります。  (1)Workbooks.Open Filename:=pthFolder & "\" & nmFile  (2)nmSheet = Workbooks(nmFile).ActiveSheet.Name  (3)Workbooks(WB_Name).Worksheets(S_MAIN).Copy After:=Workbooks(nmFile).Sheets(nmSheet) (1)と(2)は実行されますが、(3)がエラーになり、(4)に飛びます。 (4) SaveError:      MsgBox "エラー発生"      Application.DisplayAlerts = False      Workbooks(nmFile).Close    End Sub どなたか、Excel2007でエラーになる理由と解決策を教えていただけないでしょうか。 既に同じ質問が出ているかもしれませんが、VBA初心者なもので、うまく探せませんので、 ご協力をお願いいたします。

  • VBA トラップを再開させるには?

    一度ご質問させていただいたのですが、 どうも上手くできなくて・・・ <連番の付いた複数のFileを順に呼び出すプログラム> ForループでFileナンバーをインクリメントして行く方法で作成。 もしFileが存在しない場合、ラベルで警告して継続させたい。 この時、On Error GoTo をループ内で使って処理をしたのですが、 1回目は上手く行き、2回目がトラップできませんでした。何故?? Fileが存在しない場合、メッセージを出しますが、 2回目にエラーが発生したときは、トラップに掛かりません。 (***Fileが見当たりません…のコーションラベルが表示される) Resumeを使っても、エラーが発生した"後"から開始されるので それでは、Fileを開きにすら行きません。 何か、良い方法はないでしょうか???? Sub FileOpen() Dim N As Integer   For N=1 To 100 On Error GoTo ErrorRtn:   Workbooks.OpenText Filename:= N & ".csv" ErrorRtn: MsgBox  "Fileが有りません" Next End sub

  • Excel VBA セルの値をシート名にしたいのです。

    こんばんは 新しくシートを挿入させて、「シート2」の値のみをコピーさせたいと考えています。 その新しく挿入させたシート名を「シート1」のせるA3とA4の文字列をあわせたものにしたいのですが、どうしたらよいのでしょうか。 途中まで考えたところでいきずまってしまいました。 どうか英知をお貸しください。 宜しくお願い致します。 A3には日付、A4には名前が入力されています。 Dim sheetName As String Worksheets("月度集計").Activate Sheets.Add After:=Sheets(Sheets.Count) ActiveSheet.Name = Worksheets("Sheet1").Cells(3, 3).Value On Error Resume Next Worksheets(1).Name = sheetName On Error GoTo 0 Range("f2").Select

  • Excel2003VBA

    お世話になっております。 手作業マクロの記録で下記作業を行い、一部修正をして一度はうまく動作していたのですが 1点 問題が御座いまして独自に色々試していたのですが、どうにもうまくいかないので どなたかご教授いただけませんでしょうか。 Sub ●●用() ' ' ●●用 Macro ' 12月1月の店舗を抽出し新しいブックに移動する。 ' Selection.AutoFilter Field:=3, Criteria1:="=12月", Operator:=xlOr, _ Criteria2:="=1月" Selection.AutoFilter Field:=8, Criteria1:="(店名)" Range("A4:W2076").Select Selection.Copy Sheets.Add ActiveSheet.Paste Application.CutCopyMode = False Worksheets("Sheet1").Select Worksheets("Sheet1").Move Workbooks("営業部まとめ.xls").Sheets("全件表示").Activate Selection.AutoFilter Field:=3 Selection.AutoFilter Field:=8 Range("A5").Select ActiveWorkbook.Save End Sub まず、 >Worksheets("Sheet1").Move ここだけあれば >Worksheets("Sheet1").Select こっちは必要ないでしょうか? あと、上記の中で > Worksheets("Sheet1").Select この部分なのですが、毎回「Sheet1」とは限らないので「アクティブシート」にしたいと思い色々試してみましたが 全てエラーとなり、結局元にもどしてしまいました。 > Worksheets("Sheet1").Move あと出来ればこれも移動させた後でデスクトップに名前を付けて保存までしたいのですが どのようなコードを追加すればよろしいでしょうか。 宜しくお願い致します。

専門家に質問してみよう