1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VBSでSQLServerに接続しExcelにデータ出力

Last updated at Posted at 2020-05-24

#はじめに
VBScriptでSQL Serverに接続しSELECTした後にデータをExcelに出力する方法を調べたのでメモします。
コードや記載にコメントが少ないですが備忘録のような記事です。申し訳ございません。
落ち着いたらコメントを追記していきます。

#SQLServerにテスト用DBおよびテーブル、データを登録

--DB作成
CREATE DATABASE dbTest;

--Table作成
use dbTest;
CREATE TABLE [dbo].[Employee](
	[No] [int] NOT NULL,
	[Name] [nchar](15) NOT NULL,
	[RegDate] [date] NOT NULL,
 CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED 
(
	[No] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

--作成したTableに100万件テストデータを登録
DECLARE @p_InsertNumber Bigint    -- INSERTする行数
SELECT @p_InsertNumber=1000000;  -- 100万に設定

WITH Base AS
  (
    SELECT
      1 AS n
    UNION ALL
    SELECT 
      n + 1
    FROM
      Base
    WHERE
      n < @p_InsertNumber
  ),
  Nums AS
  (
     SELECT
       Row_Number() OVER(ORDER BY n) AS n
     FROM
       Base
  )
  INSERT INTO Employee 
  SELECT
      n
    , 'test'
    ,  GETDATE()
  FROM
    Nums
  WHERE 
    n <= @p_InsertNumber
OPTION (MaxRecursion 0); -- 再帰クエリの再帰回数の上限をなくす

#VBScriptでSQL Serverに接続しSELECTした後にデータをExcelに出力

Option Explicit

'データベース接続情報を定義(Windows認証)
Const MYPROVIDERE = "Provider=SQLOLEDB;"
Const MYSERVER    = "Data Source=DESKTOP-TEST\SQLEXPRESS;"   'サーバー
Const MYNINSYO    = "Trusted_connection=yes;"                   'Windows認証の場合
Const MYDATABASE  = "Initial Catalog=dbTest;"                   '接続するデータベース名

Dim cn
Dim rs
Dim workbook
Dim excelObj
Dim worksheet
	
on error resume next

Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Set excelObj = CreateObject("Excel.Application")

if Err.Number = 0 Then
	'データベース接続
	cn.ConnectionString = MYPROVIDERE & MYSERVER & MYNINSYO & MYDATABASE
	cn.Open
	rs.ActiveConnection = cn
	
	If Err.Number = 0 Then
		'Excelの機能を利用するために必要

		'Excelを非表示
		excelObj.Visible = False
		'Excelブックを新規作成
		Set workbook = excelObj.Workbooks.Add()

		Call SelectTable("Select * from Employee where No < 100;",1, "テスト1")
		Call SelectTable("Select * from Employee1 where No < 10;",2, "テスト2")
		Call SelectTable("Select * from Employee where No < 5;",3, "テスト3")
		If Err.Number <> 0 Then
			Wscript.Echo Err.Description
		Else
			'名前つけて保存
			workbook.SaveAs("C:\Users\Desktop\test.xlsx")
			'ワークブックを閉じる
			workbook.Close
		End If

		Set workbook=Nothing
	Else
		Wscript.Echo Err.Description
	End If

end if
'Excelを閉じる
worksheet.Close
excelObj.Quit
Set excelObj = Nothing
'データベース切断
rs.Close
cn.Close
On Error Goto 0
Wscript.Echo "処理終了"


'データベース接続しSelect実行
Sub SelectTable(sql,cnt, name)
	'Select実行
	rs.Source = sql
	rs.Open
	Call ExcelWrite(cnt, name)
	rs.Close
End Sub

'データをExcelに出力
Sub ExcelWrite(cnt, name)
	Dim i
	Dim j

	'シートを指定(名前Or番号で指定)
	Set worksheet = workbook.Sheets(cnt)
	worksheet.Name = name

	i = 1
	Do Until rs.EOF
	    For j = 0 To rs.Fields.Count - 1
	        If i = 1 Then
	            worksheet.Cells(i, j + 1) = rs.Fields(j).Name
	        End If
	        worksheet.Cells(i + 1, j + 1) = rs(j).Value
	    Next
	    rs.MoveNext
	    i = i + 1
	Loop

End Sub

Excel出力で例外が発生した場合、Excelのタスクが残ってしまうというところがまだ解決していません。。

#Excel VBAでSQL Serverに接続しSELECTした後にデータをExcelに出力
いろいろ検討した結果、Excel VBAでSQL Serverに接続しSELECTした後にデータをシートに出力した方が簡潔ということになりました。
以下にサンプルを載せます。

Option Explicit

' SQL ServerにSELECT文を発行し、レコードセットへ取得し、Excelに書き出す。
Sub SQL_GetRecordSet()
 
    On Error GoTo ErrorProc
 
    Application.ScreenUpdating = False
    Dim DBSrv As String
    Dim DBName As String
    Dim strSQL As String
    Dim strConn As String
    Dim strSheetName As String
 
    '----------------------------------------------------
    ' DBSrvにDBサーバ名、DBNameにデータベース名
    '----------------------------------------------------
    DBSrv = "DESKTOP\SQLEXPRESS"
    'DBSrv = "DBSERVER\SQLEXPRESS,49391" 'ポート指定付
    DBName = "dbTest"
 
    '----------------------------------------------------
    ' 発効するSQLの作成(レコードセットへ取り込むSELECT文)
    '----------------------------------------------------
    strSQL = "SELECT * FROM Employee(NOLOCK)"
 
    '----------------------------------------------------
    ' 接続文字列の指定
    '----------------------------------------------------
    'Windows認証
    strConn = "Provider=SQLOLEDB;Data Source='" & DBSrv & "';Initial Catalog='" & DBName & "';Trusted_Connection=Yes"
    'SQL Server認証
    'strConn = "Provider=SQLOLEDB;Data Source='" & DBSrv & "';Initial Catalog='" & DBName & "';UID=【ユーザ名】;PWD=【パスワード】;"
 
    '書き込み先のシート作成
    Worksheets.Add after:=Worksheets(Worksheets.Count)
    strSheetName = Format(Now, "yyyy年MM月dd日hh時mm分ss秒")
    ActiveSheet.Name = strSheetName
    Worksheets(strSheetName).Cells.NumberFormatLocal = "@"
 
    'Excelに書き出し
    Call WriteExcel(strConn, strSQL, strSheetName)
 
    MsgBox "正常に書き出し完了"
    Exit Sub
 
'エラー処理
ErrorProc:
 
    MsgBox Err.Number & vbCrLf & Err.Description
 
End Sub

Sub WriteExcel(strConn As String, strSQL As String, strSheetName As String)
    Dim i As Long
    Dim j As Long
    Dim rs As Recordset
    
    'オブジェクト生成
    Set rs = New ADODB.Recordset
    'SQLを実行し、読み取り専用でレコードセットへ取得
    rs.Open strSQL, strConn, adOpenForwardOnly, adLockReadOnly, adCmdText

    'レコードセットへ先頭へ
    rs.MoveFirst
 
    'Excelに書き出し
    i = 1
    Do Until rs.EOF
        For j = 0 To rs.Fields.Count - 1
            If i = 1 Then
                Worksheets(strSheetName).Cells(i, j + 1) = rs.Fields(j).Name
            End If
            If IsNull(rs(j).Value) Then
                Worksheets(strSheetName).Cells(i + 1, j + 1) = "NULL"
            Else
                Worksheets(strSheetName).Cells(i + 1, j + 1) = rs(j).Value
            End If
            
        Next
        rs.MoveNext
        i = i + 1
    Loop
 
    'クローズ
    rs.Close
    Set rs = Nothing
End Sub

###参考にしたサイト
http://itdiary.info/microsoft-office/post-1355/

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?