- ベストアンサー
VBAでSQLのテーブル実名と別名を同じセルに出力
以前、VBAで[文字列を各セルに出力]という質問をさせていただいた者です。 現在SQLの結合条件を各セルに出力ということをやっています。 そこでは、結合条件の文字列を一文字ずつ見ていき、スペースごとに区切るという処理をしています。 そこで、各セルに出力していったのですが、テーブルに別名が付いていた時、そこにスペースがあるため、一つとして見られてしまい、同じセルには出力できません。 現在は以下の通りです。 論理 | | | | 演算子|テーブル名|条件|テーブル名 | ―――――――――――――――――――― |EMP | I |EMP | EMP_1 ON |EMP.DEPTNO | = |EMP_1.DEPTNO| これを 論理 | | | | 演算子|テーブル名|条件|テーブル名 | ―――――――――――――――――――― |EMP | I |EMP EMP_1 | ON |EMP.DEPTNO | = |EMP_1.DEPTNO| という風にしたいのです。 どなたかご教授ください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
Sub SplitSQL() '今回はセレクト文のみで考えます。 '複合条件の場合で()付きのものは対象にしません。( A OR B ) AND Cのような条件 Dim strSQL As String Dim strWork As String Dim field() As String Dim alias() As String Dim tables() As String Dim work() As String Dim i As Integer 'strSQL = "SELECT A.TABLEA AliasA, B.TABLEB AliasB, C AS AliasC FROM TABLEA,TABLEB WHERE AliasA = AliasB" 'strSQL = "SELECT A.TABLEA AliasA, B.TABLEB AliasB, C FROM TABLEA,TABLEB WHERE AliasA = AliasB" '大文字小文字の区別をしないで1文字目から文字が含まれるかをチェック If InStr(1, strSQL, "SELECT", vbTextCompare) = 0 Or InStr(1, strSQL, "FROM", vbTextCompare) = 0 Then Exit Sub End If 'FROMの前まで取り出す strWork = Left(strSQL, InStr(1, strSQL, "FROM", vbTextCompare) - 1) 'SELECT文を取り除く strWork = Right(strWork, Len(strWork) - (InStr(1, strSQL, "SELECT", vbTextCompare) + Len("select") - 1)) 'カンマ区切りでfieldに格納する field = Split(strWork, ",") 'これでfieldの中には別名の配列が完成 '以下はおまけ ReDim tables(UBound(field)) ReDim alias(UBound(field)) For i = 0 To UBound(field) field(i) = Trim(field(i)) '別名とテーブル名の対応する配列を作る work = Split(field(i), " ") 'A.TABLEA AliasA またはC AS AliasCなので、1配列目にテーブル名、配列の末尾に別名が来る。 tables(i) = work(0) '別名が存在する場合は格納、存在しない場合はvbnullstring If UBound(work) <> 0 Then alias(i) = work(UBound(work)) End If Next i For i = 0 To UBound(tables) MsgBox ("テーブル名=" & tables(i) & "別名=" & alias(i)) Next i End Sub こんなイメージでしょうか? がんばってくださいね。
その他の回答 (2)
- AKARI0418
- ベストアンサー率67% (112/166)
回答1さんの指摘にもありますが、実際のテーブル名とエイリアスの区別を現在の状態では区別することができない状態にあります。 私の意見ですが、実際のテーブル名とエイリアスを区別できる情報を取得して行えばよいと思います。 たとえば、実際にデータベースにアクセスし、スキーマ情報を取得して、テーブル名とエイリアスを区別する方法や固定値で改めて持つとか、エクセルの別シートに登録させるなどやり方はさまざまあると思います。 一番簡単なのは、エイリアスをつける時は必ずASをつけなければいけないというルールを作ることでしょうか。 ほかにはテーブル名や項目はカンマ区切りになっているはずですので、FROM区が出現するまでの間に出現するカンマの個数を取得すれば、テーブルの個数がわかりますし、カンマまでをひとつのテーブル名とすれば、1つのセルに出力することも可能です。
お礼
お礼が遅くなってしまい申し訳ありません。 そうですよね、実名と別名の区別を付けることができればいいのかなとも思ったのですが、あれだけで、区別しなければいけないのです。 なので、どうしたもんかと。。。
- nda23
- ベストアンサー率54% (777/1415)
先ず、テーブルが出てくる範囲を考えます。だいたい"FROM"から "WHERE"までの間と考えられますので、この部分を切り出します。 次に、この部分列内部にサブクエリがあると困るので、"("~")"を 除去します。(正規表現オブジェクトを使うと簡単) その後、テーブル間の区切り","(カンマ)でSplitし、更に各配列 要素に対し、空白でSplitします。2回目のSplitでできた最初の 要素がテーブル名、2番目が別名のはずです。 尚、サブクエリには別名が付いているはずで、この場合は本体が除去 されていますので、2回目のSplitの後、最初の要素が空文字に なります。これは除外してください。 ところで、SQL実行対象のDBシステムは何ですか?サブクエリの 記述方が微妙に違うので、要注意です。
お礼
お礼が遅くなってしまい申し訳ありません! DBシステムは今のところ、オラクルとUDBとSQLサーバーです。 最初にやった時は、Splitを使ったのですが、結合条件が複数あった場合うまくいかなかったので、一文字ずつ読み込む方を選んだのです。 Splitを使わずにEMPとEMP_1をEMP EMP_1という風にする方法ってないんでしょうか??
お礼
ありがとうございます! AKARI0418さんのを基に完成形を組んでいきたいと思います。 大変勉強になりました!