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

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

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

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

Q&A

解決済

2回答

29193閲覧

ADODB.Stream 保存時エラー

coko1

総合スコア276

VBA

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

0グッド

0クリップ

投稿2016/11/10 02:59

編集2016/11/10 03:39

ADODB.Streamでファイルを作成していてSaveToFileで保存する際に、
’アプリケーション定義またはオブジェクト定義のエラーです’とエラーが発生します。
変数SAVEPATHには保存先のパス、TEXTFILE保存ファイル名が定義されています。わからないのはSAVEPATHがローカルのパスだった場合はエラーが発生せず保存できるのですが、サーバーのパスだった場合だと保存がなされないことです。原因の解決方法がわかる方がいたら助けていただけると嬉しいです。

Set ADO = CreateObject("ADODB.Stream") ADO.Charset = "UTF-8" ADO.Mode = 3 '書き込みモード ADO.Type = 2 'テキストデータ ADO.Open //----------------// テキストの内容作成 //----------------// ADO.Position = 0 'ストリームの位置を0にする ADO.Type = 1 'データの種類をバイナリデータに変更 ADO.Position = 3 'ストリームの位置を3にする Dim byteData() As Byte '一時格納用 byteData = ADO.Read 'ストリームの内容を一時格納用変数に保存 ADO.Close '一旦ストリームを閉じる(リセット) ADO.Open 'ストリームを開く ADO.Write byteData 'ストリームに一時格納したデータを流し込む ADO.SaveToFile SAVEPATH & "/" & TEXTFILE, 2 ←ここでエラー ADO.Close

リンク内容
上記のサイトで、ドライブ文字を割り当てていないネットワークドライブに、カレントドライブを変更することはできません。と記述されていました。
解決策として【WSHを使うやり方】が載っていました。

Sub Sample2() With CreateObject("WScript.Shell") .CurrentDirectory = "\\EPSON\E\Develop\" End With MsgBox CurDir End Sub

これを自分の処理にどうくわえたらよいのでしょうか?改めて力を貸していただけると助かります。

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

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

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

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

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

Y.H.

2016/11/10 03:11

「SAVEPATH がサーバーのパスだった場合」とは具体的にどういう値がSAVEPATH に入っているのでしょうか? UNCパス("\\server\共有名\dir")? ネットワークドライブとしてドライブ文字が割りあたっている("X:\dir")?
coko1

2016/11/10 03:12

前者になります。
Y.H.

2016/11/10 03:42

カレントディレクトリの変更方法の件については本質問と関係ないようなので別質問とした方がいいです。
guest

回答2

0

UNCパス形式ではディレクトリの区切り文字は''です。

基本的にWindows(dos)ではディレクトリの区切り文字は''ですが
LocalのPathの場合は'/'でも受け入れてくれるのでしょう。

カレントディレクトリの変更とかややこしいことは不要で "/"を""に変更するだけです。

VBScript

1'ADO.SaveToFile SAVEPATH & "/" & TEXTFILE, 2 ' ←ここでエラー 2ADO.SaveToFile SAVEPATH & "\" & TEXTFILE, 2 ' '/'ではなく'\' 3

テストスクリプト

VBScript

1Set sr = CreateObject("ADODB.Stream") 2dim path 3dim Arr(2) 4Arr(0)="line 0" 5Arr(1)="" 6Arr(2)="line 2" 7 8WScript.StdOut.WriteLine "--start--" 9 10with sr 11 .Charset = "UTF-8" 12 .Mode = 3 '書き込みモード 13 .Type = 2 'テキストデータ 14 .Open 15 16 For i = 0 To UBound(Arr) 17 WScript.StdOut.WriteLine Arr(i) 18 .WriteText Arr(i), 1 19 Next 20 path="d:\temp" 21 WScript.StdOut.WriteLine path & "\out.txt" 22 .SaveToFile path & "\out.txt", 2 23 24 path="\\fileserver.local\attach\junktest" 25 WScript.StdOut.WriteLine path & "\out2.txt" 26 .SaveToFile path & "\out2.txt", 2 27 28 path="d:\temp" 29 WScript.StdOut.WriteLine path & "/out3.txt" 30 .SaveToFile path & "/out3.txt", 2 31 32 path="\\fileserver.local\attach\junktest" 33 WScript.StdOut.WriteLine path & "/out4.txt" 34 .SaveToFile path & "/out4.txt", 2 35 36 .Close 37End With 38WScript.StdOut.WriteLine "--end--"

実行結果

D:>cscript //NOLOGO aaa.vbs
--start--
line 0

line 2
d:\temp\out.txt
\fileserver.local\attach\junktest\out2.txt
d:\temp/out3.txt
\fileserver.local\attach\junktest/out4.txt
D:\aaa.vbs(34, 5) ADODB.Stream: ファイルへ書き込めませんでした。

