エクセルマクロ（Excel-VBA）でSnowflakeからSQLでデータを取得する

# Excel-VBAでSnowflakeからSQLでデータを取得する

↓ この記事ではこんな感じのツールを作ります。マクロの前提知識が無くても動くところまで行くと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/0741c020-be3d-13d3-1910-20426315b78e.png)

## はじめに
Excel-VBAでSnowflakeに接続する記事がなかったので書いてみました。
初めてQiitaで記事を投稿します。読みにくいところあるかと思いますがご容赦ください。

## 全体の流れ
1.SnowflakeODBCドライバーのインストール、DSN設定
2.Excel準備、Excel-VBAを記述、接続テスト

## 1.Snowflake ODBCドライバーのインストール ～ DSN設定
作業の流れ
1.1 インストーラのダウンロード
1-2 インストールモジュールの実行
1-3 ODBCでのテスト接続＆DSN設定

### 1-1. インストーラのダウンロード
以下のsnowflake Developersページにて、「ODBC FOR WINDOWS」を選択すると最新のインストールモジュールが取得できる。
（ダウンロードサイト）
https://developers.snowflake.com/odbc/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/2fa977c9-7efe-fc65-65c1-845b4d8829af.png)

### 1-2. インストールモジュールの実行

ダウンロードしたインストールモジュール（msiファイル）をエクスプローラでダブルクリック等をして実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/6bfd0c4c-e36a-7f46-51d2-67f7e990b9c6.png)
　↓ Setup Wizardが表示されるので「Next」押下
![wizard1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/30536aed-759d-b7e2-3efb-4a307e425607.png)
　↓ （インストールPathを変更したい場合は直接編集して）「Next」押下
![wizard2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/3eecb454-d0e9-6095-45da-1fa8bcab3937.png)
　↓「Install」押下
![wizard3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/2a3b130c-88d4-0a60-c21a-17e0ecd60b29.png)
　↓「Finish」押下
![wizard4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/5399c6fd-f5e5-cd93-295b-b7c96ec6469e.png)

### 1-3. ODBCでのテスト接続＆DSN設定
画面左下の虫眼鏡からODBCを検索し、起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/e0c7a511-8a69-0fa9-9e0b-c0fa17572c90.png)

　↓ ODBCデータソースアドミニストレータ の画面が表示されるので「追加」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/a3e0dbe0-1ecf-8c53-97a5-b47fcc484fff.png)

　↓ リスト下部の「SnowflakeDSIIDriver」を選択し、「完了」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/6ab711bf-3f73-f864-6c7c-c52ddab3e016.png)

　↓
以下の接続設定画面にて以下を入力して「Test..」を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/8b6532ce-e2f5-8001-53d9-b47adcc2ce8c.png)
| 設定箇所 | 設定内容 |
|:-:|:-|
| Data Source | snowflake-test |
| User | （SnowflakeユーザID） |
| Password | （Snowflakeパスワード） |
| Server | （サーバ名）例：アカウントIDがAB12345（※）でAWS東京リージョンの場合<br>AB12345.ap-northeast-1.aws.snowflakecomputing.com <br>※アカウントIDが不明な場合、Snowsight等で```select current_account();```を打てば確認できます。（大抵の場合はSnowsightのURLの一部にアカウントIDが埋め込まれているのでわかると思います。） |


　↓ 特に問題なければ以下のようにSUCCESSと表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/652e1dab-3db2-f0fa-d3e9-458480328258.png)

　↓ 元の画面に戻り、OKを押してDSN登録完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/675d93db-b0fa-0dc5-cca6-e3792dc79209.png)

　↓ 「snowflake-test」が追加されたことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/836fa2ce-2d44-8228-90e1-0fb9b0f3a2aa.png)

（参考URL）
Windows用 ODBC ドライバーのインストールおよび構成
https://docs.snowflake.com/ja/user-guide/odbc-windows.html#step-1-install-the-odbc-driver

## 2.Excel準備、Excel-VBAを記述、接続テスト
作業の流れ
2-1. マクロが有効なBOOKの作成
2-2. Excelシートの準備
2-3. マクロの設定
2-4. テスト実行！

