• ベストアンサー

エクセルVBAでのエラーの対処方法

よろしくお願いします。 A1:1 B1:あ A2:2 B2:い A3:3 B3:う と書いてあるまとめシートと、1、2、3というシートがあるとします。 シート1のA1セルに「あ」、シート2のA1セルに「い」、シート3のA1セルに「う」と書き込まれるように、まとめA列の文字列からシート名を呼び出して書き込むようにVBAを組んでいます。 Dim sht_n As Variant Dim sht_c As Integer i = 7 sht_n = Worksheets("まとめ").Index sht_c = ThisWorkbook.Sheets.Count For sht_n = sht_n + 1 To sht_c Step 1 If Cells(i, 1).Value = "" Then i = i + 1 Else wb = Cells(i, 1).Value Worksheets("まとめ").Cells(i,2).Select Selection.Copy ThisWorkbook.Worksheets(wb).Activate Range("A1").Select Selection.PasteSpecial Paste:=xlValues こんな感じ。 下手なのは分かってます。あと、現在使っているものから書き出しているので間違えてる部分もあるかもしれません。 この状態だと、シート1がない場合にはエラーが出てしまって、そこで終わってしまいます。 まとめシートが空欄の場合はエラーを回避しているのですが、シートがない場合の回避方法が分かりません。 On Error Resume Nextは使わずに、シートがない場合にエラーを回避する方法はありますでしょうか。 分かるかた、よろしくお願いします。

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

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

こんにちは。 >どのように回避すべきかというところに至りたかったので、 繰り返しますが、シートのセルにあらかじめキメウチにする限りは、エラーを承知でコーディングしたほうがよいと思います。ただ、初級の人には、エラートラップは難しいです。失敗を繰り返しながら覚えるのですが。 エラー処理の学習レベルに関しては、以下をご覧ください。 http://vbae.odyssey-com.co.jp/vbae/pro2003.html シート名に数字を使う場合、マクロでシート名を入れて作らない限りは、不明なエラーが発生することがあるので、そのために、本来は、特殊なコードになるはずですが、今回はそういうことはないということで作りました。 '----------------------------- Sub ErrorSample()   Dim mSht As Worksheet   Dim i As Integer   Dim shName As String   Dim sh As Worksheet      Set mSht = Worksheets("まとめ")      For i = 1 To mSht.Range("A65536").End(xlUp).Row     shName = mSht.Cells(i, 1).Value     If shName <> "" Then       On Error Resume Next       Set sh = Worksheets(shName)       If Err.Number = 0 Then         sh.Cells(1, 1).Value = mSht.Cells(i, 2).Value       End If       On Error GoTo 0       Set sh = Nothing     End If   Next i   Set mSht = Nothing End Sub

aa723aa
質問者

お礼

改めてありがとうございます。 大変勉強になりました。 また、リンク先も非常に勉強になっております。 普通にコーディングしているつもりでもエラーはどんどん出てくる有様なので、間違えながら、間違えてるとVBAに怒られながら、上手にコーディングできるようにがんばりたいと思います。

その他の回答 (4)

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.4

>On Error Resume Nextは使わずに、シートがない場合にエラーを回避する方法はありますでしょうか。 事前にDictionaryオブジェクトにシート名を放り込んでおいて”まとめ”のA列を順に取得し、 Dictionaryにあれば存在するし、なければ存在しないのでそこで処理を分けるとか? On Error Resume Nextを使った方が楽だと思いますけどね。

aa723aa
質問者

お礼

ありがとうございます。 Dictionaryオブジェクトという方法もあるのですね。なるほどです。

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

#2の修正 #いずれにしても、エラーは発生しますから、あまり良い方法はないと思います。 あえて、その都度、ループで全シートをチェックすれば、エラーは発生しませんが……。

aa723aa
質問者

補足

ありがとうございます。 実は、かなりの初心者です。 仕事上必要になったこともあり、勉強も兼ねて書いています。 On Error Resume Nextは勉強していく上で知った方法です。また、エラーが出ることも分かった上で作っています。 「勉強」という事で、ただ回避するだけではなく、どのように回避すべきかというところに至りたかったので、このような質問を投げかけました。考えうるエラーに対して何かしらの対策を施したいという気持ちからです。

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

こんにちは。 >On Error Resume Nextは使わずに、 なぜ、そのような条件が必要なのでしょうか。 エラートラップが分かって、そうおっしゃっているとは思います。エラートラップを使いこなせられるなら、レベル的には相当に上級クラスだと思います。その上の質問なら、ご自身で考えたほうがよいのではないでしょうか。エラートラップを使わない方法もありますが、いずれにしても、エラーは発生しますから、あまり良い方法はないと思います。 A1:1 B1:あ A2:2 B2:い A3:3 B3:う Worksheets(シート名)が、予め決められているものに対して、ループで名前を探す方法はあっても、私からすれば、初心者でエラートラップの使い方が分からないのか、それとも、わざと制限したコードになるのだと思います。エラートラップを使わない理由自体が分かりません。

  • pkh4989
  • ベストアンサー率62% (162/260)
回答No.1

こんにちは。 コードを変えてみました。ご参考に Sub test()   Dim wR     As Long   Dim c      With Sheets("まとめ")     For wR = 1 To .Range("A" & Rows.Count).End(xlUp).Row '←入力行数を求める       If .Cells(wR, 1) <> "" Then 'シート名が入力されている         For Each c In Worksheets           'シート存在チェック           If c.Name = Trim(.Cells(wR, 1)) Then             '存在する場合のみ設定             Sheets(c.Name).Range("A1") = .Cells(wR, 2)           End If         Next       End If     Next   End With End Sub

aa723aa
質問者

補足

ありがとうございます。 なんとなく理解はできたのですが、これ、このままだと動かなかったんです・・・(すいません。)

関連するQ&A