使用 Excel VBA 运行 SQL 查询
作者:迹忆客
最近更新:2023/03/19
浏览次数:
Excel 的强大功能之一是数据处理和数据可视化。在数据方面,结构化查询语言 (SQL) 非常有用,因为它是用于从数据库中获取数据的主要编程语言。
通常,SQL 程序具有内置的数据输出接口,你可以在其中查看查询结果。但是,这些数据输出接口中没有一个能够与 Excel 可以提供的灵活性和功能水平相匹配。
在本教程中,我们将结合 SQL 的数据提取能力和 Excel 的数据处理能力。该方案通常用于建立数据中心的行业,并且不可避免地需要快速简便的数据提取。
下面的代码使用允许通过远程数据源连接的 ADO
对象将 Excel 与 SQL 服务器连接起来。有了这个对象,VBA 可以访问和操作数据库。
但是,ADODB
对象不会随 VBA 使用的默认库自动提供。要启用 ADODB
对象,我们需要在 References
工具栏中启用它。
为此,请按照以下步骤操作。
现在一切就绪。
下面的代码块有八个参数;请参阅下表:
参数 | 说明 |
---|---|
Sql |
要运行的 Sql 脚本 |
nRow |
返回提取数据的行 |
nCol |
返回提取数据的列 |
sheetDes |
返回提取数据的工作表 |
usrID |
在数据库中访问的用户名 |
pssWrd |
要在数据库中访问的用户名密码 |
sidStr |
要使用的 SID |
hst |
要使用的主机名 |
Sub getData(Sql As String, nRow As Integer, nCol As Integer, sheetDes As String, usrID as String, pssWrd as String, sidStr as string, hst as String)
Dim Connct As ADODB.Connection
Dim RcrdSet As ADODB.Recordset
Dim RcrdVal As Variant
Dim reference_x As Integer
Dim reference_y As Integer
Dim records_count As Integer
'CONNECTION STRING
connection_string = "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = hst)(PORT = 1521))(CONNECT_DATA = (SID = sidStr)))"
user_id = usrID
pass_word = pssWrd
'EXCEL PRINT LOCATION
reference_col = nCol
reference_row = nRow
' start ------ default connection setup & SQL execution code (Do not Edit entries)
cs = "Provider=OraOLEDB.Oracle;Data Source=" & connection_string & ";User Id=" & user_id & ";Password=" & pass_word & ";"
Set Connct = New ADODB.Connection
Set RcrdSet = New ADODB.Recordset
With Connct
.CursorLocation = adUseClient
.Open cs
.CommandTimeout = 0
RcrdSet.CursorType = asOpenForwardOnly
RcrdSet.Open (Sql), Connct
records_count = CInt(RcrdSet.RecordCount)
' end ------ default connection setup & SQL execution code (Do not Edit entries)
' start ------ default data print setup & close procedures (Do not Edit)
If records_count > 0 Then
RcrdSet.MoveFirst
For x = 0 To RcrdSet.Fields.Count - 1
ThisWorkbook.Sheets(sheetDes).Cells(reference_row, x + reference_col) = RcrdSet.Fields(x).Name
Next
ThisWorkbook.Sheets(sheetDes).Cells(reference_row + 1, reference_col).CopyFromRecordset RcrdSet
End If
End With
RcrdSet.Close
Connct.Close
Set RcrdSet = Nothing
Set Connct = Nothing
'end ------ default data print setup & close procedures (Do not Edit)
End Sub
现在,假设我们有以下关于你的数据库和数据库连接的信息:
Host: database1
SID: database1@server.com
Username: username123
Password: pw123
database1
、table1
内容:
| Names | Age | Gender | Sports |
|------------|----------|--------------|--------------|
| Juan | 17 | Male | Chess |
| Pedro | 19 | Male | Badminton |
| Maria | 25 | Female | Volleyball |
| Rodolfo | 29 | Male | Basketball |
| Cathy | 18 | Female | Chess |
| Michelle | 21 | Female | Swimming |
| Glen | 24 | Male | Billiards |
SQL 查询:
Select Names, Gender, Sports
from table1@database1
where Age <= 25
要执行此 SQL 查询并输出 Excel 工作簿第 1 列和第 1 行的 Sheet1
上的条目,请使用以下代码块:
Sub getData(Sql As String, nRow As Integer, nCol As Integer, sheetDes As String, usrID As String, pssWrd As String, sidStr As String, hst As String)
Dim Connct As ADODB.Connection
Dim RcrdSet As ADODB.Recordset
Dim RcrdVal As Variant
Dim reference_x As Integer
Dim reference_y As Integer
Dim records_count As Integer
'CONNECTION STRING
connection_string = "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = hst)(PORT = 1521))(CONNECT_DATA = (SID = sidStr)))"
user_id = usrID
pass_word = pssWrd
'EXCEL PRINT LOCATION
reference_col = nCol
reference_row = nRow
' start ------ default connection setup & SQL execution code (Do not Edit entries)
cs = "Provider=OraOLEDB.Oracle;Data Source=" & connection_string & ";User Id=" & user_id & ";Password=" & pass_word & ";"
Set Connct = New ADODB.Connection
Set RcrdSet = New ADODB.Recordset
With Connct
.CursorLocation = adUseClient
.Open cs
.CommandTimeout = 0
RcrdSet.CursorType = asOpenForwardOnly
RcrdSet.Open (Sql), Connct
records_count = CInt(RcrdSet.RecordCount)
' end ------ default connection setup & SQL execution code (Do not Edit entries)
' start ------ default data print setup & close procedures (Do not Edit)
If records_count > 0 Then
RcrdSet.MoveFirst
For x = 0 To RcrdSet.Fields.Count - 1
ThisWorkbook.Sheets(sheetDes).Cells(reference_row, x + reference_col) = RcrdSet.Fields(x).Name
Next
ThisWorkbook.Sheets(sheetDes).Cells(reference_row + 1, reference_col).CopyFromRecordset RcrdSet
End If
End With
RcrdSet.Close
Connct.Close
Set RcrdSet = Nothing
Set Connct = Nothing
'end ------ default data print setup & close procedures (Do not Edit)
End Sub
Sub testSQLVBAConnection()
Dim sqlStr As String
sqlStr = "Select Names, Gender, Sports "
sqlStr = sqlStr & " from table1@database1 "
sqlStr = sqlStr & " where Age <= 25 "
Call getData(sqlStr, 1, 1, "Sheet1", "username123", "pw123", "database1@server.com", "database1")
End Sub
testSQLVBAConnection
输出:
| Names | Gender | Sports |
|------------|--------------|--------------|
| Juan | Male | Chess |
| Pedro | Male | Badminton |
| Maria | Female | Volleyball |
| Cathy | Female | Chess |
| Michelle | Female | Swimming |