はじめに

多量の行が表示されないように、このブログは1コンテンツしか表示されない。ブログアーカイブから、他の記事を捜してくれ。

環境作れし。
・gawk 3.1.5 for Windows をググッて入手。
・gawk.exeをpathの通ったフォルダにぶち込めし。
 (「windows パスを通す」ググッて)
 (面倒なら、C:\windowsにぶち込む)
・環境変数「awkpath」にスクリプトを保存するフォルダを設定。
 (「環境変数 設定 windows」ググッて)
 (面倒なら、C:\windowsに、紹介されているスクリプトぶち込む)

2020年11月27日金曜日

VBA : SQLSelectSelected : 改修 : Select 結果を result という名のExcel テーブルに出力

ココで最新版を公開している、自画自賛 DB 不要 SQL 実行環境 ”SQLSelectSelected” であるが、また、ちょい改修をいれたぞ。

Select 結果が展開される表組を Excelテーブルに作り込む様に修正した。

初回 Select 時はシート有効データの最後に追加しているが、これをExcelテーブルにして、2回目からは、同じ場所を上書きするように修正した。

resultt テーブルを cut & paste で移動すれば、以降の Select 実行でも、移動先の result テーブルを上書きする。

このツール、マジ凄くね? 

日本では著作権を放棄できないので著作権自体は保持するが、業務利用も含めて使用権は制限なしだ。 SQLデバッグで泣いてるおまいら、このツールで応援するぞ。再販は認めん。

動作環境を確認したが、現時点で最新OSの windows10(64bit) + 自腹で買ったExcel2019 で開発した。 CPUはAtomだ笑え。

Microsoft Access Database Engine 2016 Redistributable をインストールすれば、なんと windows8(32bit) + Excel2013 でも完璧に動いたぞ。 Lenovo MiiX とかいう 7inch の Atom タブレットだ。大いに笑え。

おまいらの Core i プロセッサなら問題ないはず。 早く SQLデバッグを終わらせて、皆で「星を紡ぐ子供たち」 にハマろう。フレンド申請受付中だぞ。




VBA : SQLSelectSelected で使用した関数のインターフェース仕様。ワークシート関数として使用可だ。

 前記事で公開した SqlSelectSelected とともに作成された、外部使用可能な関数のインターフェース仕様だ。

変換後SQLの検証、Oracleコンバートの一次変換に使ってくれ。

VBAで作成された Public Function をワークシート関数に使用すると、シート再描画が激遅だ。

concatsep以外の関数、Oracle2MsSql、Oracle2ExcelSqlはブック中での多用回避に留意しろし。


concatsep  汎用関数として使用可

Oracle2MsSqlText  他の自作マクロ等から呼出し可

Oracle2MsSql  Oracle⇒Access(SQLServer)変換の一次加工に使用可

Oracle2ExcelSql  SQLSelectSelectedマクロエラー時のSQL文法チェックに使用


Function concatsep(<セル範囲>[,[<列間セパレータ>][,<行間セパレータ>]]) as string


セル範囲の値をテキストとして結合する

列間、行間セパレータの省略値はセル内改行コード”chr(10)" になる

SQLテキストの場合、列間セパレータを半角スペース、行間セパレータを chr(10) に設定する


例. =concatsep(C13:G23," ",CHAR(10))


Function Oracle2MsSqlText(<SQL文字列>) as string

Oracle用のSQL文をAccess用のSQL文に変換する

(よく使われ、変換が比較的簡単なOracle方言のみ)


例. =Oracle2MsSqlText("select * from TABLE1")



Function Oracle2MsSql(<セル範囲>) as string

セル範囲に記載された、Oracle用のSQL文をAccess用のSQL文に変換する

内部でconcatsep,Oracle2MsSqlTextを呼び出している


例. =Oracle2MsSQL(C13:G23)



Function Oracle2ExcelSql(<セル範囲>) as string

セル範囲に記載された、Oracle用のSQL文を、SQLSelectSelectedマクロが使用するExcel用のSQL文に変換する

