プロが教えるわが家の防犯対策術!

VBA初心者です。
ActiveWorkbookの各シートをCSVで保存し、
不要なCSVを削除するというマクロを作成しています。

ActiveWorkbookと同じ場所にフォルダを作成するまではできるのですが
その中にCSVファイルが作成されず、tempフォルダやDocumentフォルダに
作成されてしまう為、Kill~のところでファイルが見つからずエラーとなってしまいます。
※時々ActiveWorkbookフォルダの中にCSVが作成されることもあります。

パス名が長すぎるとエラーになることがあるとのことでしたので
ActiveWorkbookの場所を階層の浅い場所に置いた場合は成功しました。
しかし、ActiveWorkbookの場所は決まっていない為、
できればショートパスに変換したいのですがFSOというのが
いまいちわからず苦戦しています。

そもそもパスの長さが問題なのかも合わせて
解決策を頂けると助かります。
※ちなみにエラーが出るときのパスは150字前後程度です。

宜しくお願い致します。
現段階のマクロは以下です。
↓↓↓↓

Sub saveAsCSV()

Dim フォルダ名 As String
Dim パス名 As String
Dim ファイル名 As String
Dim データ As Variant
Dim 行数 As Long
Dim 列数 As Long
Dim i As Long
Dim j As Long
Dim k As Long
フォルダ名 = ActiveWorkbook.Name
フォルダ名 = Left(フォルダ名, Len(フォルダ名) - 5)
パス名 = ActiveWorkbook.Path & "\" & フォルダ名
If Dir(パス名, vbDirectory) = "" Then
MkDir パス名
End If
ChDir パス名
Application.ScreenUpdating = False
For i = 1 To Worksheets.Count
Worksheets(i).Activate
Range("A1").CurrentRegion.Select
行数 = Selection.Rows.Count
列数 = Selection.Columns.Count
ファイル名 = ActiveSheet.Name & ".csv"
Open ファイル名 For Output As #1
For j = 1 To 行数
For k = 1 To 列数 - 1
データ = Selection.Cells(j, k).Value
Print #1, データ; ",";
Next k
Print #1, Selection.Cells(j, 列数).Value
Next j
Close #1
Next i

Sheets("INPUT").Select
Application.ScreenUpdating = True
MsgBox ActiveWorkbook.Path & "\" & フォルダ名 & " フォルダーにCSVファイルを出力しました。"

Kill ActiveWorkbook.Path & "\" & フォルダ名 & "\" & "vvv.csv "
Kill ActiveWorkbook.Path & "\" & フォルダ名 & "\" & "www.csv "
Kill ActiveWorkbook.Path & "\" & フォルダ名 & "\" & "xxx.csv "
Kill ActiveWorkbook.Path & "\" & フォルダ名 & "\" & "yyy.csv "
Kill ActiveWorkbook.Path & "\" & フォルダ名 & "\" & "zzz.csv "

End Sub

質問者からの補足コメント

  • 早速のご回答ありがとうございます。

    上記のVBAはシート名以外、そのままボタンに組み込んでいるものです。

    「パス名 = ActiveWorkbook.Path & "\" & フォルダ名」
    で、開いているエクセルと同じ場所にフォルダを作り、
    その中をCSVの作成場所として指定しているつもりなのですが。

    ちなみに「ActiveWorkbook.Path」にカーソルを合わせると、
    エクセルのある場所のパスが表示されます。

    そうなんです、シートを指定してCSV保存をしたかったのですが、
    いろいろ検索やテストしてみたのですがうまくいかず、
    とりあえず、「一括作成+不要データ削除」の組み合わせが単純だと思い
    このようなものになっています。
    指定シートは決まっているので、「シートを指定する」指示が
    単純に数行追加するだけならば、Kill~を削除して使用したいです。

    No.2の回答に寄せられた補足コメントです。 補足日時:2019/12/11 11:12

A 回答 (5件)

> 「パス名 = ActiveWorkbook.Path & "\" & フォルダ名」


> で、開いているエクセルと同じ場所にフォルダを作り、
> その中をCSVの作成場所として指定しているつもりなのですが。
つもりではなく、デバッグでステップ実行していった時、問題なく求めたパスにフォルダおよびファイルが作成されているのでしょうか?
(最低でもvvv.csv, www.csv, xxx.csv, yyy.csv, zzz.csv が求めた位置に作成されるか?)

