エクセル の学校
8.一覧 9.HOME
1.Top 2.Last

[[20240422165445]]

[ 初めての方へ | 一覧(最新更新順) |

|
| 全文検索 | 過去ログ | エクセルの学校HOME ]

 

『説明お願いします。』(シエンタ)

    For Each varval In Split(txbReadFile.Text, vbCrLf)
        On Error GoTo Read_ERROR
        Set wb = Workbooks.Open(vartmp(1), UpdateLinks:=0)
        Set ws = Nothing
        For Each vartmp In wb.Worksheets
            If vartmp.Name = "Sheet1" Then Set ws = vartmp: Exit For
        Next
	<<<読込処理>>>
Read_ERROR:
        If not(wb Is Nothing) Then wb.Close: Set ws = nothing:  Set wb = Nothing
    Next

txbReadFile.Textに以下の4つをいれます。 実際には c.xlsx, d.xlsx のファイルは存在しません。

A.xlsx b.xlsx c.xlsx d.xlsx

この場合 c.xlsx は Open でエラーが発生して Read_ERROR に飛びますが d.xlsx の場合は Read_ERROR に飛ばないで エラーメッセージが表示されて停止してしまいます。 どうしてでしょうか?

< 使用 Excel:Excel2016、使用 OS:Windows10 >


[[20240411111556]] が同じ話でしょうね、参照ください。 (xyz) 2024/04/22(月) 17:14:15
ありがとうございます。

少しだけてこずりましたが、 以下のようにして処理できるようになりました。

    For Each varval In Split(txbReadFile.Text, vbCrLf)
        On Error GoTo Read_ERROR
        :
        :
Read_ERROR:
    Resume Read_SKIP
Read_SKIP:
    Next
(シエンタ) 2024/04/23(火) 10:25:48

 うーん、
 また、それだと正常処理でもRead_ERROR を通りませんか?
 こんなことではないんですか?

     For Each varval In Split(txbReadFile.Text, vbCrLf)
         On Error GoTo Read_ERROR
         Set wb = Workbooks.Open(vartmp(1), UpdateLinks:=0)
         Set ws = Nothing
         For Each vartmp In wb.Worksheets
             If vartmp.Name = "Sheet1" Then Set ws = vartmp: Exit For
         Next
         <<<読込処理>>>
 myLabel:    
     Next
     Exit Sub
 Read_ERROR:
         If not(wb Is Nothing) Then wb.Close: Set ws = nothing:  Set wb = Nothing  ' これの必要性は議論ありますね。不要でしょうね。
         Resume myLabel
     End Sub

(xyz) 2024/04/23(火) 10:45:46


 論点からはずれた余談です。

 これは単なる例だと思いますが、
 こうした場合は、何をエラーに出すかという議論もあるんでしょうね。
 Dir関数でファイルの存在をチェックして、不在なら予め警告を出すという方法も
 あるでしょう。

 # 参照したスレッドでも、シートのIndexがシートの個数を超えていたら
 # エラーに出す前に警告を発する考え方もあります。
 # 何もかも先回りしていたら大変だ、エラーでいい、というのもアリですか。 
(xyz) 2024/04/23(火) 10:53:53

処理としてはエラーが出たらそのファイルは無視して 次のファイルを読んで処理したいのであえて exit sub は入れていません。

最初はファイルの存在をチェックしてと考えたのですが ファイルが壊れているかどうかのチェックしたり ファイルが他で開かれている場合とか なので、このような形にしました。

とにかく最終的には オープン時もそうですが処理でエラーがかかったときには

 Read_ERRORに飛んでエラーになったファイル一覧を作っておいて
一覧を表示して読めなかったよと警告しようかと思ったのです。
(シエンタ) 2024/04/24(水) 16:08:56

 | 処理としてはエラーが出たらそのファイルは無視して
 | 次のファイルを読んで処理したいのであえて
 | exit sub は入れていません。

 私のコードを気にされたのなら、私のはFor .. Nextのあとで
 Read_ERROR: 以下が実行されないために必要です。
 あなたのコードには必要ありません。

 ただし、あなたのコードでは、ファイルが実際にあっても、
 Read_ERROR: 以下の処理が実行されませんか、という心配です。
 個人的には、Read_ERROR: がループの中にあるのは、難しい処理ですね、という印象です。
 問題ないというのであれば結構です。

 余談に関するコメントありがとうございました。さらなるコメントは控えます。

(xyz) 2024/04/24(水) 16:24:50


ありがとうございます。 もう一度よく見返してみて 理解できました。 エラー処理は本文の外で行って 処理した後にもとに戻すということをするんですね。 なるほどです。 goto文はあちこち飛ぶので 訳が分からなります。

(シエンタ) 2024/04/25(木) 16:31:14


 実行エラーを拾った際、無視するのであれば、
 On Error Resume Next
 を使用することが多いですが、試してみてください。

     For Each varval In Split(txbReadFile.Text, vbCrLf)
         Dim errNumber&
         On Error Resume Next
         Set wb = Workbooks.Open(vartmp(1), UpdateLinks:=0)
         errNumber = Err.Number
         On Error GoTo 0
         If errNumber = 0 Then
             On Error Resume Next
             Set ws = wb.Worksheets("Sheet1")
             errNumber = Err.Number
             On Error GoTo 0
             If errNumber = 0 Then
                 '<<<読込処理>>>
             End If
         End If
         If Not wb Is Nothing Then
             wb.Close
             Set ws = Nothing
             Set wb = Nothing
         End If
     Nex

(tkit) 2024/04/25(木) 17:26:57


見た目はラベルが多くて訳が分からなくなることはないので 個人的にはラベルの少ないこちらの方が好みですが

この場合はエラーが出そうなところにすべて On Error Resume Next を 入れていかなければならないのが難点ですね。

その時その時で臨機応変に対応していきます。 ありがとうございました (シエンタ) 2024/04/26(金) 11:21:49





[ 一覧(最新更新順) |

]

キーボードヒント:[Home]または[Fn+Home]キーで一番上へ戻ります

YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.