### 2-1. マクロが有効なBOOKの作成
Excelで新規ブックを作成⇒名前を付けて保存からファイルの種類をExcel マクロ有効ブック（*.xlsm）を指定し、適当なファイル名を付けて保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/0824216d-71db-396f-656f-0d1bc20ba8e2.png)

### 2-2. Excelシートの準備
今回はB3セルにSQLを記入、C7セル以降に結果を表示するツールを作成します。
###### ■ 2-2-1. Excelシートの設定
以下を実施し、ツール画面を作成する
・B列の幅を広げる
・3行目の高さを広げる
・B2セルに「SQL」と記入
・B7セルに「SQL結果⇒」と記入
（設定例）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/ac0d8683-4414-5318-3a4a-ab01ddf9da78.png)

###### ■ 2-2-2. 実行用ボタンを設定する
開発タブ（※）から「挿入」⇒ActiveXコントロールの「コマンドボタン」を選択し、B4セルあたりに配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/a8e24cdf-1a76-2dea-f662-ca3085b3263c.png)

※開発タブが表示されていない場合は以下を参考にして表示してから実行してください。

https://support.microsoft.com/ja-jp/office/-%E9%96%8B%E7%99%BA-%E3%82%BF%E3%83%96%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B-e1192344-5e56-4d45-931b-e5fd9bea2d45#:~:text=%5B%E9%96%8B%E7%99%BA%5D%20%E3%82%BF%E3%83%96%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%201%20%5B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%5D%20%E3%82%BF%E3%83%96%E3%81%AE%20%5B%E3%83%AA%E3%83%9C%E3%83%B3%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%A8%AD%E5%AE%9A%5D%3E%20%E3%81%AB%E7%A7%BB%E5%8B%95%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%202,%5B%E3%83%AA%E3%83%9C%E3%83%B3%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%A8%AD%E5%AE%9A%5D%20%E3%81%8A%E3%82%88%E3%81%B3%20%5B%E3%83%A1%E3%82%A4%E3%83%B3%20%E3%82%BF%E3%83%96%5D%20%E3%81%AE%E4%B8%8B%E3%81%AE%20%5B%E9%96%8B%E7%99%BA%5D%20%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%20%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%82%92%E3%82%AA%E3%83%B3%E3%81%AB%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

　↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/de18b63d-d397-1ece-c980-39e4ba6b3dc4.png)
　↓
配置したコマンドボタンを右クリック⇒「プロパティ」でボタン名等を設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/1285dfee-abaa-f3b1-fb81-f9499e252cba.png)
（設定箇所）
| 項目名 | 値 |
|:-:|:-:|
| （オブジェクト名） | Button_SQL実行 など |
| Caption | SQL実行 など |

　↓ 以下のようにボタン名が変更されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/50f197c3-4348-beba-ecaf-a1e504dd3e44.png)

### 2-3. マクロの設定

###### 2-3.1 ボタン押下時のプロシージャを作りつつExcel-VBA Editorの起動
開発タブにて「デザインモード」がオンになっていることを確認（なっていない場合はクリックして切り替える）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/9b613bde-bdb1-de0e-368e-d336b1bf1f3e.png)
先ほど作成した「SQL実行」ボタンをダブルクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/72fb4710-4408-3cf9-eb50-5ea15d86f4d5.png)
　↓ 以下のようにExcel-VBA用のエディタ画面が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/045cab09-a613-f778-8eb3-37f45d831bc9.png)

###### 2-3-2. 参照設定
「ツール」タブより、「参照設定」を選択、以下２つのライブラリにチェックを入れて「OK」を押下
・Microsoft ActiveX Data Object 6.1 Library
・Microsoft ActiveX Data Object Recordset 6.0 Library
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/9c61330c-0af3-7cd8-4879-4f3108c75f1a.png)

###### 2-3-3. VBA記述
Editorに表示されている以下の部分を↓の変更後ソースコードに置き換えます。
```vb
Private Sub Button_SQL実行_Click()

End Sub
```

※ ソースコード先頭の接続設定にてuid（ユーザID）、pwd（パスワード）、role、warehouseの部分をご自身の設定に変更してください。
roleとwarehouseがわからない場合は、一度snowsightのワークシート画面右上にて以下を確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/e55bf8ca-dd75-7c57-4e2a-cc57b27469ce.png)