内部でOracle2MsSqlを呼び出している


例. =Oracle2ExcelSql(C13:G23)






2020年11月26日木曜日

VBA : SQLSelectSelected マクロ : バインド変数対応

 すでに公開した、Excel のみで SQL を実行できる、自画自賛の SQL 検証ツールだ。

 今回は、実行する SQL文でバインド変数を使えるように改修してみたぞ。

 

 ex.

   while sheet1@テストマスタ.項番 = sheet2%param1

   

 sheet2 の任意セルに、範囲がsheet2の"名前" を定義すれば、当該セルの内容を param1 として SQLに渡すことができる

 

 注意点

 ・範囲がブックの"名前"は処理されない

 ・テーブル名と同様に、SQL文と同一シートにある"名前"はシート名を省略して記載できる

   ... sheet1 の SQL で sheet1 の"名前" param2 を使う ⇒ "sheet1%param2" or "%param2"

 

 ・"名前"のセル範囲中、左上のセルの値が受け渡される

 ・"名前"の示すセルの表示形式が文字列(@)の場合、SQLにはシングルクォート(')の引用符が自動付加される

 

 以下、バインド変数を付加し、リテラルの確認を付加したSQLのサンプルだ

 

 select 本人.項番

  ,本人.氏名 as 本人氏名

  ,家族.*

  ,'123abc' as リテラル

  ,"123abc" as リテラル2

 from sheet1@testtable as 本人

 INNER JOIN sheet2@家族 as 家族

 on 本人.項番 = 家族.社員番号

 where 本人.項番 = '1'

 and 家族.項番 > sheet1%param1

 

 

 バインドに直接関係ないが、本マクロSQLやExcelSQLの文法上の制限をまとめた

 本マクロのSQL文法は、ExcelSQL文法(AccessSQL)にテーブル名指定法とバインド変数指定法を拡張したものだ

 

 ・本マクロのSQL文法/テーブル指定法

     [<シート名>]@<excelテーブル名>

 

 ・本マクロのSQL文法/バインド変数指定法

     [<シート名>]%<シート範囲の"名前">

 

     シート名、テーブル名は半角英数、全角カタカナひらがな漢字、半角アンダーバーが使用できる

     全角認識はアバウトなので許してくれ

 

 ・ExcelSQL文法/変数型

     基本的にバリアント型なので、数値のように扱えば数値、文字のように扱えば文字としてふるまう

     しかし、SQL中にリテラルを記述する場合、明確に文字列として記載するので、テーブル項目側も型を明確にする必要がある

     具体的には、Excelテーブル(表組)中で文字列として扱う項目のデータは、表示形式を文字型に設定しなくてはいけない

     

     1.バリアントのままSQLで使用する場合

         data = ABC

         

     2.文字型であることを明確にする場合

         data = 'ABC' または data = "ABC"

         

 ・ExcelSQL文法/引用符

     ダブル/シングルクォート("),(')のどちらでも使用できるが、文字列型バインド変数の場合シングルクォートを付加している

     ただしセル中では先頭のシングルクォートは非表示となり、実際のデータからも排除される

     先頭にシングルクォートを記載しなくてはいけない場合、手前に1文字の半角スペースを付加して、シングルクォートが消えないように留意しろし


Ora2MsSQL.bas ※2020/11/27更新

SQL.bas ※2020/11/27更新

 

2020年11月20日金曜日

SQLSelectSelectedマクロ動作検証(操作方法)

さて、前記事で公開したSQLSelectSelectedマクロだが、表結合の動作検証もかねて、実際の操作手順を解説するぞ。

手抜き資料なので、見辛さは堪忍してくれ。


初心者向けにSQLを解説しているサイトの、例題表組、SQLをそのままコピペでwebから持ってきて、同一結果がでる事を確認している。

白羽の矢が立ったサイトはココだ、Mochizukiさん、勝手に使って申し訳ない。


web上から例題の表組を任意ワークブックの任意の場所に張り付ける

dogsテーブルownersテーブル
bcdefg
5idnameowner_ididname
61aka11ichiro
72ao22jiro
83shiro13saburo
94kuro4

②れぞれ表組範囲を選択しCTRL+Tを押下しExcelテーブルとする。※表組範囲の選択は、ヘッダ行も含めて選択する

テーブル領域のいずれかのセルを選択すると、Excelメニューに「デザイン」のタブが現れる

左端の「テーブル名」に、SQLで使用するテーブル名称を入力する











同webからSQLをテーブルを設定したシートの任意セルに貼り付ける

SELECT * FROM dogs
INNER JOIN owners
ON dogs.owner_id = owners.id;

本マクロの仕様に合わせ、テーブル名部分全てに"@"を付加する

SELECT * FROM @dogs
INNER JOIN @owners
ON @dogs.owner_id = @owners.id;

⑥⑤のSQLテキストセルを選択した状態で、SQLSelectSelectedマクロを実行

SELECT * FROM [Sheet2$B5:D9]
INNER JOIN [Sheet2$F5:G8]
ON [Sheet2$B5:D9].owner_id = [Sheet2$F5:G8].id;
※⑤のSQLは左記SQLに、内部で変換され実行される

SQLを実行したワークシートデータ有効最下行にSelect結果が展開される

※展開されたSelect結果中の項目名がテーブル名で修飾される場合、Excel参照形式の表記になる。


項目名がみっともないので、テーブル名をasで別名定義し、オリジナルのSQLと同じ表題にする

SELECT * FROM @dogs as dogs
INNER JOIN @owners as owners
ON dogs.owner_id = owners.id;

⑨⑧のSQLテキストセルを選択した状態で、SQLSelectSelectedマクロを実行する

⑩SQLを実行したワークシートデータ有効最下行にSelect結果が展開される


⑪同様にLEFT OUTER JOIN サンプルを実行

SELECT * FROM @dogs as dogs
LEFT OUTER JOIN @owners as owners
ON dogs.owner_id = owners.id;

⑫同様にLEFT OUTER JOIN サンプルを実行

SELECT * FROM @dogs as dogs
RIGHT OUTER JOIN @owners as owners ON dogs.owner_id = owners.id;





2020年11月19日木曜日

VBA : SQLSelectSelectedマクロ : DB無しEXCELのみで SQL 単体実行ができちゃう君


最新版はこちら

Excel単独で、SQL実行環境を作ってみた。設計段階でのSQL検証や、SQL研修、SQL単体試験での出力想定値算出等に使ってくれ。もう一度言うが、Excel単独で、DBサーバ、DBクライアントは一切必要ない。

実行できるのはSelect文のみだ。Access用のSQLであれば動作するがデータソースがEXCELなので、インデックス、NULL禁止項目、データ型、項目長の定義ができない。依存するSQLはNGだ。JOIN,GROUP HAVING,EXISTS 等、問題なしで動くぞ。
また、前記事のOracle→AccessSQL変換を呼び出しているが、CASE,DECODEがあると激遅になるので注意しろし。OracleSQL変換で失敗するとSQLが空になるので、Oracle2MsSQL
ワークシート関数で、変換結果を確認してくれ。

ソースコードに "SQL.bas" とか名前を付け保存し、XLSM(マクロ対応ワークブック)のVBAエディタからインポートしてくれ。前の記事の"OR2MSSQL.bas" もインポートし、参照設定で”Microsoft ActiveX Data Objects 6.1 Library"を参照してくれ。
Accessの再配布ライブラリを導入 or データコネクションで Jetエンジンを指定すればExcel2013でも動くらしいぞ。もちろん2013は未検証だ。


最新版はこちら

2020年11月18日水曜日

VBA : Oracle2MsSQL : Oracle⇒Access SQL変換ワークシート関数

300ステップに近い大物マクロだぞ。

セル範囲をパラメタにして、変換結果を返す関数だ。

「なんちゃって変換」なので、変換できない文もあるぞ。

変換作業の一次変換だと割り切って使ってくれ。

以下のOracle関数、Oracle文に対応している。


SUBSTR ⇒ mid

LENGTH ⇒ len

SYSDATE ⇒ now

TO_NUMBER ⇒ CInt

  単純置換。


TO_CHAR ⇒ str

  数値から文字への変換のみ対応。日付のTO_CHARはNG


NVL ⇒  iif

  iif関数にパラメタ追加し変換

  

DECODE ⇒ iif

  iif関数の入れ子に変換

  

CASE ⇒ iif

  iif関数の入れ子に変換

  "CASE WHEN xxx=yyy" , "CASE xxx WHEN yyy" 両方に対応。

  CASE文の入れ子も変換できるが、そもそもそんな汚いSQL書くなし。


いずれかの変換で誤変換される場合、内部関数、Ora2MsSqlText中にフラグがあるので、false立てて機能を切ってくれ。


Macroのつぼ
「VBAのバグじゃね?」と、思わずヒイたぞ。
例えば、For i = 10 to 0 Step -1 のループ中で、添え字"i"を11に変えてループ継続させてみた。
※ループ中特定条件で、ループを最初からやり直す処理だな。
ループのNext前処理として、Step -1 が実行され、i=10で実行されるところ、i=11のままだった。
※2020/11/20 最適化したので、ループ添え字書き換えロジックは排除された
 
Forループの中で、脱出条件やループ添え字を変えるような、汚いことはするなというMSのお達しだ。
当該処理にはdo,while,until,loopを使えし。CASE文の変換はOSのメモリ状態次第で、数秒~数十秒掛かる場合があるぞ。
1ブックにこの関数を多用すると再描画でもどってこないから気を付けろし。

ソースコードに "OR2MSSQL.bas" とか名前を付け保存し、XLMS(マクロ対応ワークブック)のVBAエディタからインポートしてくれ。

※2020/11/19 最適化の為一部修正 
 

2020年11月10日火曜日

VBA : ConcatSep : セパレータ指定セル範囲文字列結合ワークシート関数

指定されたセル範囲のValueを文字列として結合するワークシート関数だ。

他マクロからの呼び出しやワークシート関数として使える。

結合時のセパレータを指定できるが、セパレータ指定を省略した場合、LF(セル内改行)をセパレータとして結合する。ただし、結合結果末尾にはセパレータは付加されない


使い方

=ConcatSep(<セル範囲>,[<セパレータ文字列>])

第二パラメタは省略可でディフォルト値はvbLF(セル内改行)となる

ex.

Macroのつぼ
ペーストされたテキストデータ等を1テキストに変換する。

本関数に限らずワークシート関数をVBAで作成すると、再描画時が致命的に遅くなる場合がある。
アドイン(.xla、.xlam)で作った方がイイと思う。

 

2020年11月9日月曜日

VBA : RegChg : 正規表現置換ワークシート関数

ぶっちゃけ、何年ぶりの更新よ!?

他マクロからの呼び出しやワークシート関数として使える。

ソース文字列(orセル)の中でマッチした正規表現パターンを、置換文字列に置き換える。部分文字列も使えるし、大文字小文字Case指定も出来る。

使い方

=RegChg(<検索対象>,<正規表現パターン>,<"置換パターン>,[IgnoreCase:true/false])

第四パラメタは省略可でディフォルト値はtrue。IgnoreCaseとなる

ex.
=RegChg("TestType of File1,"T","tt")
=RegChg("TestType of File1,"T","tt",true)
   戻り値は""ttesttttype of File1"

=RegChg("TestType of File1"Test(.*)File([0-9]+)","$1$2")
   戻り値は""Type of 1"
Macroのつぼ
WSH等で使われるComモジュールのRegExpをExcelから呼び出している。

マクロ作るのメンドーで、ワークシート関数でナントカしたいヤシ、そのまま使ってくれ。アドイン(.xla)で作った方がイイと思う。

指定セル範囲を直接置換する機能も公開予定だ。