英文:
How to know if my Recordset is full and extract it to an Excel Sheet?
问题
我正在编写一个宏来将请求转换为SQL查询,执行它并将其返回到一个新的Excel工作表中。
我称之为“Result”的对象应该执行查询,基本上代码的其余部分应该允许我提取数据并将其放在Excel工作表中。
在研究这个主题后,我得到了以下代码,它产生了错误3021:“没有当前记录”。
Result是一个对象,connection是一个对象(用于连接),requete是一个字符串,它是应该执行的SQL查询。Output是一个变体(我不知道这是用来做什么的)。
我在这一行上遇到错误 Debug.Print Result(i-1)
。
我进一步研究后,它引导我首先使用.EOF
测试,然后编写代码的其余部分来使用 GetRows()
获取查询结果。
这段代码运行,但总是得到“未找到数据”。所以我卡在这里,因为我不知道第一部分是否有效。
我不知道问题出在哪里,是代码、记录集还是查询?
以下是整个函数(我已经更新了建议的部分,但我再次遇到了3021错误):
Function fct_resultat(fichier_type As Integer, Sql As String, rgD As Range) As Variant
Dim connection As Object
Dim Result As Object
Dim SaveName As Variant
Dim Wb_Res As Workbook
Dim Ws_res As Worksheet
Dim i As Integer, j As Integer
Dim nbcol As Integer, nbrow As Integer
Dim requete As String
Set Wb_Res = Workbooks.Add
Set Ws_res = Wb_Res.Worksheets(1)
Set connection = CreateObject("ADODB.Connection")
With connection
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.Open
End With
requete = Sql
Set Result = connection.Execute(requete)
Do
Ws_res.Range("A1").CopyFromRecordset Result
Result.MoveNext
Loop Until Result.EOF
此外,关于查询本身(requete),它是通过各种函数构建的字符串(目标是从用户输入创建查询)。因此,它是一个变量字符串,在代码中早些时候定义了(我有一个用于我的sql_string和执行查询的函数)。
以下是SQL查询字符串的示例:
SELECT bps_codeFonds, Portefeuille, bps_libellePaysEmetteur,
bps_libTypeInstr, bps_libSousTypeInstr, id_inventaire,
bps_pruDevCot
FROM [Donnees$]
WHERE bps_deviseCotation="DKK" AND
bps_quantite<10000
ORDER BY AuM ASC;
我对VBA和SQL非常熟悉,但这是我第一次处理应该连接这两种语言的对象。
英文:
I'm writing a macro to translate a request into an SQL query, execute it and return it on a new Excel Sheet.
The object I called "Result", should execute the query, and basically the rest of the code that should allow me to extract the data and put it on an Excel Sheet.
After researching the subject, I got the following code, which produced
>error 3021 : 'No Current Record'.
Result is an object, connection is an object (for the connection), requete is a string, which is the SQL query that should be executed.
Output is a variant. (I don't get what this is meant to be used for.)
I get the error on the line Debug.Print Result(i-1)
.
Set Result = connection.Execute(requete)
Do
For i = 1 To Result.Fields.Count
Debug.Print Result(i - 1)
Output = Output & Result(i - 1) & ";"
Ws_res.Cells(1, 1).CopyFromRecordset Result
Next i
Output = Output & vbNewLine
Result.MoveNext
Loop Until Result.EOF
I researched a bit more, and it led me to "test" with .EOF first, then write the rest of the code to get my query with GetRows()
.
If not Result.EOF Then
Output = Result.GetRows()
nbcol = UBound(Output, 1) + 1
For i = 1 To Result.Fields.Count
For j = 1 To nbcol
Debug.Print Output(i, j)
Next j
Next i
Ws_res.Cells(1, 1) = Output
Else
MsgBox ("No Data found")
End If
This code runs, but it always gets me "No Data Found". So I'm stuck on this as I can't know if the first bit works.
I don't know where the problem comes from, the code, the recordset or the query?
Here is the whole function (I've updated the bit that causes me a problem with what was suggested, but I have again the 3021 error):
Function fct_resultat(fichier_type As Integer, Sql As String, rgD As Range) As Variant
Dim connection As Object
Dim Result As Object
Dim SaveName As Variant
Dim Wb_Res As Workbook
Dim Ws_res As Worksheet
Dim i As Integer, j As Integer
Dim nbcol As Integer, nbrow As Integer
Dim requete As String
Set Wb_Res = Workbooks.Add
Set Ws_res = Wb_Res.Worksheets(1)
Set connection = CreateObject("ADODB.Connection")
With connection
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.Open
End With
requete = Sql
Set Result = connection.Execute(requete)
Do
Ws_res.Range("A1").CopyFromRecordset Result
Result.MoveNext
Loop Until Result.EOF
Additionally, regarding the query itself (requete), it is a string which has been built through various functions (the goal being creating a query from inputs by the user). Therefore, it is a variable string, defined earlier in the code (I have a function for my sql_string and a function to execute the query).
Here is an example of the sql query string (I'm French, which explains all the details in French):
SELECT bps_codeFonds, Portefeuille, bps_libellePaysEmetteur,
bps_libTypeInstr, bps_libSousTypeInstr, id_inventaire,
bps_pruDevCot
FROM [Donnees$]
WHERE bps_deviseCotation="DKK" AND
bps_quantite<10000
ORDER BY AuM ASC;
I am quite familiar with VBA and SQL, but it is my first time handling objects that should connect the two languages.
答案1
得分: 1
这段代码对我有效:
Sub Tester()
fct_resultat "select * from [Donnees$] where false"
End Sub
'Your Function returns no result, so make it a Sub...
Sub fct_resultat(Sql As String)
Dim connection As Object, Result As Object, SaveName As Variant
Dim Wb_Res As Workbook, Ws_res As Worksheet
Set Wb_Res = Workbooks.Add
Set Ws_res = Wb_Res.Worksheets(1)
Set connection = CreateObject("ADODB.Connection")
With connection
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & ThisWorkbook.FullName & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.Open
Set Result = .Execute(Sql)
End With
If Not Result.EOF Then
'This copies the content of the entire recordset,
' so there's no need to use it in a loop
Ws_res.Range("A1").CopyFromRecordset Result
Else
Ws_res.Range("A1").Value = "No results"
End If
End Sub
如果你的特定SQL没有返回任何结果,需要检查你的数据以确保它实际上有匹配的记录。
英文:
This code works for me:
Sub Tester()
fct_resultat "select * from [Donnees$] where false"
End Sub
'Your Function returns no result, so make it a Sub...
Sub fct_resultat(Sql As String)
Dim connection As Object, Result As Object, SaveName As Variant
Dim Wb_Res As Workbook, Ws_res As Worksheet
Set Wb_Res = Workbooks.Add
Set Ws_res = Wb_Res.Worksheets(1)
Set connection = CreateObject("ADODB.Connection")
With connection
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & ThisWorkbook.FullName & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.Open
Set Result = .Execute(Sql)
End With
If Not Result.EOF Then
'This copies the content of the entire recordset,
' so there's no need to use it in a loop
Ws_res.Range("A1").CopyFromRecordset Result
Else
Ws_res.Range("A1").Value = "No results"
End If
End Sub
If your specific SQL is not returning any results, you need to check your data to make sure it actually has matching records.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论