エクセルマクロでcsvファイルをまとめる方法

このQ&Aのポイント
  • エクセルマクロを使用して、「csv」フォルダ内の複数のcsvファイルの一部のデータをまとめる方法を紹介します。
  • エクセルマクロを実行すると、csvファイルを順番に開き、指定したセルのデータを「まとめ」ファイルに貼り付けます。
  • csvファイルを処理し終わるまで、繰り返し処理を行います。アレンジは可能ですが、この方法はシンプルで効率的です。
回答を見る
  • ベストアンサー

このようなエクセルマクロを組みたいのですが...

下記のようなマクロを組みたいと思っていますが、 知見がほとんどないので教えていただきたいと思います。 "csv"というフォルダにランダムなファイル名でcsv形式のファイルが100以上保存されています。 目的は、 そのcsvファイル内の一部のデータをひとつのファイル(ファイル名を"まとめ"とします)に移して並べたいと思います。 <前提> "csv"フォルダと"まとめ"ファイルは既に開かれている状態とします。 "まとめ"ファイルを開いた状態で、マクロを走らせると、 (1)csvファイルが開く (2)セルA1とB1をコピー (3)"まとめ"ファイルのA1、A2へ貼り付け(行と列を変更) (4)csvファイルを閉じる (5)次のcsvファイルが開く (6)セルA1とB1をコピー (7)"まとめ"ファイルのB1、B2へ貼り付け(行と列を変更) (8)csvファイルを閉じる 以降、"csv"フォルダの中身をすべて処理できるまで繰り返し。 という風に考えていますが、 当方あまり知識が無くアレンジが難しいためできる限りシンプルにと考えています。 そのため、もしこうした方が...等あればアドバイスいただけるとありがたいです。 すみませんがよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.6

