Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


10213 / 13644 ツリー ←次へ | 前へ→

【22961】ファイルを開く時のエラー回避 VBA初心者 05/3/8(火) 23:27 質問[未読]
【22965】Re:ファイルを開く時のエラー回避 かみちゃん 05/3/9(水) 6:46 回答[未読]
【23016】Re:ファイルを開く時のエラー回避 VBA初心者 05/3/10(木) 0:10 お礼[未読]
【23021】Re:ファイルを開く時のエラー回避 かみちゃん 05/3/10(木) 7:20 発言[未読]
【23067】Re:ファイルを開く時のエラー回避 ちゃっぴ 05/3/12(土) 2:10 発言[未読]
【23071】Re:ファイルを開く時のエラー回避 かみちゃん 05/3/12(土) 8:05 発言[未読]
【23074】Re:ファイルを開く時のエラー回避 ichinose 05/3/12(土) 9:07 発言[未読]
【23075】Re:ファイルを開く時のエラー回避 G-Luck 05/3/12(土) 9:24 発言[未読]
【23087】Re:ファイルを開く時のエラー回避 ちゃっぴ 05/3/12(土) 19:06 回答[未読]
【23089】Re:ファイルを開く時のエラー回避 かみちゃん 05/3/12(土) 19:25 発言[未読]
【23090】Re:ファイルを開く時のエラー回避 ちゃっぴ 05/3/12(土) 19:59 発言[未読]

【22961】ファイルを開く時のエラー回避
質問  VBA初心者  - 05/3/8(火) 23:27 -

引用なし
パスワード
   毎度スイマセン。

ファイル1を開くマクロを作ったのですが、対象のファイルと同じフォルダ内にある場合のパスをFile_Path1、同じフォルダに無い場合、対象のファイルのある場所をFile_Path2としました。
対象ファイルが無い場合、
On Error GoToでエラー回避で次の操作に移ろうと思ったのですが、この操作だと、1番目に回避出来ても、2番目に同じエラーが発生(対象ファイルが結局なかった場合)した時は回避出来ませんでした。

ちなみに作ったマクロは以下の通りです。

'-----------------------------------------------------------------
Sub File1_Open()

Dim ファイル1 As String
Dim FN1, FN2 As Variant
Dim File_Path1 ,File_Path2 As Path

'対象ファイルと同じフォルダに存在する
FN1 = File_Path1 & "\" & ファイル1
  
On Error GoTo Tugi1

Workbooks.OpenText Filename:=FN1, _
     StartRow:=1, _
     DataType:=xlDelimited, _
     TextQualifier:=xlDoubleQuote, _
     ConsecutiveDelimiter:=True, _
     Tab:=True, _
     Semicolon:=False, _
     Comma:=True, _
     Space:=True, _
     Other:=False

GoTo Tugi2

'-----------------------------------------------------------------
Tugi1:
'対象ファイルと同じフォルダ内にない場合

FN2 = File_Path2 & "\" & ファイル1

On Error GoTo FIN

Workbooks.OpenText Filename:=FN2, _
     StartRow:=1, _
     DataType:=xlDelimited, _
     TextQualifier:=xlDoubleQuote, _
     ConsecutiveDelimiter:=True, _
     Tab:=True, _
     Semicolon:=False, _
     Comma:=True, _
     Space:=True, _
     Other:=False    
Tugi2:
 作業マクロ '(モジュール参照)
FIN:
End Sub
'-----------------------------------------------------------------

2回目のエラーを回避したらよろしいでしょうか?

【22965】Re:ファイルを開く時のエラー回避
回答  かみちゃん  - 05/3/9(水) 6:46 -

引用なし
パスワード
   こんちには。かみちゃん です。

>2回目のエラーを回避したらよろしいでしょうか?

ファイルの存在チェックをDir関数を使ってすればいかがでしょうか?

Option Explicit

Sub File1_Open()
 Dim ファイル1 As String, FN1 As String, FN2 As String
 'Dim File_Path1, File_Path2 As Path ← データ型Pathとは?
 Dim File_Path1, File_Path2 As String

 FN1 = File_Path1 & "\" & ファイル1
 'FN1が存在しない場合
 If Dir(FN1) = "" Then
  FN1 = File_Path2 & "\" & ファイル1
 End If
 'Path1または、Path2にファイル1が存在する場合
 If Dir(FN1) <> "" Then
  Workbooks.OpenText Filename:=FN1, _
       StartRow:=1, _
       DataType:=xlDelimited, _
       TextQualifier:=xlDoubleQuote, _
       ConsecutiveDelimiter:=True, _
       Tab:=True, _
       Semicolon:=False, _
       Comma:=True, _
       Space:=True, _
       Other:=False
  作業マクロ '(モジュール参照)
 End If
End Sub

【23016】Re:ファイルを開く時のエラー回避
お礼  VBA初心者  - 05/3/10(木) 0:10 -

引用なし
パスワード
   ▼かみちゃん さん:

