こんにちはExcel 2007 on Win 7の環境でVBAを書いています。
ある別のアプリケーションがつかんでいるテキストファイルを新しい内容に置き換えたいのですが、うまくいかずに困っています。当初は「Open filename For Input As #n」の方法で開いて、編集して、保存することができていたのですが、アプリケーションの都合上、ファイルをUTF-8で保存する必要が出てきました。そのため、ADODB.Streamで書き直すことになったのですが、最後の「SaveToFile filename, 2」とすると、「アプリケーション定義またはオブジェクト定義のエラー」が出て書き込むことができません。
「Open file」して「Close」したり「Unlock」したりしたのですが、ADODB.StreamのSaveToFileで上書き保存できる状態になりません。
大元のアプリケーションをいったん終了させれば良いのでしょうが、それでは本末転倒なのです。
お知恵を貸してください
No.4ベストアンサー
- 回答日時:
こんにちは。
#3の回答者です。概ね、状況は理解しました。まだ、*ちょっと理解していない部分はあるけれども、私は、アプリ側の「排他制御」モードと読んでいます。アプリ側が許しているものとそうでないものがありますし、「排他」にするか、オプションで選べるものもあります。排他モードでも、種類を選べるものもあります。
だから、Open ~ For Input As ** でも、ADODB.Stream でも本来、ロックされた状態ですと、同じ結果というか、編集・保存は出来ないはずです。それで、ふつう、そういう場合は、一旦、ダミーファイルでコピーで作ってやって、それを加工して、アプリが終わった時点で戻すというようなステップにします。
*理解してない部分
#1の回答
>でも Open filename For Input As #n だと編集して保存できちゃうんですよ。
補足#3
>であれば、Open コマンドで開いて編集して保存できるのは何なんでしょう。
もしかしたら、ロック解除のタイミングがあるかもしれません。ロックが解除になる時が存在しているなら、それはループで書き込みできる時を調べればよいと思います。ただし、Excel 等のVBAでは長い時間は無理だと思います。メモリが累積していくはずですから。
最初の話の部分は、例えば、このようなことです。
'//モジュール始め
Const myPath = "D:\Test1\"
Const fName = "abc.txt"
Dim dummyFn As String
Sub MacroSample1()
Dim fn As String
Dim objFS As Object
Dim objFile As Object
''"他のアプリケーションが使用中のファイル"
dummyFn = "$" & fName 'ここでダミーに切り替える
Shell "cmd.exe /c copy " & myPath & fName & "," & myPath & dummyFn
fn = myPath & dummyFn
Open fn For Output As #1
Print #1, "open for output" & Now() & vbCrLf
Close #1
End Sub
Sub ADODBTest()
'fName = "D:\Test1\abc.txt"
'"他のアプリケーションが使用中のファイル"
Dim strm As Object
Set strm = CreateObject("ADODB.Stream")
strm.Type = 2
strm.Charset = "UTF-8"
strm.Open
strm.WriteText "ADODB" & Now() & vbCrLf
strm.Position = 0 '念のため、このコードがなくてもエラーになった
strm.SaveToFile myPath & dummyFn, 2 'ダミーファイルに書き込む
strm.Close
Set strm = Nothing
End Sub
'///
話が中途になっていますが、とりあえず、ここまで調べてみてください。
*の部分は、今は、ちょっと不安が残ります。
ループで断続的にファイルのロック状態を調べるのです……。
ダメなら、別のアプリが終わった時点でも、VBA側から戻してあげればよいと思います。
根本的な謎は解決していないのですが、やりたいことは実現できました。書いてくださったコードがヒントになりました。
まず、新たに生成するファイルは、まだ存在していない新規のダミーファイルにしました。
次のようなコードにしたところ、事実上上書き保存ができました。
strm.SaveToFile dummyFile, 2
cmd = "cmd.exe /c copy /Y """ & dummyFile & """ """ & fName & """"
Shell cmd
cmd = "cmd.exe /c del /Q """ & dummyFile
Shell cmd
やはり SaveToFile の上書きは、表現が適切かわかりませんが、「厳しい条件」があるように感じました。
No.3
- 回答日時:
こんちには。
このご質問は、一度、VBAコードを出してから話をしたほうがよいと思います。
>ある別のアプリケーションがつかんでいるテキストファイル
でも、Open filename for input で出来ていたというなら、別のアプリなど関係ないのではありませんか?別のアプリというのは、Excel以外という意味だと思いますが。
>Open filename For Input As #n だと編集して保存できちゃうんですよ。
ただ、これで保存ということではあっても、これだけでは、Application側のコマンドが実行中です。その後、Close #n で、始めて終わるわけなのです。
つまり、一連のコマンドのストーリーを終わらせるっていうのは、当たり前だと思うのです。
>編集して、保存することができていたのです
それが出来ているというなら、ロックは掛かっていません。
しかし、私の知っている範囲では、コマンド実行中で、オブジェクトの支配下にあるものを、横から割り込むことは出来なかった気がします。(やったことはないけれど)
私が想像するのは、コードの修正は、おそらくは、本当に簡単なことなんだろうと思うのです。
UTF-8 にするために、ADODB.Stream で云々はいいけれども、言葉だけでは伝わらないのです。
それに、Opne filename ~とは、別の流れなのです。こちらを一旦、終わらせていないのではないでしょうか。
ここの質問でも、話半分だったから、いえ、私の思い違いで、解決にまでは、二転三転してしまったのです。
http://oshiete.goo.ne.jp/qa/9054919.html
もし、見当はずれの内容でしたら、どうかスルーしてください。返事は不要です。
ありがとうございます。
Open コマンドと ADODB を比較するコードを作ってみました。
やはり、Open コマンド (for outputでした)だと保存でき、ADODB の SaveToFileでは保存できませんでした。
Sub OpenTest()
Dim fName As String
fName = "他のアプリケーションが使用中のファイル"
Open fName For Output As #1
Print #1, "open for output"
Close #1
'結果、対象ファイルの中身は「hoge」だけになります。
End Sub
Sub ADODBTest()
Dim fName As String
fName = "他のアプリケーションが使用中のファイル"
Dim strm As Object
Set strm = CreateObject("ADODB.Stream")
strm.Type = 2
strm.Charset = "UTF-8"
strm.Open
strm.WriteText "ADODB"
strm.Position = 0 '念のため、このコードがなくてもエラーになった
strm.SaveToFile fName, 2 'この時にファイルに書き込めないエラーが発生して止まる
strm.Close
Set strm = Nothing
End Sub
エラーは今試したところ、実行時エラー 3004 ファイルへ書き込めませんでした。となりました。以前は「70」のエラーも出ていたように思いますが。
No.2
- 回答日時:
それはOSの根幹部分でやっていることなのでVBA如きで歯が立たないのはあたりまえ。
ウイルス活動としてセキュリティソフトにブロックされるようなコードを書かないと無理だろう。
どうしても保存したいのであれば、
別名で保存して他で使用しているアプリケーションが終了したら書き換える
などの手段を講じてはどうか。
他で使用されて編集されていたらその内容を問答無用で破棄することになるが・・・。
ありがとうございます。
やっぱりアプリケーションをいっかい終了させてから、ファイルを上書き保存し、再度開き直すまでをすべてVBAに書き込もうと思います。
Open コマンドでは普通にできていたので、ADODB.Streamになったらとたんに使いづらく(ファイルが無駄に増える)ことになったのでどうにかならないかと思案していたところです。
No.1
- 回答日時:
>使用中(ロック)のファイルを上書き
いやいや、それこそむしろ本末転倒でしょう?
それをさせないためにロックしているのだから・・・
ありがとうございます。
そうなんですねー
でも Open filename For Input As #n だと編集して保存できちゃうんですよ。今まで通り、タイムスタンプと付けたファイル名で新規ファイルを作成してアプリケーションに読み込ませ直すか(これでと新規ファイルが増殖しちゃって汚いんですけど)、あるいはアプリケーションをいったん閉じてから上書き保存して再度起動するのが無難ですかねぇ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
あるあるbotに投稿したけど採用されなかったあるある募集
あるあるbotに投稿したけど採用されなかったあるあるをこちらに投稿してください
-
VBAでCSVファイルが使用中かどうかの確認
Visual Basic(VBA)
-
エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの
Excel(エクセル)
-
ADODB.Streamを使用してUTF-8を出力
Visual Basic(VBA)
-
-
4
いつもお世話になっております 以前と同様 VBAでフォルダ内のファイルを1つのブックに格納(ファイル
Excel(エクセル)
-
5
実行時エラー3001「引数が間違った型、許容範囲外、または競合しています。」
Visual Basic(VBA)
-
6
エクセルマクロ(VBA)でテキストに出力、3つのテキストファイルに名前を付けて保存するには
Excel(エクセル)
-
7
Excel VBAでエラーが出ます。
Excel(エクセル)
-
8
Excelファイルのマクロによる排他制御
Excel(エクセル)
-
9
バックグラウンドのプロセスのエクセルを閉じる方法
Visual Basic(VBA)
-
10
EXCEL VBAでテキストファイルの特定の場所にデータを書き込む方法
Visual Basic(VBA)
-
11
《エクセルVBA》「他の人が該当ファイルを使用中の場合」の処理
Excel(エクセル)
-
12
エクセルVBAでmeに相当するものは?
Excel(エクセル)
-
13
EXCEL VBA セルに既に入力されている文字に文字を追加する
Excel(エクセル)
-
14
コマンドプロンプトの「%1」と「%~1」の違いがわからない
その他(プログラミング・Web制作)
-
15
同じ文字列なのにfalseになってしまいます。
Excel(エクセル)
-
16
【ExcelVBA】各セルをダブルクォーテーションで括ってCSV保存したい
Visual Basic(VBA)
-
17
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
18
日付型のフィールドに空白を入れる方法を教えてください
その他(データベース)
-
19
バッチ終了時にDOS窓を閉じるコマンド
その他(プログラミング・Web制作)
-
20
エクセルのエラーメッセージ「400」って?
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルでファイルの最終更新...
-
VB6.0でエクセル保存する時の保...
-
VBAで、強制保存してブックを閉...
-
エクセル:マクロ:保存時に連...
-
Corel Digital Studioの動画をS...
-
読み取り専用ファイルを上書き...
-
AccessVBAでレポートをPDFで出力
-
VB6でEXCELの表をHTML形式で保...
-
Pivot table で集計されたデー...
-
コマンドプロンプトでデスクト...
-
コードエディタの緑色の部分
-
VBAでPDF作成をしたあと、指定...
-
WSHでExcelファイルを上書きし...
-
マイドキュメントのフォルダの...
-
vlan internal allocation poli...
-
沢山のフォルダにあるファイル...
-
PCファイルの完全な削除方法
-
onedriveで同期解除をしたら、...
-
Safariのブックマークの消し方
-
TXTファイルを上書き保存する前...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルでファイルの最終更新...
-
Excel VBAでほかのアプリケーシ...
-
読み取り専用ファイルを上書き...
-
Excel VBAで作成したマクロをxl...
-
コマンドプロンプトでデスクト...
-
VBAで、強制保存してブックを閉...
-
Pivot table で集計されたデー...
-
VBA メモ帳の上書き保存がしたい
-
エクセルで「名前を付けて保存...
-
vbaでIEの名前を付けて保存(A)...
-
ASPでファイルを保存するダイア...
-
タイトルバーやメニューバーの...
-
VBScriptで日本語が変です
-
【Excel VBA】自動的にバックア...
-
VBAでPDF作成をしたあと、指定...
-
ファイルのダウンロード保存先...
-
エクセル:マクロ:保存時に連...
-
AccessVBAでレポートをPDFで出力
-
ExcelVBAでデスクトップのPATH...
-
EclipseでJavaScriptファイルの...
おすすめ情報
ちなみに、#3の回答で書いたコードの ADODBTestは、問題のアプリケーションを閉じると正常に動作します。
また、OpenTestでファイルを正常に更新できるのですが、そのあとも問題のアプリケーションでは古い内容のデータを扱っています。おそらくですが、問題のアプリケーションは対象ファイルの内容をいったん内部に取り込んで処理をしているので、リアル タイムには更新されないようにできているのだと思います。
さらに、コマンド プロンプトでOpenfilesを実行したところ、やはり問題のアプリケーションがこの対象ファイルを使用していると表示されました。ロックの仕組みについて詳しくないので正確な表現なのかわかりませんが、やはりこの状態は、問題のアプリケーションが対象ファイルを使用していると呼んで良いのだと思います。であれば、Open コマンドで開いて編集して保存できるのは何なんでしょう。