如何使用 vba 从 SSMS 数据库中检索一列数据作为数组
How do I retrieve a column of data as an array using vba - from an SSMS database
我正在寻找 return 一列数据,用作 excel 中的组合框。为此,我使用记录集 return 来自存储过程的数据。我遇到的问题是我无法弄清楚如何填充甚至显示我正在 returning 的信息 - 或者即使我正在 returning 所有数据。
我知道网上有一些解决方案建议使用 "rs.GetRows" 来填充数组,但是我没有成功。我最初打算通过索引记录集中的记录并单独添加它们来填充数组。这个问题是我永远无法获得记录集的大小,因为我使用的是动态 SQL,所以我的数组大小永远不会相同。我已经有一段时间了,我想知道是否有一个好的方法来做到这一点。
VBA代码
Public Sub SQL_SP_Column_Data2(ByVal sql_col As String, _
ByVal sql_table As String)
On Error GoTo RunTimeError
Dim array1() As Variant
Dim sqlconxn As ADODB.connection
Dim sqlcmd As ADODB.Command ' Operates as a command between SQL and vba
Dim sqlrs As ADODB.recordSet
Dim conxnString As String
Application.ScreenUpdating = False
' String used to establish a connection to the database
conxnString = "driver={SQL Server};" & _
"server='server_name';" & _
"uid='username';" & _
"pwd='password';" & _
"database='database_name';"
Set sqlconxn = New ADODB.connection
Set sqlcmd = New ADODB.Command
Set sqlrs = New ADODB.recordSet
sqlconxn.ConnectionTimeout = 30
sqlconxn.Open conxnString ' makes the connection between SQL
MsgBox "Connection 1 state: " & GetState2(sqlconxn.state)
sqlcmd.CommandType = adCmdStoredProc ' sets command to a stored procedure
sqlcmd.CommandText = "GET_COLUMN_DATA" ' name of the stored procedure
sqlcmd.ActiveConnection = sqlconxn ' makes the sql connection
sqlcmd.Parameters.Append _
sqlcmd.CreateParameter("@column_name", adVarChar, adParamInput, 255, sql_col)
sqlcmd.Parameters.Append _
sqlcmd.CreateParameter("@data_table_name", adVarChar, adParamInput, 255, sql_table)
sqlrs.Open sqlcmd
If sqlrs.EOF Then
array1() = sqlrs.GetRows
Debug.Print "VALUES: " + array1(i)
sqlrs.MoveNext
i = i + 1
End If
RunTimeError: ' Reportd any errors that might occur in the system and
Dim strError As String
strError = "ERROR: " & Err.Number & vbCrLf & Err.Description
MsgBox strError
Debug.Print strError
Exit Sub
End Sub
我正在使用上面的 GetRows,因为它是最受推荐的方法,但我无法让它按照我想要的方式工作。在这个例子中,我通常得到 ERROR: 0 or subscript out of range.
SQL 存储过程
USE AFCD
GO
ALTER PROCEDURE dbo.GET_COLUMN_DATA (@column_name nvarchar(max),
@data_table_name nvarchar(max)) AS
BEGIN
DECLARE @query nvarchar(max)
SET @query = 'SELECT ' + @column_name +
' FROM ' + @data_table_name + ''
EXEC sp_executesql @query
END
当我测试这个存储过程时,我实际上得到了我想要的数据我知道我的存储过程 returning 我想要的,但我不知道如何在 [=50] 内得到它=].
预期输出示例:
如果 vba sub 的输入是 - "WIRE_TYPE"、"WIRE_INDEX"
SQL_SP_Column_Data2 "WIRE_TYPE", "WIRE_INDEX"
那么输出应该是这样的:
Stainless Steel
Steel ER70S-3
Steel ER70S-6
Titanium(1)
Titanium(2)
SOLUTION - 这部分代码引用了我的 vba 并且在我执行 SQL SP 之后。感谢蒂姆威廉姆斯的回答。
If Not sqlrs.EOF Then
array1() = sqlrs.GetRows()
End If
Dim i As Integer
For i = 0 To 4
Debug.Print "VALUES: " + array1(0, i) ' 2D array!!!
Next i
您的 If
测试已关闭,GetRows 不需要循环:
If Not sqlrs.EOF Then
array1() = sqlrs.GetRows()
End If
记住 GetRows()
returns 一个 zero-based 二维数组,因此在访问值时需要提供两个维度,例如。
array1(0, 2) 'first field, third row
我正在寻找 return 一列数据,用作 excel 中的组合框。为此,我使用记录集 return 来自存储过程的数据。我遇到的问题是我无法弄清楚如何填充甚至显示我正在 returning 的信息 - 或者即使我正在 returning 所有数据。
我知道网上有一些解决方案建议使用 "rs.GetRows" 来填充数组,但是我没有成功。我最初打算通过索引记录集中的记录并单独添加它们来填充数组。这个问题是我永远无法获得记录集的大小,因为我使用的是动态 SQL,所以我的数组大小永远不会相同。我已经有一段时间了,我想知道是否有一个好的方法来做到这一点。
VBA代码
Public Sub SQL_SP_Column_Data2(ByVal sql_col As String, _
ByVal sql_table As String)
On Error GoTo RunTimeError
Dim array1() As Variant
Dim sqlconxn As ADODB.connection
Dim sqlcmd As ADODB.Command ' Operates as a command between SQL and vba
Dim sqlrs As ADODB.recordSet
Dim conxnString As String
Application.ScreenUpdating = False
' String used to establish a connection to the database
conxnString = "driver={SQL Server};" & _
"server='server_name';" & _
"uid='username';" & _
"pwd='password';" & _
"database='database_name';"
Set sqlconxn = New ADODB.connection
Set sqlcmd = New ADODB.Command
Set sqlrs = New ADODB.recordSet
sqlconxn.ConnectionTimeout = 30
sqlconxn.Open conxnString ' makes the connection between SQL
MsgBox "Connection 1 state: " & GetState2(sqlconxn.state)
sqlcmd.CommandType = adCmdStoredProc ' sets command to a stored procedure
sqlcmd.CommandText = "GET_COLUMN_DATA" ' name of the stored procedure
sqlcmd.ActiveConnection = sqlconxn ' makes the sql connection
sqlcmd.Parameters.Append _
sqlcmd.CreateParameter("@column_name", adVarChar, adParamInput, 255, sql_col)
sqlcmd.Parameters.Append _
sqlcmd.CreateParameter("@data_table_name", adVarChar, adParamInput, 255, sql_table)
sqlrs.Open sqlcmd
If sqlrs.EOF Then
array1() = sqlrs.GetRows
Debug.Print "VALUES: " + array1(i)
sqlrs.MoveNext
i = i + 1
End If
RunTimeError: ' Reportd any errors that might occur in the system and
Dim strError As String
strError = "ERROR: " & Err.Number & vbCrLf & Err.Description
MsgBox strError
Debug.Print strError
Exit Sub
End Sub
我正在使用上面的 GetRows,因为它是最受推荐的方法,但我无法让它按照我想要的方式工作。在这个例子中,我通常得到 ERROR: 0 or subscript out of range.
SQL 存储过程
USE AFCD
GO
ALTER PROCEDURE dbo.GET_COLUMN_DATA (@column_name nvarchar(max),
@data_table_name nvarchar(max)) AS
BEGIN
DECLARE @query nvarchar(max)
SET @query = 'SELECT ' + @column_name +
' FROM ' + @data_table_name + ''
EXEC sp_executesql @query
END
当我测试这个存储过程时,我实际上得到了我想要的数据我知道我的存储过程 returning 我想要的,但我不知道如何在 [=50] 内得到它=].
预期输出示例: 如果 vba sub 的输入是 - "WIRE_TYPE"、"WIRE_INDEX"
SQL_SP_Column_Data2 "WIRE_TYPE", "WIRE_INDEX"
那么输出应该是这样的:
Stainless Steel
Steel ER70S-3
Steel ER70S-6
Titanium(1)
Titanium(2)
SOLUTION - 这部分代码引用了我的 vba 并且在我执行 SQL SP 之后。感谢蒂姆威廉姆斯的回答。
If Not sqlrs.EOF Then
array1() = sqlrs.GetRows()
End If
Dim i As Integer
For i = 0 To 4
Debug.Print "VALUES: " + array1(0, i) ' 2D array!!!
Next i
您的 If
测试已关闭,GetRows 不需要循环:
If Not sqlrs.EOF Then
array1() = sqlrs.GetRows()
End If
记住 GetRows()
returns 一个 zero-based 二维数组,因此在访问值时需要提供两个维度,例如。
array1(0, 2) 'first field, third row