（変更後ソースコード）
```vb
Private Sub Button_SQL実行_Click()

    ' Snowflake接続設定
    Dim conn_str As String
    conn_str = "Provider=MSDASQL;" & _
               "DSN=snowflake-test;" & _
               "uid=Administrator;" & _   '★★★変更箇所★★★
               "pwd=xxxxxx;" & _          '★★★変更箇所★★★
               "ROLE=ACCOUNTADMIN;" & _   '★★★変更箇所★★★
               "WAREHOUSE=WAREHOUSE_XS;"  '★★★変更箇所★★★
 
    ' Snowflake接続
    Dim conn As New ADODB.Connection
    Set conn = New ADODB.Connection
    conn.ConnectionTimeout = 900
    conn.CommandTimeout = 900
    conn.Open conn_str 'コネクション取得
 
    conn.CursorLocation = adUseClient
 
    '*** SQL実行準備
 
    'B3セルからSQL文取得
    Dim sql_text As String
    sql_text = Range("B3").Value
 
    'command準備
    Dim adoCmd As New ADODB.Command
    Set adoCmd.ActiveConnection = conn
    adoCmd.CommandType = adCmdText
    adoCmd.CommandText = sql_text
 
'    'SQLにパラメータマーカー（例：where column1 = ?）を設定する場合、
'    '以下のような感じで記述することができます。
'    '実行パラメータ取得
'    Dim test_param As String
'    test_param = Range("B9").Value
'
'    '実行パラメータのセット
'    Dim param As ADODB.Parameter
'    Set param = New ADODB.Parameter
'    Set param = adoCmd.CreateParameter(Str(1), adVarChar, adParamInput, Len(test_param) * 3, test_param)
'    adoCmd.Parameters.Append param
 
    '結果セット受け取り準備
    Dim recordset As New ADODB.recordset
    Set recordset = New ADODB.recordset

    'SQLを実行しrecordsetに格納
    Set recordset = adoCmd.Execute() ' SQL実行
 
    '*** 結果をC7セル以降に張り付け
    Dim out_row As Integer '出力位置（行）
    Dim out_col As Integer '出力位置（列）
    Dim i As Integer
    out_row = 7 '7行目
    out_col = 3 'C列
 
    ' C7セルに結果行数の表示
    Cells(out_row, out_col).Value = "結果： " & recordset.RecordCount & " 件"
 
    ' C8の行に結果のヘッダ部分を反映(フィールド数分出力)
    For i = 0 To recordset.Fields.Count - 1
        Cells(out_row + 1, out_col + i).Value = recordset(i).Name
    Next i
 
    ' C9セル以降に結果部分の反映
    Cells(out_row + 2, out_col).CopyFromRecordset recordset
 
 
    '*** コネクション切断
    recordset.Close
    conn.Close
 
    ' 後片付け
    Set conn = Nothing
    Set recordset = Nothing
    Set adoCmd = Nothing
 
    MsgBox ("実行完了！")
End Sub
```


（参考URL）
接続パラメータ
https://docs.snowflake.com/ja/user-guide/odbc-parameters.html#connection-parameters

### 2-4. テスト実行！
実行するときは開発タブの「デザインモード」をオフにします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/98468d1a-0204-6cf3-0ccd-5d9a19e3acd1.png)

B3セルに適当なSELECT文を入力します（事故防止のためにlimit句はつけておきましょう）
```sql
例
select * 
from snowflake.information_schema.tables
limit 100
```
###### !悲しい事故防止が起きないように以下実行前に一度Excelを保存しましょう。 
「SQL実行」ボタンを押します
　↓
以下のようにC7セル以降にSQL実行結果が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/7469b77a-5e6c-c8bb-acba-8c9be55a252c.png)

## おわりに
ソースコードの解説の代わりにコメントを多めに入れてみました。
Excelの別のセルでWHERE句条件を入れたい場合でパラメータマーカー（```where column1 = ?```）を使用したい場合の例もコメントに入れておいたので興味があればやってみてください。
尚、当記事執筆時点（2022/11/13）ではパラメータで日本語文字列が入る際、記述例のようにパラメータの桁数を入力文字の3倍等に設定しないとパラメータの文字が途中で切れた状態でSQLが実行されてしまいますので注意が必要です。

それでは良いSnowflakeライフを！