> 指定シートは決まっているので、「シートを指定する」指示が
> 単純に数行追加するだけならば、Kill~を削除して使用したいです。
単純に数行追加するだけだと思いますが、それを追加しないということは、
無駄な処理およびパフォーマンスの遅延、後から見た時に作ったくせに消してる意味がわからん、ということを理解した上での選択かと思います。
    • good
    • 0
この回答へのお礼

> デバッグでステップ実行していった時、問題なく求めたパスにフォルダおよびファイルが作成されているのでしょうか?
> (最低でもvvv.csv, www.csv, xxx.csv, yyy.csv, zzz.csv が求めた位置に作成されるか?)
フォルダは必ず指定した場所に作成されます。
CSVファイルの保存パスが問題のようでしたので調べたところ
ChDirはネットワークパスが無効とのことを知り、WSHで回避しました。

> 単純に数行追加するだけだと思いますが、それを追加しないということは、
> 無駄な処理およびパフォーマンスの遅延、後から見た時に作ったくせに消してる意味がわからん、ということを理解した上で> の選択かと思います。
まったくその通りです。本来は単純明解で無駄のないものが良いのですが、
現段階で求められている業務が、とりあえずアウトプットすることです。
「単純に数行」を検索してもなかなか思ったものが出てこなかったので
サンプルあるもの(一括保存+不要データの消去)の組み合わせで対処しました。
アウトプットの使用が目的である為、VBA初心者の私にとっては
このような選択となってしまいました。
このような業務を繰り返し行い、適切なマクロが作成できるよう頑張ります。
ありがとうございました。

お礼日時:2019/12/11 14:02

こんにちは、参考になるコードを示した方が良いか、アドバイスが良いか、、


ChDir パス名  これの意味は分かりますか?  たぶん、行いたい処理には不要かと思います。

Worksheets(i).Activate
Range("A1").CurrentRegion.Select
 行数 = Selection.Rows.Count
 列数 = Selection.Columns.Count

Select、Selectionは必要以外使わないようにした方が良いかと
Selectはシート上に残ります。

例えば、(同様の処理と対象オブジェクトを明確に)
Worksheets(i).Activate
  With ActiveSheet ’後でWithは閉じます
    行数 = .Range("A1").CurrentRegion.Rows.Count
    列数 = .Range("A1").CurrentRegion.Columns.Count

ファイル名 = ActiveSheet.Name & ".csv"
With ActiveSheetを使えば、下記で良いです
ファイル名 = .Name & ".csv"

Kill~ 怖いです。書いたものを削除するなんてYQAみたいです~。。
書き方は色々あるかと
Open の処理前で条件を設定
If ファイル名 = "vvv.csv" Or ・・・・
Else
Open ・・・

または、もっと前の
For i = 1 To Worksheets.Count の後で
If i = 3 Or i= ・・・・ Then GoTo スキップ先(Next i 行の上行)

とか、最後のシートインデックス5枚をCSV作成したくないなら、(以外にこれだったりして)
For i = 1 To Worksheets.Count -5 とかなら、ハウス的にはなりますが、IF要りませんね。

Open ファイル名 For Output As #1
ここに、問題が、、この問題が今回のポイントですね。極端に言うとこの問題が解決されれば、Killもエラー無く処理できると思いますし。

Open記述のファイル名 の部分はフルパスが必要です。(これテストに出ますよ^^)
これを見ると、ChDir パス名の理解とOpen ファイル名 の間違いがなんとなく結びつきますが。
ファイル名 の頭に¥が付いていない事も気にしてください。
パス名 & "\" & ファイル名

データ = Selection.Cells(j, k).Value Selectionは、With ActiveSheetなので  
データ = .Cells(j, k).Value  で良いかと、、下のコードのSelectionもすべて

Close #1
Next i 
の部分は、おそらく、、こんな行になれば、、いい感じではないでしょうか

    Close #1
   End If
  End With
 Next i

Kill~部分は要りません。
あと、エラー処理と n = FreeFile くらいかな

ほとんど書いてしまいましたが、参考になれば幸いです。
    • good
    • 0
この回答へのお礼

