質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

5064閲覧

エクセルマクロでFileを開く時エラーが出ます

atsunofu

総合スコア59

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2018/12/19 00:56

csv Fileの内容を定期的(10分間隔、2File有るので実質5分置き)にエクセルFileにコピーし
データの内容をグラフ化する処理を行っています。
グラフはエクセルファイルに設定しているのでデータが書き換わる事で更新しています。

1Fileのみで動作させた時は問題無いのですが、2File同時動作させると、8時間程度動作した所で毎回
「実行時エラー1004 'Open' メソッドは失敗しました 'Workbooks' オブジェクト」
が出て停止してしまいます。

どなたか問題がわかる方ご教授いただけないでしょうか。
よろしくお願いいたします。

【確認してみたこと】
◆1Fileのみで動作させた場合は、複数回、2File共、希望している15日間の内14日迄動作を確認しています。

◆Fileを開く前にcsv Fileを開いているのでここでSleep処理を設定(10秒、100秒)して開くのを待ったり、
またPB:PlotBook を開く際にエラーが出ているので、ここでSleep処理(10秒、100秒)等を設定しても発生

◆PB:PlotBookには100個のグラフを描写しているので、そこを20個まで減らして実施しても発生しました。

◆処理時間が長くなっていないかを確認してみましたが、1処理に掛かる時間は25秒程度で
動作している8時間の間変動無しです。

Codeは下記です

Option Explicit Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Sub Timer() '指定の経過時間毎にマクロを走らせるタイマー Dim mySpan(2160) As Date Dim span As Date, n As Integer span = Now + TimeValue("0時00分30秒")    ’2つ目を動作させる時はここを+ TimeValue("0時05分30秒") として5分置きに動作 Debug.Print "span =" & span For n = 0 To 2160 '21600min = 15days mySpan(n) = span Application.OnTime span, "CopyPlotandJudge" span = DateAdd("n", 10, span) Next End Sub Sub CopyPlotandJudge() Application.ScreenUpdating = False Application.DisplayAlerts = False '1)エクセルファイルがあるフォルダパスを入力 Call CopyPlot(ThisWorkbook.Path) '2)メール送信処理 If ThisWorkbook.Worksheets(1).Range("B31") <> "OK" And ThisWorkbook.Worksheets(1).Range("C31") = "OK" Then Call SendMail End If End Sub Sub CopyPlot(Path As String) Dim FSO As Object 'FileSystemObjectを定義 Dim sFile As Variant, sCopy As Variant, PFile As Variant 's=ソースファイル とソースコピーファイルを定義 Dim DB As Workbook, DS As Worksheet 'DB:データブック、DS:データシート Dim PB As Workbook, PS As Worksheet, RS As Worksheet 'PB:PlotBook、PS:Plotデータシート、RS:ResultSheet On Error GoTo errorhndler Application.ScreenUpdating = False Application.DisplayAlerts = False Set FSO = CreateObject("Scripting.FileSystemObject") 'フォルダ内のソースファイルをRename Copy Debug.Print Now & " の処理です。" sFile = "\(IP)\Logdata\" & Left(ThisWorkbook.Name, 5) & "\df_last1000.csv" sCopy = ThisWorkbook.Path & "\df_last1000Copy.csv" PFile = ThisWorkbook.Path & "\" & Left(ThisWorkbook.Name, 5) & "_PlotSheet.xlsx" Debug.Print sFile & " To " & sCopy Debug.Print PFile FSO.CopyFile sFile, sCopy 'コピーしたソースcsv Fileを定義 Debug.Print Now & " 1" Set DB = Workbooks.Open(Filename:=sCopy, ReadOnly:=True) Set DS = DB.Worksheets(1) 'プロットデータブックの読み取り専用を解除 Sleep 1000 SetAttr PFile, vbNormal Debug.Print Now & " 2" 'プロットデータブックを開き、data Sheetと結果Sheetを定義 Set PB = Workbooks.Open(Filename:=PFile)    ’=========毎回ここで停止します。========== Sleep 10000 Set PS = PB.Worksheets("data") Set RS = PB.Worksheets("Result") 'ソースcsvからdata Sheetへコピー DB.Activate DS.Activate DS.Range("A2:A1001").Select DS.Range(Selection, Selection.End(xlToRight)).Copy PS.Activate PS.Cells(2, 1).PasteSpecial Paste:=xlPasteValues DB.Close '結果Sheetの内容をMacro Sheetへ入力 '前回の判定結果を記録 ThisWorkbook.Worksheets(1).Range("B31").Copy ThisWorkbook.Worksheets(1).Range("C31").PasteSpecial Paste:=xlPasteValues Debug.Print Now & " グラフFileの判定結果と最終時間をマクロシートに記載します。" PB.Activate RS.Range("B19").Copy ThisWorkbook.Worksheets(1).Range("B31").PasteSpecial Paste:=xlPasteValues PS.Cells(Rows.Count, 3).End(xlUp).Copy ThisWorkbook.Worksheets(1).Range("C28").PasteSpecial Paste:=xlPasteValues 'グラフFileのsheetをアクティブシートに設定 PB.Activate RS.Activate ' Windows.Arrange ArrangeStyle:=xlArrangeStyleTiled ' Windows("DE_57_PlotSheet.xlsx").Activate With ActiveWindow .Width = 500 .Height = 1360 .Top = 0 .Left = 0 .Zoom = 50 End With PB.Save PB.Close '念のためFSOをクリア Set FSO = Nothing '読み取り専用に設定し再度開く SetAttr PFile, vbReadOnly Set PB = Workbooks.Open(Filename:=PFile) Set PS = PB.Worksheets("data") Set RS = PB.Worksheets("Result") Debug.Print Now & " Windowサイズを修正します。" PB.Activate RS.Activate With ActiveWindow .Width = 500 .Height = 1360 .Top = 0 .Left = 0 .Zoom = 50 End With Exit Sub  ’この後メール送信Macroが有りますがここでは異常が出ていないので割愛します。

