カテゴリー名: [ADOによるデータベースの新規作成]
CSVファイルをデータベースとして新規作成します。
今回は 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 は、ユーザーがわざわざ書かなくても自動的に作成されます。
test.csv というファイルをカレントフォルダに作成します。
したがって、テーブル名は test.csv になります。
データベース名は、カレントフォルダの名前です。
「氏名」と「身長」の二つのフィールドからなるレコードを3人分登録します。
まずは VBScript を掲げます。解説は、その後に記します。
下のVBScriptを実行すると test.csv, schema.ini の二つのファイルが作成されます。
既にそれら二つが存在する場合は、それらを削除した上で新たに作成します。
テーブル作成、レコードセットによるデータの書き込みの部分は、Excelファイルの場合と同じです。必要に応じて「Excelファイルの新規作成」を参照してください。
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
CSVをデータベースとして扱う場合、ファイル名がテーブル名、フォルダ名がデータベースの名前になります。それら名前の取得方法をざっと見ておきます。
test.csv
というファイル名だけ代入しています。FSO.GetAbsolutePathName(CsvFile)
によって、CsvFileの絶対パス(フルパス)を取得し、CsvPathに代入します。FSO.GetParentFolderName(CsvPath)
によってCsvPathのドライブ名+フォルダ名を取得し、CsvFolderに代入します。FSO.GetFileName(CsvPath)
によってCsvPathからファイル名の部分だけを取り出します。CsvTableには test.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が予め存在していないと、エラーが発生します。
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 もあるようですが、どちらを指定してもカンマ区切りになってしまいます。
テーブル(つまり 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
[test.csv]
: テーブル名。ColNameHeader=True
: 1行目をヘッダーとみなす。CharacterSet=932
: 文字コードはShift_JISの拡張版(cp932)。Format=CSVDelimited
: 書式はカンマ区切り。Col1=氏名 Char Width 20
: 第1フィールドの名前とタイプ。Col2=身長 Float
: 第2フィールドの名前とタイプ。schema.ini には、一つのテーブルだけでなく複数のテーブルの情報が記録されます。
サンプルのVBScriptでは、事前に既存の schema.ini を削除した上でテーブルを新規作成していますが、実践的なプログラムでは schema.ini を安易に削除するのは避けた方がいいと思います。
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]
になることはありません。
〜 以上 〜