1.データが勝手に日付型に変換される!
1-1,A,09011112222
1-2,B,08011112222
1-3,C,05011112222
このようなCSVファイルをエクセルで処理したいことがありますよね。CSVファイルを開くVBAコードはこんな感じ。
Sub main()
Dim myFile As String, MyPath As String
Dim wb As Workbook
MyPath = ThisWorkbook.Path & "\"
myFile = "csvdata.csv"
Set wb = Workbooks.Open(MyPath & "\" & myFile)
End Sub
実行すると、ご丁寧にも以下のように自動で日付に変換してくれます。前ゼロも取り除いてくれます。(0落ち、ゼロ落ち)
この仕様を、「ありがたい!」と考える人がこの世に何人存在するのだろうかという疑問はさておき、対処法を記しておきます。
2.対処法
ここを見ている人は紆余曲折を経てこのページにたどり着いているはずですので、結論だけ書きます。
VBAのOPENステートメントでは、CSVの各項目に対してデータ型指定が出来ないので使いません。代わりに「外部データの取り込みウィザード」をVBAから実行します。
まずは、「マクロの記録」機能を利用してウィザード実行用のVBAコードを生成します。
「マクロの記録」を開始してから以下の操作を実施します。
「データ」-「外部ファイルの取り込み:テキスト」でCSVファイルを選択し、文字列としてデータを取り込みします。
(なお、この操作が分かりづらい場合は【Excel】エクセルでマクロ記録する方法 - komekichix’s diaryも参考にしてください。)
なお、Microsoft365、Office 2021のエクセルではウィザードの起動方法が異なりますので、こちら
【Excel】Microsoft 365やoffice 2021のエクセルで型指定でCSVファイルをインポートする方法 - komekichix’s diary
を参考にしてください。
手動操作で「マクロの記録」を流用して作成したコードは以下のようになります。
なお、型指定(.TextFileColumnDataTypes = Array)はcsvファイルの項目数を超えてもエラーとならないので、必要十分なだけ項目定義しておけば汎用的に使えます。
Sub main()
Dim myFile As String, MyPath As String
Dim wb As Workbook
MyPath = ThisWorkbook.path & "\"
myFile = "csvdata.csv"
Set wb = Workbooks.Add
Call opencsv(wb, MyPath, myFile)
End Sub
Sub opencsv(wb, pathnm, filenm)
With wb.ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & pathnm & filenm _
, Destination:=Range("$A$1"))
.Name = filenm
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 932
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array( _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
実行した結果は以下のようになります。希望通りに読み込めました。
新たなファイルに保存しても元のデータのままです。
めでたしめでたし。
以上です。