tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルEXCEL シートをレコードセットに取り込む
記事No16508
投稿日: 2019/12/21(Sat) 20:49
投稿者EXCEL使い
EXCELVBAについて質問です。
私は、生業としてVBプログラマをしておるんですが
つい最近、エクセルのシートデータがレコードセットに
取りこめることを知り、目からうろこで開発をしております。

そこで開発していて行き詰ってしまっていろいろなサイトを
探し回ってこのサイトにたどり着いた次第です。
質問というのは、エクセルのシートをレコードセットに
取り込んだ際に、ある特定のセルから先の情報がレコードセットに
取り込むことができないということです。
取り込み元のシートは、A列からDW列まで127列あるシートで
それを、シートとコネクトして取り込む方法で行っています。
ですが、取り込んだ後ウォッチで中身を見るとItem(10)以降が
全てNull値になってしまって値が取り込めないのです。
原因がわからず悩んでしまって、どうにかならないかと思って
投稿させていただきました。お教授いただけると幸いです。

[ツリー表示へ]
タイトルRe: EXCEL シートをレコードセットに取り込む
記事No16509
投稿日: 2019/12/21(Sat) 22:07
投稿者魔界の仮面弁士
Recordset として取り込む際のミドルウェアとして、
OLE DB の JET Provider ないしは ACE Provider さもなければ
ODBC の Excel Driver あるいは、DAO の Excel I-ISAM 機能を
使っているものと推察します。


これらの機能を使って、Excel 表や HTML 表からデータを取り込む場合、
先頭n件のデータ内容(既定では 8 行目まで)によって、
そのフィールドのデータ型が自動判断される仕様です。

その結果、そのフィールドが数値型や日付型やブール型と判断された場合には、
それに合致しないデータが含まれていたセルに関しては、取り込み時に
値が Null(もしくはエラー)として扱われる仕様になっています。


これについては、接続時の文字列パラメーターに対して『;IMEX=1』を付与することで、
この問題を改善することができるでしょう。どのミドルウェアで接続しているかによって
設定場所が異なりますが、ひとまず下記が参考になるかと思います。

http://hanatyan.sakura.ne.jp/vbhlp/dao_002.htm
http://www.hanatyan.sakura.ne.jp/logbbs/wforum.cgi?no=7083&reno=7080&oya=7027&mode=msgview



ちなみにレジストリには、この型判定の行数等を設定するための項目が存在します。
Jet 3.0〜3.5 の場合、Jet 4.0 の場合、ACE の場合、そして 32bit/64bit ととで
それぞれレジストリキーの場所が異なりますが、内容は基本的に同じです。下記を参照。
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/initializing-the-microsoft-excel-driver?WT.mc_id=DT-MVP-8907&tabs=office-2016

このレジストリ設定は HKEY_LOCAL_MACHINE 配下の設定を元に動作しますが、
自分のアプリだけを別設定としたい場合は、HKEY_CURRENT_USER の下に設定して、
そのレジストリパスをプログラムから渡すことでカスタム動作に変更できます。

…とはいえ、通常の案件でレジストリを操作する必要はほぼ無いでしょう。
まずは IMEX=1 の指定を試してみてください。

[ツリー表示へ]
タイトルRe^2: EXCEL シートをレコードセットに取り込む
記事No16510
投稿日: 2019/12/22(Sun) 13:37
投稿者EXCEL使い
魔界の仮面弁士さん、返信ありがとうございます。

> Recordset として取り込む際のミドルウェアとして、
> OLE DB の JET Provider ないしは ACE Provider さもなければ
> ODBC の Excel Driver あるいは、DAO の Excel I-ISAM 機能を
> 使っているものと推察します。
使っているのは、Excel Driverだったと思います。

