Как узнать, заполнен ли мой набор записей? И как его извлечь и поместить на лист Excel?

У меня проблема с макросом, который я пишу для проекта, где я должен иметь возможность преобразовать запрос в sql-запрос, выполнить его и вернуть на новый лист Excel. У меня проблема с объектом, который я назвал «Результат», который должен выполнять запрос, и, в основном, остальной код, который должен позволить мне извлечь данные и поместить их на лист Excel.

У меня есть пара проблем. Сначала, после долгих исследований по этому вопросу, я добрался до следующего кода, который выдавал ошибку 3021: «Нет текущей записи».

Для небольшого контекста: Result — это объект, соединение — это тоже объект (для соединения), requete — это строка, представляющая собой SQL-запрос, который должен быть выполнен. Вывод - это вариант (если честно, я действительно не понимаю, для чего этот вывод предназначен) Я получаю сообщение об ошибке в строке "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

Итак, я снова провел небольшое исследование, и это привело меня к тому, что я сначала провел своего рода «тест» с .EOF, а затем написал остальную часть кода, чтобы попытаться получить мой запрос с помощью 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

Этот код работает хорошо, но он всегда дает мне «Данные не найдены». Так что я как бы застрял на этом, так как не могу знать, работает ли первый бит или нет.

Так что теперь я немного растерялся, так как не знаю, откуда берется проблема, если она из кода, набора записей или самого запроса?

Вот вся функция (я обновил бит, который вызывает у меня проблему с тем, что было предложено, но у меня снова ошибка 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, но я впервые работаю с объектами, которые должны связывать два языка, поэтому, надеюсь, я не слишком запутан.

Требуется только одна строка Ws_res.Range("A1").CopyFromRecordset connection.Execute(requete)

CDP1802 31.03.2023 19:04
NextRecordset используется только в том случае, если ваш запрос возвращает несколько наборов записей: вы можете игнорировать это направление. Единственный тест, который вам действительно нужен, это If Result.EOF - если это правда, ваш запрос не дал записей. Если вы используете CopyFromRecordset, то это считывает весь набор записей за один раз - после того, как вы вызвали, курсор вашего набора записей останется в конце записей, поэтому вы не сможете получить доступ к каким-либо записям, если сначала не вызовете (например) MoveFirst для переместите курсор. Может быть полезно обновить ваш вопрос, чтобы добавить полный код, включая объявления ваших переменных.
Tim Williams 31.03.2023 19:49

Большое спасибо за быстрый ответ! Для теста с If Result.EOF мой запрос не вернул никакой записи? Если да, то есть ли у вас какие-либо идеи о том, что я сделал неправильно и как я могу изменить код, чтобы получить свои данные?

ally 31.03.2023 20:36
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
62
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 не возвращает никаких результатов, вам нужно проверить свои данные, чтобы убедиться, что в них действительно есть совпадающие записи.

Другие вопросы по теме