データベースとしてのCSVファイルの新規作成

カテゴリー名: [ADOによるデータベースの新規作成

2016/08/16

 CSVファイルをデータベースとして新規作成します。

関連の Program Page


《このページの目次》


    

1. 概要

 今回は CSVファイルの test.csv を作成します。

 作成するデータベースの中身は、「Excelファイルの新規作成」のときと同じです。

 氏名と身長のデータが3人分記録されているデータベースを作成します。表形式で示すと下のとおり。

氏名 身長
鈴木 172.3
高橋 168.5
田中 183.6

    

 データベースを作成する手順は、ExcelファイルやAccessファイルの場合と基本的に同じです。

 ただ、一つのCSVファイルを一つのデータベースとして取り扱うことはできません。

 test.xlsなどのExcelファイルであれば、その中に複数のワークシート(データベースでいうとテーブル)を含めることができます。

 一つのAccessファイルに複数のテーブルを設けることができるのは言うまでもありません。

 しかし、CSVファイルの場合はそういう訳にいかないので、一つのCSVファイルを一つのテーブルに見立てます。

 そして、CSVファイルが属するフォルダを一つのデータベースに見立てます。そうすれば、そのフォルダの下に複数のCSVファイル(テーブル)を置くことができます。

 また、CSVファイルにフィールドのタイプ(文字列型、数値型など)の情報を盛り込むことができないので、同じフォルダ内に schema.ini というファイルを作成して、それに付随の情報を記録します。

 schema.ini は、ユーザーがわざわざ書かなくても自動的に作成されます。

目次に戻る


    

2. CSVファイルの作成

 test.csv というファイルをカレントフォルダに作成します。

 したがって、テーブル名は test.csv になります。

 データベース名は、カレントフォルダの名前です。

 「氏名」と「身長」の二つのフィールドからなるレコードを3人分登録します。

 まずは VBScript を掲げます。解説は、その後に記します。

 下のVBScriptを実行すると test.csv, schema.ini の二つのファイルが作成されます。

 既にそれら二つが存在する場合は、それらを削除した上で新たに作成します。

 テーブル作成、レコードセットによるデータの書き込みの部分は、Excelファイルの場合と同じです。必要に応じて「Excelファイルの新規作成」を参照してください。

    

△ create_csv.vbs

 1Option Explicit
 2Dim CsvFile, HeaderYN, TypeStr
 3Dim FSO, CsvPath, CsvFolder, CsvTable, SchemaPath
 4Dim ShellObj, DriverStr, ConnStr, CN, RS, sql
 5
 6CsvFile = "test.csv"
 7HeaderYN = "Yes"
 8TypeStr = "氏名 varchar(20),身長 float"
 9
10Set FSO = CreateObject("Scripting.FileSystemObject")
11CsvPath = FSO.GetAbsolutePathName(CsvFile)
12CsvFolder = FSO.GetParentFolderName(CsvPath)
13If FSO.FolderExists(CsvFolder) = False Then
14    On Error Resume Next
15    FSO.CreateFolder(CsvFolder)
16    If FSO.FolderExists(CsvFolder) = False Then
17        WScript.Echo CsvFolder & "が存在しません!"
18        WScript.Quit
19    End If
20End If
21CsvTable = FSO.GetFileName(CsvPath)
22SchemaPath = CsvFolder & "\schema.ini"
23If (FSO.FileExists(CsvPath) = True) Then FSO.DeleteFile(CsvPath)
24If (FSO.FileExists(SchemaPath) = True) Then FSO.DeleteFile(SchemaPath)
25Set FSO = Nothing
26
27Set ShellObj = CreateObject("Wscript.Shell")
28If ShellObj.Environment("Process").Item( _
29        "PROCESSOR_ARCHITECTURE") = "x86" Then  ' 32bit版の場合
30    DriverStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
31Else  ' 64bit版の場合
32    DriverStr = "Provider=Microsoft.ACE.OLEDB.12.0;"
33End If
34Set ShellObj = Nothing
35
36ConnStr = DriverStr & "Data Source=" & CsvFolder & ";" & _
37    "Extended Properties=""text;HDR=" & HeaderYN & ";FMT=Delimited;"";"
38Set CN = CreateObject("ADODB.Connection")
39CN.Open ConnStr
40sql = "create table " & CsvTable & " (" & TypeStr & ");"
41CN.Execute(sql)  ' テーブル作成
42
43Set RS = CreateObject("ADODB.Recordset")
44sql = "select * from " & CsvTable & ";"
45RS.Open sql,CN,0,2,1
46RS.AddNew
47    RS.Fields("氏名").Value = "鈴木csv"
48    RS.Fields("身長").Value = 172.3
49RS.Update
50RS.AddNew
51    RS.Fields(0).Value = "高橋csv"
52    RS.Fields(1).Value = 168.5
53RS.Update
54RS.AddNew Array("氏名", "身長"), Array("田中csv", 183.6)
55RS.Update
56RS.Close
57CN.Close
58Set RS = Nothing
59Set CN = Nothing

目次に戻る


    

(1) CSVファイルとそのフォルダ名

 CSVをデータベースとして扱う場合、ファイル名がテーブル名、フォルダ名がデータベースの名前になります。それら名前の取得方法をざっと見ておきます。

 サンプルのVBScriptでは CsvFile と CsvTable が同じ test.csv です。

 わざわざCsvTableを取得しなくてもいいようなものですが、もしCsvFileに C:\work\test.csv というフルパスが代入されたり、あるいは、\work\test.csv とか .\test.csv などのように、ファイル名だけでない形式で指定されたらどうでしょうか。

 その場合は、やはりCsvPath(フルパス)からファイル名だけを取り出してCsvTable(テーブル名)を得なければなりません。

    

 なお、create_csv.vbsでは CsvFolder がまだ存在しないフォルダである場合、それを作成するようにしています。

 とはいっても、多重階層をなすフォルダを一気に作ることはしません。

 C:\aa\bb\cc\test.csv のケースにおいて、C:\a というフォルダは存在するけれども bb も cc も存在しないのであれば、C:\aa\bb\cc というフォルダの作成には失敗します。

 C:\aa\bb が存在し、その下の cc が存在しないという場合は、ccの作成に成功します。

 この先のデータベースの作成において、CsvFolderが予め存在していないと、エラーが発生します。

目次に戻る


    

(2) 接続文字列(ConnectionString)

 test.csvが存在するフォルダが C:\work の場合でいうと、データベースに接続するための接続文字列が下のようになります。

 長いので2行にして掲げますが、ほんとは1行です。

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\work;
Extended Properties="text;HDR=Yes;FMT=Delimited;";

 上は JET.4.0 を指定しているので 32bit用です。
 64bit用は下のようになります。

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\work;
Extended Properties="text;HDR=Yes;FMT=Delimited;";

    

 HDR=Yes というのは、ヘッダーの扱いを指定するものです。

 Yesだと、CSVファイルの1行目にフィールド名を書き出します。

 つまり、1行目が "氏名","身長" となります。

 Noにすれば、1行目にいきなりデータがきます。

 つまり、1行目が "鈴木",172.3 となります。

 サンプルのVBScriptでは、このHDRの Yes か No かを変数 HeaderYN に代入するょうにしています。

    

 FMT=Delimited は、区切り文字をカンマにするとの指定です。
正式には CSVDelimited にすべきかもしれません。

 他にタブ区切りの TabDelimited、固定長の FixedLength もあるようですが、どちらを指定してもカンマ区切りになってしまいます。

目次に戻る


    

(3) テーブルの作成とschema.ini

 テーブル(つまり test.csv)の作成は、SQL命令文の create table で行います。

 該当箇所を掲げると下のとおり。

Set CN = CreateObject("ADODB.Connection")
CN.Open ConnStr
sql = "create table test.csv (氏名 varchar(20),身長 float);"
CN.Execute(sql)

 上が実行されるとき、既に test.csv が存在しているとエラーになります。

 なので、サンプルのVBScriptでは予め test.csv を削除するようにしています。

    

 create table でテーブルが作成されるとき、test.csv と一緒に schema.ini というファイルも作られます。

 これは、test.csv のフィールド情報などが記録されたファイルです。

 メモ帳などのエディタで読み書きできるテキストファイルです。下のような内容です。

[test.csv]
ColNameHeader=True
CharacterSet=932
Format=CSVDelimited
Col1=氏名 Char Width 20
Col2=身長 Float

    

 schema.ini には、一つのテーブルだけでなく複数のテーブルの情報が記録されます。

 サンプルのVBScriptでは、事前に既存の schema.ini を削除した上でテーブルを新規作成していますが、実践的なプログラムでは schema.ini を安易に削除するのは避けた方がいいと思います。

目次に戻る


    

(4) テーブル名のもう一つの書き方

 CSVファイルを扱う場合、テーブル名が test.csv となります。半角のピリオドが出てきます。

 SQLになじみのある人なら違和感を覚えるかもしれません。半角ピリオドが特別の意味を持つからです。

 たとえば、テーブル名が TestTable であり、それに「身長」というフィールドがある場合、「TestTableというテーブルの“身長”というフィールド」を正確に記述すると、TestTable.身長 と書きます。

 この記述ルールをCSVファイルにそのまま応用すると test.csv.身長 となりますが、これはエラーになります。

 こうした正確な記述が必要になったときは、ピリオドをシャープ記号に変換し、更に、角括弧で囲みます。

 つまり [test#csv].身長 と書きます。

 複雑なSQL命令文を用いないのであれば test.csv のままでいいと思いますが、
[test#csv] という表記も覚えておくと便利なことがあると思います。

    

 ちなみに、テーブルを作成するとき、次のSQLを実行したとします。

create table [test#csv] (氏名 varchar(20),身長 float);

 この場合もちゃんと test.csv というファイルが作られます。

 ファイル名が test#csv とか [test#csv] になることはありません。

〜 以上 〜