#Excelでも動確してますが、これがなぜマイナス評価なのかわからん。

投稿2016/11/10 03:36

編集2016/11/10 14:00
Y.H.

総合スコア7914

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

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

ynakano

2016/11/10 03:39

(Excel)VBAの話ではないのですか?
Y.H.

2016/11/10 03:50

本質問のADODB.Streamの使用に関しては、Excel VBAだろうがWord VBA だろうがPowerPoint VBAだろうが cscript/wscriptだろうがClassicASPでのVBScript だろうがExcelに縛られる部分が無いので全て同じです。異なる部分があればご指摘いただければと思います。
ynakano

2016/11/10 04:01

問題は「SAVEPATHがローカルのパスだった場合はエラーが発生せず保存できるのですが、サーバーのパスだった場合だと保存がなされないこと」ではないのでしょうか? ローカルには保存できていると読み取れるのですが。
Y.H.

2016/11/10 04:04

そうです。その原因がUNCパスのディレクトリ区切り文字に'/'を使用しているからです。この回答に記述の通り、ディレクトリ区切り文字に'¥'を使用するとサーバーのパスでも正常に保存されます。
hatena19

2016/11/10 05:34

個人的にはこちらの回答がベストアンサーです。プラスを押しておきました。 UNCパスには'/'が使えないという単純な原因ですよね。 念のために Access VBA でも'¥'に置き換えるだけで正常保存されるのを確認しました。
Y.H.

2016/11/10 05:42

@hatena19さん。ベストアンサーは質問者さんの判断なので何とも思わないですが、マイナス評価の理由は知りたかったので。(私の知らない何か間違いがあるのかもとか思ってしまう)
guest

0

ベストアンサー

Excel VBAという前提で回答します。
この場合、"\"で始まるネットワークドライブに保存するには若干面倒な処理が必要です。
まず、どのプロシジャ(Sub xxx~End Subの間)にも含まれない部分に下記1行を追加します。

Declare PtrSafe Function SetCurrentDirectory Lib "kernel32" Alias "SetCurrentDirectoryA" (ByVal CurrentDir As String) As Long

※PtrSafeは64bit環境でのみ必要なようです。

SAVEPATH変数には"\"で始まるUNCパスを定義します。
そして"ADO.SaveToFile ..."の前に以下の行を追加します。

SetCurrentDirectory (SAVEPATH)

※どこに書くかは適宜判断して下さい。

そして
流れとしては、SetCurrentDirectory関数でUNCパス上のディレクトリに移動して、そこにファイルを書き出すことになります。「ADO.SaveToFile SAVEPATH & "/" & TEXTFILE, 2」は以下のように書き換えてください。

ADO.SaveToFile TEXTFILE, 2

また、SetCurrentDirectory関数はExcelが標準で持っていないので、kernel32.dllを呼び出して使用しています。

最後に、coko1さんの質問文にあったコードを丸コピー&適宜補足して試したのですがあちこちエラーが出ました。
ですのでテストは以下の点に絞っています。
・ADOでUTF-8のファイル作成をする。
・SetCurrentDirectoryのDLL呼び出しとディレクトリ移動。
・UNCフォルダ上にファイルが作成できること。

【補足】SetcurrentDirectoryWというものもあります。UNICODEの場合はこちらでないとダメなようです。

###2016/11/10 13:15追記
質問の編集を受けて追記します。
随分簡単な方法があったのですね。
これを使うのなら以下の通りにすればよいと思います。

"ADO.SaveToFile ..."の前に以下の行を追加します。

CreateObject("WScript.Shell").CurrentDirectory = SAVEPATH

「ADO.SaveToFile SAVEPATH & "/" & TEXTFILE, 2」は以下のように書き換えてください。

ADO.SaveToFile TEXTFILE, 2

これであっさりできました(テストの前提条件は先ほどと同じ)。
DLLなんか使わなくてラクですね。

投稿2016/11/10 03:58

編集2016/11/10 04:19
ynakano

総合スコア1894

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

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

coko1

2016/11/10 04:39

できました!ご丁寧にいろいろな解決法を提示して頂いて本当にありがとうございました。
ynakano

2016/11/10 04:41

自分としてもVBScriptでUNCパスにchdirするというのは目からウロコでした。
hatena19

2016/11/10 08:41

質問のコードの間違いは、Windowsではディレクトリの区切り文字は '\' であるのに '/' を使っているということです。'/' を '\' に変更すれば、ローカルでもサーバーでも問題なく保存されます。 これがベストアンサーだと、あとから見た人が、サーバーに保存するときは、カレントディレクトリを移動させなければならないという誤解をあたえかねませんのであえてマイナスを押しました。
ynakano

2016/11/10 08:59

確か完全なミスリードですね。 ご指摘ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問