大変ご丁寧なご回答をいただきありがとうございます。

ActiveWorkbookがネットワークパスであるため
ChDirが無効とのことを知り、現段階ではWSHで回避しました。

今回は検索→貼付の作業でしたので、
もっと遠回しでないものを..ともどかしく思いましたが、
回答者様のような、ココはこれにした方がとのアドバイスをいただくと
非常に勉強になります!
一度上記のを参考に動かしてみたいと思います。
ありがとうございました。

お礼日時:2019/12/11 14:15

こんにちは



他の方も指摘なさっているように、ディレクトリがきちんと制御できているかの問題かと。
適当なポイントで、チェックを入れて調べ、絞り込んでいけば原因も特定できるのではないでしょうか?
さしあたり、ChDir パス名 のあたりで
 Debug.Print "[" & Dir(パス名, vbDirectory) & "]"
 Debug.Print "[" & パス名 & "]"
のようなことをしてみればいかがでしょう。
([]を附しているのは、確認しにくいスペースなどを見える化するためです)
デバッガーのウォッチ式を利用すれば、さらに様々なことが確認できるはずです。

なお、ご質問には関係ありませんが、これも他の方々が指摘なさっていることですが、「CSVファイルを書き出してから消去する」という手順自体が非効率的としか思えません。
不要なファイルはあらかじめ決まっている(vvv~zzz)ようですので、書き出し処理の前にチェックして、不要なシートに関してはスキップするようにしておけば済むものと思います。
Kill文を並べ立てるよりも、短くて済むのではないでしょうか?
まぁ、プログラムの長さの問題よりも、処理の効率のほうが大切だと思いますけれど・・・
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

ActiveWorkbookがネットワークパスであるため
ChDirが無効とのことを知り、現段階ではWSHで回避しました。

前回答者様への返信の通り、初心者である故の方法の選択です。
皆様がおっしゃる通り、非常に無駄なプログラムであることは理解しているのですが、
とりあえずアウトプットしたかったく、
検索しても思い通りのサンプルにたどり着かなかったので
よく引っかかるもので組み合わせました。
今回のことで非常に勉強になりましたので、
回数を重ね、無駄のないマクロが作成できるよう頑張ります。

ありがとうございました。

お礼日時:2019/12/11 14:21

> ActiveWorkbookと同じ場所にフォルダを作成するまではできるのですが


> その中にCSVファイルが作成されず、tempフォルダやDocumentフォルダに
> 作成されてしまう為、
では、CSVが作成されるパスに誤りがあるのではないでしょうか。
パスの長さが問題になるならば、作成するタイミングでエラーになるかと思います。

作ったのに消す、というのがそもそも理解できませんが。
不要ならそもそも作らなければいいのでは。

パスの長さ云々は確かに現象として存在しますが、現在直面している問題はそれとは別問題のようにしか聞こえません。
この回答への補足あり
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。

上記のVBAはシート名以外、そのままボタンに組み込んでいるものです。

「パス名 = ActiveWorkbook.Path & "\" & フォルダ名」
で、開いているエクセルと同じ場所にフォルダを作り、
その中をCSVの作成場所として指定しているつもりなのですが。

ちなみに「ActiveWorkbook.Path」にカーソルを合わせると、
エクセルのある場所のパスが表示されます。

そうなんです、シートを指定してCSV保存をしたかったのですが、
いろいろ検索やテストしてみたのですがうまくいかず、
とりあえず、「一括作成+不要データ削除」の組み合わせが単純だと思い
このようなものになっています。
指定シートは決まっているので、「シートを指定する」指示が
単純に数行追加するだけならば、Kill~を削除して使用したいです。

お礼日時:2019/12/11 11:13

パスにスペースがあるとか

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

早速のご回答ありがとうございます。

上記のVBAはシート名以外、そのままボタンに組み込んでいるものです。

「パス名 = ActiveWorkbook.Path & "\" & フォルダ名」
で、開いているエクセルと同じ場所にフォルダを作り、
その中をCSVの作成場所として指定しているつもりなのですが。

ちなみに「ActiveWorkbook.Path」にカーソルを合わせると、
エクセルのある場所のパスが表示されます。

お礼日時:2019/12/11 11:14

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


人気Q&Aランキング