Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 7 Professional : Excel 2013)
「エラー処理」の「night0813」さんへ
投稿日時: 18/08/14 20:44:05
投稿者: もこな2

night0813 さんの引用:
http://www.moug.net/faq/viewtopic.php?t=77376
最終的にOn Error処理で動くようになりました。
また、For Each文は削除しました。

こちらについて、既に解決済みにされていますので、余計なお世話かもしれませんが、安易にOn Error〜は使わない方がよいとおもいます。
確実に想定通りのエラーしか出ないのであればそれでもいいのかもしれませんが、想定外のエラーが出たときに最悪クラッシュする可能性が否定できません。
 
また、既に他の回答者さんからも指摘がありますが、提示されたものだけですと「wb」や「FileName」をどのように定義しているのか(=どのように使いたいのか)が読み取れません。
ですので、もちろん個人情報が特定されるような部分は適当な内容に返るなどして隠す必要がありますが、一連のコードを提示して皆さんに添削をお願いすると、新たな発見があるかもしれません。
 
ちなみに、
(1) C:\Work に保存されている 「test.xlsx」というブックを開いて
(2) 勤務表(提出用)というシートの(無ければ、強制的に追加)A1セルに「準備完了」と書き込む
というようなことであれば、On Errorを使わずとも↓のようなコードで実現できるとおもいます。
 
Sub Sample()
    Const シート名 As String = "勤務表(提出用)"
    Dim WS As Worksheet, tmp As Worksheet
 
    With Workbooks.Open("C:\Work\test.xlsx")
         
        '開いたブックのシート名を順番にチェックして、条件に合うものがないか探します。
        For Each tmp In .Worksheets
            '条件にあうものがみつかったら「WS」にセットしてループを抜けます
            If tmp.Name = シート名 Then
                Set WS = .Worksheets(シート名)
                Exit For
            End If
        Next tmp
         
        '「WS」にセットされてなかったら(条件にあうシートが見つからなかったら)
        '新しいシートを追加して、「WS」にセットします。(名前も変えます)
        If WS Is Nothing Then
            Set WS = Worksheets.Add(after:=.Worksheets(.Worksheets.Count))
            WS.Name = シート名
        End If
         
        'ココまでで、正常に動作すれば「WS」に、ターゲットにしたブックの「勤務表(提出用)」が
        'セットされているはずなので、以降、当該シートにやりたい処理を記述する。
        With WS
            .Range("A1").Value = "準備完了"
        End With
         
        'オマケ(上書き保存して閉じる処理)
        Application.DisplayAlerts = False
        .Save '←実はここで、上書き保存してるから、「DisplayAlerts = False」にしなくても
        .Close '確認メッセージは出ません。
        Application.DisplayAlerts = True
    End With
     
End Sub

回答
投稿日時: 18/08/14 22:26:03
投稿者: simple

もこな2 さん、スレッドの立ち上げありがとうございました。
「エラー処理」
http://www.moug.net/faq/viewtopic.php?t=77376
ですね。
 
私もちょっと唐突感のある終わり方だなあ、少し残念と思って見ておりました。
 
この場をお借りしていくつかコメントします。
 
課題はflagを使ったコードかと(勝手に)思っていました。
でもよく読むと、手法を限定しているわけではなかったのかな。
しかし、折角皆さんからの指摘もあるわけですから、
flagを使ったものもよく理解されたほうがよいかと思いました。
 
 
ちなみに、もこな2さんのご指摘(エラー処理は危険)ですが、
実は、こちらのサイトの「即効テクニック」の
シートの存在確認のスレッドでも、エラー処理を利用した方法が示されています。
「特定の文字列を含むシートの存在を判定する」
http://www.moug.net/tech/exvba/0040036.html
ですので、一定の市民権は得ているものと思います。
# 数年前に、即効テクニックの記事全般を題材に、皆さんであれこれ議論(改善提案)したことがありました。
# その際も特にそうした問題指摘はなかったと記憶しています。
 
なお、(質問者さんに向けて)エラー処理の留意点のいくつかを書くと、

@対象となる処理が想定しえない副作用を持つものでないこと
Aエラー対象処理は限定的にすること
  つまり、On Error Resume Next を使ったら、最短距離でそれを
  On Error Goto 0 
  で解消しておくこと
  (元に戻すのを忘れると、他の箇所でのエラーを隠蔽してしまいますので。)
かと思います。
 
失礼しました。

投稿日時: 18/08/19 13:26:51
投稿者: もこな2

simpleさんフォローありがとうございます。
そうですよね。
エラートラップをきちんと記述して、エラー番号で分岐するなど考えてあれば、想定外エラーに気づくのでしょうけど、単純に「On Error Resume Next」だけ入れてるならちょっと怖いなーと思った次第でしした。
simpleさんのSampleのように、想定してるエラーが起こる箇所?がおわったら、「On Error GoTo 0」でちゃんと戻してるなら余計な心配だったかもしれません。
 
元質問者さんからは特に書き込みがなさそうなので閉じておきます。