Access VBAでUTF-8のCSVファイルをインポートする機会がありまして、そんなの以前作ったよな、と実行してみると、日本語が文字化けしてる!!
AccessでUTF-8データをインポートするにはもうひと工夫必要でした。
コピーしてそのまま使えるサンプルを作成しましたのでご査収ください。
システムで生成されたデータがUTF-8だったというケースには多く直面します。
Accessで扱うデータの文字コードはShift-JISなので、Shift-JISのデータであれば普通に取り込んで正しく表示することができますが、UTF-8のデータを取り込むと日本語が正しく表示されません。
もはやUTF-8が主流なので、Access側で文字化けを防ぐ工夫をしてやるのが手っ取り早い方法です。
文字化けを防ぐ方法として「ADODB.Stream」オブジェクトを使用して取り込む際に文字コードを設定してやる事で、UTF-8でも文字化けせずにインポートを実現できます。
文字コードがUTF-8のCSVデータをインポートするコード
サンプルコード
参照設定は「Microsoft Active Data Object x.x Library」にチェックを付けてください。
「ADODB.Stream」オブジェクトはCreateObjectで生成しているので、参照設定は不要です。
事前バインディングと実行時バインディングが混在しているのが気持ち悪い方は、各自で統一してください。
Public Function FncImportCsv(ByVal strPath As String, _
ByVal strTable As String, _
Optional ByRef strMessage As String = "") As Boolean
On Error GoTo Err_Sec
Dim bRet As Boolean: bRet = False
Dim strLine As String
Dim arrLine As Variant
Dim arrFields() As String
Dim i As Long, j As Long
Dim adoSt As Object
'ADODB.Streamオブジェクトのインスタンスを生成
Set adoSt = CreateObject("ADODB.Stream")
Dim adoRs As New ADODB.Recordset
'ADODB.Recordsetオブジェクトのインスタンスを生成
adoRs.Open strTable, CurrentProject.Connection, , adLockOptimistic
i = 0
With adoSt
.Charset = "UTF-8" 'StreamのCharsetを"utf-8"に設定する
.Open 'StreamをOpen
.LoadFromFile (strPath) 'ファイルからStreamオブジェクト変数にデータを読み込み
Do Until .EOS 'Streamの末尾まで繰り返す
strLine = .ReadText(adReadLine) 'Streamから1行取り込み
If i = 0 Then
arrFields = Split(strLine, ",", , vbTextCompare) 'カンマで分割してフィールド名用の配列に格納
Else
arrLine = Split(Replace(strLine, """", ""), ",", , vbTextCompare) 'カンマで分割してデータ用の配列に格納
adoRs.AddNew 'Recordsetに1行追加する
For j = 0 To UBound(arrFields)
adoRs.Fields(arrFields(j)) = arrLine(j) '読み込んで分割したデータをフィールドに格納する
Next j
adoRs.Update 'Recordsetの更新内容を反映する
End If
i = i + 1
Loop
adoRs.Close
.Close
End With
Debug.Print "Record Count:", CStr(i)
bRet = True
Exit_Sec:
On Error Resume Next
Set adoRs = Nothing
Set adoSt = Nothing
FncImportCsv = bRet
Exit Function
Err_Sec:
strMessage = "ErrNo : " & Err.Number & ": ErrDescription : " & Err.Description
'Call sOutputLog("FncImportCsv: " & strMessage) '(エラーログ出力)
Resume Exit_Sec
End Function
このCSVの条件として、先頭行にカンマ区切りでフィールド見出しを持ち、インポート先テーブルのフィールド名と同一である事と、数値桁のカンマ区切りは除去された状態になっている事が前提です。2点についてご注意ください。
「FncImportCsv」プロシージャの引数は3つ。
それぞれ次の意味の値をセット/リターンします。
第1引数:インポート対象となるCSVファイルのフルパスを記述。
第2引数:Accessのテーブル名を指定。
第3引数:当プロシージャでエラーが発生した場合、エラー番号とDescriptionをセットします。呼び出し元に返却することができます。
「Err_Sec:」のブロック内にコメントアウトで記載した「Call sOutputLog(...)」は、エラーの内容をテキストファイルに出力するプロシージャを呼び出しています。
必要に応じてコメントアウトを外してください。
「sOutputLog」プロシージャは以下の記事で紹介しています。
呼び出し例
上記コードを呼び出す方のコードは、次のように記述します。
Dim strMessage As String
If Not FncImportCsv("c:\data\utf8data.csv", "t_test", strMessage) Then
MsgBox(strMessage)
End If
実行してみると、CSV1行目のフィールド名に合致するフィールドにデータが正しくインポートされて、日本語が正しく表示されている事が確認できたと思います。
Streamを使用しているからか、よほどの大量データでもない限り実行速度はそれほど気にならない程度でしょう。
参考
文字コードがShift-JISのCSVデータをインポートするには
ちなみに、Shift-JIS形式のテキストをインポートする方法として、こちらの記事でサンプルコードを紹介しています。
文字コードの指定ができないため、UTF-8の場合上のSQL文でインポートする方法を使う事ができず、今回「ADODB.Stream」の使用となりましたが、個人的にはSQL好きなのでAccessからSQLを発行する際にも文字コード設定が可能になったらいいのになぁ、とちょっと思っています。