● Excel2000・2003~「ピボット」や「Microsoft Query の結果表」にて、ソースの表の指定時にMicrosoft Queryを使った場合の「CommandText(SQL文)」のVBAでの自動変更について
目次
★ はじめに
★ VBAプログラムで「CommandText(SQL文)」を扱える(=自動書き換え)できる条件
★ VBAプログラムで「CommandText(SQL文)」を自動変更すると何ができるの?
★ 「CommandText(SQL文)」をVBAで自動書き換えする場合に使う変数について
★VBAプログラムで 「CommandText(SQL文)」を自動書き換えする例
※Shift+TABキー、もしくは、Homeキー、Homeキー+TAB数回、を押すと、目次付近に戻れます。
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
「ピボット」でも、「Microsoft Query の結果表」でも、ソースのデータを「Microsoft Query(外部データソース)」で作った場合に限り、VBAプログラムにて「CommandText」が扱えます。
※これでピボットソースを作った時 ↓ や、Microsoft Query でExcelに結果を返した時です。
「CommandText」の内容は「SELECT・・・」といったような「SQL文」です。
ピボットソースやMicrosoft Queryの結果表を作る際に、「ExcelファイルやAccessファイルと等々から、どのデータをどのように抜き出したか」、が書かれています。
(SQL文とは・・・データ管理の世界では、「世界標準」と言っても過言ではない・かつ・複式簿記と同じくらいの有名度の自動データ集計&リストアップ命令群です。)
そして「CommandText(SQL文)」がVBAで自由に書き換えられると、Accessとのピボット連携が強化できたり、Excelのミニシステム化、自動集計化、などがさらにパワーアップします(と思います。多分・・・。)
ピボットのフィールドリストの内容もVBAで自由に自動的に変更できます。なので利用価値が高いと思います。
ちなみに、そのほかの場合・・・つまり、ピボットのソースを「外部ソース」で作ってない場合・・・、例えば「単純にシートを選択しただけの普通のピボットのソース」の場合は、「CommandText」は扱えません。
今回の記事では、Excelの2000と2003を使って、その「CommandText(SQL文)」をVBAで自動修正・自動変更するために、どんなデータ型を使ったらいいか、などを調べてみました。参考文献が見つからなかったので、僕が根本的に何か考え違いをしている部分もあるかもしれませんが、分かったところだけでもご紹介いたします。
なお、ピボットソースとMicrosoft Queryの結果表の「CommandText(SQL文)」を扱ううち、ピボットソースのほうだけ「配列」という仕組みを利用するのですが、テストでは「配列の各要素ごとに文字数の制限」がありました。そして、その上限文字数は状況によってまちまちです(テストでは何故かそうでした)。その理由は現時点ではわかりません。この場合も、参考文献が見つからなかったので、僕が根本的に何か考え違いをしているのかもしれません。その際は大変申し訳ございません。
★ VBAプログラムで「CommandText(SQL文)」を扱える(=自動書き換え)できる条件
・ピボットの場合
ピボットのソースが、Microsoft Query によってかたちづくられている場合に限ります。
例えば Excel2000・2003の場合、ピボットのソースを指定するとき、ウィザードの最初のほうで「外部データソース」を指定した場合です。
また、ピボットテーブルツールバーなどから、ピボットテーブルウィザードにて、「戻る」ボタンを押した場合、ダイアログに「データの取り出し」ボタンが表示される場合もそうです。
実は、「外部データソース」 ボタンも、「データの取り出し」ボタンも、押すと出てくるのは「Microsoft Query」の画面です。
つまり、「外部データソース=データの取り出し=Microsoft Query」・・・
「外部データソース」も、「データの取り出し」も「Microsoft Query そのもの」ということなのです。
ちなみに、「外部データソース(Microsoft Query)」を使った場合、AccessのmdbファイルやExcelのxls・xlsm・xlsxファイルだけでなく、その他のデータベースでも、ピボットソースの指定先にすることができますが、そのすべてがOKです。「CommandText(SQL文)」を扱うことができます。
ピボットの場合は、とにかくソースが「外部データソース」で作られていれば、
「CommandText(SQL文)」を扱うことができます。すなわち、VBAで自動書き換えができます。
「外部データソース」で作られたピボットソースではない場合や、ウィザードの「戻る」を押したときに何らかのシートが点滅する点線で囲まれるような場合、そのような場合は、「CommandText(SQL文)」を扱えません。
・Microsoft Query の結果表の場合
必ず、「CommandText(SQL文)」を扱えます。
つまり、「CommandText(SQL文)」の自動修正ができます。
★ VBAプログラムで「CommandText(SQL文)」を自動変更すると何ができるの?
・【ピボットの場合】
(01)「フィールドリスト」の内容を自動的に書き換えることができます。
例えば、表示させたいフィールド・一時消しておきたいフィールドなどを簡単に指定し分け、更新することができます。
・【Microsoft Query の結果表の場合】
次項の【両方とも】に準じます。
・【両方とも】
(01)リレーション構成などをSQL文にて自動切り替えできます。
(リレーション=VLOOKUP関数での紐付けのようなこと)
(02)「CommandText(SQL文)」を次々と自動的に切り替えて集計やリストアップを行う
(03)同じ構成のソース表なら、複数のファイル間でも瞬時に自由に切替できます。
たとえば同じ列構成でファイル名やシート名だけが違うソースファイルが複数あったとして、その時に、集計専用のExcelファイルなどにおいて、「それらの複数のソースファイルの中から、目的に合ったソースファイルを自由に自動的に瞬時に切り替えして色々調べたい・・・」といった場合に、いちいち、戻るボタンで別のソースファイルを指定しなおさなくても大丈夫になります。ソースファイルがmdbでもxlsでも同じです。
(04)ソースをmdbからxlsに自動切り替えしたい、などができます。
(05)集計機能のシステム化(既存集計ファイルの流用・コピペ増殖)
ピボットもMicrosoft Queryも両方を含むまったく同じ集計手順・表構成のExcelファイルで「ファイル名だけ変えたい」という場合・かつ・その自ファイル自体にもソース表が含まれるような場合・・・に、「その自ファイルの複製を作りさえすれば、あとはソース指定に自ファイル名に自動書替えするだけで別の集計システムのできあがり。処理が1分~5分で終わる。」というようなことができます。
(06)重複を簡単にとりのぞく、再度表示させる、を何度も瞬時に切り替えする。
★ 「CommandText(SQL文)」をVBAで自動書き換えする場合に使う変数について
ピボットの場合は文字列型かVariant型の配列(要素ごとに文字数制限あり)、Microsoft Query の場合は配列じゃなくて普通の文字列型でいいようです。
僕はピボットの場合は、Variant型の配列が便利じゃないかなと思います。
何かエラーが出るようなことがあれば、文字列型の配列のほうがいい場合もあるかもしれません。ただ、まだそこまでテストできていません。
なお、参考文献が無いので よくわからないのですが、ピボットの配列の場合は下図のように要素毎に文字数制限があるようです。制限は文字数だけのようなので、たとえば 1つの要素のなかでSELECT句の一部とFROM句の一部がつながっていても問題は無いようです。また、空文字が値となっている要素があっても問題ありません。
また、SQL文が、「SLELECT句、FORM句、WHERE句等々、全部」で、半角でその文字数 以内(要素1つ分以内)だと、その場合は、配列じゃなくても単一の文字列型の変数でも大丈夫みたいです。
Microsoft Query の場合は、このような配列のことを考えなくてもいいみたいです。ただ、テストが不十分で、実は、数千文字まで、とかの制限があるのかもしれません。その際は申し訳ございませんが、ご自分でもチェックしてみてください。
このテストは、2000と2003なので、もしかしたら2007以降は、ピボットでも配列じゃなくてもよくなってるかもしれません。その場合も、ご自分でもどちらなのかチェックしてみてください。
★VBAプログラムで 「CommandText(SQL文)」を自動書き換えする例
以下は、Excel2000や2003での「ピボットテーブル」の場合の、自動書き換え例です。
ピボットから mdbファイル(Accessのファイル)を覗きに行った時の例です。
好きなフィールド名の「SqlStr02 = SqlStr02 & "T顧客マスタ.ビル名, "」のような行をコメントアウトすれば、そのフィールドはピボットテーブル上のフィールドリストから消すことができます。コメントアウトを解いて再実行すれば、再度、フィールドリストに表示できます。
プログラムについては、まず、ピボットの書き換えの場合、SQL文を代入する変数には、Variant型を使っています。配列として使用します。(多分、文字列型の配列を使ってもOKではないかと思われます。)
なお、Excel2000や2003の場合、その配列の変数においては、1要素あたりで、半角で394文字前後(バージョンその他によって405文字とか307文字とか)を超えるとダメみたいです。「型がちがう」みたいなエラーになります。
また、SQL文が、「SLELECT句、FORM句、WHERE句等々、全部」で、半角でその文字数 以内だと、その場合は、配列じゃなくても単一の文字列型の変数でも大丈夫みたいです。
※Excelファイルを覗きにいった場合は、フィールド名(列名)に「'」が含まれるので少し変わります。句と句のあいだには、最低1つの半角スペースが必要です。1つ以上あれば、2つでもいくでも構いません。ただし、全角スペースはエラーとなります。
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 |
' ' ' Sub test03() Dim SqlStr01 As String Dim SqlStr02 As String Dim SqlStr03 As String Dim SqlStr04 As String Dim SqlStr05 As String ' Dim SqlStrALL As String '要らなかった。半角394文字以内のSQL文用。 Dim SQLArrey As Variant ' Debug.Print Worksheets("ソース2").QueryTables(1).Sql ' Debug.Print Worksheets("ソース2").QueryTables(1).CommandText SqlStr01 = "SELECT " SqlStr01 = SqlStr01 & "T顧客マスタ.顧客ID, " SqlStr01 = SqlStr01 & "T顧客マスタ.名, " SqlStr01 = SqlStr01 & "T顧客マスタ.姓, " SqlStr01 = SqlStr01 & "T顧客マスタ.氏名, " SqlStr01 = SqlStr01 & "T顧客マスタ.名フリガナ, " SqlStr01 = SqlStr01 & "T顧客マスタ.姓フリガナ, " SqlStr01 = SqlStr01 & "T顧客マスタ.国籍, " SqlStr01 = SqlStr01 & "T顧客マスタ.性別, " SqlStr01 = SqlStr01 & "T顧客マスタ.年齢, " SqlStr01 = SqlStr01 & "T顧客マスタ.郵便番号, " SqlStr01 = SqlStr01 & "T顧客マスタ.住所01, " SqlStr01 = SqlStr01 & "T顧客マスタ.住所02, " SqlStr01 = SqlStr01 & "T顧客マスタ.TEL, " SqlStr01 = SqlStr01 & "T顧客マスタ.市, " SqlStr01 = SqlStr01 & "T顧客マスタ.区, " SqlStr01 = SqlStr01 & "T顧客マスタ.郡, " SqlStr01 = SqlStr01 & "T顧客マスタ.町, " SqlStr01 = SqlStr01 & "T顧客マスタ.字等, " SqlStr01 = SqlStr01 & "T顧客マスタ.番地 , " SqlStr02 = SqlStr02 & "T顧客マスタ.ビル名, " SqlStr02 = SqlStr02 & "T顧客マスタ.棟など, " SqlStr02 = SqlStr02 & "T顧客マスタ.部屋名, " SqlStr02 = SqlStr02 & "T顧客マスタ.階, " SqlStr02 = SqlStr02 & "T顧客マスタ.お仕事, " SqlStr02 = SqlStr02 & "T顧客マスタ.趣味, " SqlStr02 = SqlStr02 & "T顧客マスタ.愛読書カテゴリ, " SqlStr02 = SqlStr02 & "T顧客マスタ.ネット通販, " SqlStr02 = SqlStr02 & "T顧客マスタ.内ネットオークション, " SqlStr02 = SqlStr02 & "T顧客マスタ.免許更新日, " SqlStr02 = SqlStr02 & "T顧客マスタ.ダイエット, " SqlStr02 = SqlStr02 & "T顧客マスタ.エステ, " SqlStr02 = SqlStr02 & "T顧客マスタ.オススメ料理店, " SqlStr02 = SqlStr02 & "T顧客マスタ.年収_ご夫婦込み, " SqlStr02 = SqlStr02 & "T商品マスタ.商品ID, " SqlStr03 = SqlStr03 & "T商品マスタ.メーカー名, " SqlStr03 = SqlStr03 & "T商品マスタ.アイテム, " SqlStr03 = SqlStr03 & "T商品マスタ.上代, " SqlStr03 = SqlStr03 & "T商品マスタ.下代, " SqlStr03 = SqlStr03 & "T商品マスタ.入荷数, " SqlStr03 = SqlStr03 & "T商品マスタ.色系統, " SqlStr03 = SqlStr03 & "T商品マスタ.ターゲット年齢層, " SqlStr03 = SqlStr03 & "T商品マスタ.全商品ID表示フラグ, " SqlStr03 = SqlStr03 & "T売上明細.売上ID, " SqlStr03 = SqlStr03 & "T売上明細.売上日, " SqlStr03 = SqlStr03 & "T売上明細.顧客ID, " SqlStr03 = SqlStr03 & "T売上明細.お名前, " SqlStr03 = SqlStr03 & "T売上明細.電話番号, " SqlStr03 = SqlStr03 & "T売上明細.商品ID, " SqlStr03 = SqlStr03 & "T売上明細.アイテム, " SqlStr03 = SqlStr03 & "T売上明細.実売単価, " SqlStr03 = SqlStr03 & "T売上明細.仕入単価, " SqlStr03 = SqlStr03 & "T売上明細.売上点数, " ' SqlStr02 = SqlStr02 & "T売上明細.売上金額(1行当り), " ' SqlStr02 = SqlStr02 & "T売上明細.仕入金額(1行当り), " ' SqlStr02 = SqlStr02 & "T売上明細.レシートNo" '句ごとじゃなくて、文字数ごとの配列のようなので、次のように、SELECT句とFROM句が混ざってもいいし, 'フィールドとフィールドのあいだや、各句のあいだに、半角スペースならいくつ入ってもOKです。 SqlStr04 = " T売上明細.仕入単価, T売上明細.売上点数, T売上明細.売上金額(1行当り), T売上明細.仕入金額(1行当り), T売上明細.レシートNo FROM `D:\pos\pos_ac`.T顧客マスタ T顧客マスタ, `D:\pos\pos_ac`.T商品マスタ T商品マスタ, `D:\pos\pos_ac`.T売上明細 T売上明細" '配列の要素の1つが、値が空文字でもOKのようです。 SqlStr05 = "" SqlStr06 = " WHERE T売上明細.顧客ID = T顧客マスタ.顧客ID AND T売上明細.商品ID = T商品マスタ.商品ID" 'ac 'ピボットの「CommandText」に代入する値の生成 SQLArrey = Array(SqlStr01, SqlStr02, SqlStr03, SqlStr04, SqlStr05, SqlStr06) ' Debug.Print SqlStr01 ' Debug.Print SqlStr02 ' Debug.Print SqlStr03 Worksheets("Sheet1").PivotTables(1).PivotCache.CommandText = SQLArrey Worksheets("Sheet1").PivotTables(1).PivotCache.Refresh '※ ピボットの「CommandText」の内容を変更することで、ピボットのフィールドリストの中の項目を、自動的に増やしたり減らしたり ' 内容変更することができます。 '結局、Microsoft Query の結果表の「CommandText」とピボットの「CommandText」は文字数制限?に違いがあるようです。 'とりあえずピボットの「CommandText」の場合は、句ごとに区切られているわけではなく、 '「一定の文字数」で区切られた文字列型の配列みたいです。 ' 'その文字数は、1つの要素あたり、半角で394文字(?)くらいまでみたいです。 '(本当の文字数の制限の仕様はちゃんと調べてないので良く分かっていません。すみません。 ' エラーが出る境目を調べたらだいたいそのくらいでした。 ' エラーのときは、「型が一致しません」、みたいなエラーになります。 ' なので、SELECT句は300文字ずつくらいで区切ればいいようです。) '※ Microsoft Query の結果表の「CommandText」は、かなりの単一の文字列型変数で、半角で394文字以上、 ' テストでは1000文字近くでも大丈夫だったので、そのへんまでは多分大丈夫です。 ' また、Microsoft Query の結果表の「CommandText」は、 'また、句と句のあいだや、フィールドとフィールドのあいだには、半角スペースがいくつあってもエラーになりませんでした。 '全角スペースは1個でもあるとエラーになるのでタイプミスしないように注意が必要です。 '半角で394文字以内に収まるSQL文なら、変数は、単一の文字列型でも文字列型の配列(Variant型)でもどちらでもいいみたいです。 'SQL文が半角で394文字を超えると、文字列型の配列(Variant型)でないとエラーになるようです。 'なお、配列の要素の数の制限(上限)はテストしてないのでわかりません。 'ただ、どこかの要素の値が「""(空文字)」であっても大丈夫です。 'また、SELECT句に、いくつの要素を使ってもかまわないし、 'FROM句やWHERE句などが、何番目の要素にこないといけない、という制限は無いようです。 'あと、ピボットのCommandTextの場合は、文字数で区切られた配列なので、 '要素の値が、SELECT句の一部とFROM句が混ざったものになっても大丈夫みたい。 'もちろん、句ごとで割ったほうがプログラムが見やすくなるので、基本的にはそうしたほうがいいです。 'また、WHERE句の前か、FROM区のあとにスペースが無いと、「FROM句が正しくない」といったようなエラーになります。 'VBE6.DLLのバージョンがOffice2000の中での古いバージョン(6.0.87.14)でも動きました。 'Officeのバージョン、あるいは、VBE6や7のバージョンでもしかしたら動きや文字数制限などが異なるかもしれません。 '事前のテストが必要です。 '当方でやったテストは今のところ、 'バージョン2000での Microsoft Query の結果表の「CommandText」とピボットの「CommandText」の違い '同じくバージョン2000での、Excelシートをソースにした場合と、mdbファイル(Accessのファイル)をソースにした場合の 'SQLの書き方が異なる、という点、です。 'Excelシートをのぞきに行って、ピボットのソースをMicrosoftQueryde作るケースの「CommandText」の書き換えは 'まだテストしていません。 'あと、バージョン2003での Exelシートをのぞきに行っての、 'Microsoft Query の結果表のExcelシートだけの「CommandText」の書き換えの方法、のみです。 'mdbはやってません。 '各バージョンで、 'ピボットのソースにMicrosoftQueryを使う場合で、ソースのモトがExcelファイルの場合とmdbの場合、 'Microsoft Query での同じこと、をテストする必要があるかもしれません。 'とくにバージョンの切れ目、2003から2007とか。VBE6.DLLからVBE7.DLLとか。 'ピボットに関しては、ソースにMicrosoftQueryを使う場合(mdb、xls等ともに)しか、「CommandText」の書き換えはできません。 '通常のExcelシートを直接見に行っている場合はSQLを使ってないみたいなので・・・ '※「名前定義」した表はどうなるのかテストしていません。 '全てのバージョンで試してはいませんが、ここでのテストがその他のバージョンの場合の参考にしていただければ幸いです。 End Sub ' ' ' |
- 投稿タグ
- ExcelVBA, Excelの独学, Excel連携VBA, パソコンでの自動化, ビジネスパソコンの基礎, ピボットテーブル関連, マクロ, 自動化