初心者のためのExcelマクロ超入門(絶対できるVBA開発)

マクロがまったくわからない人のためにエクセルマクロやVBAについてできるだけわかりやすく書いています。Twitter:@shuhhohhey

初心者のためのExcel エクセルマクロVBA入門-実践基礎:CSVファイルの読み込み(取り込み)その3

もういろんなものに対応してしまおうではないか!

さて、これからちょこちょこやっていきますが、CSVの取り込みをさらに突っ込んでいきます。
今回のパターンは・・・

もろもろあるけど、とりあえず改行とか入ってても対応してみようではないか!

です。

そもそも、改行とか入ってたら、CSVファイルとしてどうなの?とかそういう議論は置いといて、今回はこれで行きます。ただし、改行はlfです。つまり、エクセルのセル内で行われる改行に対して、対応しましょう!ということです。

というのも、CSVファイルは基本的にやっぱりなんだかんだで「Excel」で作る。からです。
エクセルで作って、CSV形式にして保存!なんてよくやる行為だと思います。そのなかで、やはりセル内で改行したデータなんかも当然あり得るわけで、、、今回はそんなデータを元にCSVの取り込みをしてみたいと思います。

レッツ!トライ!!

そんなわけで、今回取り込むデータはこんなデータ。

商品番号,商品名,商品説明,在庫,価格,URL
A10001,商品名ほげ1,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ1の説明です。
途中にカンマ,もあったりします。",100,2500,http://example.com/hoge1
A10002,商品名ほげ2,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ2の説明です。",120,6500,http://example.com/hoge2
A10003,商品名ほげ3,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ3の説明です。",22,4800,http://example.com/hoge3
A10004,商品名ほげ4,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ4の説明です。
途中に,カンマもあったりします。",453,320,http://example.com/hoge4
A10005,商品名ほげ5,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ5の説明です。",44,489,http://example.com/hoge5
A10006,商品名ほげ6,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ6の説明です。",58,599,http://example.com/hoge6

エクセルで見るとこんな感じ。

f:id:drumer2sh:20140325203103p:plain

このような感じで、改行を含む場合には""ダブルクオートで囲まれています。これを読み込みましょう!というわけです。えぇ・・・かなりげんなりとしているでしょうが、意外と行けると思いますよ?また、途中でカンマなどがあっても大丈夫なようにも対応してみます。大変ですが、頑張ってみましょう!まぁ、途中で半角のカンマなんてあるCSVファイルはそうそうあるものではないのですが、もしそういうファイルを読み込まなければいけない場合に、役に立つと思います。

まぁ、今回はかなり汎用的に作るのでカンマがあってもなくても大丈夫です。ついでにダブルクオートで囲っていようが、いまいが、シングルで括っていようがいまいが実は関係ありません。

いつも通りやってみましょう。最初と最後を書いて・・・

Public Sub ReadCsv()



End Sub


やることを日本語で書いて・・・

Public Sub ReadCsv()

	'CSVファイルを開く
	
	'行の終端(EOF)まで繰り返す
	
		'1行を読み込む
	
		'1行を配列に格納する
		
		'シートに書き出す
	
	'繰り返しが終わり
	
	'ファイルを閉じる
	
End Sub

という感じですが、ここで1つ困ったことがあります。「1行読み込む」とはいえ、改行してますけど?これってどうなの?という所です。

Line Inputはlfを無視する!ReadLineはlfを無視しない!


これが意外と重要でして、ファイルを開くには実はざっくりと2つの方法があります。

  • Openメソッドを使う方法
  • FSO(File System Object)を使って開く方法


この2つです。単純なファイルへの書き出しとか、読み込みなんかは実はこのFSOを利用する方法が結構便利です。FSOには色々なメソッドが用意されていてそれを利用することができます。開く、閉じるは勿論のこと、例えば、ファイルを移動したり、コピーしたり、ファイルが実際にあるか調べたりと、いろんなことができるので結構便利です。ですので、普通にファイルに対して何かをするのならこの方法がおすすめです。

FSOを利用する場合はVBEの[ツール]→[参照設定]で「Microsoft Scripting Runtime」にチェックを付ける必要があります。エクセルをインストールすると必ず入っているものなので、このチェックを付けることだけ忘れないようにしましょう。

f:id:drumer2sh:20140325203129p:plain


簡単にFSOを利用した場合のコードです。

Public test()

    Dim objFso As FileSystemObject
    Dim objTS As TextStream
    Dim strFileName As String

    ' 処理開始
    Set objFso = New FileSystemObject
    Set objTS = objFso.OpenTextFile(strFilePath, ForReading)

End Test

ただ開くだけなら、これで十分ですし、開かなくても、1文目のNewで作ったオブジェクトで、ファイルをコピーしたり移動したりが可能です。


ただし・・・・

この場合でReadLineを使って1行読み込むと、lfまでしか読み込まない


というデメリットがあるのです。今回に限りこの方法が使えません。つまりさっきのCSVだと・・・

A10001,商品名ほげ1,"商品説明をします。これは商品説明文です。

しか読み込みません。これでは、改行を含んだCSVファイルを読み込めないわけです。


そこで出てくるのが1つ目の方法、Openメソッドです。特に何もないオーソドックスな方法ですが、今回の場合はこちらでないといけないのです。
途中までは前々回と同じです。

Public Sub ReadCsv(ByVal strFilePath As String)

    Dim intFF As Integer            ' FreeFile値
    Dim strLine As String
    Dim vntREC As Variant
    Dim cnt As Long
    
    cnt = 1
    ' ファイル番号を取得する
    intFF = FreeFile
    
    ' strFilePathで指定されたファイルを開いて
    Open strFilePath For Input As #intFF
    
    ' 開いたファイルの行数分繰り返し
    Do Until EOF(intFF)
    
        ' 一行読み込んで・・・
        Line Input #intFF, strLine
 	
		'1行を配列に格納する
		
		'シートに書き出す
	
	'繰り返しが終わり
	
	'ファイルを閉じる
	
End Sub

はい、ここまではこれで良いです。こうすると、きちんと・・・変数strLineに・・・

A10001,商品名ほげ1,"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ1の説明です。
途中にカンマ,もあったりします。",100,2500,http://example.com/hoge1


というデータがすべて入ってきます。後はこれを・・・・


これを・・・・


ハテ・・・どうしましょう?


ここからが、実は本題です。カンマが特になければ、この後普通にカンマで分割してあげれば、問題ありません。前々回でやったことをそのままやれば、それで通ります。ですが、今回はカンマが中にあります。単純にカンマで分割すると・・・

A10001,
商品名ほげ1,
"商品説明をします。これは商品説明文です。
改行が含まれています。
改行が含まれています。
商品名ほげ1の説明です。
途中にカンマ,
もあったりします。",
100,
2500,
http://example.com/hoge1

となってしまい、本来ダブルクオートで囲まれた値が2つに分かれてしまいます。ではどうしないといけないのか?ということを次回やりましょう!


今日はここまで!

かしこ