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" 'パス内のcsvファイル Set wb = Workbooks.Open(MyPath & "\" & myFile) '選択したファイルを開く End Sub
実行すると、ご丁寧にも以下のように自動で日付に変換してくれます。前ゼロも取り除いてくれます。(0落ち、ゼロ落ち)
この仕様を、「ありがたい!」と考える人がこの世に何人存在するのだろうかという疑問はさておき、対処法を記しておきます。
2.対処法
ここを見ている人は紆余曲折を経てこのページにたどり着いているはずですので、結論だけ書きます。
VBAのOPENステートメントでは、CSVの各項目に対してデータ型指定が出来ません。よって、OPEN関数を使う限りは問題を解消できません。
代わりに「外部データの取り込みウィザード」を利用します。ウィザード処理を担っている関数をVBAから呼び出すのです。
外部データの取り込みウィザード関数を調べるためには、「マクロの記録」機能を利用してウィザード実行用のVBAコードを生成します。
「マクロの記録」を開始してから以下の操作を実施します。
「データ」-「外部ファイルの取り込み:テキスト」でCSVファイルを選択し、文字列としてデータを取り込みします。
(なお、この操作が分かりづらい場合は【Excel】エクセルでマクロ記録する方法 - こめきちdiaryも参考にしてください。)
なお、Microsoft365、Office 2021のエクセルではウィザードの起動方法が異なりますので、こちら
【Excel】Microsoft 365やoffice 2021のエクセルで型指定でCSVファイルをインポートする方法 - こめきちdiary
を参考にしてください。
手動操作で「マクロの記録」を流用して作成したコードは以下のようになります。
なお、型指定(.TextFileColumnDataTypes = Array)はcsvファイルの項目数を超えてもエラーとならないので、必要十分なだけ項目定義しておけば汎用的に使えます。
Sub main() Dim myFile As String, MyPath As String '変数宣言 Dim wb As Workbook MyPath = ThisWorkbook.path & "\" '自分のパスを取得 myFile = "csvdata.csv" 'パス内のcsvファイル Set wb = Workbooks.Add ' ブックを作成 Call opencsv(wb, MyPath, myFile) '作成したブックに読み込み End Sub ' CSVファイルをテキスト形式で読み込む(日時項目の自動変換対策) 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
実行した結果は以下のようになります。希望通りに読み込めました。
新たなファイルに保存しても元のデータのままです。
めでたしめでたし。
以上です。