質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Q&A

解決済

3回答

8491閲覧

VBAマクロでselectSQLを作成

chanrina0920

総合スコア18

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

0グッド

0クリップ

投稿2017/10/10 07:26

編集2017/10/10 08:58

###前提・実現したいこと
エクセルにテーブル名一覧の記載があるシートとカラム一覧の記載があるシートがあります。
カラム一覧のシートには対応するテーブルも記載があり、そのカラムがどのテーブルに属するものか
確認ができます。

【例】
*テーブル一覧記載シート
|テーブル名|
|顧客テーブル|
|顧客管理テーブル|
・・・

*カラム一覧記載シート
|テーブル名|カラム名|
|顧客テーブル|顧客名|
|顧客テーブル|顧客年齢|
|顧客管理テーブル|顧客名|
|顧客管理テーブル|顧客ID|
|顧客管理テーブル|顧客住所|
・・・

VBAマクロを利用してシートに記載のあるテーブルよりカラムを選択するSQLをループで回して
作成したいと思います。

上の例を元に作成したいイメージは 
SELECT 顧客名,顧客年齢
FROM 顧客管理テーブル
で、カラム名が指定するテーブル名のものでなくなったら次のループで

SELECT 顧客名,顧客ID,顧客住所
FROM  顧客管理テーブル
という風に次のSELECT文を作成するようにしたいです。

###発生している問題・エラーメッセージ
作りたいイメージはあるのですが、どこから手を着けていいのかまったくわかりません。

###該当のソースコード
特にループを回す部分で次のSQLの作成にどう切り替えればいいのかが不明です。

###補足
やりたい処理の流れ
①テーブル名とカラム名を定義
②テーブルシートの一番最初のテーブル名を見に行き
テーブル名にsetする
③カラムシートの一番最初のカラムを見に行き、テーブル名が②でセットしたものと同じであれば
カラム名にsetする
④テーブル名が②と一致しなくなるまで繰り返し、カラム名は,でつなげる
⑤カラム名の一致をしなくなったら、ループを抜け、sqlを作成する
繰り返し

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

baseballyama様がコレクション使用での回答でしたので、配列使用で作成してみました。
お役に立てば幸いです。
一覧記載シートはどちらも2行目からのデータ始まりです。

