CSVファイルを読み込む
来源:互联网 发布:大数据全套视频百度云 编辑:程序博客网 时间:2024/04/28 10:26
CSVのデータを扱うとき、次のようにブックとして開いていませんか。
Sub Sample1() Workbooks.Open "C:\Data\Sample.csv"End Sub
CSVファイルはアイコンの絵がExcelでかつ、ダブルクリックするとExcelが起動して開かれます。そのことから「CSVファイルはExcelのデータファイル」と勘違いしているユーザーも多いですが、CSV形式のファイルは単なるテキスト形式のファイルです。
CSV形式は、Excelが登場するはるか以前の、MS-DOS時代から使われていた汎用のファイル形式です。決して、Excel専用のデータ形式などではありません。
Sample1のように、CSVファイルをブックとして開くと「001」が「1」になったり、「2-1」が「2月1日」のシリアル値に変換されるなど、自動変換機能が働いて読み込みと同時にデータが変換されてしまいます。
こうした問題に頭を悩ます声をたびたび聞きますが、そもそもCSV形式ファイルをブックとして開くことが原因です。
CSVファイルはテキスト形式ですから、テキストファイルとして扱えば、自由に操作できます。
テキストファイルからデータを読み取るには、
(1)テキストファイルを開く(Openステートメント)
(2)1行分のデータを読み込む(Line Inputステートメント)
(3)読み込んだデータをセルに代入する
(4)開いたファイルを閉じる(Closeステートメント)
という流れで処理します。
■テキストファイルを開く
テキストファイルを開くOpenステートメントは、ブックを開くWorkbooks.Openメソッドとは違います。
Excelなどのアプリケーションで対象のファイルを読み込むのではなく、いわば、ファイルを管理しているWindows(OS)に対して「使用許可」を得るようなものです。
Openステートメントの書式は次のとおりです。
Open ファイル名 For 目的 As 番号
ファイル名にパスを指定しないと、カレントフォルダが対象になるので、できるだけパスを指定した方が良いでしょう。
「目的」には、そのファイルに対して何をするかを指定します。
Input:ファイルから読み込む
Output:ファイルに上書きする
Append:ファイルに追記する
もし間違った「目的」を指定すると「ファイルモードが不正です」というエラーが発生するので、エラーになったら正しく直してください。
ただし、Outputと「書き込む」目的で開いたファイルに「Line Input」を実行すると、エラーになると同時に、ファイルのデータが消えてしまうので注意してください。
「番号」には数値を指定します。
たいていは「#1」を指定します。複数のファイルを同時に開く場合は、もちろん数値が重複してはいけません。
そのため、現在使用可能な「番号」を返すFreeFile関数もありますが、一般的にはファイルを10個も20個も開くことは希です。
たいていは1つしか開きませんので「#1」と覚えておけばいいでしょう。
Openしたファイルはこれ以降その番号で特定します。
そのとき「1」と数値だけ指定するときと「#1」とナンバー記号をつけて指定するときの2通りがあります。
たとえば、Line Input #1 は、#をつけないとエラーになります。
EOF(1) は、#をつけるとエラーになります。
Close #1 は、#をつけてもつけなくても正常に動作します。
どの命令で#が必須かは、使っていれば自然と覚えます。エラーになったら修正してください。
■データを読み込む
さて、Openステートメントで開いたファイルから1行分のデータを読み込むにはLine Inputステートメントを使います。
Line Inputステートメントの書式は次のとおりです。
Line Input #番号, 変数
Line Inputステートメントは、読み込んだデータを必ず変数に格納します。
Line Input #1, Range("A1")
のように、直接セルに代入することはできません。
Line Inputステートメントは、改行コードまで1行分のデータを読み込みます。
読み込むと、読み込みポイントが次行に移ります。読み込みポイントがファイルの終端に達するまでLine Inputステートメントを実行すれば、すべてのデータを読み込むことができます。
これには、Do Loopを使います。
Do 読み込みポイントがファイルの終端ではない間Line Input #1, 変数Loop
読み込みポイントがファイルの終端に達したかどうかは、EOF関数でわかります。
EOFは「End Of File」の頭文字です。EOF関数は、引数にファイルの番号を指定すると、そのファイルの読み込みポイントが「終端に達している」ときTrueを返します。
Do Until EOF(1)Line Input #1, 変数Loop
これで、CSVファイルの全データを「1行ずつ」読み込むことができます。
読み込みが終わったら、最後にファイルを閉じます。
Close #1
ここまでをまとめると、次のようになります。
Sub Sample2()Dim buf As StringOpen "C:\Data\Sample.csv" For Input As #1Do Until EOF(1)Line Input #1, buf''読み込んだデータをセルに代入するLoopClose #1End Sub
CSVファイルの実体は、Excel専用のデータ形式ではなく、単なるテキストファイルです。
CSVファイルをブックとして開くと「001」が「1」に自動変換されてしまうなどの問題があるので、CSVは「テキストファイルとして開いて」自分でセルに代入すると良いでしょう。
■読み込んだデータをワークシートに出力する
では、読み込んだ1行分のデータをカンマで分割して、各セルに代入する動作を考えてみましょう。ここでは次のような1行分のデータを例にして解説を進めます。
---- Sample.csv-----001,モグタン,平成12年1月10日,冬眠はしない--------------------
ある文字列が、ある文字で区切られているとき、文字列を区切り文字で分割してくれるのがSplit関数です。
Split(文字列, 区切り文字)
CSVデータの区切り文字はカンマ(,)なので、次のように指定します。
Split(文字列, ",")
Split関数は、分割した各データを配列形式で返します。
しかし、その配列の要素数は事前にわからないことが多いので、受け取る変数はバリアント型で宣言しておくのが一般的です。
Dim tmp As Varianttmp = Split(文字列, ",")
文字列が「001,モグタン, 平成12年1月10日,冬眠はしない」のときは、
tmp(0):001
tmp(1):モグタン
tmp(2):平成12年1月10日
tmp(3):冬眠はしない
という配列になります。配列の先頭が0から始まる点に留意してください。
このような一次元配列を「横方向のセル範囲」に代入するときは、次のように一括代入が可能です。
Sub Sample3() Dim tmp As Variant tmp = Split("001,モグタン,平成12年1月10日,冬眠はしない", ",") Range("A1:D1").Value = tmpEnd Sub
このとき、代入するセル範囲(ここではRange("A1:D1"))と、配列の要素数を一致させるのがポイントです。
配列の要素数はUbound関数で取得できるので、次のように書くことも可能です。
Sub Sample4() Dim tmp As Variant tmp = Split("001,モグタン,平成12年1月10日,冬眠はしない", ",") Range("A1").Resize(1, UBound(tmp) + 1).Value = tmpEnd Sub
しかし、ここはあえて、次のように1セルずつ代入する方法で話を進めましょう。
また、このように、対象のセルを行と列で指定する場合は、RangeではなくCellsを使うのがセオリーです。
Sub Sample5() Dim tmp As Variant tmp = Split("001,モグタン,平成12年1月10日,冬眠はしない", ",") Cells(1, 1).Value = tmp(0) Cells(1, 2).Value = tmp(1) Cells(1, 3).Value = tmp(2) Cells(1, 4).Value = tmp(3)End Sub
Cellsで指定する行位置を変数とし、1ずつ増加すれば、CSVデータをセルに分割して代入することができますね。まとめると、こんな感じです。
Sub Sample6() Dim buf As String, tmp As Variant, n As Long Open "C:\Data\Sample.csv" For Input As #1 Do Until EOF(1) Line Input #1, buf tmp = Split(buf, ",") n = n + 1 Cells(n, 1).Value = tmp(0) Cells(n, 2).Value = tmp(1) Cells(n, 3).Value = tmp(2) Cells(n, 4).Value = tmp(3) Loop Close #1End Sub
しかし、これでは相変わらず「001」が「1」になってしまいます。
「平成12年1月10日」はシリアル値ではなく文字列として代入されてしまいます。
こうした問題には、代入するセルを個別に操作します。
たとえば「001」を「001」のまま代入するには、セルの表示形式を文字列にしてから代入します。
また、「平成12年1月10日」をシリアル値にするにはDateValue関数を使います。
Sub Sample7() Dim buf As String, tmp As Variant, n As Long Open "C:\Data\Sample.csv" For Input As #1 Do Until EOF(1) Line Input #1, buf tmp = Split(buf, ",") n = n + 1 With Cells(n, 1) .NumberFormat = "@" .Value = tmp(0) End With Cells(n, 2).Value = tmp(1) Cells(n, 3).Value = DateValue(tmp(2)) Cells(n, 4).Value = tmp(3) Loop Close #1End Sub
このように、個々のデータに対して、好みの設定をすることで、どんなCSVデータであっても、望む形式でワークシートに取り込むことができます。
● 補足 ●
Line Inputステートメントは、CR(キャリッジリターン)+ LF(ラインフィールド)コード、またはCRコードのみで改行したテキストファイルは1行ずつ読むことができますが、LFコードのみで改行したテキストファイルは1行ずつ読み込むことができません。
LFコードで改行したテキストファイルを読む方法については「LFコードで改行したファイルを読み込む」を参照してください。
- CSVファイルを読み込む
- CSVファイルの読み込み
- ファイルのアップロード、ダウンロード、CSVファイルの読み込み
- Java 文字列のバイト数を取得する方法 Javaで,CSVファイルをDBへ書き込み
- VisualforceでCSVファイルとExcelファイルを出力するには
- CSV
- CSV
- csv
- csv
- csv
- CSV
- []csv
- csv
- csv
- CSV
- CSV
- csv.js导出csv
- csv File.
- ajax获取后台数据,页面Json数据按照json格式化输出
- 为你的博文构建目录
- 02. Oracle 11g 服务启动与停止批处理文件
- 算法提高 打水问题
- #学志#项目进度01
- CSVファイルを読み込む
- 功能测试用例基础设计模型
- Android4.4蓝牙耳机HFP流程分析-3
- 关于mybatis sql语句的错误笔记
- hdoj2824 The Euler function(欧拉函数)
- JavaSE 学习参考:类的封装
- 初试Kotlin(一)
- GYM 100090 F.Asperger Syndrome(set)
- Importing theano: AttributeError: 'module' object has no attribute 'find_graphviz'