回答ありがとうございます。

少し変形させないと使えなかったので以下の様にしました。

FN1 = File_Path1 & "\" & ファイル1
 If Dir(FN1) = "" Then
  GoTo Next_1
 End If

これで、ファイル1が指定されたパスに無い場合、
GoTo Next_1で次の操作が可能になりました。

【23021】Re:ファイルを開く時のエラー回避
発言  かみちゃん  - 05/3/10(木) 7:20 -

引用なし
パスワード
   こんにちは。かみちゃん です。

>これで、ファイル1が指定されたパスに無い場合、
>GoTo Next_1で次の操作が可能になりました。

個人的には、GoTo ステートメントは、多用すると複雑になりますし、エラーチェ
ックも困難になります。敢えて利用すべきものでもないと考えていますので、以下
のようにすることもできるかと思います。

FN1 = File_Path1 & "\" & ファイル1
If Dir(FN1) = "" Then
'ファイルがない場合の処理
Else
'ファイルがある場合の処理
End If

【23067】Re:ファイルを開く時のエラー回避
発言  ちゃっぴ  - 05/3/12(土) 2:10 -

引用なし
パスワード
   >>これで、ファイル1が指定されたパスに無い場合、
>>GoTo Next_1で次の操作が可能になりました。
>
>個人的には、GoTo ステートメントは、多用すると複雑になりますし、エラーチェ
>ックも困難になります。

Fileが開けないErrorになる場合は、いろいろなCaseがあって、
Fileが存在しないというのは、その中のひとつに過ぎません。

いちいち、全部のCaseを洗い出してCheckするとなると
工数もかかりますし、何より複雑になってわかりづらくなります。

また、Fileを開く時にはOpen MethodをCallした時点で、
Fileの存在Checkは内部で自動的に行っているので
事前にFileの存在Checkをするだけ無駄ともいえます。

こういう場合、On Error Statementをうまく使うほうが
はるかに望ましいです。

Gotoが嫌なのであれば、

On Error Resume Next
Set wbkTarget = Workbooks.Open(〜)
On Error Goto 0
If Err.Number = 0 Then
  ' Error処理
Else
  ' 正常処理
End If

という使い方もありますね。

というよりも、GOTOでわかりにくくなるような長いProcedureなら
分割してしまえば、GOTOを使っても可読性は落ちないはずです。
(1Procedureに何度もGotoを使うような長いProcedureを作ること自体が
そもそもの問題といえます。)

また、Fileの存在Checkがどうしても必要であれば、(めったにないと思いますが)
Dirを使うのは最悪で、FSOのFileExistを使用するべきですね。

DirだとExcelで開けるFileでも、ErrorになってしまうCaseが存在しますので・・・

【23071】Re:ファイルを開く時のエラー回避
発言  かみちゃん  - 05/3/12(土) 8:05 -

引用なし
パスワード
   こんにちは。かみちゃん です。

>Dirを使うのは最悪で、FSOのFileExistを使用するべきですね。
>
>DirだとExcelで開けるFileでも、ErrorになってしまうCaseが存在しますので・・・

これは、VBAでDir関数に260(Excel97は、261)バイト以上のパス名を指定すると「ファイルが見つかりません」のエラーになるケースのことでしょうか?
いつも、エラーになる場合があることを認識しながら、簡単なので、Dir関数を使
っていますので、それ以外に「最悪」な理由があれば、教えてください。

【23074】Re:ファイルを開く時のエラー回避
発言  ichinose  - 05/3/12(土) 9:07 -

引用なし
パスワード
   ▼かみちゃん さん、みなさん、おはようございます。

>
>>Dirを使うのは最悪で、FSOのFileExistを使用するべきですね。
>>
>>DirだとExcelで開けるFileでも、ErrorになってしまうCaseが存在しますので・・・
>
>これは、VBAでDir関数に260(Excel97は、261)バイト以上のパス名を指定すると「ファイルが見つかりません」のエラーになるケースのことでしょうか?
>いつも、エラーになる場合があることを認識しながら、簡単なので、Dir関数を使
>っていますので、それ以外に「最悪」な理由があれば、教えてください。

ファイルをオープンする時は、やっぱりOn Errorステートメントでしょうか?
ファイルが見つからない以外に思いつくエラーとしては、シェアエラーですね
つまり、別のプロセスでファイルがロックされている場合です。

以下のコードは別プロセスではないですが、

'====================================================
Sub main()
  flnm = ThisWorkbook.Path & "\book1.xls"
  Call mk_sample_open(flnm)
  On Error Resume Next
  Workbooks.Open flnm
  If Err.Number <> 0 Then
   MsgBox Err.Description
   End If
  Close #1
End Sub
'====================================================
Sub mk_sample_open(flnm)
  Open flnm For Input Lock Read As #1
End Sub

このマクロを含むブックとbook1.xlsは同じフォルダ内にあるという条件です。
確認してみて下さい

