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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

VBA

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

Q&A

解決済

3回答

6486閲覧

VBAのオートフィルターを使ってCSV出力を行いたい

sjsaijdi

総合スコア3

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

VBA

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

0グッド

1クリップ

投稿2020/11/18 06:13

編集2020/11/18 08:52

前提・実現したいこと

VBAを利用してExcelの値をCSVに出力するプログラムを作成しています。
オートフィルターを利用してB列の絞込を行いながら順番に出力していきたいです。

例えば下記のような表があったときは列2の情報(東京都・愛知県・大阪府)で絞込を順に行い、別々のCSVとしてその行の情報を出力したいと思っています。

列1列2列3列4列5
1東京都Aさん23歳
2愛知県Bさん53歳
3東京都Cさん29歳
4大阪府Dさん31歳
5愛知県Eさん48歳
6大阪府Fさん12歳

###実現イメージ

東京都.csv

列1列2列3列4列5
1東京都Aさん23歳
3東京都Cさん29歳

愛知県.csv

列1列2列3列4列5
2愛知県Bさん53歳
5愛知県Eさん48歳

大阪府.csv

列1列2列3列4列5
4大阪府Dさん31歳
6大阪府Fさん12歳

発生している問題・エラーメッセージ

実際にコードを書いて出力したところ、各県の名称のファイルが出力されたものの、セルの絞込がクリアできていないのか、

東京都⇒東京都のみのデータ(想定通り)
愛知県⇒東京都と愛知県のデータ(想定通りではない)
大阪府⇒東京都と愛知県と大阪府のデータ(想定通りではない)

上記のように出力されてしまいます。

セルのクリアがうまくいっていないか、検索で変数を入れるところがうまく実装できていないかと思うのですが、VBAは初心者でありよくわからなかったので、皆様のお力をお借りしたいと思っています。

よろしくお願いいたします。

該当のソースコード

VBA

1 2 Dim cmax 3 Dim csvFile As String 4 Dim i As Integer 5 6 SaveDir = ThisWorkbook.Path 7 8 'B列の最終行の数を取得 9 cmax = Worksheets("active").Range("B65536").End(xlUp).row 10 11 12 13 '最終行まで繰り返す 14 For i = 2 To cmax 15 16 Dim atai As String 17 'ataiにフィルターの絞込を行っている単語を入れる 18 If atai <> Worksheets("active").Range("B" & i).Value Then 19 atai = Worksheets("active").Range("B" & i).Value 20 End If 21 22 '「フィルターの絞込を行っている単語名.csv」の名称のファイルをカレントディレクトリに作成する 23 csvFile = SaveDir & "\" & atai & ".csv" 24 25 '高さをカウント 26 lngRowMax = Range("$A$" & Rows.Count).End(xlUp).row 27 28 29 '書き込みを行うファイルを開く 30 Open csvFile For Output As #1 31 32 'フィルターの絞込がされていたら解除する 33 If ActiveSheet.FilterMode = True Then 34 ActiveSheet.ShowAllData 35 End If 36 37 'ataiの単語でB列のフィルター動作させる 38 ActiveWorkbook.Worksheets("active").Range("A2:E" & cmax).AutoFilter Field:=2, Criteria1:=atai 39 40 Dim j As Long 41 For j = 1 To 5 42 '1行目の各列のタイトルを書き込む 43 Print #1, ActiveSheet.Cells(1, j).Value&; ","; 44 Next j 45 '改行 46 Print #1, vbCr; 47 48 Dim c As Long, k As Long 49 50 For c = 2 To lngRowMax 51 For j = 1 To 5 52 '絞り込んだデータを基にCSV書き込みを行う 53 Print #1, ActiveSheet.Cells(c, j).Value&; ","; 54 Next j 55 '改行 56 Print #1, ActiveSheet.Cells(c, j).Value & vbCr; 57 Next c 58 'ファイルを閉じる 59 Close #1 60 61 '次の行に行く 62 Next i 63 64 'フィルターの絞込を解除する(全件表示) 65 If ActiveSheet.FilterMode = True Then 66 ActiveSheet.ShowAllData 67 End If

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

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

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

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

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

guest

回答3

0

ベストアンサー

オートフィルターされたセルを扱うのは、いろいろと落とし穴がありそうですね。
http://officetanaka.net/excel/vba/tips/tips155.htm
を参考にすると、オートフィルターされている結果を他のシートにコピーするのが1番確実なようです。
作業用のシートとして"作業用"というシートを作成しておきます。
そちらにオートフィルターされている結果をコピーした後、"作業用"シートの内容をCSVに出力します。