Public Sub CreateSql() '1.テーブル一覧記載シート(A) Dim sheetA As Worksheet Dim endRowA As Long Set sheetA = ThisWorkbook.Worksheets("テーブル一覧記載シート") endRowA = sheetA.Cells(Rows.count, 1).End(xlUp).Row '最終行取得 Dim tableNamesA() As String 'テーブル名格納用配列 Dim n As Long Dim i As Long ReDim tableNamesA(endRowA - 2) '配列初期化(要素は0始まり、ヘッダー行含めずでデータ数=>最終行-2) n = 0 For i = 2 To endRowA tableNamesA(n) = sheetA.Cells(i, 1).Value 'テーブル名を配列に格納 n = n + 1 Next '2.カラム一覧記載シート(B) Dim sheetB As Worksheet Dim endRowB As Long Set sheetB = ThisWorkbook.Worksheets("カラム一覧記載シート") endRowB = sheetB.Cells(Rows.count, 1).End(xlUp).Row '最終行取得 Dim tableNamesB() As String 'テーブル名格納用配列 Dim columnNamesB() As String 'カラム名格納用配列 ReDim tableNamesB(endRowB - 2) '配列初期化(要素は0始まり、ヘッダー行含めずでデータ数=>最終行-2 ReDim columnNamesB(endRowB - 2) '同上 n = 0 For i = 2 To endRowB tableNamesB(n) = sheetB.Cells(i, 1).Value 'テーブル名を配列に格納 columnNamesB(n) = sheetB.Cells(i, 2).Value 'カラム名を配列に格納 n = n + 1 Next '3.テーブル名でマッチング、カラム名取得、Sql作成 Dim foundNames() As String '取得カラム名格納用配列 Dim j As Long Dim k As Long Dim query As String For j = LBound(tableNamesA) To UBound(tableNamesA) 'テーブル一覧記載シートの取得データ数分ループ query = "SELECT " 'Sql文字列初期化 n = 0 For k = LBound(tableNamesB) To UBound(tableNamesB) 'カラム一覧記載シートの取得データ数分ループ If tableNamesA(j) = tableNamesB(k) Then 'テーブル名が一致したらカラム名を格納 ReDim Preserve foundNames(n) foundNames(n) = columnNamesB(k) n = n + 1 End If Next query = query & Join(foundNames, ",") & " FROM " & tableNamesA(j) & ";" 'Sql文字列作成 Debug.Print query ReDim foundNames(0) '次のループのために取得カラム名格納用配列を初期化 Next End Sub

投稿2017/10/10 14:00

編集2017/10/11 08:47
moh1ee

総合スコア73

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chanrina0920

2017/10/11 08:29

ご回答ありがとうございます。確認させていただきます!
moh1ee

2017/10/11 08:49

下から3つめの「Redim ~ '次のループのために ・・・」の部分を修正しました
guest

0

ベストアンサー

簡単ではありますがVBAを作成しました。
イミディエイトウインドウに結果を出しているので、必要に応じて出す場所は変更頂けたらと思います。

コードの上部の定数部分を変更すれば実際のシートの状況に適合して動くと思います。

VBA

1Option Explicit 2 3' 定数宣言(ここを実際の値に変更して下さい) 4Const テーブル一覧シート名 As String = "テーブル一覧" 5Const カラム一覧シート名 As String = "カラム一覧" 6Const テーブル一覧シート_テーブル列 As Long = 1 7Const カラム一覧シート_テーブル列 As Long = 1 8Const カラム一覧シート_カラム列 As Long = 2 9Const IS_HEADER As Boolean = True 10' IS_HEADERは、各シートの1行目がヘッダ情報である場合(=SQL文の生成が不要な場合)に True を、そうでない場合に False を設定下さい 11 12' SQL文を生成 13Public Sub CreateSql() 14 15 ' 変数宣言 16 Dim tableSheet As Worksheet 17 Dim columnSheet As Worksheet 18 Dim rng As Range 19 Dim r As Long 20 Dim r2 As Long 21 Dim tableName As String 22 Dim columnNames As Collection 23 Dim columnName As Variant 24 Dim sql As String 25 26 ' テーブル一覧シート と カラム一覧シートを取得 27 With ThisWorkbook 28 Set tableSheet = .Worksheets(テーブル一覧シート名) 29 Set columnSheet = .Worksheets(カラム一覧シート名) 30 End With 31 32 ' 全テーブル走査 33 Set rng = tableSheet.Columns(テーブル一覧シート_テーブル列) 34 For r = IIf(IS_HEADER, 2, 1) To rng.Cells(rng.Cells.Count).End(xlUp).Row 35 ' テーブル名取得 36 tableName = tableSheet.Cells(r, テーブル一覧シート_テーブル列).Text 37 38 ' 全カラム取得 39 Set rng = columnSheet.Columns(カラム一覧シート_テーブル列) 40 Set columnNames = New Collection 41 For r2 = IIf(IS_HEADER, 2, 1) To rng.Cells(rng.Cells.Count).End(xlUp).Row 42 If columnSheet.Cells(r2, カラム一覧シート_テーブル列).Text = tableName Then 43 columnNames.Add columnSheet.Cells(r2, カラム一覧シート_カラム列).Text 44 End If 45 Next 46 47 ' SQL文生成 48 sql = "" 49 sql = "SELECT" 50 For Each columnName In columnNames 51 sql = sql & IIf(sql = "SELECT", " ", ", ") & CStr(columnName) 52 Next 53 sql = sql & " FROM " & tableName 54 55 ' 結果出力 56 Debug.Print sql 57 58 Next 59 60End Sub

投稿2017/10/10 12:21

yamashita_yuich

総合スコア316

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chanrina0920

2017/10/11 08:31

回答ありがとうございます。試してみたところsql作成できました。カラムが多いためかsqlが文途中で改行されてしまいます。(カラム名が途切れてしまう)何か対処法はございますでしょうか。
yamashita_yuich

2017/10/11 08:36

まずは原因を特定する必要があります。 文字が長いからといって勝手に改行コードが入ることはありません。 それはセル内改行があるからではないでしょうか?
guest

0

列名の列挙が必要なければ、

="select * from " & テーブル一覧記載シート!A2

みたいに項目を*で指定することで、全項目取得するSQLになります。

投稿2017/10/10 08:41

sazi

総合スコア25138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chanrina0920

2017/10/10 08:44

回答ありがとうござます。カンマで区切り列挙したいです。
sazi

2017/10/11 08:32

因みに、どういった利用目的でしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問