【環境】
Excel 2016 32bit
Windows10 Pro 64bit

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

morinatsu

2018/12/19 13:47

これが原因とも思いませんが、PFileを2回オープンしているのに、クローズが1回のみなのが気になりました。
atsunofu

2018/12/20 00:02

morinatsuさん、ご意見ありがとうございます。 最後にPFileを開いた後、表示を継続する必要が有るのでクローズしていませんでしたが、 最初にクローズしていませんでした。クローズ処理を追加して試してみます。
guest

回答2

0

ベストアンサー

さすがに8時間の検証はできないので、コードからの推測によるアドバイスになります。
的外れでしたら申し訳ありません。


ある程度の時間は正常に動作するものが、長期の繰り返し処理の中で異常をきたす、ということですよね。
ざっくりですが、以下のような原因が推測できます。

①処理回数によって変数などがオーバーフローする
⇒エラーが発生する箇所では考え難そう。

②ゴミが貯まってメモリ不足になる
⇒これは可能性ありか?

③処理中の環境変化
・処理遅延により前回のタイマー処理が終わる前に次のタイマー処理が発生した
⇒一回毎の処理は一定間隔(25秒)で終わっているということなので考え難い?

・解放が間に合わずファイルロックされた
⇒解放に5分もかかるのは考え難いか・・・?

・割り込み処理が発生した
・その他の外的要因など
⇒ここらへんになると特定が難しいです。。

また、根本的な問題として
④非常に稀に発生するデータ依存のエラー
という可能性も考えましたが、これもエラー発生個所から見て薄そうです。


個人的には、まずは一番ありそうなところで②を疑っています。

コード内でメモリにゴミを残しそうな記述としては、DB.ClosePB.Closeなどでブックを閉じてはいますが、変数としては明示的に解放していないあたりでしょうか。
大丈夫な気もしますが、基本的にSetしたObjectは再利用する前に明示的に開放Set xx = Nothingしてあげた方が無難な気がします。

さしあたりここら辺を確認されてみてはどうでしょうか。
参考になれば幸いです。

投稿2018/12/20 04:49

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

atsunofu

2018/12/20 04:55

jawa さん 御意見ありがとうございます。 上記開放の手順を全てで実施してみます。 検証に最低8h掛かるので、明日迄検証してダメであれば諦めます。
atsunofu

2018/12/21 00:36

