● ADO:Excel2010で、開かれていない閉じたままのブック・Excel(xls)データをできるだけ速く読み込む方法ーその2(ADOにて)
目次
★ サンプルファイルのダウンロードとプログラムコード
★ ACEエンジン系の方法と、JET系の方法の比較メモ
★ レコードセットの範囲設定の方法各種
★ Cnの接続文字の、ISAM形式について
★ 参考Web記事
※Shift+TABキー、もしくは、Homeキー、Homeキー+TAB数回、を押すと、目次付近に戻れます。
※関連記事
『Excel2010で、開かれていない閉じたままのブック・Excel(xls)データをできるだけ速く読み込む方法(DAOにて)』
『~SQLにて「閉じたExcelファイルを ”閉じたまま” 書き込む方法01」~Microsoft Queryを利用する場合~』
『Excel2010で、『 開かれていない閉じたままのブック・Excel(xlsやxlsx・xlsm)ファイルのデータ 』を読み込むだけでなく、書き込む方法の一覧表(DAOやADOにて)』
『ADO:Excel2010で、開かれていない閉じたままのブック・Excel(xls)データをできるだけ速く読み込む方法ーその2(ADOにて)』
『Access2000VBA・Excel2000VBA独学~別の閉じたExcelファイルを ”閉じたまま” 読み込みや書き込をする方法~5つ』
サンプルファイルのダウンロード
https://euc-access-excel-db.com/00000WPZIP/tes1_ADO.zip
※ウィルスチェックはVirustotalで行いました。
サンプルファイルの名前は、「tes1_ADO.xlsm」です。
解凍してから「Dドライブにtest01というサブフォルダをつくりその中」とデスクトップの2か所にコピペして、デスクトップ側の「tes1_ADO.xlsm」から試してみてください。
Sheet2が選択されて開いているとおもいますので、そのままの状態で、「開発」タブから「Visual Basic」のボタンを押して、VBE(Visual Basic Editor)を開きます。
その後、「Module1」の「ReadByADO01」を実行します。(プログラム内のどこかをいったんクリックしてから、F5キーを押すと実行できます。)
2010以降でファイルを開いた場合は、「コンテンツの有効化」を押してからお試しください。
このサンプルは別ファイルの「d:\test01\tes1_ADO.xlsm」の、「静的な表-意外とわかりにくい」というシート(複数のクロス集計表があるシート)の内容の一部を、Sheet2に吸い込み・転記するものです。(「静的な表-意外とわかりにくい」というシートはADOにて「システムテーブル」として扱っています。あと、Sheet2はだいぶ後ろのほうのシートです。)
VBEの「ツール→参照設定」にて、「Microsoft ActiveX Data Objects 2.8 Liblary」にチェックが入ってないとエラーになりますのでそこを事前に確認してください。
※「SrcXLFName = "d:\test01\tes1_ADO.xlsm" 」の行で、右辺の「"d:\test01\tes1_ADO.xlsm"」を、「UNCパス」で記述して、ファイルサーバの共有フォルダに在るExcelファイルを指定することもできます。つまり、LAN経由での読み込みもできます。
その際は右辺を「"\\ファイルサーバー名\共有フォルダ名\tes1_ADO.xlsm"」みたいな感じに書き換えます。
(ここでは、「\」は、半角の「¥」を意味しています。)
では、以下、サンプルプログラムです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
' ' Option Explicit Sub ReadByADO01() '★ 変数設定とオブジェクト変数について Dim Cn As ADODB.Connection '読込対象のXLSファイルの「ADO接続文字用のオブジェクト」用の変数 '文字列型かとおもったらオブジェクト型でした・・・。 'DAOでいうと、DAOでよく使われる「db」とか「dbs」といった 'オブジェクト(あるいはオブジェクト変数)と同じ・・・って感じなんですね。 'DB=Cn=というオフジェクト、つまりVBAプログラム内で '「ファイルというオブジェクト」を操作できるようにするために利用します。 'そのためのオブジェクト変数。 'CnにExcelファイルのパスやその他の設定をこの変数に代入することで、操作可能となります。 Dim Rs As ADODB.Recordset '読込対象のシートの「ADOデータ範囲?設定用のオブジェクト=レコードセット」用の変数。 'ADOやDAOでは、純粋なExcelオブジェクトのように '「Excelシート(セル)の値やAccessテーブルをダイレクトにいじる」というこができません。 'いったん「レコードセット」と呼ばれる、「動的な表を一時保管する器」の中に、 '加工対象の表、あるいはシートの中の任意の表範囲をいったん仮格納する必要があります。 'で、その中でいろいろといじってから、その結果を、元のシート(セル)等々に返します。(反映させます。) 'ここでの例の場合は「Rs」というオブジェクト変数に、 'シートの名前・あるいはSQL文とその他の設定値を代入することで、 'VBAプログラム内でレコードセットが操作できるようになります。 '「Rs」は、そのためのオブジェクト変数です。 Dim SrcXLFName As String '読込対象のXLSファイルのフルパス格納用の変数 Dim SrcSHTName As String '読込対象のシート名の格納用の変数 Dim StrSQL01 As String Dim WS01 As Worksheet '自ファイルのデータ転記対象のシートを格納(=指定)するためのオブジェクト変数 Dim i As Integer 'そのシートの行数を表すための変数 '================================== '★ ちょと関係のある脱線:「オブジェクト変数」とは? '以降の(01)~(06)の内容をもう少し詳しく書き換えた以下のURLのほうもご参考にしてみてください。 ' 『用語:「オブジェクト変数」とは?(ついでに「コレクション」についても少し・・・)』 'https://euc-access-excel-db.com/tips/ct90_yougo/obujekuto-hennsuu-toha01 ' '「オブジェクト変数」とは、文字列や数値ではなく、「オブジェクト」という '「ユニット丸ごと・その機能丸ごと」を「代入」できる変数のことです。 ' '「オブジェクト」とは「セル、シート、ブック、ピボットテーブル、コマンドボタン、エラー管理機能」等々、 ' 目に見える・見えないに関係なく、各種の機能・メニューコマンドたち」のことをさします。 ' 'イメージ的には・・・、 ' 通常の変数には文字列か数値やYes/Noなどしか代入できませんが、 '「オブジェクト変数」には '「前述のような”オブジェクト”が持つ機能丸ごとも含めて、オブジェクトそのもの」を ' 代入できる・・・、そんなイメージです。 ' 'で、実際に「オブジェクト変数」にオブジェクトを代入する、といった場合・・・、 ' '例えば(のちにも出てきますが)、「静的な表-意外とわかりにくい」という名前の「シート」丸ごとを '「Sht01」というオブジェクト変数に代入した場合は、次のようなことができます。 ' '(01)「静的な表-意外とわかりにくい」という長ったらしい名前の「シート」丸ごとを ' プログラムの中では「Sht01」という「仮名」で書けることになります。 ' プログラムがすっきりとします。 ' '(02)「静的な表-意外とわかりにくい」という名前の「シート」丸ごとを ' プログラムの中では「Sht01」という「オブジェクト」として「操作」、 ' できるようになります。 ' '(03)「操作」とは「メソッド」という命令を使う、という意味でもあります。 ' 普通の変数では、文字列か数値などを加工することしかできませんが、 ' オブジェクト変数に対しては、「メソッド」というオブジェクト専用の命令が ' 使えるようになります。 ' それで「オブジェクト」を「操作」「動かす」ことをします。 ' ちなみに、各「メソッド」たちは特定のオブジェクトに特化・紐付いた命令たちです。 ' 「メソッド」を使うと、オブジェクト(=プログラムとしては「オブジェクト変数」のこと)を ' 自由に「動かす」ことができるようになります。 ' (=オブジェクトの持つ、機能を利用する・動かす、といったことができます。) ' メソッドには ' 例えば「複数ワークシート管理機能(WorkSheets)」というオブジェクトなら、 ' 次のような専用のメソッド(命令)があります。 ' ・Move(××シートの後ろに移動しろ) ' ・PrintOut(印刷プレビューを表示しろ) ' ・PrintPreview(印刷プレビューを表示しろ) ' ・Select(シートを選択しろ) ' ・Copy(シート内のすべてのセルの値や機能はもちろん、シートの持つ機能や設定値等々丸ごと全てをコピーしろ) ' ・Delete(シートを削除しろ) 'すべてのオブジェクトに、同じメソッドが紐付いているわけではありません。 'オブジェクトごとに、使えるメソッドが異なります。 '(03)「オブジェクト(=オブジェクト変数)」が扱えてオブジェクトが動かせるようになると、 ' 各オブジェクトの「プロパティ(性質・特性・各種設定)」の「設定値」や「入力値」などが ' 取得できるようになります。 ' それらを取得することで、 ' 例えば、「もしこのオブジェクトのこの設定値がこの値の場合は、こういう風に動け」・・・ ' ・・・という形の命令を書くことができます。 ' つまり、オブジェクトに対して、「おいおまえ、ロボットのように動け」と命令できるわけです。 ' 普通の変数の場合は、数値や文字列をひったり貼ったり集計したりができるくらいで、 ' 「ロボットのように動け」と命令できません。 ' できたとしも、実際に自動的にロボットのように動くわけでもありません。 ' でもオブジェクト変数があるおかげで、逆にそれがとてもやりやすくなります。 ' '(04)「オブジェクト変数」を使うことで、「オブジェクト」を「まるでロボットかのように」、 ' 動かすことができるようになります。 ' 「メソッド」や「ステートメント」といった命令語たちや ' 「プロパティ」と呼ばれるオブジェクトの持つ各種設定値を使って。 ' '(05)「シートがもつ機能の設定値」・・・、例えば「セルの値」「数式」などを取得することが簡単になります。 ' 例えば、「静的な表-意外とわかりにくい」という名前のシートの、A1セルの数式を取得したい場合は、 ' 「Worksheets("静的な表-意外とわかりにくい").Range("A1").Formula」 ' と書くことで取得ができます。 ' ' が、その「静的な表-意外とわかりにくい」というシートの機能丸ごとを ' オブジェクトとして、「Sht01」というオブジェクト変数に代入してしまうと、 ' 「Sht01.Range("A1").Formula」 ' と短く書いても同じ数式が取得できます。 ' ' ついでに言うと、「セルA1」を表す「Range("A1")」もオブジェクト変数に代入してしまうことができます。 ' ' その場合、例えば「Sht01」のA1セル・・・、 ' ・・・A1セルはVBAでは「Range("A1")」と書き表しますが、 ' それを「CelA1」というオブジェクト変数に代入したとすると ' 「Worksheets("静的な表-意外とわかりにくい").Range("A1").Formula」と長ったらしく書かなくても、 ' 「CelA1.Formula」と、とても短く書くことができます。 ' ' メソッドで言うと、「Copy(=コピーしろ)」という命令を使うことで、 ' 「セルA1をコピーしろ」というプログラムを ' 「Worksheets("静的な表-意外とわかりにくい").Range("A1").copy」と書くのではなく、 ' 「CelA1.Copy」と、短く書けてしまいます。 ' そして、このコピーの場合、セルの値だけでなく、数式もセルの色書式も、 ' セルのもつ機能のすべてをコピーします。 ' (セルA1に色を付けてから「CelA1.Copy」とやると、その直後にどこか適当なセルに ' 「貼り付け」をすると、セルの数式も色も張り付きます。) ' '(06) なお、オブジェクト変数にオブジェクトを代入するには「Set」という命令を使います(それが必要です)。 ' プログラムには、英語の文法のように「構文」があるのですが、 ' その「構文」としては「Set= ××××××」という構文になります。 ' 普通の変数の場合は「=」記号だけで数値や文字列の代入ができますが、 ' オブジェクト変数の場合は、「Set= ××××××」という構文が必要になります。 ' 前述の各例も、省略してしまいましたが、「Set= ××××××」という命令を書くことが ' 前提となっています。 '脱線終わり '================================== '★ 以下、メインプログラムです。 SrcXLFName = "d:\test01\tes1_ADO.xlsm" '読み込みたい先のファイルのフルパスを指定 ' SrcXLFName = "\\ファイルサーバー名\tes1.xls" ' SrcXLFName = "\\ファイルサーバー名\tes1-2.xlsm" SrcSHTName = "静的な表-意外とわかりにくい$" '「静的な表-意外とわかりにくい」という名前のシートを 'システムテーブルとして読み込む設定をする。 '「$」を付けると「システムテーブルとして読み込む」 'という意味になる。 Application.ScreenUpdating = False 'Excelの画面描画をいったん停止。今の画面のまま変化させないようにする。 Set Cn = New ADODB.Connection 'ADOにてのデータ接続(ファイル内容の読み込み)ができるようにするための準備 Set Rs = New ADODB.Recordset 'ADOにてのレコードセット(シート内データ範囲?)が作れるようにするための準備 'ADOで読込先のファイルに接続。(読込先のファイルを開く) '------------------------------------------------------------------------------------------------ 'ACEエンジン系のADO操作(2007以降のxlsm・xlsx・accdb?用のファイルの開き方) 'でもテストしたところ、2000~2003のxlsのファイルもこちらで読めてしまいました。 'しかもJETのように数値が読み込まれないケースがありませんでした。 '複数のクロス集計表があるシート=列名のセルがぐっちゃぐちゃにとびとびに存在するシートの場合は 'こちらのACEエンジン系でやるほうがいいかもです。 '後述の JET形式のように数字が読み込まれないということがないので。 'JET形式では、元シートの8行目だか5行目までを読みにいき、最初に見つかったセルの書式で 'データ型を勝手に決める、というような雰囲気で列のデータ型を決めているようですが、 'その際、クロス集計表が複数あるシートだと、列名が書かれたセルの位置は 'シートの一行目ではなく、ぐっちゃぐちゃなっていて、どこにあるかわかりません。 'で、ADOだかExcelだかが、列名のセルを読んだどき、1行目に列名が無いもんですから、 '列名であっても列名と認識できず「あ、この列は文字列型だ」と判断してしまい、 'データのなる数値のほうを「文字列じゃないから読まなくていい」みたいな感じになってしまって '読んでくれないことがあります。 'ACE形式での読み込みではそれがなく、文字列だろうが数値だろうが、一応、値を読み込んでくれます。 'また、1行名が全部列名で、1シートに1つの動的な表だけ、という場合なら、JET形式での読み込みでも '「読み込めないセルが出てくる」、ということはありません。 ' '(★★★注:後日判明。後述。 ' 新しいJET系のコードでは自動決定された列のデータ型と異なる ' データでも読み込めました。「;IMEX=1」を追記したほうのコードです。 Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ "Data Source=" & SrcXLFName & ";" & _ "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1;Readonly=False""" '------------------------------------------------------------------------------------------------ 'JETエンジン系のADO操作(2000~2003のxls・mdb用のファイルの開き方) 'こちらのコードを使う際は、この前段階の「SrcXLFName = "d:\test01\tes1_ADO.xlsm"」の '内容を、SrcXLFName = "d:\test01\×××.xls" と、xls(2003以前形式)にしてください。 'もちろん、「d:\test01」フォルダの中には、新たに1つ、xlsmのファイルの内容をxlsファイルに '作り直したものを置いておきます。 ' '複数のクロス集計表があるシート=列名のセルがぐっちゃぐちゃにとびとびに存在するシートの場合は '数値が読み込まれない場合があります。 'なのでその場合はACE形式の読み込みのほうがいいかも。 'きっちりした動的な表ならこちらでもOKかと思います。 '(後日判明。以下のコードは自動決定された列のデータ型と異なるデータは ' 読み込めないっぽいです。 'cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & SrcXLFName & ";" & _ "Extended Properties=""Excel 8.0;HDR=Yes;"";" ' '★★★注:成功したコード!!! さらに後日判明!! ' 「Extended Properties」に「;IMEX=1」を追記すると、 ' セルに入力された値に関わらず、以下のコードで全値を読み込めました。 ' 僕の環境だけだといけないので、皆さんもご自分の環境でお試しください。 'Cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & SrcXLFName & ";" & _ "Extended Properties=""Excel 8.0;HDR=YES;IMEX=1""" '------------------------------------------------------------------------------------------------ '「レコードセット」を開くためにSQL文を設定。 '「レコードセット」は、ADOやDAOにて「各種操作ができる表」のことです。 ' ADOやDAOでは、ExcelVBAのように、ExcelシートやAccessテーブル・セルをダイレクトはいじれないので、 ' いったん、「レコードセット」と呼ばれる、ある意味「一時保管用の表」の中に、 ' 加工対象の表、あるいは表範囲を仮格納します。 ' そしてその中でいろいろといじってから、その結果を、元のシートやテーブルに返し(反映させ)ます。 ' Excelの場合は、そのレコードセットは何も指定しなければシート丸ごとか、 ' セル範囲を指定すれば、シートの一部・・・、となります。 ' StrSQL01 = "SELECT * FROM [" & SrcSHTName & "A1:N15" & "]" 'このようにシート名のあとにセル範囲を追記すると、そこまでの範囲を見に行って、その範囲内で、データが入力されている部分を自動判別してくれて、レコードセットを作ってくれます。 StrSQL01 = "SELECT * FROM [" & SrcSHTName & "]" 'セル範囲を指定しないと、シート丸ごとのすべての範囲を見に行って、データが入力されている部分を自動判別してくれて、レコードセットを作ってくれます。 'SQL文にて、レコードセットを開く。「レコードセット=データの入力された範囲?」を決定しつつ。 Rs.Open StrSQL01, Cn, adOpenStatic, adLockOptimistic, adCmdText Set WS01 = Worksheets("Sheet2") 'データを吸い込むシートの定義(データを転記するシートの定義づけ) i = 2 '列名のことを考えて、 '読み込みデータを 2行目から入力したい場合は 2とする。 '「HDR=NO」にしたとき、列名も読み込んで '1行目から入力したいなら 1とする 'ここでは前者でテストしてます。 WS01.Range("A2:C30").ClearContents '読み込み先のファイルの行数が増減するといけないので、 '一応、転記するシートをきれいに空白しておく。 '前回よりデータ行数が少ないと、前回のデータが残ってしまうので。 Do Until Rs.EOF 'SQL文で抜き出したレコードセットの最後の行(=「EOF」)まで。1行ずつ読み行く。 '※「Loop」の行までの作業を繰り返します。 ' Debug.Print Rs(0) & "---" & Rs(1) & "---" & Rs(2) & "---" & Rs(3) & "---" & Rs(17) & "---" & Rs(18) & "---" & Rs(19) ' '目的のシートの A列・B列・C列・・・・に、読み込んだデータを転記 ' '列を列名で指定する場合のやり方 ' WS01.Range("A" & i) = Rs.Fields("F1") 'レコードセット側のカレント行の「F1」列の値を「Aのi」セルに転記 ' WS01.Range("B" & i) = Rs.Fields("F2") 'レコードセット側のカレント行の「F2」列の値を「Bのi」セルに転記 ' WS01.Range("C" & i) = Rs.Fields("F3") 'レコードセット側のカレント行の「F3」列の値を「Cのi」セルに転記 ' WS01.Range("D" & i) = Rs.Fields("F4") 'レコードセット側のカレント行の「F4」列の値を「Dのi」セルに転記 ' ' WS01.Range("G" & i) = Rs.Fields("F18") 'レコードセット側のカレント行の「F18」列の値を「Gのi」セルに転記 ' WS01.Range("H" & i) = Rs.Fields("F19") 'レコードセット側のカレント行の「F18」列の値を「Hのi」セルに転記 ' WS01.Range("i" & i) = Rs.Fields("F20") 'レコードセット側のカレント行の「F20」列の値を「iのi」セルに転記 ' '------------------------------------------------------------------------------------------------ '列を列名で指定する場合のやり方 WS01.Range("A" & i) = Rs.Fields(0) 'レコードセット側のカレント行の「F1」列の値を「Aのi」セルに転記 WS01.Range("B" & i) = Rs.Fields(1) 'レコードセット側のカレント行の「F2」列の値を「Bのi」セルに転記 WS01.Range("C" & i) = Rs.Fields(2) 'レコードセット側のカレント行の「F3」列の値を「Cのi」セルに転記 WS01.Range("D" & i) = Rs.Fields(3) 'レコードセット側のカレント行の「F4」列の値を「Dのi」セルに転記 WS01.Range("G" & i) = Rs.Fields(17) 'レコードセット側のカレント行の「F18」列の値を「Gのi」セルに転記 WS01.Range("H" & i) = Rs.Fields(18) 'レコードセット側のカレント行の「F18」列の値を「Hのi」セルに転記 WS01.Range("i" & i) = Rs.Fields(19) 'レコードセット側のカレント行の「F20」列の値を「iのi」セルに転記 ' '------------------------------------------------------------------------------------------------ Rs.MoveNext '読み取り先のデータ(SQL文で抜き出したレコードセット)の次の行に移動 i = i + 1 '自ファイル側(Excelファイル側)も次の行に移動 Loop Rs.Close: Set Rs = Nothing ' 作ったオブジェクトの破棄:一応メモリリークを起こさないように?作ったオブジェクトをメモリから消す Cn.Close: Set Cn = Nothing ' 同上 Application.ScreenUpdating = True 'Excelの画面描画を再開。画面の変化が普通に表示されるようにする。 End Sub ' ' |
ACEエンジン=Excel2007~2016の場合
'------------------------------------------------------------------------------------------------
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strFileName & ";" & _
"Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1;Readonly=False"""
'------------------------------------------------------------------------------------------------
xlsmはもちろん読めますし、かつ、xlsも読めます。
(xlsでも「12」のままで読めるみたいです。12とかは)
こちらの形式で読みに行くと、
1枚シートに複数のクロス集計表がある場合、
DAOと同じようにすべてのセルの値を、
1列の中にあるセルのデータの表示形式(データ型)が違っていても、
読み込めるみたいです。
8行目までのセルの値でデータ型が決まるらしいです。
JETのほうの接続文字だと、
8行目以前と以降のデータ型が違うと、
8行目以降が空白で読み込まれてしまいます。
(ちゃんと読み込む方法があるのかも?)
もしDAOではなく、「ADOでやる場合は」、
8行目以前と以降でデータの表示形式(データ型)が
違う場合は、「JET形式でちゃんと両方とも読みこめるやり方」が
見つかるまでは、xlsm、xlsx、xls、すべて、
ACEエンジンの構文で読みにいくほうが良いっぽいです。
(JET形式にもともとそういう方法が無いかもしえないけど)
===================
JETエンジン=Excel2000~2003の場合
'------------------------------------------------------------------------------------------------
'cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strFileName & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes;"";"
'------------------------------------------------------------------------------------------------
こちらの形式では、xlsmやxlsxはもともと読めません。
xlsはもちろん読めるけど、でも、
8行目以前と以降のデータの表示形式(データ型)が違うと、
8行目以降(あるいは最初に認識されたデータ型以外のデータ型)は
空白で読み込まれてしまいます。
(特に、1シートに、複数のクロス集計表があって、「列名」のセルの位置がぐっちゃぐちゃで、正しく「シートの行番号1の行」に無い場合。)
なので、動的な表以外はJETエンジンの構文で読み込まないほうがいいかもです。
(ちゃんと読み込める方法が見つかるまでは。見つからないかもだけど)
'注:成功したコード!!! 後日判明!!!!
'「Extended Properties」に「;IMEX=1」を追記すると、
'JET形式でのアクセスでも、セルに入力された値に関わらず、全値を読み込めました。
'読めたのは今のところ「xls」拡張子のファイルだけですが・・・。
'僕の環境だけだといけないので、皆さんもご自分の環境でお試しください。
'こちらの環境としてはWindows10+Excel2010です。
'その環境にて、xlsファイルを読みにいった場合のテスト結果です。
Cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & SrcXLFName & ";" & _
"Extended Properties=""Excel 8.0;HDR=YES;IMEX=1"""
※「IMEX=1」などの値については、『Excel2010で、開かれていない閉じたままのブック・Excel(xls)データをできるだけ速く読み込む方法(DAOにて)』の「(02)読み込み時の列名について」の後半部分(この項の図のすぐあと)をお読みになってみてください。(あるいは(03)のすぐ上。)
あるいは、こちら→『DAOでExcelデータを読み込みテキストボックスに表示』
★ レコードセットの範囲設定の方法各種
こちらの→「ADO.NETでExcelファイルに接続する」のサイトに、詳しいCnの接続文字の説明があります。
ここから少し引用させていただきます。
=========引用ここから========
【接続文字について】
?Provider: Microsoft.ACE.OLEDB.12.0
?Data Source: ファイル名
?Extended Properties: ISAM形式; オプション
ISAM形式は Excel 12.0、Excel 12.0 Xml、Excel 12.0 Macro、Excel 8.0 など。 HKLM\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access\Access Connectivity Engine\ISAM Formats (もしくはそれに準ずる場所)で一覧が見れます。オプションは・・・
? HDR=NO:ヘッダ行なし(F1, F2, ...といった列名になる)
? MAXSCANROWS=[1..16]:データ型の自動判定に使われる行数
【レコードセットのデータ範囲について】
?[名前](Excelで定義した領域名)
?[シート名$](データが入力されている左上から右下までの範囲)
?[シート名$名前]
?[シート名$セル範囲]([シート名$] の範囲内のみ)
をテーブル名として、SELECT/INSERT/UPDATEが普通に使えます。ただしDELETEはできない。
=========引用ここまで========
上記の部分がとても勉強になりました!!
[シート名$名前]・・・ここでの「名前」は名前の定義での名前なのかな???
[シート名$](データが入力されている左上から右下までの範囲)・・・マジ、勉強になります!!
取得できるデータの範囲というか、自動的に「F1」が設定される場合などについて「そうかぁ~、だから、かあ~!」と納得できました。
こちらのサイトはその他の有用な情報もいっぱいあります。
どうぞ、ご覧になってみてください。
前項の、「ADO.NETでExcelファイルに接続する」のサイトに、接続文字の、ISAM形式について、レジストリの以下の項目を見てくださいと書いてありました。
HKLM\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access\Access Connectivity Engine\ISAM Formats
僕の環境ではこのキーは存在せず、以下のキーでした。(たぶん・・・)
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\14.0\Access Connectivity Engine\ISAM Formats]
これはWindows10の64bitに、Office2010パーソナル・32bitをインストールした環境下でのキーです。
このキーの内容を「.reg」拡張子のファイルにエクスポートします。
それをテキストファイルに変えて(拡張子をregからtxtに書き換えて)読んでみますと・・・以降のような記述が見つかります。
========
省略したキーの内容→→→HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\14.0\Access Connectivity Engine\ISAM Formats
その他にもいっぱい設定値を省略しています。
[・・・キー内容省略・・・\ISAM Formats\dBASE 5.0]
"Engine"="Xbase"
"ExportFilter"="dBASE 5 (*.dbf)"
"ImportFilter"="dBASE 5 (*.dbf)"
[・・・キー内容省略・・・\ISAM Formats\dBASE III]
"Engine"="Xbase"
"ExportFilter"="dBASE III (*.dbf)"
"ImportFilter"="dBASE III (*.dbf)"
[・・・キー内容省略・・・\ISAM Formats\dBASE IV]
"Engine"="Xbase"
"ExportFilter"="dBASE IV (*.dbf)"
"ImportFilter"="dBASE IV (*.dbf)"
[・・・キー内容省略・・・\ISAM Formats\Excel 12.0]
"OutputFormat"="Excel Binary Workbook (*.xlsb)"
"ExportFilter"="Excel バイナリ ブック (*.xlsb)"
"ImportFilter"="Excel バイナリ ブック (*.xlsb)"
"Engine"="Excel"
[・・・キー内容省略・・・\ISAM Formats\Excel 12.0 Macro]
"OutputFormat"="Excel Macro-Enabled Workbook (*.xlsm)"
"ImportFilter"="Excel マクロ有効ブック (*.xlsm)"
"Engine"="Excel"
[・・・キー内容省略・・・\ISAM Formats\Excel 12.0 Xml]
"OutputFormat"="Excel Workbook (*.xlsx)"
"CanLink"=hex:01
"ExportFilter"="Excel ブック (*.xlsx)"
"ImportFilter"="Excel ブック (*.xlsx)"
"Engine"="Excel"
[・・・キー内容省略・・・\ISAM Formats\Excel 5.0]
"Engine"="Excel"
"ExportFilter"="Microsoft Excel 5.0/95 ブック (*.xls)"
"ImportFilter"="Microsoft Excel (*.xls)"
"OutputFormat"="Microsoft Excel 5.0/95 Workbook (*.xls)"
"ReportFormat"="Microsoft Excel 5.0/95 Workbook"
[・・・キー内容省略・・・\ISAM Formats\Excel 8.0]
"Engine"="Excel"
"ExportFilter"="Excel 97-2003 ブック (*.xls)"
"OutputFormat"="Excel 97 - Excel 2003 Workbook (*.xls)"
"ReportFormat"="Excel 97 - Excel 2003 Workbook"
[・・・キー内容省略・・・\ISAM Formats\Exchange 4.0]
"Engine"="Exchange"
"ImportFilter"="Exchange()"
[・・・キー内容省略・・・\ISAM Formats\HTML Export]
"Engine"="Text"
"ExportFilter"="HTML ドキュメント (*.html;*.htm)"
[・・・キー内容省略・・・\ISAM Formats\HTML Import]
"Engine"="Text"
"ImportFilter"="HTML ドキュメント (*.html;*.htm)"
[・・・キー内容省略・・・\ISAM Formats\Jet 3.x]
"Engine"="Jet 3.x"
[・・・キー内容省略・・・\ISAM Formats\Outlook 9.0]
"Engine"="Exchange"
[・・・キー内容省略・・・\ISAM Formats\Text]
"Engine"="Text"
"ExportFilter"="テキスト ファイル (*.txt;*.csv;*.tab;*.asc)"
"ImportFilter"="テキスト ファイル (*.txt;*.csv;*.tab;*.asc)"
"OutputFormat"="MS-DOS Text (*.txt)"
"ReportFormat"="MS-DOS Text"
"FormatFunction"="txt,SOA_RptToAscii,1,MS-DOS Text (*.txt)"
==============
これを見ると、
(*.xlsb)バイナリブック →「Excel 12.0」
(*.xlsm)マクロ有効ブック →「Excel 12.0 Macro」
(*.xlsx)Excel ブック →「Excel 12.0 Xml」
(*.xls)Excel 5.0/95 ブック →「Excel 5.0」
(*.xls)Excel 97-2003 ブック →「Excel 8.0」
(*.txt;*.csv;*.tab;*.asc) →「Text」
って書けばいい感じなのかな~???なんてイメージが浮かびます。
実際には、「Excel 12.0」でも、*.xlsm が開けちゃいますけど、そのへんはよくは分かりません・・・。
このレジストリ設定には、そのほかにもいろんな設定値が見つかりますので、何かの役に立つかもしれません。
ADOでExcelデータを読みに行く件について
以下のURLも参考にしてください。
https://antonsan.net/vt/excel-db/heading-3/page-019
https://ameblo.jp/realsystems/entry-11946216560.html
https://excelwork.info/excel/excelado/
http://blog.sorceryforce.net/?p=154
https://qiita.com/unarist/items/6cc35bb9fe502ced332f
http://www.accessclub.jp/ado/12.html
https://oshiete.goo.ne.jp/qa/8109288.html
http://hanatyan.sakura.ne.jp/vbhlp/dao_002.htm
Accessの64bitのDAOについて
http://note.phyllo.net/?eid=1106279
Excel 64bit DAO
https://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGHP_jaJP680JP697&q=Excel+64bit+DAO&gws_rd=ssl
Excel2010、DAO3.6が参照不可になる原因
http://excelshogikan.com/tips/tips093.html
Jet / ACE エンジン
http://dxr165.blog.fc2.com/blog-entry-117.html