ExcelVBA~Excelファイル(Excelシートの表データ)をのぞきに行ってそのRecordsetオブジェクトの結果をQueryTableオブジェクトに受ける方法
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
●参考Webページ
Recordsetオブジェクトの結果をQueryTableオブジェクトで受け取る
↑ここはAccessのmsbファイルのデータをExcelからのぞきに行って、シートにQueryTableオブジェクトで受け取っています。
本記事は、Excelシートをのぞきに行って、ExcelのQueryTableオブジェクトで受けます。
●はじめに
ADOなどのレコードセットをQueryTableオブジェクトで受け取ると、
自動的に名前範囲の定義設定がなされますので、結果の表を定義された名前で
扱えるので、セル範囲を気にする必要がなくなる場面が増えます。
また、フィールド名(列名)の書き出しも自動なので、CopyFromRecordsetのように
ループ処理でそのコードを書かなくても済みます。
また、QueryTableオブジェクトのプロパティが使えるため、
セル幅の自動調整なども長いコードを書かなくても済みます。
CopyFromRecordsetを使う場合は、それらのどれもが、できませんので、
何らかの理由がない限り、QueryTableオブジェクトを利用したほうが
よさそうに目に映ります。
ただし、MicrosoftQueryやODBC接続でのQueryTableオブジェクトとは違って、
アクティブシートに結果表示はされるものの、
ODBC接続じゃないせいか、
『「編集できない」「MicrosoftQuery」』、
みたいになります。
例えば右クリックして「クエリの編集」メニューをクリックすると
「この外部データ範囲はプログラムによって生成されているため、編集できません」
というエラーになって、MicrosoftQueryの画面が出てきません。
ただ、クエリ編集できる方法はどこかにあるのかもしれません。
とはいえ、前述のとおり、QueryTableオブジェクトのプロパティや
メソッドが、新規作成時やRecordsetの内容変更時などに使えるので
便利になるシーンも増えるとは思います。
便利な順番でいくと、
(a)ODBC接続+QueryTableオブジェクト出力(表の右クリでMsQuery画面も使える)
(b)ADO(OLEDB?)接続+QueryTableオブジェクト出力(MsQuery画面使用不可)
(c)ADO(OLEDB?)接続+Range.CopyFromRecordset出力(特に何もできない。
値が貼り付くのみ)
という感じかもしれません。
もちろん、シーンによっては、
「(c)ADO(OLEDB?)接続+Range.CopyFromRecordset出力 が一番
目的に合っていた・・・」、
ということもあるでしょうから、
必ずしもこの順位での決めつけはいけません。
●「xlsx」拡張子のExcelシートをのぞきに行ってそのRecordsetをQueryTableオブジェクトに受けた場合
(列名のループでの書き込みが不要だし、QueryTableオブジェクトのメンバーが使えたり、名前定義の自動範囲設定、列幅自動調整などが使える。)
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 |
' ' Sub ReadByADO01_QeryTable0001() '参考URL 'https://antonsan.net/study/excel/excel067.php 'ただし、以下のコードだとQueryTableとして 'アクティブシートに結果表示はされるものの、 'ODBC接続でないせいか、 '『「編集できない」「MicrosoftQuery」』、 'みたいになります。 '右クリックして「クエリの編集」メニューをクリックすると '「この外部データ範囲はプログラムによって生成されているため、編集できません」 'というエラーになって、MicrosoftQueryの画面が出てきません。 'ただ、クエリ編集できる方法はどこかにあるのかもしれません。 '★変数設定 Dim Cn As ADODB.Connection '読込対象のXLSファイルの '「ADO接続文字用のオブジェクト」用の変数 Dim Rs As ADODB.Recordset '読込対象のシートの '「ADOデータ範囲?設定用のオブジェクト ' =レコードセット」用の変数。 Dim o_SrcWb01 As Workbook '読込対象のブック 'を格納(=指定)するためのオブジェクト変数 Dim s_SrcWbFlPath As String '読込対象のXLSファイルの 'フルパス格納用の変数 Dim s_SrcWsNm As String '読込対象のシート名の格納用の変数 Dim s_SQL01 As String 'どの列と行をどのように読み込むかの 'SQL文を格納するための変数 Dim o_DistWs01 As Worksheet '読み込んだデータを転記する先のシート 'を格納(=指定)するためのオブジェクト変数 Dim i As Integer 'ソースのシートのインデックスを '格納(=指定)するための変数 Dim j As Integer 'レコードセットの列のインデックスを '格納(=指定)するための変数 Dim s_DistCellAddr01 As String '2つ目以降のソースシートを読み込んだ際に 'それを転記先シートに書き込むときの、 'その起点となるセルのアドレスを格納するための変数 '▼一応、データが大量だと遅くなってしまうので ' 画面描画をいったん停止。 ' デバッグ時などはコメントアウトする。 Application.ScreenUpdating = False 'Excelの画面描画をいったん停止。 '今の画面のまま変化させないようにする。 '★以下、メインプログラムです。 ' Set o_SrcWb01 = ThisWorkbook ' 'データを読み込みたい、そのソースとなるブックの設定 ' Set o_SrcWb01 = Workbooks.Open("D:\1\縦結合テスト.xlsm") ' Set o_SrcWb01 = Workbooks.Open("\\Fsvr01\Fld01\test.xlsm") ' s_SrcWbFlPath = o_SrcWb01.FullName ' 'そのブックのフルパスを取得。 ' '(以下のような指定も可。) s_SrcWbFlPath = "D:\1\aa.xlsx" Set Cn = New ADODB.Connection 'ADOにてのデータ接続(=ファイル内容の読み込み) 'ができるようにするための準備 Set Rs = New ADODB.Recordset 'ADOにてのレコードセット(=シート内データ範囲?)が '作れるようにするための準備 Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ "Data Source=" & s_SrcWbFlPath & ";" & _ "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1;Readonly=False""" 'ADOで読込先のソースファイルに接続。 '(=読込先のソースファイルを開く) '▼転記先のシートの内容をいったんクリア ' ※転記先のシートが一番左にあることが前提です。 Set o_DistWs01 = ActiveSheet '読み込んだデータを転記するシートの設定 o_DistWs01.Cells.ClearContents '読み込み先のファイルの列数や行数が増減するといけないので、 '一応、転記するシートをきれいに空白しておく。 '前回よりデータ列数や行数が少ないと、 '前回のデータが残ってしまうので。 s_SrcWsNm = "申請$" 'ソースとなるシートの名前を指定 s_SQL01 = "SELECT * FROM [" & s_SrcWsNm & "]" 'SQL文の作成 Rs.Open s_SQL01, Cn, adOpenStatic, adLockOptimistic, adCmdText 'SQL文に基づいレコードセットを生成 ' '以下の2行は、CopyFromRecordsetのときに使うものなのでコメントアウト ' s_DistCellAddr01 = "A2" ' o_DistWs01.Range(s_DistCellAddr01).CopyFromRecordset Rs With ActiveSheet.QueryTables.Add(Rs, Range("A1")) .Name = "VBA_QT" .Refresh End With 'A1セルから右を列名に(=A1セルを起点に)、 'レコードセットの内容を 'QueryTableオブジェクトに出力します。 Rs.Clone Set Rs = Nothing ' ' 作ったオブジェクトの破棄: ' '一応メモリリークを起こさないように? ' '作ったオブジェクトをメモリから消す Cn.Close Set Cn = Nothing ' 同上 '▼Excelの画面描画を再開。 Application.ScreenUpdating = True '画面の変化が普通に表示されるようにする。 End Sub ' ' |
●同じく「xlsx」拡張子のExcelシートをのぞきにって、CopyFromRecordsetで受けた場合
(列名のループでの書き込みが必要になってしまう。)
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 |
' ' Sub ReadByADO01_CopyFromRsPast0001() '★変数設定 Dim Cn As ADODB.Connection '読込対象のXLSファイルの '「ADO接続文字用のオブジェクト」用の変数 Dim Rs As ADODB.Recordset '読込対象のシートの '「ADOデータ範囲?設定用のオブジェクト ' =レコードセット」用の変数。 Dim o_SrcWb01 As Workbook '読込対象のブック 'を格納(=指定)するためのオブジェクト変数 Dim s_SrcWbFlPath As String '読込対象のXLSファイルの 'フルパス格納用の変数 Dim s_SrcWsNm As String '読込対象のシート名の格納用の変数 Dim s_SQL01 As String 'どの列と行をどのように読み込むかの 'SQL文を格納するための変数 Dim o_DistWs01 As Worksheet '読み込んだデータを転記する先のシート 'を格納(=指定)するためのオブジェクト変数 Dim i As Integer 'ソースのシートのインデックスを '格納(=指定)するための変数 Dim j As Integer 'レコードセットの列のインデックスを '格納(=指定)するための変数 Dim s_DistCellAddr01 As String '2つ目以降のソースシートを読み込んだ際に 'それを転記先シートに書き込むときの、 'その起点となるセルのアドレスを格納するための変数 '▼一応、データが大量だと遅くなってしまうので ' 画面描画をいったん停止。 ' デバッグ時などはコメントアウトする。 Application.ScreenUpdating = False 'Excelの画面描画をいったん停止。 '今の画面のまま変化させないようにする。 '★以下、メインプログラムです。 ' Set o_SrcWb01 = ThisWorkbook ' 'データを読み込みたい、そのソースとなるブックの設定 ' Set o_SrcWb01 = Workbooks.Open("D:\1\縦結合テスト.xlsm") ' Set o_SrcWb01 = Workbooks.Open("\\Fsvr01\Fld01\test.xlsm") ' s_SrcWbFlPath = o_SrcWb01.FullName ' 'そのブックのフルパスを取得。 ' '(以下のような指定も可。) s_SrcWbFlPath = "D:\1\aa.xlsx" Set Cn = New ADODB.Connection 'ADOにてのデータ接続(=ファイル内容の読み込み) 'ができるようにするための準備 Set Rs = New ADODB.Recordset 'ADOにてのレコードセット(=シート内データ範囲?)が '作れるようにするための準備 Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ "Data Source=" & s_SrcWbFlPath & ";" & _ "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1;Readonly=False""" 'ADOで読込先のソースファイルに接続。 '(=読込先のソースファイルを開く) '▼転記先のシートの内容をいったんクリア ' ※転記先のシートが一番左にあることが前提です。 Set o_DistWs01 = ActiveSheet '読み込んだデータを転記する先のシートを指定 o_DistWs01.Cells.ClearContents '読み込み先のファイルの列数や行数が増減するといけないので、 '一応、転記するシートをきれいに空白しておく。 '前回よりデータ列数や行数が少ないと、 '前回のデータが残ってしまうので。 s_SrcWsNm = "申請$" 'ソースとなるシートの名前を指定 s_SQL01 = "SELECT * FROM [" & s_SrcWsNm & "]" 'SQL文の作成 Rs.Open s_SQL01, Cn, adOpenStatic, adLockOptimistic, adCmdText 'SQL文に基づいてレコードセットを生成 '「レコードセット=データの入力された範囲?」を '決定しつつ。 '▼SQL文にて、ソースシートからどの列と行をどのように読み込むかを設定。 '基本、列名の書き換えだけでOKだと思います。 'ただし、実際のソースシートの列名の末尾に、スペースなどが '隠れていないことが前提です。 'なお、セル範囲を指定しない場合は、 'ソースシート丸ごとのすべての範囲を見に行ってくれて、 'データが入力されている部分を自動判別してくれて、 'レコードセットを作ってくれます。 's_SQL01 = "SELECT * FROM [" & s_SrcWsNm & "A1:N15" & "]" 'このようにシート名のあとにセル範囲を追記指定することも可能。 'そこまでの範囲を見に行って、その範囲内で、 'データが入力されている部分を自動判別してくれて、 'レコードセットを作ってくれます。 s_DistCellAddr01 = "A2" '出力先のセルの番地の指定 '列名はレコードセットの中には含まれていないので 'ループで書き出さないといけないので、データのみの '起点セルを指定します。 For j = 1 To Rs.Fields.Count o_DistWs01.Cells(1, j) = Rs.Fields(j - 1).Name Next j '列名のみを、シートへの転記 '「HDR=Yes」でデータをレコードセットの取り込んだので、 '列名は、Rsを貼り付けても貼り付かないため。 o_DistWs01.Range(s_DistCellAddr01).CopyFromRecordset Rs 'CopyFromRecordset にて、転記先のシートに 'レコードセットの内容を書き出す。 '「HDR=NO」だと、列名もシートに書き出されるが、 '「HDR=Yes」はレコードのみとなる。 ' なお、「HDR=NO」だと、転記後にセルに緑の三角エラーが ' 出るが「HDR=Yes」のときは出ない。 ' 今回は、「HDR=Yes」でやっている。 Rs.Close Set Rs = Nothing ' ' 作ったオブジェクトの破棄: ' '一応メモリリークを起こさないように? ' '作ったオブジェクトをメモリから消す Cn.Close Set Cn = Nothing ' 同上 '▼Excelの画面描画を再開。 Application.ScreenUpdating = True '画面の変化が普通に表示されるようにする。 End Sub ' ' |
1 2 3 4 |
' ' ' ' |
1 2 3 4 |
' ' ' ' |
1 2 3 4 |
' ' ' ' |
1 2 3 4 |
' ' ' ' |
- 投稿タグ
- 「ニセモノ」への道, 「本物」に近づくために, AccessVBA, Accessの独学, Access操作の基礎, ADO/DAO, ExcelSQL, ExcelVBA, Excelの独学, Excel操作の基礎, Excel連携VBA, MicrosoftQuery, ODBC, SQL, パソコンでの自動化, ビジネスパソコンの基礎, ビジネス一般常識, マクロ, ワークシート関数, 独学, 自動化