エクセルVBAでCSV取込み~改行がされないパターンの対処法


return key

photo credit: Return via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルVBAでCSVファイルを取り込む方法シリーズです。

前回、Splitを使ってCSVからのデータをワークシートに転記をする方法についてお伝えしました。

エクセルVBAでCSVデータをカンマで区切ってワークシートに取り込む方法
エクセルVBAでCSVを取り込む方法です。今回は、Splitという命令と配列を使ってCSVのレコードをカンマで区切ってワークシートに転記をしていく方法について解説をしていきます。

ただし、残念ながらこのプログラムではうまく取り込めない例がいくつか存在しています。

今回はそのうちの一つ、CSVをワークシートに取り込んだときに改行されずに一行になってしまうパターンについてどう回避するかについてお伝えしたいと思います。

ではよろしくお願いします!

スポンサーリンク

前回のおさらい:CSVファイルを一行ずつ取得してカンマでスプリットする

まず前回のおさらいですが、プログラムはコチラでしす。

[vb]
Sub getCSV()

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)

Dim strPath As String
strPath = “C:\Users\Noriaki\Dropbox\40_ブログ\vba-csv\test\ラーメン店アンケート.csv”

Dim i As Long, j As Long
Dim strLine As String
Dim arrLine As Variant ‘カンマでsplitして格納

Open strPath For Input As #1 ‘csvファイルをオープン

i = 1
Do Until EOF(1)

Line Input #1, strLine
arrLine = Split(strLine, “,”) ‘strLineをカンマで区切りarrLineに格納

For j = 0 To UBound(arrLine)

ws.Cells(i, j + 1).Value = arrLine(j)

Next j
i = i + 1
Loop

Close #1

End Sub
[/vb]

おおまかな流れとしては

  1. OpenでCSVファイルをオープン
  2. CSVファイルが終了するまで
    1. CSVファイルから1行取得
    2. 取得した文字列をカンマでSplit
    3. Splitした要素をセルに転記
  3. CloseでCSVファイルをクローズ

という流れになります。

このプログラムでうまく取り込めないCSVのパターンはどういったものでしょうか。

CSVを取り込んでも改行がうまくされないパターン

とあるCSVを上記プログラムで取り込んでみると…

エクセルVBAでCSVファイル取り込んで改行されない

うまく取り込めません。

本来、一行ずつ改行してほしいところなのですが、改行されずにすべての値が1行目に転記されてしまいました。

このように改行がうまくできないパターンが存在します。

CSVファイルに問題があるのか、エディタで確認をしてみます。

LFコードを含むCSVファイル

うーん…とくに問題があるようには見えませんね。

再度先ほどのエクセルの出力結果をよく見てみますと

エクセルVBAでLFコードはセル内改行に

I1セルに注目して頂くと二つの値が1つのセルに格納されていました。いわゆるショートカットキーで Alt + Enter とするセル内改行ですね。

この辺りに解決のヒントがありそうです。

3種類の改行コード

世の中で取り扱われている「改行」にはいくつかの種類があることをご存知でしたか?

調べてみますと

 改行コードとは、テキストファイル中で改行を意味する文字コードのこと。正確には、改行してカーソルを行頭に復帰する動作を指示するコードのこと。
 文字コード体系の種類には依存しないが、もともと「CR」(Carriage Return : 行頭復帰)と「LF」(Line Feed : 改行)の2つのコードが存在していたことから、WindowsではCR+LF、Mac OSではCR、UNIXではLFが使われている。

IT用語辞典:改行コード

とこのように、プラットフォームでメインで使う改行コードが異なるということなんですね。

CSVはプラットフォーム間でデータをやりとりすることも多いわけで、別のプラットフォームで作成したCSVはこの「改行コードの違い」が発生している場合があるということですね。

改行がされなかった理由

たね明かしをしますと、今回使用したCSVの一行の終わりを表す改行コードにはLFコードが使われていたんですね。

Line InputではCRコードが出現するまでを一行として判別しますので、LFコードがあっても一行の終わりとは判定されません。

ではLFコードは無視されているのか?ということなのですが、そうではありません。

勘のいい方はお気づきだと思いますが、一方でLFコードはセル内改行として処理 をされていたんですね。

これにて理由はわかりましたので、プログラムを修正していきます。

CSVファイルのLFコードを判定してSplitするプログラム

修正したプログラムはこちらです。

[vb]
‘CSVファイルの取り込み LFコードでスプリット→カンマでスプリットするパターン
Sub getCSV2()

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)

Dim strPath As String
strPath = “C:\Users\Noriaki\Dropbox\40_ブログ\vba-csv\test\ラーメン店アンケート_vbLf.csv”

Dim i As Long, j As Long
Dim strLine As String
Dim tmp As Variant ‘LFコードでsplitして格納
Dim arrLine As Variant ‘カンマでsplitして格納