【23075】Re:ファイルを開く時のエラー回避
発言  G-Luck  - 05/3/12(土) 9:24 -

引用なし
パスワード
   皆さんこんにちは、
ichinoseさん、かみちゃん
そんなエラーがあるとは、初めて知りました。勉強になります。

ちゃっぴさん、私も同意見です。
ただ、下記コードで
On Error Goto 0
とすると、Errがクリアされて、0になると思います。
私もどこにOn Error Goto 0を入れるかいつも迷うのですが、Ifの後につけるべきではないでしょうか?
あるいは、 wbkTarget Is Nothing で判定するか。

>On Error Resume Next
>Set wbkTarget = Workbooks.Open(〜)
'On Error Goto 0
>If Err.Number = 0 Then
>  ' Error処理
>Else
>  ' 正常処理
>End If
On Error Goto 0

割り込みでした。

【23087】Re:ファイルを開く時のエラー回避
回答  ちゃっぴ  - 05/3/12(土) 19:06 -

引用なし
パスワード
   >これは、VBAでDir関数に260(Excel97は、261)バイト以上のパス名を指定すると「ファイルが見つかりません」のエラーになるケースのことでしょうか?
>いつも、エラーになる場合があることを認識しながら、簡単なので、Dir関数を使
>っていますので、それ以外に「最悪」な理由があれば、教えてください。

無効な(存在しない)UNCを指定したときもErrorになりますね。

あと、260Byteからわかるように、VBA.FileSystem Classは
Unicodeを一度ANSIに変換してから処理してます。
したがって、PathにUnicode拡張文字が含まれる場合Errorになります。
(もっとも、PathにUnicode拡張文字をつけること自体問題ですが・・・)

また、これは純粋に使い方の問題になりますが、
第2引数のAttributesのことです。
既定では、標準の属性しかされませんのでDirでSampleを書くなら
そのことくらいは注意しておいた方がいいとおもいます。

あと、Dir関数を使っていると、もう一度Dir関数をたたいてやらないと
FileHandleがCloseされないという問題も存在します。

以上、VBA.FileSystem Class は問題山積みですので、
わたしは一切使用しません。

【23089】Re:ファイルを開く時のエラー回避
発言  かみちゃん  - 05/3/12(土) 19:25 -

引用なし
パスワード
   こんにちは。かみちゃん です。

>>これは、VBAでDir関数に260(Excel97は、261)バイト以上のパス名を指定すると「ファイルが見つかりません」のエラーになるケースのことでしょうか?
>>いつも、エラーになる場合があることを認識しながら、簡単なので、Dir関数を使
>>っていますので、それ以外に「最悪」な理由があれば、教えてください。
>
>無効な(存在しない)UNCを指定したときもErrorになりますね。

なるほど、そういうエラーも確かにありますね。
ichinoseさんのおっしゃっている原因もよくわかります。
いつもDir関数で、ファイルの存在チェックだけしていた(ファイル存在チェックだけだと、間違いではないと思いますが)ので、この機会に勉強して、見直してみたいと思います。
ありがとうございます。

【23090】Re:ファイルを開く時のエラー回避
発言  ちゃっぴ  - 05/3/12(土) 19:59 -

引用なし
パスワード
   > ichinoseさんのおっしゃっている原因もよくわかります。
> いつもDir関数で、ファイルの存在チェックだけしていた
>(ファイル存在チェックだけだと、間違いではないと思いますが)ので、
> この機会に勉強して、見直してみたいと思います。

仕様・要件によるでしょうね。
個人で使うのであれば、いざとなれば自分でDebugしてやれば
いいだけの話ですが、配布するとなると変わってきます。

事前にFileを扱うことに関して、きちっとした仕様を固めていればいいのですが、
通常はそこまで詳細に仕様を固めていないと思いますので、
その場合Windows標準機能で出来ることはすべて意識する必要があるでしょう。
(意識してCodingしない場合、Bugとなります。)

ExcelでBookが開けない原因は、他にも以下のようなCaseが存在します。

1. NTFSのAccess権で許可されていない(Networkの場合共有のAccess権も)
2. Excelで扱えるPath長を超えている
  (170文字くらいで引っかかりますが、環境により異なります。
  Shellの制限あたりの絡みがくさいですが、詳細は不明です。)

また、前にも書きましたが・・・VBAでErrorになるのはCodeで呼び出した
Method等が、そういった例外となるような条件を自動的に判別しているので
わざわざ2度Checkする必要はないでしょう。
(もし、そういったCheckを行っていないのであれば、
Application Errorが発生するでしょうし・・・)

ErrorにならないようにCodingする必要があるのは、VBAでTrapされていない
Error、つまりはApplication Errorが発生するような場所でしょうね。

事前にCheckしてErrorを発生させないようにCodingすることは、
非常に重要ですが、ことVBAに関する限り、VBAで発生するErrorを
上手に使ってやることが、一歩上を目指す上では必要でしょう。

10213 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free