- ベストアンサー
エクセルのVBAでファイルの状態を調べるコマンド
エクセルのVBAでファイルのコピーをしたいのですが、コピー元がOPEN状態だとコピーできません。 FileCopy "C:\A.XLS", "C:\B.XLS" そこで、上記のコマンドを実行する前に、コピー元がOPEN状態かどうかを判断させて、OPEN状態だと実行を5秒待つようなマクロを記述したいのですが、可能でしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#3です。 > 演算時にバックアップソフトとのバッティングが考えられます。 FileCopyステートメントは開いていると失敗しますが、エクスプローラ等では普通にコピー出来ます。 まぁ、バックアップソフトでコピー&リネーム出来るかは不明ですけど、、、 取り合えず #1さんの方法で書いてみました。 コピーを試みて失敗したら5秒待ち、1分程経っても成功しない場合は終了します。 良い方法かどうかは解りません。 Sub Test() Dim StartTime As Single, Cnt As Integer Cnt = 1 On Error GoTo ER: FileCopy "C:\A.XLS", "C:\B.XLS" MsgBox "コピーが完了しました", vbInformation, "成功" Exit Sub ER: If Cnt <= 12 Then StartTime = Timer Do While Timer < StartTime + 5 DoEvents Loop Cnt = Cnt + 1 Resume Else MsgBox "コピー出来ません。", vbCritical, "失敗" End If End Sub
その他の回答 (4)
- popesyu
- ベストアンサー率36% (1782/4883)
アルゴリズム的にはファイルAの更新時(保存ボタンを作ってそちらで上書き保存とバックアップ処理を行う or Closeイベントでバックアップさせる)にバックアップを取るだけで問題ないような気がするのですが・・・? ファイルAのオープンチェックについては、それが両方ともPC1上で行われるのであれば、プロセスや同名のブックが開かれているかを確認するだけで可能ですが、別PC上で行われるのであればやはりエラーが発生するのかどうかで判別するしかないでしょう。 それにそもそもその手のエラーは開かれている時だけ発生するという訳でもありません。更新される側のファイルBが使用中とか、別PCへのコピーならアクセス権限やLANの問題などでもエラーは出ますよ。
お礼
Closeイベントでバックアップするなど、いろいろと勉強になりました。 ありがとうございました。
- papayuka
- ベストアンサー率45% (1388/3066)
#2の補足を読む限り、バックアップソフトを常駐させておいた方が遥かに楽な気がしますが、、、 フリーでもシェアでも多数公開されてますので。 http://www.vector.co.jp/vpack/filearea/winnt/util/backup/ http://www.vector.co.jp/vpack/filearea/win95/util/backup/
補足
バックアップが最終目的ではなく、コピーされたファイルBをもとに演算を行いたいと考えているので、バックアップソフトでコピーを行うと、今度は演算時にバックアップソフトとのバッティングが考えられます。 (1)ファイルAのオープンチェック (2)オープンチェックがokなら(3)の処理、NGなら5秒待機後(1)へ (3)ファイルAをファイルBにコピー (4)ファイルを元に演算を行い、ファイルCを作成 上記の(1)から(4)までの処理をVBAの中で完結させたいので、(1)のファイルAのオープンチェックがしたいのですが、無理なのでしょうか?
- popesyu
- ベストアンサー率36% (1782/4883)
5秒待つってのはあまり実用性がないアルゴリズムですよ。実際にお使いのソフトでそんなエラー待ち処理をしているソフトってないでしょ? エラーが出たらダイアログが出て中断するとか、エラー内容を出して続行ボタンをおしたら再試行を実行させるとかにするのが普通です。あるいは有無を言わさずアプリが落ちるとかw 現実的にエラーが発生する状況を想定すれば、5秒なり10秒なり待ったところで、ユーザー側がそのエラー状況を解除しない限りはエラーは続くのですから、時間制限でループさせることの意味がまるでありません。 で、その手のエラーの判別については、実際に開いているエクセルファイルがあるかどうかという判別で処理は可能ですが、そんな手間をかけるよりもエラー制御で処理するのがまた一般的な対応法です。 例えば以下のコードを試してみてください。 On Error Resume Next Err.Clear FileCopy "C:\A.XLS", "C:\B.XLS" MsgBox (Err.Number) MsgBox (Err.Description) 何かのエラーが起きたときにどのようなエラーが起きたかをキャッチすることができます。エラーナンバーによって、どのようなエラーが起きているか、あるいは起きていないかが判別できるので、それにあわせて処理を分岐するようにします。
補足
説明不足ですみません。 パソコンが2台(PC1、PC2)あって、PC1がPC2に保存されている共有ファイルAを不定期に更新し、そのファイルをPC2が5分ごとにファイルBにコピーしたいと考えています。 たまたまPC1がファイルAを更新中に、PC2がファイルのコピーを行うとバッティングしてしまいエラーになるので、ファイルをコピーする前にファイルAのオープンチェックを行いたいと思っています。
- deecyan
- ベストアンサー率38% (89/233)
onerr を書いて エラーになったら 5秒待って resume したらいいのでは? でも エラーになった回数を記録して 何回かしたら EXITしたほうがいいかな? または MSGBOXを出して 待つ手もありますよ
お礼
コードまで考えていただき、ありがとうございました。 おかげさまで目的を達成することができました。 DoEventsは知らなかったのですが、この命令により別の懸案事項もクリアできました。 どうもありがとうございました。