- ベストアンサー
VBA初心者のためのCSVファイル読み込みとエクセル書き込み
- VBA初心者がフォルダを指定してCSVファイルを読み込み、一行ごとにエクセルファイルに書き込む方法について解説します。
- また、完成したエクセルファイルを印刷する方法や、フォルダ内のファイルがなくなるまで処理を繰り返す方法も紹介します。
- VBAのコードを使用して、CSVファイルの読み込みとエクセル書き込みを効率的に行う方法を学びましょう。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#2 DOUGLAS_ です。 ご質問文内にお示しの コード【A】は、【B】フォルダ内のファイル一覧の取得 http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_080.html と、【C】CSV形式テキストデータの読み込み(カンマ数不定版) http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_030.html をご参考にされたようですので、前回答を取消して、下記のように改めます。 2つの VBA を合併していらっしゃいますが、内容的には【B】の中に【C】を入れていますので、【B】の中の「Cells(GYO, 1).Value = strFILENAME」と「strFILENAME = Dir()」との間に【C】の コード を挿入することになりますね。 【A】【B】【C】を並べて比較してみますと、「定数・配列の宣言部」は別として、コーディング の順序に誤りが3ヶ所あることに気がつきます。 1つ目は、【C】の作業に入るところの先頭にある「intFF = FreeFile」が漏れ落ちていること、もう一つは、【B】の最後の「strFILENAME = Dir()」と「Loop」とが【C】の操作の途中に入ってしまっていること、最後の1つは、【C】の途中の「GYO = 1」が残ったままになっていますので、ファイル名 が変わるたびに「GYO」が初期化されてしまっていることです。 更に、strFILENAME について、【B】と【C】で共用していらっしゃいますが、【B】の strFILENAME は [GetOpenFilename メソッド] で取得された「D:\hoge\hoge.csv」というような フルパス 文字列であるのに対して、【A】【C】では [Dir 関数] で取得された「hoge.csv」というような ファイル名 だけの文字列になっています。 従って【A】の誤りは、 1)31行目の「strFILENAME = Dir()」の次に intFF = FreeFile を挿入 2)32行目の「Open strFILENAME For Input As #intFF」を Open strPATHNAME & "\" & strFILENAME For Input As #intFF に改める 3)33行目「GYO = 1」を削除 4)31行目の「strFILENAME = Dir()」と60行目の「Loop」とを61行目の「Close #intFF」の後ろに「Close #intFF」・「strFILENAME = Dir()」・「Loop」 の順序になるように移動 することによって改善されます。 ついでに、【A】を具に拝見いたしまして、いろいろと気にかかった点を列挙いたします。 1)9行目で宣言していらっしゃる「cnsFILTER」はどこにも出てきませんね。 コード をいろいろと弄り回した後には、定数・変数などにも一通り目を通して、不要なものは削除する習慣を付けられることをお薦めいたします。 2)Application オブジェクト を「xlAPP」・「xlAPP2」として2つの変数で宣言されていますが、「xlAPP」だけで構いません。 3)「strFILENAME = Dir(strPATHNAME & cnsDIR, vbNormal)」のところは、対象 strFILENAME が CSVファイル のみでしたら、 strFILENAME = Dir(strPATHNAME & "\*.CSV") とすることもできます。 4)「3.完成したエクセルファイルを印刷する。」につきましては、「End Sub」の前に ActiveWindow.SelectedSheets.PrintOut を挿入すればできます。 5)#1 さんがお示しの [Split 関数] の件に付きましては、「Dim POS1 As Long」を Dim POS As Variant とし、「Do Until EOF(intFF)」から2つ目の「Loop」までを下記のように改めれば可能となります。 Do Until EOF(intFF) lngREC = lngREC + 1 Line Input #intFF, strREC GYO = GYO + 1 POS = Split(strREC, ",") Cells(GYO, 1).Resize(, UBound(POS) + 1) = POS Loop
その他の回答 (3)
- mitarashi
- ベストアンサー率59% (574/965)
#1です DOUGLAS_さんの熱意に感服 CSVファイル名と、貼り付ける先頭セルを与えると、先頭セル以降の行内に、CSVファイル全体を貼り付ける関数を試しに作成してみました。改行コードはCRLFを前提としています。 こうやって、ループの外に出すと、すっきりして分かり易くなると思います。 なお、関数中のエラー処理はA列を先頭に貼り付ける事を前提としています。(^^;) Sub test() Call test2(ThisWorkbook.Path & "\Book1.csv", ActiveSheet.Range("A1")) End Sub Private Sub test2(filePath As String, destRange As Range) Dim FSO As Object, TextFile As Object Dim buf As String, buf2 As Variant Set FSO = CreateObject("Scripting.FileSystemObject") Set TextFile = FSO.OpenTextFile(filePath) buf = TextFile.ReadAll buf = Replace(buf, vbCrLf, ",") buf2 = Split(buf, ",") If UBound(buf2) > destRange.Parent.Columns.Count Then MsgBox ("データ数が多すぎます") Exit Sub End If destRange.Resize(1, UBound(buf2)) = buf2 Set TextFile = Nothing Set FSO = Nothing End Sub
- DOUGLAS_
- ベストアンサー率74% (397/534)
>3.完成したエクセルファイルを印刷する。 は別として、とりあえず、下記のようにして、お試しください。 1)29行目「GYO = GYO + 1」の後に intFF = intFF + 1 を挿入 2)31行目「strFILENAME = Dir()」を、59行目「Loop」と、60行目「Loop」との間に移動 3)33行目「GYO = 1」を削除
- mitarashi
- ベストアンサー率59% (574/965)
ざっと眺めてみましたが、随分難しくやっている気がします。 >2.読み込んだCSVファイルを一行あたり1ファイルのエクセルファイルに書き込む。 ここの意味が分かりにくいですね。 CSVファイル1個の内容をエクセルの一行に書き込み、指定フォルダに存在する全CSVファイルの内容を、エクセルの1シートにまとめる という事をやろうとしているのでしょうか? 素直に読むと、CSVファイルの一行毎にエクセルファイルを一つ作ると読めますが、一行ごと印刷してもしょうがなさそうですし... なお、CSVの一行を分解するのは、Split関数を用いると簡単です。 http://officetanaka.net/excel/vba/tips/tips62.htm