大変申し訳ございません。 私、チェック用のデータの作成を間違えていました。 Sub Sample() Dim bk As Workbook, sh As Worksheet, ts As Worksheet Dim a As Variant, b As Variant, i As Integer, c As Long Dim f As String, p As String Set ts = ThisWorkbook.ActiveSheet a = Array(1, 19, 24, 29) b = Array("B1", "B18", "B23", "F23", "B27", "F27", "C36", "C900") p = "D:\Programing\Test_01" f = Dir(p & "\*.csv") c = 0 Application.ScreenUpdating = False Application.DisplayAlerts = False Do Until f = "" Set bk = Workbooks.Open(p & "\" & f) Set sh = bk.ActiveSheet c = c + 1 For i = 0 To 3 sh.Range(b(i * 2) & ":" & b(i * 2 + 1)).Copy If i = 1 Or i = 2 Then ts.Range(ts.Cells(a(i), c), ts.Cells(a(i), c)).PasteSpecial Paste:=xlPasteValues, Transpose:=True Else ts.Range(ts.Cells(a(i), c), ts.Cells(a(i), c)).PasteSpecial Paste:=xlPasteValues, Transpose:=False End If Next i bk.Close Set sh = Nothing Set bk = Nothing f = Dir() Loop Application.DisplayAlerts = True Application.ScreenUpdating = True End Sub おっしゃるとおり、縦横の値の書き込みが間違っていました。 今回は、「Copy・Paste」を使って、縦横も正確に処理していると思うのですが・・・ 申し訳ないのですが、今一度、ご確認ください。

yomi0952
質問者

お礼

目的通りの動作を確認できました。 最後までやり取りしていただき本当に感謝です。 この手の知識がある方は尊敬しますね。 私は生産技術をやってますが回答者様のような能力があれば仕事の効率が格段に上がると思います。 今回のをベースに色々勉強していきます。 ありがとうございました。

その他の回答 (5)

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.5

今一度、データを作成して、確認したのですが、 元B1~B18をコピー まとめ先A1~A18へ入力 元B23~F23をコピー まとめ先A19~A23へ入力 元B27~F27をコピー まとめ先A24~A28へ入力 元C36~C900をコピー まとめ先A29~A893へ入力 という前提条件が合っていれば、間違いなく動いています。 「B1~B18」→「A1~A18」など、合っていますか?

yomi0952
質問者

補足

度々すみません。 元B1~B18をコピー まとめ先A1~A18へ入力 これはok 元B23~F23をコピー まとめ先A19~A23へ入力 これはng B23のみの値がすべて入っています。 元B27~F27をコピー まとめ先A24~A28へ入力 これはng B27のみの値がすべて入っています。 元C36~C900をコピー まとめ先A29~A893へ入力 これはok 行方向のコピーから列方向へ並べて貼り付け、がうまくいってないのでしょうか。 マクロはそのままコピーしており指定するフォルダ名しか変更してないです。 状況の方伝わりますでしょうか。 すみませんがよろしくお願い致します。

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.4

遅くなり、申し訳ございません。 一応、動作確認はしたつもりなのですが、問題があれば言ってください。 今回は、「csv」ファイルを、テキストファイルとして読み込むのではなく、いったん、エクセルのファイルとして開いて、そこから指定の範囲の値を、マクロを走らせているブックに書き込んでいます。 ★★★8行目を質問者の環境に合わせてから、実行してください★★★ Sub Sample() Dim bk As Workbook, sh As Worksheet, ts As Worksheet Dim a As Variant, b As Variant, i As Integer, c As Long Dim f As String, p As String Set ts = ThisWorkbook.ActiveSheet a = Array(1, 18, 19, 23, 24, 28, 29, 893) b = Array("B1", "B18", "B23", "F23", "B27", "F27", "C36", "C900") p = "D:\Programing\csv_01\csv" f = Dir(p & "\*.csv") c = 0 Application.ScreenUpdating = False Do Until f = "" Set bk = Workbooks.Open(p & "\" & f) Set sh = bk.ActiveSheet c = c + 1 For i = 0 To 3 ts.Range(ts.Cells(a(i * 2), c), ts.Cells(a(i * 2 + 1), c)).Value = _ sh.Range(b(i * 2) & ":" & b(i * 2 + 1)).Value Next i bk.Close Set sh = Nothing Set bk = Nothing f = Dir() Loop Application.ScreenUpdating = True End Sub 一応、簡単な説明をしておきます。 Set ts = ThisWorkbook.ActiveSheet 「ThisWorkbook」は、マクロを走らせているブックで、「ActiveSheet」は、前面に出ている、処理対象になっているシートのことです。 a = Array(1, 18, 19, 23, 24, 28, 29, 893) b = Array("B1", "B18", "B23", "F23", "B27", "F27", "C36", "C900") 指定の範囲を、配列変数に格納しています。 たとえば、「b(0) = "B1"」、「b(1) = "B18"」、・・・「b(7) = "C900」としています。 p = "D:\Programing\csv_01\csv" 「csv」ファイル群が存在するフォルダです。 f = Dir(p & "\*.csv") そのフォルダ内の「csv」ファイルを読み込んでいます。 c = 0 実際に書き込む、列カウント用変数の初期化。 Application.ScreenUpdating = False ファイルを開いたり閉じたりすると、画面がチカチカするのと、時間もかかるので、「画面の更新を停止」しています。 Do Until f = "" そのフォルダ内の「csv」ファイルが処理し終わるまで繰り返し。 Set bk = Workbooks.Open(p & "\" & f) 「csv」ファイルを開いています。 Set sh = bk.ActiveSheet そのファイルのアクティブシートを「sh」にセットしています。 これで、「sh.Range("A1").Value」などと記述すれば、「開いたブックのアクティブシートのセルA1の値」と記述しているのと同じで、今現在、どのブックやシートがアクティブになっているか気にする必要がありません。 c = c + 1 1列カウント。 For i = 0 To 3 全部で処理する範囲が4組ありますので、4回繰り返します。 ts.Range(ts.Cells(a(i * 2), c), ts.Cells(a(i * 2 + 1), c)).Value = _ sh.Range(b(i * 2) & ":" & b(i * 2 + 1)).Value これで、1行です。 「i * 2」は、「i」が「0」のときは、「0、2、4、6」と変化します。 したがって、「i * 2 + 1」は、「1、3、5、7」です。 これは、「a = Array(1, 18, 19, 23, 24, 28, 29, 893)」に対応していて、「a(0) = 1」、「a(1) = 18」が1組、「a(2) = 19」、「a(3) = 23」が1組、「a(4) = 24」、「a(5) = 28」が1組、「a(6) = 29」、「a(7) = 893」が1組です。 またその下も「b(0) = "B1"」、「b(1) = "B18"」が1組で、「a(0)」、「a(1)」の組に対応しています。 これで、開いた「csv」ファイルは、セルの位置を固定で読み込んで、マクロを走らせているブックには、ファイルを開くごとに、横へ横へと書き足してゆきます。 Next i を、4組実行しています。 bk.Close Set sh = Nothing Set bk = Nothing ファイルを閉じています。 f = Dir() ファイルを内容を更新しています。 Loop を、「csv」ファイルがなくなるまで、繰り返します。 Application.ScreenUpdating = True 「画面の更新」を再開しています。

yomi0952
質問者

補足

ご丁寧に回答いただきありがとうございます。 動作の方確認しました。 一部のみデータがおかしい箇所がありますので確認していただけますでしょうか。度々申し訳ありません。 データコピー後ファイルのA列のみ捉えて言うと、 A19~A23とA24~A28の部分において、 同じ数字が並ぶようになってしまっています。 A19には元のB23の数字が入っており間違いはないですが、続いてのA20~A23にもB23の値が入っているようです。(ほんとはC23~F23の値が入ってほしい) A24~A28でも同じ症状です。 その他は問題無さそうです。 すみませんがよろしくお願い致します。

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.3

こういうことでしょうか? 6行目の「p = "D:\Programing\Test_01\"」は、今は、私の環境ですので、質問者の環境に合わせてから、実行してください。 なお、「"csv"フォルダ」を開いておく必要はありません。 最後に、簡単な説明をしますので、読んで、質問者の使いやすいように変更してください。 Sub Sample() Dim n() As String, f As String Dim m As Long, p As String Dim i As Long, j As Long Dim x As String, a As Variant p = "D:\Programing\Test_01\" f = Dir(p & "*.csv") m = -1 Do Until f = "" m = m + 1 ReDim Preserve n(m) n(m) = p & f f = Dir() Loop For i = 0 To m - 1 For j = i + 1 To m If n(i) > n(j) Then x = n(i) n(i) = n(j) n(j) = x End If Next j Next i For i = 0 To m Open n(i) For Input As #1 Line Input #1, x a = Split(x, ",") Close #1 Cells(1, i + 1).Value = a(0) Cells(2, i + 1).Value = a(1) Next i End Sub 簡単な説明です。 p = "D:\Programing\Test_01\" 「csv」ファイル群が存在するフォルダを「p」に入れていますが、最後に「\」を忘れないでください。 f = Dir(p & "*.csv") そのフォルダ内のすべての「csv」ファイルが「f」に入りました。 m = -1 「csv」ファイルの個数をカウントする変数の初期化。 Do Until f = "" すべての「csv」ファイルを1つずつ処理。 m = m + 1 1個カウント(最初は「0」になります)。 ReDim Preserve n(m) 配列変数を用意。 n(m) = p & f 配列変数にフォルダとファイル名を格納しています。 f = Dir() Loop を、すべての「csv」ファイルで繰り返しています。 For i = 0 To m - 1 For j = i + 1 To m If n(i) > n(j) Then x = n(i) n(i) = n(j) n(j) = x End If Next j Next i 念のため、ファイル名をソートしています。 For i = 0 To m ソートされた結果の順番で読み込みます。 Open n(i) For Input As #1 ファイルを、「読み込み専用」で開いています。 Line Input #1, x 1行読み込んで、「x」に入れています。 a = Split(x, ",") 「Split()」というのは、区切り記号(今回はもちろん、「,」(カンマ)が区切り記号です)を使って配列変数に格納します。 たとえば、読み込んだ1行が、「a,b,c」の場合、「a(0) = "a"」、「a(1) = "b"」、「a(2) = "c"」となります。 この「a(0)」が、エクセルで言う「A1」に当たり、「a(1)」が「B1」に当たります。 Close #1 閉じています。 Cells(1, i + 1).Value = a(0) Cells(2, i + 1).Value = a(1) セルに書き込んでいます。 もちろん、ファイルを読み込むごとに、右へ右へと書き込んでいます。 Next i を、すべての「csv」ファイルで繰り返しています。

yomi0952
質問者

補足

ご回答ありがとうございました。 データ取り込みのところでアレンジしようかと試みましたが理解不足で本当に申し訳ありません。詳細を書かせていただきますのでもう少しご教示いただけますでしょうか。 元B1~B18をコピー まとめ先A1~A18へ入力 元B23~F23をコピー まとめ先A19~A23へ入力 元B27~F27をコピー まとめ先A24~A28へ入力 元C36~C900をコピー まとめ先A29~A893へ入力 その後、まとま先はB列、C列と並んでいくといった感じです。

回答No.2

>"csv"フォルダと"まとめ"ファイルは既に開かれている状態とします。 既に「"csv"フォルダを開いている」というのは、どういった状態でしょうか

yomi0952
質問者

補足

分かりにくくて申し訳ありません。 "csv"フォルダは予めダブルクリックして開かれており、タスクバーに存在(表示)している状態という説明で分かりますでしょうか。 マクロで指定するよりそちらの方がシンプルになるかと思いましたのでそのような前提で考えました。よろしくお願い致します。

  • watabe007
  • ベストアンサー率62% (476/760)
回答No.1

Sub Test()   Dim objFSO As Object, objCsv As Object   Dim v As Variant, col As Long   Set objFSO = CreateObject("Scripting.FileSystemObject")   For Each objCsv In objFSO.GetFolder("F:\csv").Files 'ホルダーのパスを明記     If objCsv.Name <> "まとめ.csv" Then 'まとめ.csvファイルは除外処理       With objFSO.OpenTextFile(objCsv)         v = Split(.ReadLine, ",")         .Close       End With       col = col + 1       'まとめ.csvファイルがアクティブな状態       ActiveSheet.Cells(1, col).Value = v(0)       ActiveSheet.Cells(2, col).Value = v(1)     End If   Next End Sub

yomi0952
質問者

お礼

今回は別の方の回答より試させていただきましたが、自身の勉強のためこのマクロも動作を確認してみます。ご回答ありがとうございました。

関連するQ&A

  • エクセルのマクロ

    素人なのですみませんが教えてください エクセルのマクロを使用して エクセルを起動して ウィンドウズ内のあるフォルダ内のエクセルファイルをコピーをして違うフォルダに貼り付けをしたいのですが、どのようにマクロを組み込むのか教えてください(マクロの式) (例)エクセル起動後エクセルのマクロにて c\Aフォルダ\aファイル←コピー c\Bフォルダ\aファイル←貼り付け

  • エクセル2010 繰り返しマクロ

    (1)g列の空白の最上行に =SUMPRODUCT(min((a:a>=f2)*(a:a<f2+730)*e:e)) と入力。 そのセルをコピーし、同じセルに値を上書き貼り付け ↓ (2)a列に(1)のセルの左隣のセル以下の数値がある行の、b列を削除 (画像の場合、(1)のセルがg1の場合、b2,b3を削除する) というのを、f列に数値がある行だけ繰り返すマクロの構文を教えてください。 大変お手数おかけいたしますが、どうぞよろしくお願いします。

  • エクセルマクロ 次のようなプログラム教えてください

    エクセルのマクロで、次のようなことをしたいと思っていますが、 素人でわかりません。 教えていただけますか。 ---------------------------------- o動かしているファイルをa.xlsとします。  a.xlsは、3行目からA列に名前、B列~D列にデータが入っていて、  各行ごとのファイルを作りたい。(行数は決まっていない)  なお、セルE1にある文字が入っている。 o各ファイルは、原紙としてgensi.xlsとして保存されているファイルに、  a.xlsのB~D列のものを入力したものを作りたい。  (B~D列のデータは、gensi.xlsのそれぞれセルC7・C8・C9に入力する)   gensi.xlsは、a.xlsと同じフォルダにあります。 o作成場所は、「C:\date」の中に、セルE1にある文字のフォルダ、A列に  ある名前のフォルダに作りたい。 (セルE1の文字のフォルダは、マクロを初めて実施するときは無いと思います  が、2回目からは存在すると思います。A列の名前のフォルダはマクロ実施時  にはありません。作成するファイル名は、A列の名前と同じ(フォルダ名と同じ).xls にします。) o実行ボタンを3つ作って、1つは今選択されている行のフォルダ・ファイルを作る。  2つ目は数字を入力させて、今選択されている行から入力した数字の行までを一括  で作成する。  3つ目は、3行目から現在入力されている行すべてを一括で作成する。 ------------------------------- 上記のことをしたいと思っています。 よろしくお願いします。 駄文ですみません。 なお、エクセルは古いバージョンでエクセル2000です。

  • エクセルのマクロについての質問です。

    ファイルA.xls __A__B__C 1_______1 2_______5 3_______7 4_______4 5_______5 6_______6 ファイルB.csv __A__B__C 1_1__5 2_5__6 3_7__7 ファイルC.csv __A__B__C 1_6__5 2_7__8 3_6__8 のような3つのファイルがあったとして ファイルA.xlsからマクロを実行して __A__B__C 1_1__5__1 2_5__6__5 3_7__7__7 4_6__5__4 5_7__8__5 6_6__8__6 ファイルB.csvをファイルA.xlsのA列とB列に ファイルC.csvをその下の最終行に貼り付けたいと思うのですが どのようにすればいいのでしょうか? 注意点としては、 (1)今は例として3行、3行の6行ですが、実際は1000行以上あり 毎回行数は変わります。 (2)ファイルA.xlsのC列には実際は関数が入っていて、 ファイルB.csvとファイルC.csvを張り付けた情報を計算して表示する ようになっています。

  • エクセルVBAでCSVを読み込んで別ファイルにまとめたいです。

    エクセルVBA初心者の者です。 マクロの記録でできたコードをいじって、 なんとか動くものができるレベルです。 Aというフォルダに20~40行程度の内容のCSVファイルが 数百個あります。開けてみないと何行あるのかわかりません。 そのAフォルダのCSVの内容をエクセルで開いて、別のエクセルファイルの一枚のシートにまとめたいのです。 最初にCSVファイル名を一枚のシートのA列に書き出すところ まではやれたのですが、それを順番に読み込んでコピペの 流れができません。 CSVファイル名読み込み 読み込んだファイル1つめCSV開く CSVの20~40行をコピー 別のエクセルファイルのシートに貼り付け 1つめCSV閉じる ↓ 読み込んだファイル2つめCSV開く 繰り返し こういうやり方じゃない方がいいのかもわかりません。 もしかして考え方も違うのでしょうか? サンプルコード教えていただけるとありがたいです。 よろしくお願いします。

  • EXCELのマクロがわかりません・・・

    現在、A列にデータが並んでいるのですが、 これを7つ区切り(例:A1~A7、A15~A21)にして、 別シートに用意した表に行列を入れ替えて、 貼り付けるマクロを作っているのですが、 なにぶんVBは素人ですので、よくわかりません。 今作ろうとしているマクロは、 「元データ」セルのA1からA7までをコピーして、 「作成データ」セルのB2を起点として、 コピーした内容の行列入れ替えを行い貼り付け、 以後、「元データ」のコピー範囲を7つづつ 下にずらし、「作成データ」の貼り付け起点を 1つづつ下にずらして、「元データ」のA列の 最後までくりかえすものです。 必ず「Range」文で引っかかってしまうのですが、 何か構文的におかしいでしょうか? かなり急ぎですので、 わかる方、よろしくお願いしますっ!! 下に、作成したマクロを貼り付けます。 Sub Macro3() ' ' Macro3 Macro ' マクロ記録日 : 2005/12/5 ユーザー名 : *** Worksheets("元データ").Activate 開始行 = -6 終了行 = 0 ペースト行 = 0 Do 開始行 = 開始行 + 7 終了行 = 終了行 + 7 ペースト行 = ペースト行 + 1 開始セル番号 = "A" & 開始行 終了セル番号 = "A" & 終了行 ペーストセル番号 = "B" & ペースト行 Range("開始セル番号:終了セル番号").Select Selection.Copy Sheets("作成データ").Select Range(ペーストセル番号).Select Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _ , Transpose:=True Loop End Sub

  • エクセル マクロ

    エクセル マクロで、シート1のA1セルないの文字列(数式)をクリックボードにコピーするマクロを組みたいのですが、セルのコピーは出来るのですが、文字列のみコピーが出来ません。貼り付けは任意でするので必要ないです。 初心者で何もわかりません。よろしくお願いします。

  • エクセル・マクロを利用しセルをコピー 貼り付け

    お世話になります。 エクセルを利用して下記の作業を行いたいのですが可能でしょうか。 条件:1つのフォルダ内に下記のエクセルファイルが2つ存在します。    (1)リスト表    (2)送付状 やりたいこと: (1)のリスト内容   A   B 1名前 電話番号 2山田 03-0000-0000 3佐藤 04-0000-0000 4工藤 05-0000-0000 リストにはマクロを組んでおきます(←ここを知りたいです) リストのマクロを作動させると フォルダ内にある送付状ファイルをコピーして新規エクセルファイルを作成します。 ファイル名はリストのB2にあります電話番号を名前として置き換えます。 次にリストにありますA2の名前をコピーし 送付状のB4へ貼り付け リストB2の電話番号をコピーし 送付状のC10へ貼り付け 保存 次に上記と同じ動作を継続的に行いますが 次のファイル名はB3の電話番号 名前のコピー先はA3に変更 貼り付け先は新規ファイルのB4 電話番号のコピー先はB3に変更 貼り付け先は新規ファイルのC10 保存 これをリストのA列が空欄になるまで繰り返します。 作業が完了した場合。「完了」表示し終了としたいです。 たとえ100名前のリスト表を作業にかけた場合 完了後はフォルダ内には(1)リスト表 (2)送付状 マクロで作成したファイル100個のエクセルが 存在することになります。 お手数をおかけいたします。 何卒宜しくお願いいたします。

  • エクセル マクロ 特定のフォルダ内 ファイルコピー

    エクセルのセルに入力されたフォルダを参照して、 CSVファイルを シート1・2・3・4に1度にコピーしたいのですが 例えば C\ドキュメント¥フォルダA |-フォルダB |-フォルダC                 |-フォルダD                 |-フォルダE                        |-フォルダ1                             |-CSVファイルA                         |-フォルダ2                             |-CSVファイルB                          |-フォルダ3                             |-CSVファイルC                         |-フォルダ4                              |-CSVファイルD 上記のアドレスで シート1のA1セルに フォルダEを入力し  シート2に CSVファイルA シート3に CSVファイルB シート4に CSVファイルC シート5に CSVファイルD それぞれすべての内容を貼り付けたいのですが 何分初心者なもので ご指導いただければと思います。  ちなみに A1セルの入力は変わるため各シートは1度削除した上で再度貼り付けを行いたいです。     

  • エクセルのマクロについての質問です。

    エクセルのマクロについての質問です。 長文申し訳ございません。 Excelマクロが何度作り直してもうまく作動せず非常に困っております。 (1)ファイルAのシート1のDB列3行目に1の値をいれます。 (2)ファイルAのDC列172行目の値をファイルBのシート名が「1」のシートのD列4行目に入れます。 (3)ファイルAのDC列2733行目の値をファイルBのシート名が「1」のシートのD列6行目に入れます。 (4)ファイルAのDC列3128行目の値をファイルBのシート名が「1」のシートのD列7行目に入れます。 (5)ファイルAのシート1のDB列3行目に1.2の値をいれます。 (6)ファイルAのDC列172行目の値をファイルBのシート名が「1.2」のシートのD列4行目に入れます。 (7)ファイルAのDC列2733行目の値をファイルBのシート名が「1.2」のシートのD列6行目に入れます。 (8)ファイルAのDC列3128行目の値をファイルBのシート名が「1.2」のシートのD列7行目に入れます。 (9)以上のようにファイルAのシート1のDB列3行目に入れる値を0.2ずつ増やしていき、その値に対応したファイルBのシートに上記のように値を入れていくという動作を20まで繰り返す。 以上のようなマクロを作る事は可能でしょうか? マクロについて勉強はしているのですが上手く使いこなせず苦労しております。 長文の質問で大変申し訳ございませんがよろしければ皆さまのお知恵をお貸しください。 宜しくお願い致します。

専門家に質問してみよう