トップ回答者
Microsoft.Jet.OLEDBでxlsファイルを読むと一部のカラムで文字が切れる

質問
-
お世話になります。VS2010で以前作成したアプリですが、この1、2週間ほどおかしな現象に悩まされています。
おかしな現象とは、下記コードでxlsファイルを読めるのですが、一部のカラムで文字列が末尾2文字(程度?)切れてしまいます。
普通にExcelで読ますと問題なく読めます。以前から使用していたアプリで、これまでは問題なく読み込めました。
作成元(弊社でなく他社からもらうファイル)に確認しても特に変わったことはないようです。
現状では、アプリで読めないので一旦エクセルに取り込みCSVで保存し直して読んでいます。
エクセルでは問題ないので、アプリ側の問題?と思っていますが・・・それまではOKだったのに・・・
この件、何か情報ないでしょうか?よろしくお願いします。VS2010 C# WinForm
var cnnStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;IMEX=1;HDR=NO\"", "ファイル名.xls"); var cnn = new System.Data.OleDb.OleDbConnection(cnnStr); var dt = new DataTable(); try { cnn.Open(); var schemaTable = cnn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null); if (schemaTable.Rows.Count < worksheetNumber) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet"); string worksheet = schemaTable.Rows[worksheetNumber - 1]["table_name"].ToString().Replace("'", ""); string sql = String.Format("select * from [{0}]", worksheet); var da = new System.Data.OleDb.OleDbDataAdapter(sql, cnn); da.Fill(dt); <- 読み込みは正常に終わりますが、カラムのデータが末尾2文字切れてしまう }
カラムのデータが切れるとは、以下のようにF11は日付で本来「20180926」となる。F13は、生年月日で日付が切れています。
F12、F14、F15は1文字のデータで、切れることなく正しく残っています。ある程度の文字数がある文字列が切れるようです。
対象のフレームワーク: .Net Framework 4
ビルドのプラットフォーム ターゲット x86 でコンパイルしています。
- 編集済み ferret001 2018年9月27日 3:29 修正・追加
回答
-
> 結局、現状、何ともし様子がないのでしょうか?
JET がダメなら ACE を使って試してみてはいかがでしょう?
行き当たりばったり式ではあまり好まれない方法かもしれませんが、万策尽きているならやむを得ないかも。
佐祐理さんがレスされている修正の不具合で JET だけの問題であれば解決する可能性はあります。
2007 Office system ドライバ: データ接続コンポーネント
https://www.microsoft.com/ja-jp/download/details.aspx?id=237342007 用のドライバは 32-bit 版のみですが、2010 以降用のドライバには 32/64-bit 版の両方があります。64-bit 版の Office をインストールしていると 64-bit 版のACE も一緒にインストールされているかもしれません。32/64-bit 版は共存できませんので注意してください
また、今回の話とは直接関係ないですが、Visual Studio から Access DB に接続して開発を行うような場合、Visual Studio は 32-bit ですので、ドライバに 64-bit 版を使うと、接続できませんので注意してください。
きちんとインストールできれば以下の記事の画像のように Visual Studio を接続できるようになります。
Access 2007 の DB を利用するアプリ開発
http://surferonwww.info/BlogEngine/post/2011/11/08/Development-of-application-which-uses-accdb-file-of-Access-2007.aspx -
回答ではないのですが、
MicrosoftのJETデータベースエンジンにゼロデイ脆弱性という問題がありました。指摘されたうちCVE-2018-8392とCVE-2018-8393は9/12の月例更新で修正されています。時期的に見てこの修正に不備があったのかもしれませんね。Microsoft社に報告した方がいいかもしれません。
- 回答としてマーク ferret001 2018年10月1日 2:20
すべての返信
-
回答ではないのですが、
MicrosoftのJETデータベースエンジンにゼロデイ脆弱性という問題がありました。指摘されたうちCVE-2018-8392とCVE-2018-8393は9/12の月例更新で修正されています。時期的に見てこの修正に不備があったのかもしれませんね。Microsoft社に報告した方がいいかもしれません。
- 回答としてマーク ferret001 2018年10月1日 2:20
-
とりあえずは、ご自分で新しくxlsファイルを作って、問題となっているxlsファイルの内容をまねてシートを作成し、プログラムで読み込ませてみる、ってところから検証されてみてはいかがでしょう。
ご質問だけでは、DataTableに格納されている値が既におかしいのか、それとも表示がおかしいだけなのか、すら判断できないので。
あと、「実行環境の」OSバージョンは最低限書いておくべきかと思います。
// なお、Win10.1803にWindows Update全部入れた環境で、似たようなシートを作って同じコードで読み込ませましたが問題なかったです。
- 編集済み Hongliang 2018年9月28日 2:05
-
> 結局、現状、何ともし様子がないのでしょうか?
JET がダメなら ACE を使って試してみてはいかがでしょう?
行き当たりばったり式ではあまり好まれない方法かもしれませんが、万策尽きているならやむを得ないかも。
佐祐理さんがレスされている修正の不具合で JET だけの問題であれば解決する可能性はあります。
2007 Office system ドライバ: データ接続コンポーネント
https://www.microsoft.com/ja-jp/download/details.aspx?id=237342007 用のドライバは 32-bit 版のみですが、2010 以降用のドライバには 32/64-bit 版の両方があります。64-bit 版の Office をインストールしていると 64-bit 版のACE も一緒にインストールされているかもしれません。32/64-bit 版は共存できませんので注意してください
また、今回の話とは直接関係ないですが、Visual Studio から Access DB に接続して開発を行うような場合、Visual Studio は 32-bit ですので、ドライバに 64-bit 版を使うと、接続できませんので注意してください。
きちんとインストールできれば以下の記事の画像のように Visual Studio を接続できるようになります。
Access 2007 の DB を利用するアプリ開発
http://surferonwww.info/BlogEngine/post/2011/11/08/Development-of-application-which-uses-accdb-file-of-Access-2007.aspx -
>ご質問だけでは、DataTableに格納されている値が既におかしいのか、それとも表示がおかしいだけなのか、すら判断できないので。
あと、DataTableのカラムの定義がどうなっているかですね。読み込む際に最初の8行でデータの型を判定していたと思いますが、その判定がおかしいのかもしれません。記憶が定かではなく、その対策を示すページも今は見れなくなっていたので、間違っていたらごめんなさい。
# 佐祐理さんが書かれている、CVE-2018-8392とCVE-2018-8393のリンク先が開けないのですが、私だけかな?
★良い回答には質問者は回答済みマークを、閲覧者は投票を!
-
時間を掛けて悩む位なら、ヘッダーありの状態にするため、excelシートを別のシートなどにコピーすることをお勧めします。
私もちょうど12列までうまく行き、13列目が小数点を含む数字のときだけnullになりました。
そうすると、ヘッダーがある、値はすべて文字とする、となり成功しました。
参考にしたurl
https://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=35570&forum=26
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & strDir _
& ";Extended Properties=""Excel 8.0;IMEX=1"""
上記のようにIMEX=1を追加してすべての行を文字列としてみなすようにしました。わざわざヘッダーを付けるためにコピーペースするワンクッションが無駄な作業が増えた感じもありますが
それで成功するなら、よしとしました。観点がずれていたら、ごめんなさい。
投稿日時: 2006-12-20 17:12返信が遅くなりまして申し訳ありません。
platiniさんのやり方(範囲指定)では、自分の所では無理でした。
しかし、参照ページを拝見して原因がわかりましたので記述します。
SELECT文で検索すると、その列に文字と数字のどちらが多いかを判断し
多いほうにするそうです。
自分の場合、数字が圧倒的に多いのでその行を数字の行とみなしてそのほか(文字列)を
NULLと認識しました。
解決策として
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & strDir _
& ";Extended Properties=""Excel 8.0;IMEX=1"""