[リストへもどる]
一括表示

投稿時間:2003/12/10(Wed) 19:01
投稿者名:太郎
URL :
タイトル:
EXCEL形式のファイルをADOで読み込む
こんばんわ、VBでプログラムを開発中ですが、行き詰まってしまったので教えて頂けないでしょうか?
EXCEL形式のファイルをADOで読み込むのですが、FIELDの値がNullになる事があるので困っています。

こちらのサンプルプログラムを参考にEXCELファイルからの読込部分を作成しました。
以下のような感じです。

    strProvider = "Provider=MSDASQL;Extended Properties="""
    strDriver = "Driver={Microsoft Excel Driver (*.xls)};DBQ="
    strConnection = strProvider & strDriver & DirPathDB & "\" & FileNameDB & """"
    adoCN.ConnectionString = strConnection
    adoCN.Open     'コネクションをオープン
    
    strSql = "SELECT * FROM [SHEET$]"
    adoRS.Open strSql, adoCN, adOpenForwardOnly, adLockOptimistic, adCmdText

ここでadoRS.Fields(1)の値がきちんと読めたりNullになったりします。

EXCELファイルの内容は以下のような感じです。属性はすべて文字列としています。

機能名        項目数
保存        8
表示位置    標識    日本語名    項目名        カラム幅
1        ORADB    日付        DDATE        1800
2        ORADB    キー        KEY        1800
3        ORADB    名称1        NM1        2500
        :
8        ORADB    …

ファイル形式をEXCELにしたのは同様の形式の定義が複数有り、それをシート単位で管理したかったの
と実行環境では不用意に変更されないようするためです。(実行環境にはEXCELはインストールしない)

上記の項目数から読み込むレコード数を決定するのですが、この値が読めたり読めなかったりします。
一旦数値属性にして保存してから文字列属性に変えると読める時もありますが不定です。
何かヒントでも良いので助けて頂けないでしょうか?

ちなみにADOを使うのは今回が初めてで、サンプルプログラムを元に試行錯誤で作成しました。

投稿時間:2003/12/10(Wed) 23:28
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: EXCEL形式のファイルをADOで読み込む
同じ列内で文字列と数値のデータが混在していませんか?
その場合Excelの方で文字列にしてもだめだったような!
多分、DAO同様 8行目までのデータで多い方のデータ型に自動的に設定
されるのだと思います。(あくまで私の推測ですが)

DAO なら IMEX=1 とすれば8行目までのデータが同一カラム(列)内に
混在している場合 テキスト型として扱いますが、ADOの場合同様にできるかは知りません。

Excelの場合はSCHEMA.INIも効かないし、 ADOでなくてもよいのならDAOを試して見て下さい。
サンプルはMSFlexGrid関係にあります。

投稿時間:2003/12/11(Thu) 20:51
投稿者名:太郎
Eメール:nomura@mahoroba.ne.jp
URL :
タイトル:
Re^2: EXCEL形式のファイルをADOで読み込む
レスありがとうございます。

> 同じ列内で文字列と数値のデータが混在していませんか?
確かにデータが入っていない行の部分にコメントなどを入れているので、第一列
以外は書式設定していない気がします。そのせいでしょうか?
試してみます。

> 多分、DAO同様 8行目までのデータで多い方のデータ型に自動的に設定
> されるのだと思います。(あくまで私の推測ですが)
なるほど、そんな仕掛けになってるんですね。

> DAO なら IMEX=1 とすれば8行目までのデータが同一カラム(列)内に
> 混在している場合 テキスト型として扱いますが、ADOの場合同様にできるかは知りません。
確かに以前にDAOで同じような事をやった時は読めてました。
ADOにはそのような引数がないのですね。

> Excelの場合はSCHEMA.INIも効かないし、 ADOでなくてもよいのならDAOを試して見て下さい。
別にADOでなくても良いのですが、このファイルから読み込んだ情報を元にORACLEからADOで
読み込むので、同じにした方が問題が少ないかと思っていました。

今は出先なのですが、あとから列全体を文字列属性にするなどを試してみます。
それでダメならDAOですかね。

ありがとうございました。結果についてはまた報告させて頂きます。

投稿時間:2003/12/12(Fri) 11:35
投稿者名:太郎
URL :
タイトル:
Re^3: EXCEL形式のファイルをADOで読み込む
早速、確認してみましたので、そのご報告です。

結果としてはうまくいきませんでした。

列全体を選択して文字列属性に変更したり、左上をクリックしてシート全体を
文字列属性にしたりしましたが、相変わらずNullが返ってきました。

> > 同じ列内で文字列と数値のデータが混在していませんか?
> 確かにデータが入っていない行の部分にコメントなどを入れているので、第一列
> 以外は書式設定していない気がします。そのせいでしょうか?
勘違いしていました。もう一つ同じ形式のファイルがあるのですが、こちらは以前に
DAOで読んでいたファイルを行削除やセルの内容だけ再入力するなどで流用している
ものなのですが、こちらの方がコメントを入れていました。
こちらのファイルは値を入力するすると同様の現象が発生したりしましたが、他のセル
からコピー&ペーストすると値が返ってきたので、そのまま使っています。

質問したファイルは後から新規に作成したもので、8行目以降は何も入力していない
状態でした。

どうもコピペした時にちゃんと読める事があるようなので、以下の事を試してみました。

下記の例の先頭が「1」の行を行ごとコピーして、先頭が「保存」の前の行に挿入
 ⇒挿入した行のFieldsの1〜3は正しく読めた(それ以外は未確認)
  2行目(先頭が「保存」の行)はFieldsの1〜3はすべてNull
コピペした行の先頭のセルに同じ行の「日付」のセルをコピー
 ⇒Fieldsの1はNull、2〜3は正しく読めた
  2行目(先頭が「保存」の行)はFieldsの1〜3はすべてNull

機能名        項目数
保存        8
表示位置        標識    日本語名    項目名        カラム幅
1        ORADB    日付        DDATE        1800
2        ORADB    キー        KEY        1800
3        ORADB    名称1        NM1        2500
        :
8        ORADB    …

レコードの先頭が2バイト文字の場合に何らかの問題があるのでしょうか?
もう一息のところなのですが、なかなかうまくいきません。
以上のことで何か分かりましたらご教示頂けないでしょうか。
よろしくお願いします。

投稿時間:2003/12/12(Fri) 12:24
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^4: EXCEL形式のファイルをADOで読み込む
前回も書きましたがExcelのファイルを使用する場合Excel上で文字列の書式設定を
しても有効になりません。
混在していればどちらかのデータ型のデータが抜けてしまいます。
DAOなら前記の方法で回避できますが。

http://support.microsoft.com/default.aspx?scid=kb;KO;194124

投稿時間:2003/12/12(Fri) 13:51
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^5: EXCEL形式のファイルをADOで
# 以下、ADO + OLE DB Provider for Microsoft Jetの場合について回答していますが、
# DAO や ODBC による接続の場合も、設定項目に関しては同様です。


事前準備:
1. レジストリエディタで、以下の項目を開きます。(Jet 4.0系の場合)
     HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel

2. "ImportMixedTypes" が "Majority Type" に設定されていた場合は、
    "Text" に修正しておいてください。既定値は"Text" です。
    ("Majority Type"の場合、データ型は多数決的に決定されます)

3. "TypeGuessRows" を 0 に設定してください。規定値は 8 です。
    これは、データ型判定に利用される行数を示します。0は全行走査です。


コード:
  拡張プロパティのIMEXフィールドに 1 を指定して、"Import mode"である事を明示します。

    Dim Cn As ADODB.Connection
    Dim RS As ADODB.Recordset
    
    Set Cn = New ADODB.Connection
    Cn.Provider = "Microsoft.Jet.OLEDB.4.0"
    Cn.Properties("Extended Properties").Value = "Excel 8.0; IMEX=1"  '☆ここが重要
    Cn.Open "C:\Book1.xls"
    Set RS = Cn.Execute("[Sheet1$]", , adCmdTable)


なお、レジストリの該当項目を編集すると、他のJETアプリケーションのExcel IISAMの
設定に影響します。通常は、この値を編集しても他のアプリへの悪影響はありませんが、
もし、システム全体に影響させたく無い、という場合は、
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0
以下の設定を、別のキー名…たとえば
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\Orator
などにコピーしておき、コピーした側の設定を編集してください。

その上で、その設定を "Jet OLEDB:Registry Path"ダイナミックプロパティに渡せば、
カスタム設定のレジストリ項目が利用される事になります。
(DAOでいうところの、DBEngineオブジェクトのIniPathプロパティに相当する機能です)

  Set Cn = New ADODB.Connection
  Cn.Provider = "Microsoft.Jet.OLEDB.4.0"
  Cn.Properties("Jet OLEDB:Registry Path").Value = "SOFTWARE\Microsoft\Jet\Orator"

投稿時間:2003/12/12(Fri) 15:51
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^6:EXCEL形式のファイルをADOで・・
フォローありがとうございます。

再度調べていたら、No.285のサンプルで私も
CN.Properties("Extended Properties") = "Excel 8.0;HDR=NO;IMEX=1"
使っていました。
最近、記憶力が低下してきたようです。(;_;)

投稿時間:2003/12/15(Mon) 21:12
投稿者名:太郎
URL :
タイトル:
Re^6: EXCEL形式のファイルをADOで
どうもありがとうございます。

bV080のレスを頂いてから、参照先の文書を参考にして正常に読めるセル
をコピペして正常に読めたのでとりあえず使っていました。

当該処理は初期設定処理の部分なので、本体部分の目処が立ったところでご指導頂いた
ことを試して見ます。

ありがとうございました。

また結果については報告しますが、しばらく間が空くかも知れませんがご了承下さい。

投稿時間:2004/01/05(Mon) 19:57
投稿者名:太郎
URL :
タイトル:
Re^7: EXCEL形式のファイルをADOで
報告が遅くなりまして申しわけありません。

魔界の仮面弁士さんからご教授頂いた方法ですが、レジストリを触るのは
他のマシンに持っていく時やディスク障害による復旧などの時に客先に
作業してもらうのが難しいと言う事で却下になりました。

しかし、レジストリの変更以外を提示された方法に変更したところ安定し
て読込めるようになり、問題は解決しました。

どうもありがとうございました。

ただ、同様の方法でCSVファイルをADOで読込むと500桁の文字列
の場合、IsNullでチェックするとNull以外と判定されるのに、その内容を
代入しようとすると内容がNullになるという奇妙な現象が発生しました。
レコードセットを読込んだ後でブレークして、Fieldの値を参照している
ソースにカーソルを当てると最初に値が表示されて、すぐにNullの表示
になりました。

これはADOの制限かなにかなのでしょうか?

当面は「'」で挟んで代入してから、両端の「'」を外すようにしたところ
値も正しく参照できているようです。

投稿時間:2004/01/05(Mon) 20:15
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^8: CSVファイルをADOで
> ただ、同様の方法でCSVファイルをADOで読込むと500桁の文字列

CSVファイルの場合は、SCHEMA.INI ファイルで解決できるかと思います。
(SCHEMA.INI ファイルでは読込データ型の指定等ができます)
SCHEMA.INI ファイルについては、ここの ADOを使ってCSVファイルをMSHFlexGridに表示する の
下部を見て下さい。