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

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

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 &amp; Result(i - 1) &amp; &quot;;&quot;
        Ws_res.Cells(1, 1).CopyFromRecordset Result
    Next i
    Output = Output &amp; 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 (&quot;No Data found&quot;)
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(&quot;ADODB.Connection&quot;)
With connection
    .Provider = &quot;Microsoft.ACE.OLEDB.12.0&quot;
    .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;
    .Open
End With

requete = Sql
Set Result = connection.Execute(requete)

Do
    Ws_res.Range(&quot;A1&quot;).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=&quot;DKK&quot;  AND 
      bps_quantite&lt;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 &quot;select * from [Donnees$] where false&quot;
End Sub

&#39;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(&quot;ADODB.Connection&quot;)
    With connection
        .Provider = &quot;Microsoft.ACE.OLEDB.12.0&quot;
        .connectionstring = &quot;Data Source=&quot; &amp; ThisWorkbook.FullName &amp; &quot;;&quot; &amp; _
                    &quot;Extended Properties=&quot;&quot;Excel 12.0 Xml;HDR=YES&quot;&quot;;&quot;
        .Open
        Set Result = .Execute(Sql)
    End With
    
    If Not Result.EOF Then
        &#39;This copies the content of the entire recordset,
        &#39; so there&#39;s no need to use it in a loop 
        Ws_res.Range(&quot;A1&quot;).CopyFromRecordset Result
    Else
        Ws_res.Range(&quot;A1&quot;).Value = &quot;No results&quot;
    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.

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:

确定