VBA

1Public Sub CSV_WithAutoFilter1() 2 Dim maxrow As Long 3 Dim maxrow2 As Long 4 Dim wrow As Long 5 Dim ws As Worksheet 6 Dim ws2 As Worksheet 7 Dim dicT As Object 8 Dim key As Variant 9 Dim csvFile As String 10 Dim SaveDir As String 11 Dim cr As Range 12 Dim str As String 13 SaveDir = ThisWorkbook.Path 14 Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義 15 Set ws = Worksheets("active") 16 Set ws2 = Worksheets("作業用") 17 ws.AutoFilterMode = False 'オートフィルタ解除 18 maxrow = ws.Cells(Rows.Count, "A").End(xlUp).Row 19 '都道府県単位のキーを集計 20 For wrow = 2 To maxrow 21 key = ws.Cells(wrow, "B").Value 22 dicT(key) = True 23 Next 24 '全キー分繰り返す 25 For Each key In dicT.keys 26 '「フィルターの絞込を行っている単語名.csv」の名称のファイルをカレントディレクトリに作成する 27 csvFile = SaveDir & "\" & key & ".csv" 28 '書き込みを行うファイルを開く 29 Open csvFile For Output As #1 30 ws.AutoFilterMode = False 31 'オートフィルタ設定 32 ws.Range("A1").AutoFilter Field:=2, Criteria1:=key 33 ws2.Cells.ClearContents 34 ws.Range("A1").CurrentRegion.Copy ws2.Range("A1") 35 '表示されている全行を処理する 36 maxrow2 = ws2.Cells(Rows.Count, "A").End(xlUp).Row 37 For wrow = 1 To maxrow2 38 Dim j As Long 39 For j = 1 To 5 40 str = ws2.Cells(wrow, j).Value 41 If j <> 5 Then 42 Print #1, str; ","; 43 Else 44 Print #1, str; vbCrLf; 45 End If 46 Next 47 Next 48 Close #1 49 Next 50 ws.AutoFilterMode = False 51 MsgBox ("完了") 52End Sub 53

尚、作業用のシートは作りたくないということであれば、こちらの方法もあります。
たまたま、こちらでうまくいっただけで、他の環境で正しく動作するかどうかはわかりませんが、
参考までに。

VBA

1Public Sub CSV_WithAutoFilter2() 2 Dim maxrow As Long 3 Dim wrow As Long 4 Dim ws As Worksheet 5 Dim dicT As Object 6 Dim key As Variant 7 Dim csvFile As String 8 Dim SaveDir As String 9 Dim cr As Range 10 Dim str As String 11 SaveDir = ThisWorkbook.Path 12 Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義 13 Set ws = Worksheets("active") 14 ws.AutoFilterMode = False 'オートフィルタ解除 15 maxrow = ws.Cells(Rows.Count, "A").End(xlUp).Row 16 '都道府県単位のキーを集計 17 For wrow = 2 To maxrow 18 key = ws.Cells(wrow, "B").Value 19 dicT(key) = True 20 Next 21 '全キー分繰り返す 22 For Each key In dicT.keys 23 '「フィルターの絞込を行っている単語名.csv」の名称のファイルをカレントディレクトリに作成する 24 csvFile = SaveDir & "\" & key & ".csv" 25 '書き込みを行うファイルを開く 26 Open csvFile For Output As #1 27 ws.AutoFilterMode = False 28 'オートフィルタ設定 29 ws.Range("A1").AutoFilter Field:=2, Criteria1:=key 30 '表示されている全行を処理する 31 For Each cr In ws.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible) 32 wrow = cr.Row 33 Dim j As Long 34 For j = 1 To 5 35 str = ws.Cells(wrow, j).Value 36 If j <> 5 Then 37 Print #1, str; ","; 38 Else 39 Print #1, str; vbCrLf; 40 End If 41 Next 42 Next 43 Close #1 44 Next 45 ws.AutoFilterMode = False 46 MsgBox ("完了") 47End Sub

投稿2020/11/19 05:42

tatsu99

総合スコア5438

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

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

0

ExcelVBA