> これらの機能を使って、Excel 表や HTML 表からデータを取り込む場合、
> 先頭n件のデータ内容(既定では 8 行目まで)によって、
> そのフィールドのデータ型が自動判断される仕様です。
>
> その結果、そのフィールドが数値型や日付型やブール型と判断された場合には、
> それに合致しないデータが含まれていたセルに関しては、取り込み時に
> 値が Null(もしくはエラー)として扱われる仕様になっています。
なるほど〜、その読み込み元のシートの1列目は日付データが入っていて
以降は、数値データが入っています。
SQL文でASを使ってフィールドの名前を変更したりしましたが駄目だったので
もしかしたらその関係かもしれませんね。

> これについては、接続時の文字列パラメーターに対して『;IMEX=1』を付与することで、
なるほど〜、そういえばこの方法を調べているときにそんな記事を見た記憶が
あります。その時は何のことやらと流してしまっていました。
明日、出社したら試してみます。
ありがとうございました。

[ツリー表示へ]
タイトルRe: EXCEL シートをレコードセットに取り込む
記事No16511
投稿日: 2019/12/23(Mon) 19:40
投稿者EXCEL使い
魔界の仮面弁士 さま

お世話になります。
先日ご教授いただいた方法の実装報告です。
教えていただいた方法を実装した結果
無事、すべての列を取得することができました。
ありがとうございました。
毎度、魔界の仮面弁士さまの深い知識に助けられて
おります。本当にありがとうございます。
今回は、現在従事している現場の規定で情報漏洩防止のため
掲示板への書き込みが禁止になっているため
自宅からの投稿でした。
そのため、詳しいソースも載せることもできない中
ご教授いただき助かりました。
ついでに、1つ質問なんですがレコードセットの列の限界は
いくつくらいなんでしょうか?
実は、別シートで同じようにデータを取り込んでいるのですが
そちらでは、『オブジェクトが見つかりません』みたいな
エラーが出てしまいます。
そのシートというのは、272列あるシートでどうも255列を超えると
上記のエラーが出ます。
255列以内であれば、すべての列がエラーなく取れます。
ですので、今は急場の策としてSELECTするフィールドを255列以内に
しています。
ですが、すべての列にデータが入っている可能性があるのでできれば
レコードセットで取りたい思っています。
やはり、仕様で255列までなんでしょうか?
よろしくお願いします。
それと、もう一つ質問があるのですが
それは、また別スレッドを立てます。
ありがとうございました。

[ツリー表示へ]
タイトルRe^2: EXCEL シートをレコードセットに取り込む
記事No16513
投稿日: 2019/12/24(Tue) 00:07
投稿者魔界の仮面弁士
> やはり、仕様で255列までなんでしょうか?

電車内から投稿しているので、資料をきちんと
調べたわけでは無いですが、確か255上限だったはず。

https://support.office.com/ja-jp/article/access-%E3%81%AE%E4%BB%95%E6%A7%98-0cf3c66f-9cf2-4e32-9568-98c1025bb47c

シート全体を読み込もうとするのではなく、
255列までとなるようなセル範囲を指定して
複数回に分けて分割して取り込むという手もあります。
ちょっと面倒ですけれどね。

[ツリー表示へ]
タイトルRe^3: EXCEL シートをレコードセットに取り込む
記事No16514
投稿日: 2019/12/24(Tue) 04:49
投稿者EXCEL使い
魔界の仮面弁士さま、返信ありがとうございます。

> 電車内から投稿しているので、資料をきちんと
> 調べたわけでは無いですが、確か255上限だったはず。
そうみたいですね〜。リンク先を見てみても最大フィールド数255って
書いてりますね。

> シート全体を読み込もうとするのではなく、
> 255列までとなるようなセル範囲を指定して
> 複数回に分けて分割して取り込むという手もあります。
> ちょっと面倒ですけれどね。
ああ、そうなんですね。そんな方法があるんですね。
私には、思いつきもしませんが。
ただ、シートとしては270列以上あるんですがその全てを
使っているわけではなく、1〜255の条件を設定できる
ために用意している箱のような意味合いなので無理して
レコードセットではなく配列に取るようにして
その際に、使っている範囲(例えば1〜60がAの商品用みたいに)
を調べて格納する方法でもいいのかなと思っていて
今は、別の方法を模索中です。
今回は、ありがとうございました。

[ツリー表示へ]