[三流君] −−>
[ASPで遊ぶ、失敗する] −−>
[バックナンバー一覧]
−−> No.101 ADO CSV接続 勝手に型を決めんなよ・・・
ADO CSV接続 勝手に型を決めんなよ・・・
今回、ADOのCSV接続でいろいろとやってみたけど、できなかった、そんなお話です。
で、解決したのが↓
[No.102 ADO CSV接続 schema.iniを使い型を設定してみた]
で、schema.iniに型を指定して読み込むことができるみたいです。
※回答を速くほしい人は、下読まないで、No.102のschema.iniの方法がいいですよ。
本文(発行内容)
こんにちは、三流プログラマーのKen3です。
今回は、
ADOのCSV接続の自動で決まってしまうデータの型について少々。
でも、解決しなかったり・・・
いつもの三流的なアプローチなので、実際はアレンジして使ってください。
※一部でも参考になればいいんだけど・・・
/*
* 1.今回のキッカケ
*/
No.080 Microsoft Text Driver (*.txt; *.csv) で接続してみた
http://www.ken3.org/asp/backno/asp080.html
から
>質問なのですがcsvファイルを接続し、データを吸い上げたときに
>IPアドレスのように111.222.333.444といった物が111.222333444とな
>って上がってきてしまいました。吸い上げた時点で既にそのような形
>式になっていましたのでどうした物かと困っています。掲示板のログ
と、質問をもらった。
/*
* 2.テストデータを作成してテストしてみる
*/
オバケが出たと言われたら、
そんなことないだろ、見間違いだろ
と
言うのだが、現実に現象が発生するのか?
コンピュータの場合は確認しやすい。
なぜ?確認しやすいかって?
それは、同じデータを流して、何度も検証できるからかなぁ。
オバケの発生条件を教えてもらったので、
私もテストデータを作成して、見物してみることにした。
作成したCSVファイルは、ヘッダー付きで下記のように作成した。
http://www.ken3.org/cgi-bin/test/test101.csv
日付,IP,URL,分数TEST,少数TEST,備考,予備
2004/12/25,192.168.0.1,ken3.org,1/20,1.25,備考の文字,1-2-3
2005-01-08,192.168.0.25,/asp/,1/3,5.10,日付の形式を少し変えた
2005/01/19 17:30,192.168.0.17,vba,2/7,5,時刻を付けた,04-05-06
まだまだ、テストデータとして、足りないけど、↑手抜きでこんな感じ。
※カンマと小数点が見難いが・・・
ADOでCSVの接続は、
'SQLのテーブル名には、ファイル名を指定します。
strSQL = "select * from test101.csv"
'接続情報の作成 ドライバーの指定と、DBQには、パスのみを指定する
Con = "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & _
Server.MapPath(".") & ";"
'↑MapPathに(".")を渡し、カレントディレクトリを渡す
こんな感じで普通に接続のテストを行ってみます。
http://www.ken3.org/cgi-bin/test/test101-1.asp
↑実行テスト
↓実行結果
日付 IP URL 分数TEST 少数TEST 備考 予備
2004/12/25 192.168 ken3.org 1/20 1.25 備考の文字 2001/02/03
2005/01/08 192.168 /asp/ 1/3 5.1 日付の形式を少し変えた
2005/01/19 17:30:00 192.168 vba 2/7 5 時刻を付けた 2004/05/06
ホントだ、出たよ、不具合が・・・
※だから読者が質問してきたんだろ読者が・・・
/*
* 3.テストデータから不具合のパターンを分析してみる
*/
結果が出たので分析してみます。
192.168.0.1 や 192.168.0.25 、 192.168.0.17
が、
192.168
と、なってしまった。
ここは、純粋に文字列で扱ってほしかったのに・・・
次に、小数点付きの数値をテストしてみると、
1.25 5.10 5
は、5.1となっているので、数値扱いされている。
頭に戻って日付、
2004/12/25 と 2005-01-08
どちらも、日付と認識されるのか、
2005-01-08が2005/01/08となった。
興味があるのが、年が無くて、月日だったら?
1/20は、変換して1月20日と見るのか、文字列の1/20と見るのか気になった。
1/20 1/3 2/7 は、大丈夫みたいだ。
とすると、あとは、2000年問題で流行った、yy-mm-dd形式は?
そこで、
1-2-3 と 04-05-06をテストしてみた。
なんと、2001/02/03と2004/05/06と自動変換されていた。
原因を探っていくと、
CSVファイルには、フィールドの型情報が無いので、
先頭から数行のデータを使って、フィールドの型を判断していて、
文字列でそのまま扱ってほしいのに、
これは日付、これは小数点付き数値などと自動で決めてしまう。
チラッと頭の毛が金髪とみただけで、心の中まで見ないで、
不良と決め付けている大人みたい・・・
なんて冴えない話は置いといて、どうしましょう???
参考資料:
http://support.microsoft.com/default.aspx?scid=kb;ja;278973
>データ型
>Excel テーブルは、従来のデータベースとは異なり、列に直接データ型を指定
>する方法がありません。代わりに、列の中の一定数の行が OLE DB プロバイダ
>によりスキャンされ、そのフィールドのデータ型が推測されます。スキャンさ
>れる行数は、デフォルトでは 8 行ですが、接続文字列の拡張プロパティで、
>MAXSCANROWS 設定に 1 〜 16 の値を指定することでスキャンされる行数を
>変更できます。
CSVの資料じゃないけど、8行スキャンして、データ型を決めているのかなぁ。
/*
* 4.原因がわかったら対策を立てるのでは?
*/
原因が頭だけ見た自動判断なら、頭に文字列のデータを置けばいいんじゃない?
チラッと頭の毛が金髪とみただけで不良少年と決め付ける大人がいるんなら、
先頭が1人でも黒髪だったら、鼻ピアスヘソピアスもOKで通るのかな。
初めだけ猫かぶるじゃないけど、先頭行を完璧な文字列として扱うように細工すれば?
いいんじゃないの?
先頭行に礼儀正しいダミー君、ダミーのデータを送り込むとか?
えっ、そんなことするの・・・セコ。。。
/*
* 5.ダミーファイルを先頭で読むか(UNION ALL でつなげるか・・・)
*/
もし、可能なら、フィールドがひと目で見てわかる、
優等生軍団じゃなくて、ダミーのファイルを1つ作成します。
ファイル名 dummy101.csvなどで1行型決めをする
http://www.ken3.org/cgi-bin/test/dummy101.csv
日付,IP,URL,分数TEST,少数TEST,備考,予備
2000/01/01,ABCDEFG,文字だよ,ここも文字,9.999,備考は文字,予備も文字列
上記を作成して、
select * from dummy101.csv
UNION ALL
select * from test101.csv
とSQLを発行してみた↓。
http://www.ken3.org/cgi-bin/test/test101-2.asp
が、
結果は、変わらなかった(笑)
修正構想は、崩れ去った・・・
/*
* 6. それならと思い、ADOでCSVに接続して .GetString を テストしてみた
*/
他に何か無いかなぁと探ってみて、
.GetString
なんてメソッドをADOで発見した。
.GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)
戻り値
Recordset をバリアント型 (Variant) 変数 (BSTR) の文字列として返します。
単語だけ見ると Get String これって文字列だよな?
.GetString(adClipString, 行数, 区切り文字, 行間の区切り, NULL時の代替)
を指定できるので、
.GetString(adClipString, , vbTab, vbCrLf, vbNullString)
と、
タブ区切り、CRLFで改行された文字列を指定してみた
期待に胸を膨らませ、テストしてみた。
http://www.ken3.org/cgi-bin/test/test101-3.asp
↑.GetStringをテストしてみた
Response.Write "<PRE>"
strDATA = rs.GetString(adClipString, , vbTab, vbCrLf, vbNullString)
Response.Write strDATA '内容を表示する
Response.Write "</PRE>"
とするが、期待通りの結果は得られず。
※データがタブと改行で区切られたので、
別の処理では何か使えるかもしれないメソッドですが、
期待した無変換では、無かったです。
/*
* 7.終わりの挨拶 </HTML>
*/
今回は、
ADOでCSV接続したときに、
192.168.0.1
が、
192.168
と
なってしまう件を調査したのですが、解決しませんでした。
やはり、テキストファイルで開いて、
自分でSplit関数で分解するしか無いのかなぁ・・・
奥が深いですよね。
今回も解決していないのですが、
何かの参考となれば幸いです。
ASP、VBScript勉強中の三流プログラマーのKen3でした。
フィードバック
で、解決したのが↓
[No.102 ADO CSV接続 schema.iniを使い型を設定してみた]
で、schema.iniに型を指定して読み込むことができるみたいです。
ASP系の→[掲示板]←を覗く、質問を書き込む
評価・感想
三流君の主なリンク先
[アクセスランキング]
[サイトマップ]
[リンク先・相互リンク先など]
Ken3の日記(weblog) --
[プログラマー業務の愚痴]
[VBA系の話題]
[ASP系の話題]
[コンビニ系ネタ]
[その他]
その他 宣伝広告