1Option Explicit 2 3Sub test() 4 Dim rngData As Range 5 Dim rngList As Range 6 Dim rngConditions As Range 7 Dim rngResult As Range 8 Dim c As Range 9 10 'セル範囲指定 11 With ThisWorkbook 12 Set rngData = .Worksheets(1).UsedRange 13 Set rngList = .Worksheets(2).Range("A1") 14 Set rngConditions = Worksheets(2).Range("C1:C2") 15 Set rngResult = .Worksheets(3).Range(rngData.Rows(1).Address) 16 End With 17 18 '準備 19 rngList.Worksheet.Cells.ClearContents 20 rngConditions(1).Value = rngData(2).Value 21 rngResult.Value = rngData.Rows(1).Value 22 23 '重複のない抽出項目のリスト作成 24 With rngData 25 Intersect(.Offset(1), .Columns("B")).Copy rngList 26 End With 27 rngList.CurrentRegion.RemoveDuplicates Columns:=1, Header:=xlNo 28 29 '項目毎に繰り返し 30 For Each c In rngList.CurrentRegion 31 '抽出条件設定 32 rngConditions(2).Value = c.Value 33 34 '抽出 35 rngData.AdvancedFilter _ 36 Action:=xlFilterCopy, _ 37 CriteriaRange:=rngConditions, _ 38 CopyToRange:=rngResult 39 40 'CSVで保存 41 rngResult.Worksheet.Copy 42 With Workbooks(Workbooks.Count) 43 .SaveAs Filename:=ThisWorkbook.Path & "\" & c.Value & ".csv", _ 44 FileFormat:=xlCSV 45 .Close SaveChanges:=False 46 End With 47 Next 48End Sub

1)フィルターオプションで抽出(別のシートに結果をコピーする機能が内包されている)
2)そのシートを新規ブックにコピー
3)CSV形式で保存

という流れではだめでしょうか?

投稿2020/11/18 10:34

mattuwan

総合スコア2136

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

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

0

絞込したい単語選定とオートフィルターしながらCSV作成の2ステップで処理する必要があります。
コードを見直してみましたので、参考にしてください。

VBA

1Sub hogeCSV() 2 Dim csvFile As String 3 Dim i As Integer, lngRowMax As Integer 4 5 Dim SaveDir As String 6 SaveDir = ThisWorkbook.Path 7 8 '最初に絞込したい単語を選定 9 Dim atai As Object 10 Set atai = CreateObject("Scripting.Dictionary") 11 12 For i = 2 To Worksheets("active").Range("B65536").End(xlUp).Row 13 If Not atai.Exists(Worksheets("active").Range("B" & i).Value) Then 14 atai.Add Worksheets("active").Range("B" & i).Value, 0 15 End If 16 Next i '次の行に行く 17 18 'オートフィルターしながらCSV作成 19 Dim v As Variant 20 For Each v In atai.Keys 21 '「フィルターの絞込を行っている単語名.csv」の名称のファイルをカレントディレクトリに作成する 22 csvFile = SaveDir & "\" & v & ".csv" 23 24 '書き込みを行うファイルを開く 25 Open csvFile For Output As #1 26 27 'フィルターの絞込がされていたら解除する 28 If Worksheets("active").FilterMode = True Then 29 Worksheets("active").ShowAllData 30 End If 31 32 '単語でB列のフィルター動作させる 33 Worksheets("active").Range("A1:E1").AutoFilter Field:=2, Criteria1:=v 34 35 '高さをカウント 36 lngRowMax = Worksheets("active").Range("B" & Rows.Count).End(xlUp).Row 37 38 Dim j As Long 39 For j = 1 To 5 40 '1行目の各列のタイトルを書き込む 41 Print #1, Worksheets("active").Cells(1, j).Value&; ","; 42 Next j 43 '改行 44 Print #1, vbCr; '改行コードは vbNewline がよいか。 45 46 Dim c As Long 47 For c = 2 To lngRowMax 48 For j = 1 To 5 49 '絞り込んだデータを基にCSV書き込みを行う 50 Print #1, Worksheets("active").Cells(c, j).Value&; ","; 51 Next j 52 '改行 53 Print #1, Worksheets("active").Cells(c, j).Value & vbCr; '改行コードは vbNewline がよいか。 54 Next c 55 'ファイルを閉じる 56 Close #1 57 Next v 58 59 'フィルターの絞込を解除する(全件表示) 60 If Worksheets("active").FilterMode = True Then 61 Worksheets("active").ShowAllData 62 End If 63End Sub

投稿2020/11/18 10:30

編集2020/11/18 11:38
TanakaHiroaki

総合スコア1063

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問