- ベストアンサー
(VBA) 保存できない
指定ディレクトリー(TurgetFolder)に保存しようとして 下記のコードを利用していますが、エラー(1004)が出ました。 添付画像参照下さい(丸数字有り) ------------------------- 'テキストデータにしたいシートを新しいブックとして作成し、そちらからテキストファイルを作成する Ws2.Copy ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText ---------------------------- ①、②、④はエラー原因では無かった。 原因は、③で フォルダー名に [ ] (左カッコ、 右カッコ) を利用した事でした。 でもフォルダー名及びファイル名に同じ [ ] があっても読み取り時は問題なく処理されます。 使用してはいけない文字があっても 他に保存する方法ありますか ? 例えば、 事前にダメ文字を書き換えて保存するとか ? EXCELの仕様で難しいのであれば諦めます。
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
> コードにある \temp\FName.txt 相当のファイルを削除したいので > 以下のURLを参考にしましたが > 書き込み禁止となって上手くいきませんでした。 開いているので削除(DeleteFile)も移動(Move)もできませんから ActiveWorkbook.SaveAs のあとにすぐ ActiveWorkbook.Close とするか なにか操作をするのでしたら操作の後に Workbooks(FName & ".txt").Close で閉じてみてください。
その他の回答 (9)
- kkkkkm
- ベストアンサー率66% (1742/2617)
> 考え方を分かりやすく解説されているURLなどを 分かりやすいかどうかは分かりませんが シートのコピーに関して簡素にまとめられています。 コピーの後にどこがアクティブになるのかの説明もあります。 VBA シートをコピーする https://www.tipsfound.com/vba/10004
お礼
kkkkkmさん、サンプルマクロで どんな状況になるか視覚的に理解できたので たいへん勉強になりました。 (個人的に視野が広くなる案件です。) https://imgur.com/sqcMXu2 >エクセルの画面をフル画面で見ていると分からないかもしれませんから、 >エクセルをモニタより小さくして確認してください) 今回もエクセル画面を大きく表示していたので 全く気が付いていませんでした。 VBAの画面で 左側のVBAProjectをチェックしていれば BOOKが追加で作成されているのを確認できたはずですが 全くスルーしてマクロコードの画面しか見ていませんでした。 教えてもらった「VBA シートをコピーする」を参考に もう少し調べてみます。 ----------------- 今回も大変参考になりました。 改めて、協力に感謝いたします。
- kkkkkm
- ベストアンサー率66% (1742/2617)
No8の補足です。 Testを実行した後でBook1を選択するとActiveWorkbookはBook1になります。
- kkkkkm
- ベストアンサー率66% (1742/2617)
> (Ws2.CopyでActiveWorkBookが > ThisWorkBookでは無くなって > 処理対象が移行されるような認識ですか ?) はい 新しいブックを1個だけ開いて Sub Test() MsgBox "This = " & ThisWorkbook.Name & vbCrLf & "Active = " & ActiveWorkbook.Name Sheets("Sheet1").Copy MsgBox "This = " & ThisWorkbook.Name & vbCrLf & "Active = " & ActiveWorkbook.Name End Sub を実行してみてください。 Sheet1のコピーが新しいブックとして出来上がります。(今回の質問でしたらWs2のシートのコピーが新しいブックとして出来上がる) マクロのある方がBook1で新規がBook2です。実行するたびに新規はBook2はBook3,Book4・・・と変化していきます。 (エクセルの画面をフル画面で見ていると分からないかもしれませんから、エクセルをモニタより小さくして確認してください) MsgBoxの結果でActiveWorkbookが移行したのがわかると思います。
- kkkkkm
- ベストアンサー率66% (1742/2617)
> ws2.copyを現在のコードの最初に追加すると > 先の添付画像(10:24)のような状態になることなく > 正常に終了して削除すべきファイルも削除されました。 過去にWs2.Copyについては 2021/09/18 11:08 回答No.4 にて 質問では Ws2.Copy ActiveWorkbook.SaveAs ですので、以下略 と、ふれてます。
お礼
kkkkkmさんは、 Ws2.Copyが存在するものとしてのアドバイスされていて 初心者の(無知な)私は、それを認識していないことが ボタンのかけ違いの大きなミスを招く結果になりました。 長々と説明がされているのに 理解が追いつかずすいません。 kkkkkmさんは、 >Ws2.Copy >がありコピーしたシート(Ws2はシートだと思います)でできた >新規ブックがActiveな状態の時に保存(ActiveWorkbook.SaveAs )しているわけではないのですか >でなければActiveWorkbookはThisWorkbookと同じになると思います。 とコメントされています。 私の認識では、 ThisWorkBookは、 現在マクロを実行しているワークブック ActiveWorkBookは、 複数のブックを処理対象にしている場合に 現在、操作対象としているワークブック との認識でした。 以下は今回の質問で 素人の勝手な想像(認識)ですが 意見をお聞かせください。 今開いているEXCELファイルは一つで 処理するブックも一つなので ThisWorkBook=ActiveWorkBook と思っていたのですが、 Ws2.Copyがあると 処理するブックが違う ThisWorkBook=ActiveWorkBook の関係が崩れる。 (Ws2.CopyでActiveWorkBookが ThisWorkBookでは無くなって 処理対象が移行されるような認識ですか ?) ----------------------------------- 素人の私には理解不足が甚だしいのですが、 考え方を分かりやすく解説されているURLなどを ご存じなら紹介ください。
- kkkkkm
- ベストアンサー率66% (1742/2617)
質問に Ws2.Copy がありコピーしたシート(Ws2はシートだと思います)でできた新規ブックがActiveな状態の時に保存(ActiveWorkbook.SaveAs )しているわけではないのですか でなければActiveWorkbookはThisWorkbookと同じになると思います。
お礼
kkkkkmさん、 やっと先の添付画像(10:24)のような状態になる原因がわかりました。 最初の質問では、下記のコードでした。 ------------------------- 'テキストデータにしたいシートを新しいブックとして作成し、そちらからテキストファイルを作成する Ws2.Copy ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText ---------------------------- で現在のコードは、教えてもらった下記のコードです。 --------------------------------------------------- 'FNameをTEXTで書き出した後で 1階層下(TurgetFolder)へもコピー Set fso = CreateObject("Scripting.FileSystemObject") ActiveWorkbook.SaveAs Filename:="C:\Users\Nubo\Downloads\temp\" & FName & ".txt", FileFormat:=xlText <-- マーク ActiveWorkbook.Close Call fso.copyFile("C:\Users\Nubo\Downloads\temp\" & FName & ".txt", TurgetFolder) Kill "C:\Users\Nubo\Downloads\temp\" & FName & ".txt" Set fso = Nothing --------------------------------------------------- つまり、 Ws2.Copy は 削除していました。 (------ と ---------- の間に囲まれたコードを 単純に入れ替えていました。) ws2.copyを現在のコードの最初に追加すると 先の添付画像(10:24)のような状態になることなく 正常に終了して削除すべきファイルも削除されました。
- kkkkkm
- ベストアンサー率66% (1742/2617)
> TurgetFolderには、過去に教えてもらった下記のコードで > C:\Users\Nobu\Downloads\temp\ が代入されていますが でしたら > フォルダー名に > [ ] (左カッコ、 右カッコ) > を利用した事でした。 は無いと思いますが…。申し訳ないですが、理解が及びません。 > ActiveWorkbook.Closeの為だと思うのですが 質問では Ws2.Copy ActiveWorkbook.SaveAs ですので、SaveAsの後に他のブックをActiveにしない限り(SaveAsの後にActiveWorkbook.Closeを即実行など)シートコピーされた新規ブックが閉じるだけだと思います。 また ActiveWorkbookを閉じられない場合 fso.copyFile か ActiveWorkbookを閉じられた後 fso.moveFile どちらかでいいと思います。
お礼
チェックが不足ですいません。 TurgetFolderには C:\Users\Nobu\Downloads\temp\ ではなく 1階層したの C:\Users\Nubo\Downloads\temp\The One [Full]¥ でした。 >ActiveWorkbookを閉じられた後 >fso.moveFile 上記コードは削除して >ActiveWorkbookを閉じられない場合 > fso.copyFile 上記コードのみ残したら 先の添付画像(10:24)のような状態には成らなくなりました。 (正常に終了します。) 反対に 私の検証不足や他のコードの影響があるのかもしれませんが copyを削除してmoveを残すコードでは先の添付画像のようになるようです 一応やりたいことはcopyの方を残すで出来ましたので万々歳です。) 又しばらく、解決にはしないので 何かコメントあればお願いします。 ------------------------- 追伸 --------------------- コードにある \temp\FName.txt 相当のファイルを削除したいので 以下のURLを参考にしましたが 書き込み禁止となって上手くいきませんでした。 https://www.tipsfound.com/vba/18006 https://hosopro.blogspot.com/2017/06/excel-vba-file-delete.html 善後策ですがEXCELを終了して手動でファイルを削除するようにしました。 ファイルの削除は、 今回の相談内容とは違う内容になるので 削除できない件については、Pending扱いとさせて下さい。 以下現在のコードです。 ----------------------- 'FNameをTEXTで書き出す > 1階層下(TurgetFolder)へコピー Set fso = CreateObject("Scripting.FileSystemObject") ActiveWorkbook.SaveAs Filename:="C:\Users\Nubo\Downloads\temp\" & FName & ".txt", FileFormat:=xlText Call fso.copyFile("C:\Users\Nubo\Downloads\temp\" & FName & ".txt", TurgetFolder) Set fso = Nothing
- kkkkkm
- ベストアンサー率66% (1742/2617)
> setの後で、 > ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText > で保存=作成 ?を行うとダメ文字が存在してもエラーが出ないとの事でしょうか ? いえ、それでは駄目なので No2の ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText は ActiveWorkbook.SaveAs Filename:="C:\temp\" & FName & ".txt", FileFormat:=xlText でした なのです。No1で変更する前のコードをコピペしてたのでNo2で訂正しました。 一旦tempフォルダに保存してTurgetFolderにコピー(移動)するというコードです。
お礼
回答ありがとうございます。 ActiveWorkbook.SaveAs Filename:= で TurgetFolderでは無く"C:\Users\Nobu\Downloads\temp\”とすればエラー無く処理できました。 実際は、 TurgetFolderには、過去に教えてもらった下記のコードで C:\Users\Nobu\Downloads\temp\ が代入されていますが 変数(TurgetFolder)では無く、ちゃんと「C:\Users\Nobu\Downloads\temp\」と明示して コードに記入しないといけないのですね。 ------------------------------------------------------------- 'フォルダーを一覧から選択 (自由に選べること) With Application.FileDialog(msoFileDialogFolderPicker) If .Show = True Then If Len(.SelectedItems(1)) = 3 Then ' c:\の場合とサブフォルダーの場合 TurgetFolder = .SelectedItems(1) Else TurgetFolder = .SelectedItems(1) & "\" End If End If End With -------------------------------------------------------------- 処理事体は下記コードで上手く出来たのですが、 ActiveWorkbook.Closeの為だと思うのですが 起動していたエクセル(.xlsm)がCTR画面から消えて (添付画像参照ください。) https://imgur.com/WnfY4RD C:\Users\Nobu\Downloads\temp\ に 新しく今まで起動していたエクセル(.xlsm)が作成(コピー?)されていました。 CTRから消えた時点で、一瞬何が起こったのか焦りました。 これを精神安定上良い方向に出来ないのでしょうか? (具体的には、どんなのが良いのかはアイデアはありません。) -------------------------------------------------------------- 'テキストデータにしたいシートを新しいブックとして作成し、そちらからTEXTを作成する Set fso = CreateObject("Scripting.FileSystemObject") ActiveWorkbook.SaveAs Filename:="C:\Users\Nobu\Downloads\temp\" & FName & ".txt", FileFormat:=xlText Call fso.copyFile("C:\Users\Nobu\Downloads\temp\" & FName & ".txt", TurgetFolder) ActiveWorkbook.Close Call fso.moveFile("C:\Users\Nobu\Downloads\temp\" & FName & ".txt", TurgetFolder) Set fso = Nothing --------------------------------------------------------------
- kkkkkm
- ベストアンサー率66% (1742/2617)
ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText は ActiveWorkbook.SaveAs Filename:="C:\temp\" & FName & ".txt", FileFormat:=xlText でした あと、ActiveWorkbookを閉じた後でしたらMoveが使えます。 ActiveWorkbook.SaveAs Filename:="C:\temp\" & FName & ".txt", FileFormat:=xlText ActiveWorkbook.Close Call fso.moveFile("C:\temp\" & FName & ".txt", TurgetFolder)
補足
kkkkkmさん、回答感謝します。 教えてもらったコードがどんな事をするのか ? 調べてみました。 >CreateObject("Scripting.FileSystemObject") VBAでファイルやフォルダを操作する(作成、削除、移動、コピー等)ときには、 「FileSystemObject」というオブジェクトを使用しないといけない。 では、Excel上に存在しない外部オブジェクト「FileSystemObject」を 使用するのにCreateObject 関数を使用する。 setで変数「FSO」をFileSystemObjectとして使うことが出来るようにする setの後で、 ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText で保存=作成 ?を行うとダメ文字が存在してもエラーが出ないとの事でしょうか ? で次の.copyFile( の存在意味も理解が出来ません。 どういう原理で処理できるのか、 解説願えれば嬉しいです。 ------------------------------------------- Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText Call fso.copyFile("C:\temp\" & FName & ".txt", TurgetFolder) Set FSO = Nothing ------------------------------------ ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText は ActiveWorkbook.SaveAs Filename:="C:\temp\" & FName & ".txt", FileFormat:=xlText でした あと、ActiveWorkbookを閉じた後でしたらMoveが使えます。 ActiveWorkbook.SaveAs Filename:="C:\temp\" & FName & ".txt", FileFormat:=xlText ActiveWorkbook.Close Call fso.moveFile("C:\temp\" & FName & ".txt", TurgetFolder)
- kkkkkm
- ベストアンサー率66% (1742/2617)
一旦tempフォルダに保存して Scripting.FileSystemObject 利用でコピーすればいかがでしょう Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") ActiveWorkbook.SaveAs Filename:=TurgetFolder & FName & ".txt", FileFormat:=xlText Call fso.copyFile("C:\temp\" & FName & ".txt", TurgetFolder)
補足
削除問題にも回答いただき感謝します。 >ActiveWorkbook.SaveAs >のあとにすぐ >ActiveWorkbook.Close >とするか とコメントを頂いたので、下記のようなコードにしました。 ---------------------------------------------------- STOP 'FNameをTEXTで書き出した後で 1階層下(TurgetFolder)へもコピー Set fso = CreateObject("Scripting.FileSystemObject") ActiveWorkbook.SaveAs Filename:="C:\Users\Nubo\Downloads\temp\" & FName & ".txt", FileFormat:=xlText <-- マーク ActiveWorkbook.Close Call fso.copyFile("C:\Users\Nubo\Downloads\temp\" & FName & ".txt", TurgetFolder) Kill "C:\Users\Nubo\Downloads\temp\" & FName & ".txt" Set fso = Nothing End Sub --------------------------------------------------- STOP まで処理が進み、停止後に F8でステップインで1行ずつトレースしていきました。 コード中の <-- マーク まで進んだ時点で 添付画像の選択画像が出た後で保存、 保存しないのいずれを選択(クリック)しても 直後に先の添付画像(10:24)のような状態に至ります。 添付画像(選択) https://imgur.com/MGsOHPB この時点でVBAの画面には何も表示されていないので トレースも何も出来なくなり、 エクセル画面の右上のXで閉じるしか選択肢が無くなります。 やはり、ActiveWorkbook.Close を記載すると上手くいきません。 又、コメントの解釈に誤りがありますか ?