如何知道我的记录集是否已满并将其提取到Excel工作表中?

huangapple go评论103阅读模式
英文:

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错误):

  1. Function fct_resultat(fichier_type As Integer, Sql As String, rgD As Range) As Variant
  2. Dim connection As Object
  3. Dim Result As Object
  4. Dim SaveName As Variant
  5. Dim Wb_Res As Workbook
  6. Dim Ws_res As Worksheet
  7. Dim i As Integer, j As Integer
  8. Dim nbcol As Integer, nbrow As Integer
  9. Dim requete As String
  10. Set Wb_Res = Workbooks.Add
  11. Set Ws_res = Wb_Res.Worksheets(1)
  12. Set connection = CreateObject("ADODB.Connection")
  13. With connection
  14. .Provider = "Microsoft.ACE.OLEDB.12.0"
  15. .connectionstring = "Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
  16. .Open
  17. End With
  18. requete = Sql
  19. Set Result = connection.Execute(requete)
  20. Do
  21. Ws_res.Range("A1").CopyFromRecordset Result
  22. Result.MoveNext
  23. Loop Until Result.EOF

此外,关于查询本身(requete),它是通过各种函数构建的字符串(目标是从用户输入创建查询)。因此,它是一个变量字符串,在代码中早些时候定义了(我有一个用于我的sql_string和执行查询的函数)。

以下是SQL查询字符串的示例:

  1. SELECT bps_codeFonds, Portefeuille, bps_libellePaysEmetteur,
  2. bps_libTypeInstr, bps_libSousTypeInstr, id_inventaire,
  3. bps_pruDevCot
  4. FROM [Donnees$]
  5. WHERE bps_deviseCotation="DKK" AND
  6. bps_quantite<10000
  7. 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).

  1. Set Result = connection.Execute(requete)
  2. Do
  3. For i = 1 To Result.Fields.Count
  4. Debug.Print Result(i - 1)
  5. Output = Output &amp; Result(i - 1) &amp; &quot;;&quot;
  6. Ws_res.Cells(1, 1).CopyFromRecordset Result
  7. Next i
  8. Output = Output &amp; vbNewLine
  9. Result.MoveNext
  10. 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().

  1. If not Result.EOF Then
  2. Output = Result.GetRows()
  3. nbcol = UBound(Output, 1) + 1
  4. For i = 1 To Result.Fields.Count
  5. For j = 1 To nbcol
  6. Debug.Print Output(i, j)
  7. Next j
  8. Next i
  9. Ws_res.Cells(1, 1) = Output
  10. Else
  11. MsgBox (&quot;No Data found&quot;)
  12. 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):

  1. Function fct_resultat(fichier_type As Integer, Sql As String, rgD As Range) As Variant
  2. Dim connection As Object
  3. Dim Result As Object
  4. Dim SaveName As Variant
  5. Dim Wb_Res As Workbook
  6. Dim Ws_res As Worksheet
  7. Dim i As Integer, j As Integer
  8. Dim nbcol As Integer, nbrow As Integer
  9. Dim requete As String
  10. Set Wb_Res = Workbooks.Add
  11. Set Ws_res = Wb_Res.Worksheets(1)
  12. Set connection = CreateObject(&quot;ADODB.Connection&quot;)
  13. With connection
  14. .Provider = &quot;Microsoft.ACE.OLEDB.12.0&quot;
  15. .connectionstring = &quot;Data Source=&quot; &amp; ThisWorkbook.Path &amp; &quot;\&quot; &amp; ThisWorkbook.Name &amp; &quot;;&quot; &amp; &quot;Extended Properties=&quot;&quot;Excel 12.0 Xml;HDR=YES&quot;&quot;;&quot;
  16. .Open
  17. End With
  18. requete = Sql
  19. Set Result = connection.Execute(requete)
  20. Do
  21. Ws_res.Range(&quot;A1&quot;).CopyFromRecordset Result
  22. Result.MoveNext
  23. 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):

  1. SELECT bps_codeFonds, Portefeuille, bps_libellePaysEmetteur,
  2. bps_libTypeInstr, bps_libSousTypeInstr, id_inventaire,
  3. bps_pruDevCot
  4. FROM [Donnees$]
  5. WHERE bps_deviseCotation=&quot;DKK&quot; AND
  6. bps_quantite&lt;10000
  7. 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

这段代码对我有效:

  1. Sub Tester()
  2. fct_resultat "select * from [Donnees$] where false"
  3. End Sub
  4. 'Your Function returns no result, so make it a Sub...
  5. Sub fct_resultat(Sql As String)
  6. Dim connection As Object, Result As Object, SaveName As Variant
  7. Dim Wb_Res As Workbook, Ws_res As Worksheet
  8. Set Wb_Res = Workbooks.Add
  9. Set Ws_res = Wb_Res.Worksheets(1)
  10. Set connection = CreateObject("ADODB.Connection")
  11. With connection
  12. .Provider = "Microsoft.ACE.OLEDB.12.0"
  13. .connectionstring = "Data Source=" & ThisWorkbook.FullName & ";" & _
  14. "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
  15. .Open
  16. Set Result = .Execute(Sql)
  17. End With
  18. If Not Result.EOF Then
  19. 'This copies the content of the entire recordset,
  20. ' so there's no need to use it in a loop
  21. Ws_res.Range("A1").CopyFromRecordset Result
  22. Else
  23. Ws_res.Range("A1").Value = "No results"
  24. End If
  25. End Sub

如果你的特定SQL没有返回任何结果,需要检查你的数据以确保它实际上有匹配的记录。

英文:

This code works for me:

  1. Sub Tester()
  2. fct_resultat &quot;select * from [Donnees$] where false&quot;
  3. End Sub
  4. &#39;Your Function returns no result, so make it a Sub...
  5. Sub fct_resultat(Sql As String)
  6. Dim connection As Object, Result As Object, SaveName As Variant
  7. Dim Wb_Res As Workbook, Ws_res As Worksheet
  8. Set Wb_Res = Workbooks.Add
  9. Set Ws_res = Wb_Res.Worksheets(1)
  10. Set connection = CreateObject(&quot;ADODB.Connection&quot;)
  11. With connection
  12. .Provider = &quot;Microsoft.ACE.OLEDB.12.0&quot;
  13. .connectionstring = &quot;Data Source=&quot; &amp; ThisWorkbook.FullName &amp; &quot;;&quot; &amp; _
  14. &quot;Extended Properties=&quot;&quot;Excel 12.0 Xml;HDR=YES&quot;&quot;;&quot;
  15. .Open
  16. Set Result = .Execute(Sql)
  17. End With
  18. If Not Result.EOF Then
  19. &#39;This copies the content of the entire recordset,
  20. &#39; so there&#39;s no need to use it in a loop
  21. Ws_res.Range(&quot;A1&quot;).CopyFromRecordset Result
  22. Else
  23. Ws_res.Range(&quot;A1&quot;).Value = &quot;No results&quot;
  24. End If
  25. 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.

huangapple
  • 本文由 发表于 2023年4月1日 00:57:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900977.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定