Open strPath For Input As #1 ‘csvファイルをオープン
Line Input #1, strLine ‘CRコードがないので1行取り込めばCSVファイル全てを取り込める
Close #1

tmp = Split(strLine, vbLf) ‘strLineをLFコードで区切りtmpに格納

For i = 0 To UBound(tmp)
arrLine = Split(tmp(i), “,”) ’tmp(i)をカンマで区切りarrLineに格納
For j = 0 To UBound(arrLine)
ws.Cells(i + 1, j + 1).Value = arrLine(j)
Next j
Next i

End Sub
[/vb]

今回のプログラムのメインの流れは

  1. Line InputでCSVファイルを文字列strLineに取り込む
  2. strLineをLFコードで分割して、分割した要素を配列tmpに格納
  3. 配列tmpに格納されている要素一つ一つに対してカンマで分割して、分割した要素を配列arrLineに格納
  4. 配列arrLineに格納されている要素をセルに書き込む

という流れです。

つまり、まず改行コードLFで分割してから、さらにそれをカンマで分割するという方針です。

以降でいくつかポイントを解説します。

LFコードのCSVは1行取り込めば全てを取り込める

まず15行~17行です。

[vb]
Open strPath For Input As #1 ‘csvファイルをオープン
Line Input #1, strLine ‘CRコードがないので1行取り込めばCSVファイル全てを取り込める
Close #1
[/vb]

前回のプログラムでは、CSVの取り込みにファイルの終わりまでを繰り返すDo Until EOF(1)~Loopを使用していましたが、今回は使用していません。

Line Inputを1回だけして、さっさとCSVファイルをCloseしてしまっています。

なぜこれで良いのでしょうか?

繰り返しになりますが、Line Input はCRコードを1行の終わりと判定します。

今回対象とするCSVファイルはCRコードが存在していないので、Line Inputはファイルの終わりまで「行の終わり」を判定することはありません。

したがって、1回Line Inputをしてしまえば、CSVファイル全体を1行として取り込めるということです。

改行コードのVBA定数

次に19行目です。

[vb]
tmp = Split(strLine, vbLf) ‘strLineをLFコードで区切りtmpに格納
[/vb]

ここが今回のキモですね。

LFコードでSplitをするのですが、「vbLf」という見慣れないものありますね。

改行コードなどを指定するときには定数というものを使います。

定数というのは、特定の値に名前をつけたものをいいます。変数に似ていますが、一度格納した値を変更することはできません。

VBAには改行コードについて定義済みの定数が用意されています。

VBA定数 プラットフォーム 名称・説明
vbCr Mac OS CRコード。キャリッジリターン
vbLf UNIX LFコード。ラインフィード
vbCrLf Windows CRコードとLFコードの組み合わせ
vbNewLine プラットフォームで適切な改行コードを使用

このように4種類の定数を利用することができます。

今回はLFコードを利用したいので、定数vbLfを使っているというわけです。

まとめ

以上、改行がうまくされないパターンのCSV、つまりLFコードを使用したCSVファイルをエクセルVBAで取り込む方法についてお伝えしました。

配列が複数出てくるので若干ややこしいかも知れませんが、CSVの取り込み処理は一度作成するといろんなプログラムで使い回しが利くので、ぜひマスター頂ければと思います。

次回ですが、これ以外にもCSVがうまく取り込めないパターンがいくつかありますので、それを一つ一つやっつけていきたいと思います。

エクセルVBAでダブルクォーテーションで囲まれているCSVファイルを取り込む
エクセルVBAでCSVファイルを取り込む方法シリーズです。今回はデータがダブルクォーテーションで囲まれているパターンのCSVをエクセルVBAで取り込む方法についてお伝えしたいと思います。

どうぞお楽しみに!

連載目次:エクセルVBAで色々なCSVファイルを取り扱う

様々なソフトウェア間のデータ交換の際に一般的に多く活用されているCSVファイル。エクセルで取り込んで集計や加工することもたくさんあることと思います。このシリーズでは、CSVファイルをエクセルVBAで取り込むためのテクニックについてお伝えしています。
  1. CSVとは何か?そしてエクセルでCSVファイルを扱うときの注意点
  2. エクセルVBAでCSVを読み取る初心者向けの最も簡単なプログラム
  3. エクセルVBAでCSVデータをカンマで区切ってワークシートに取り込む方法
  4. エクセルVBAでCSV取込み~改行がされないパターンの対処法
  5. エクセルVBAでダブルクォーテーションで囲まれているCSVファイルを取り込む
  6. エクセルVBAでデータにカンマが含まれてしまっているCSVを取り込む
  7. 文字化けよさようなら!エクセルVBAでUTF-8のCSVを読み込む方法

タイトルとURLをコピーしました