海外旅行から帰ってきたら、まず何を食べる?

いつもお世話になります

今、Scriptファイルを利用してExceのデータでAutoCad上に作画させていますが
時々データ量および処理速度の差によって、Scriptファイルの書き込みエラーが
発生します
今はApplication.Waitで調整していますが、妙案があったら教えてください

'...ファイルの定義
Set stm = New ADODB.Stream
stm.Charset = "UTF-8"
stm.LineSeparator = adLF

stm.Open
  (作図)ファイル作成

Application.Wait [Now() + "00:00:03"]    '...エラーが起きないように3秒調整
stm.SaveToFile PLTFname1, 2        '...ファイル書き込み(ここでエラーが起きる)
stm.Close
Application.Wait [Now() + "00:00:01"]
SendKeys "script" & Chr(13) & PLTFname1 & Chr(13)

stm.Open
  (作図)

Application.Wait [Now() + "00:00:03"]
stm.SaveToFile PLTFname1, 2
   ・
   ・
 (作図とScript 処理を繰り返します)

いつもすみません、変な質問で
以上、よろしくお願い申しあげます

A 回答 (4件)

こんにちは



以下は、想像と空想での回答ですので、対策になるのかもわかりませんけれど・・

通常、ADODB.Streamからの出力処理にApplication.Waitが必要だというような情報は見つかりませんので、ご提示のケースに特有の問題であろうと推測します。

ご提示の処理ですと、VBAからのファイル出力とAutoCad側でのファイル読み込みとが交互におきるため、多分、その排他処理の交通整理で発生しているのではないかと推測します。
(その割には3秒は長いような気もしますけれど・・)
実際に問題となっている原因を調べられれば、それを回避する方法のヒントになると思いますけれど・・


AutoCad側のスクリプト処理がどのような仕組みなのか知りませんけれど、小分けにせずにまとめて1ファイルに出力することは不可能なのでしょうか?
(これなら、Waiteは出力後の1回だけで済むはずと思います)
また、スクリプトの処理時間が瞬時なのか、多少時間がかかるのかなども関係してくると思います。

小分けすることが必須であるのなら、同じPLTFname1を上書きして使い回すようなことはせずに、連番などで別ファイルとして出力すれば、出力時にエラーが起きることは回避できるのではないかと推測します。
(全部の処理が終わったところで、ファイル群は削除すれば済むでしょう)
ただし(AutoCad側の仕様は知りませんけれど)、スクリプトの実行速度とVBAからの次のSendKeyとの関係を制御することが必要なのかも知れません。
(前の処理が終わらないうちに、次のkeyが送信された場合の反応が不明なので)

AutoCad側の状態(コマンドを受け付けられるか否か)などを取得する方法があれば(statusなどで)、そちらを監視してコマンドを送るようにすればタイミングを測れるので(あるいはエラーが返るのならエラー処理で監視してもよい)、一律のWaiteをかける必要もなくなるのではないでしょうか?
    • good
    • 1
この回答へのお礼

こんにちは
いつもお世話になります

作図には少し時間が掛かる量なので小分けにしています
Scriptファイルの名前を変える方法は良いかもしれませんね
チャレンジしてみます

本当にいつも助かります
これからもよろしくお願い申しあげます

お礼日時:2024/08/02 11:17

No3です。



>作図には少し時間が掛かる量なので小分けにしています
>Scriptファイルの名前を変える方法は良いかもしれませんね

妄想の続きですが・・
ファイル名を変えれば、出力時のエラーはなくなるのではないかと推測します。
ただし、AutoCad側の処理に時間がかかるとのことですので、作図処理が終わらないうちに連続してコマンドを送った場合にどうなるのかが問題になりそうな気がします。

以下では、考え方も方法も変わってしまいますけれど・・
AutoCadでもMS VBAが使えたと記憶しています。
ですので、エクセルからSendkeysでCadを操作することをやめて(=あまり良い方法とは言えないと思いますので)、AutoCad側のVBAをメインとして、
 ・エクセルを開き
 ・そのデータを利用して作図する
ような仕組みにしておけば、Sendkeysのような必要もなくなるはずです。
時間待ちなどの煩わしい制御を考慮する必要もなくなるので、ご質問のような問題も生じないのではないかと推測します。

「計算はエクセル側で処理したい」という事情があるのなら、AutoCad側のVBAからエクセル側のプロシージャを呼び出して結果を受け取るような構造にしておけば、ファイルを介さずともデータの受け渡しが可能になりそうに思いますし、作成してある「エクセル側の計算処理」もほぼそのまま利用できるのではないかと想像します。
    • good
    • 0
この回答へのお礼

こんにちは
再度、ありがとうございます

私たち社員が使っているのはAutoCad LTと廉価版Ares StanDardを
使っていますので、Cad側にはVBAは無いのです
その環境下でプログラムを構築していかなければなりません
今後はどうなるかは会社上司の考え方とお金次第になると思います

プログラマは私一人(78歳)プログラム歴50年です
これからもよろしくお願い申しあげます

お礼日時:2024/08/02 15:03

On Error Resume Next <---- ここを追加した



'...ファイルの定義
Set stm = New ADODB.Stream
stm.Charset = "UTF-8"
stm.LineSeparator = adLF

stm.Open
  (作図)ファイル作成

Application.Wait [Now() + "00:00:03"]

For i = 0 To 10 <---- ここを追加した
stm.SaveToFile PLTFname1, 2

If Err.Number = 0 Then <---- ここを追加した
Exit For <---- ここを追加した
End If <---- ここを追加した
Application.Wait [Now() + "00:00:01"] <---- ここを追加した

Next <---- ここを追加した

stm.Close
Application.Wait [Now() + "00:00:01"]
SendKeys "script" & Chr(13) & PLTFname1 & Chr(13)



    • good
    • 0
この回答へのお礼

早速ありがとうございます

そうですね、
3秒のWaitタイムはいらないですね
やってみますね

ありがとうございました
これからもよろしくお願いいたします

お礼日時:2024/08/01 16:27

(1) On Error Resume Next を最初に記載し、エラーが発生しても処理が止まらないようにする



(2) SaveToFile を実行している処理を ループにして
1秒待つ→書き込む→エラーならループ2週目(2秒待つ)→書き込み→エラーならループ3週目(3秒待つ)→・・・
のように上限を設けたループにして書き込みができるタイミングに書き込みするように制御する

※エラーかどうかは「Err.Number」の値が0か否かで判定する


などはいかがですか?
    • good
    • 0
この回答へのお礼

いつもありがとうございます

ご丁寧にプログラムに追加してもらい
恐縮です
これからもよろしくお願い申しあげます

お礼日時:2024/08/01 16:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A