jawa さん 上記開放の手順を全てで実施してみましたが再発しました… 全て8時間35分ぐらいで発生 ありがとうございました。他の手を考えたいと思います。
jawa

2018/12/21 00:47

単体では15日も動作するということなのでさすがに8時間で破綻はないかな、とは思っていたのですが。 単体で開くものと複数で開くものでは多少コードも違うはずなので、直ればいいな~と思っていたのですが残念です。 ただ、開放については [参考⇒](https://teratail.com/questions/23082) の記事にも記載がある通りやっておいたほうがいいようです。 お力になれず申し訳ありません。
atsunofu

2018/12/26 04:50

jawa さん 御見識をお借りしありがとうございました。 その後 エクセルマクロをbatで定期実行する様に変更してみましたが、 こちらでも同じ(と思われる)エラーが出ています。難しいです。
jawa

2018/12/26 08:48

原因を特定して解消するか、別手段での実装を検討するか、考えどころですね。。 原因を特定するのならとにかくいろいろやってみる他なさそうです。 ・エラーが発生したときのCSVを初回で読み込んだ場合にエラーにはならないか? ⇒データ由来のエラーか否かの確認 ・タイマーの処理間隔を短くした場合、早くエラーは早く発生するか? ⇒処理回数によるエラーか、継続時間によるエラーかの確認 ・単発のマクロ起動を繰り返してはどうか? ⇒定期的にバッチ処理で行ったというのはこれでしょうか。 単発処理でエラーになるのなら、コーディング自体の問題というよりもデータや外的要因(端末負荷や割込処理等)といったところが怪しくなってきます。 どれか当たれ的なアドバイスしかできず申し訳ないです。
atsunofu

2018/12/27 05:34

jawaさん >定期的にバッチ処理で行ったというのはこれでしょうか。 はいそうです、処理が完了した時点でマクロBookをマクロでCloseし、 10分後に再度bat Fileで起動、という処理を5分ずらして2つ並列で処理を繰り返しました。 また御意見いただいた内容ですと >エラーが発生したときのCSVを初回で読み込んだ場合にエラーにはならないか? ⇒これはエラーになった事は有りません。 >タイマーの処理間隔を短くした場合、早くエラーは早く発生するか? ⇒逆の内容ですが、30分間隔にする(2つ並列なので15分間隔)と3倍の25時間ぐらいで  同様のエラーが発生するのを複数回確認しています。  ですのでjawaさんの仰るObjectの開放が肝かと考えたのですがうまく行きませんでした。  現在はVbsでFile Open処理を行い、それをタスクスケジューラで定期実行する事を試みています。
guest

0

直接の回答ではありません、私ならこれを試してみるというだけの物です。
③はぶっちゃけ面倒なので、①②をとりあえず試してみると良いかもしれません。

①処理を定期的にOSに返す
コード中の定期的に通る任意の場所に『DoEvents』を入れる。

②クリップボードのクリア
何かの貼り付けの直後(?)に『Application.CutCopyMode = False』を入れる。

③マクロを開いているエクセルとは別に
別途エクセルアプリケーションを作成し、そこでやりたい処理を行う。
そして定期的にアプリケーションを閉じたり上げたりする。

'注)例は適当です。 Sub Sample1() Dim myExcel As Object Set myExcel = CreateObject("Excel.Application") '■ いろいろ操作 ■ 'myExcel.Visible = True 'myExcel.Workbooks.Add myExcel.Quit Set myExcel = Nothing End Sub

投稿2018/12/19 08:08

torisan

総合スコア678

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

atsunofu

2018/12/19 08:26

torisan さん ありがとうございます。 DoEvents と Sleepの違いが解っておらず、試していませんでした。 取り急ぎ 1,2,を実装して1日動かしてみます。
atsunofu

2018/12/20 00:04

1,2,を実装しましたが、やはり8時間で停止していました。 別の方からの意見で事前にPFileをクローズする処理を追加して試行中です。
torisan

2018/12/21 02:39

後は、 毎回マクロファイルを終了するようにしてしまって、 タスク(とAuto_open?)で都度マクロファイルを起動してみる等でしょうか? そちらの環境に合うかどうかはわかりませんが、 余裕があれば試してやってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問