2017-10-27 2 views
0

Allgemeine Erklärung:MS Access OpenRedcordset Lesen falsche Zeichenfolge

  1. meiner Anfrage 2_Total einen einzelnen Wert zurückgibt:

    Access Return

  2. Führen Sie die VBA-Funktion, die die Abfrage in eine Excel exportiert Datei:

    My Excel Output

Problem:OpenRecordset liest nicht die richtige Abfrage. Meine Abfrage sollte in meine Excel-Datei exportiert werden. Doch mein VBA zeigt auf falsches Zeug.

Meine Vermutung ist, dass die Zeile qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]" nicht genügend Informationen liefert?

SQL

SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold 
FROM dbo_SO_SalesHistory 
WHERE (((dbo_SO_SalesHistory.InvoiceDate) 
BETWEEN [Forms]![RUN]![textBeginOrderDate] AND [Forms]![RUN]![textendorderdate])); 

VBA

Option Compare Database 

Option Explicit 
Public Function TRANS2() 

    Dim xlApp As Excel.Application 
    Dim xlWB As Excel.Workbook 
    Dim xlWS As Excel.Worksheet 
    Dim acRng As Variant 
    Dim xlRow As Integer 

    Dim db As DAO.Database 
    Dim qry As QueryDef 
    Dim rst As Recordset 
    Dim prm As DAO.Parameter 
    Dim strSQL As String 

    Set db = CurrentDb 
    Set xlApp = New Excel.Application 
    Set xlWB = xlApp.Workbooks.Open("C:\Users\J\Desktop\August 2017.xlsx") 
    Set xlWS = xlWB.Worksheets("Totals") 

    xlRow = (xlWS.Columns("K").End(xlDown).Row) 
    Set qry = db.QueryDefs("2_Total") 

    strSQL = strSQL & " [dbo_SO_SalesHistory].[InvoiceDate] Between #" _ 
    & [Forms]![Run]![textBeginOrderDate] & "# And #" _ 
    & [Forms]![Run]![textendorderdate] & "#" 

    qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]" 

    Set rst = db.OpenRecordset("2_Total", dbOpenDynaset) 

    Dim c As Integer 
    c = 11 'C is the one that stores column number, in which c=1 means column A, 11 is for column K, 12 for Column L 
    xlRow = xlRow + 11 

    Do Until rst.EOF 
     For Each acRng In rst.Fields 
      xlWS.Cells(xlRow, c).Formula = acRng 
      c = c + 1 
     Next acRng 
     xlRow = xlRow + 1 
     c = 1 
     rst.MoveNext 
     If xlRow > 25 Then GoTo rq_Exit 
    Loop 


rq_Exit: 
    rst.Close 
    Set rst = Nothing 
    Set xlWS = Nothing 
    xlWB.Close acSaveYes 
    Set xlWB = Nothing 
    xlApp.Quit 
    Set xlApp = Nothing 
    Exit Function 

End Function 
+2

Ihr Code ist extrem verwirrend: 1. Sie bereiten eine Abfrage in der Zeichenfolge 'strSQL' vor, die nirgends verwendet wird. 2. Sie definieren ein QueryDef 'qry', das nirgends verwendet wird. 3. Das einzige, was Sie in Ihrer Excel-Datei ausgeben, ist der Inhalt Ihres ersten Datensatzes, der das Ergebnis Ihrer 2_Total-Abfrage erfasst, die nur eine Zeile und Spalte zurückgibt, die also nichts mit der von Ihnen angezeigten Excel-Datei zu tun hat . All das ist ein Mysterium für mich. –

+0

@ThomasG No.3 ist das Problem/Problem, das ich jetzt habe. Meine 2_Total-Abfrage gibt einen einzelnen Wert zurück, den ich in meine Excel-Datei exportieren möchte. Aber es druckt irrelevante Zeichenfolge in der Excel-Datei. –

+0

@ThomasG Jeder Rat zu diesem Thema würde sehr geschätzt werden. Ich bin ein Neuling für VBA. Schätzen Sie, dass Sie auf einige Probleme in meinem Code hingewiesen haben –

Antwort

2

Betrachten Sie die Querydef vor OpenRecordset Freigabe als das Re-Cord-Aufruf, da Sie die zuletzt gespeicherte Instanz Abfrage und nicht die Änderungen an der SQL verwendet nie offiziell speichern:

qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]" 
Set qry = Nothing 

Set rst = db.OpenRecordset("2_Total", dbOpenDynaset) 

Or besser noch, öffnen Sie das Recordset direkt von querydef, mit QueryDef.OpenRecordset:

qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]" 

Set rst = qry.OpenRecordset(dbOpenDynaset) 

Aber als @ThomasG Kommentare, überprüfen Sie sorgfältig Ihren Code und integrieren Sie den obigen Vorschlag entsprechend. Diese SELECT-Anweisung scheint keine einreihige, einspaltige Ergebnismenge auszugeben. Ihre gepostete SQL gibt jedoch eine Zeile/ein Spaltenaggregat zurück. Ich vermute, dass Sie vorhatten:

Ich empfehle jedoch die Verwendung von Parametrisierung für sauberer, sicherer, wartbarer Code.

Und ja, oben VBA Zeichenfolge kann und sollte selbst als Access-Abfrageobjekt gespeichert werden. Es ist also nicht nötig, SQL jedes Mal neu zu schreiben.Binde einfach jedes Mal verschiedene dynamische Parameter!

+0

Vielen Dank so sehr. Ich kann dir nicht genug danken. Du bist fantastisch und unglaublich. Vielen Dank für Ihre Zeit und beraten. –

+0

Es tut mir so leid, aber kann ich Ihnen eine weitere Frage stellen? Ich bekomme Artikel nicht in diesem Sammlungsfehler in der Zeile gefunden, qry! BeginDate = [Formulare]! [Ausführen]! [TextBeginOrderDate]. Jeder diesbezügliche Rat wird sehr geschätzt! –

+0

Sind Sie sicher, Abfrage beginnt mit 'PARAMETERS [BeginDate] Datetime, [EndDate] Datetime; Versuchen Sie, "[...]" die Namen einzuklammern. Siehe Aktualisierung. – Parfait

1

ich viel haben, gelöscht, aber wenn "2_Totals" ist SQL-Code genau:

SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold 
FROM dbo_SO_SalesHistory 
WHERE (((dbo_SO_SalesHistory.InvoiceDate) 
BETWEEN [Forms]![RUN]![textBeginOrderDate] AND [Forms]![RUN]![textendorderdate])); 

Dann wird die folgender Code wird das nachschlagen Wert und platzieren Sie es in der Zelle, auf die in Excel verwiesen wird. Es gab eine Schleife, die anscheinend keinen Sinn ergab, da die Abfrage einen einzelnen Wert zurückgibt, also entfernte ich sie. Ich verstehe nicht, warum Sie die letzte Zeile finden, aber fügen Sie dann 11 Zeilen hinzu, aber wenn es die falsche Zelle ändert, kommentieren Sie die Zeile xlRow = xlRow + 11.

Option Explicit 
Public Function TRANS2() 

    Dim xlApp As Excel.Application 
    Dim xlWB As Excel.Workbook 
    Dim xlWS As Excel.Worksheet 
    Dim xlRow As Integer 
    Dim dblOutput As Double 
    Dim db As DAO.Database 

    Set db = CurrentDb 
    Set xlApp = New Excel.Application 
    Set xlWB = xlApp.Workbooks.Open("C:\Users\J\Desktop\August 2017.xlsx") 
    Set xlWS = xlWB.Worksheets("Totals") 

    xlRow = (xlWS.Columns("K").End(xlDown).Row) 

    dblOutput = DLookup("[SumOfDollarsSold]", "2_Totals") 

    xlRow = xlRow + 11 

    xlWS.Cells(xlRow, 11).Value = dblOutput 

rq_Exit: 
    Set xlWS = Nothing 
    xlWB.Close acSaveYes 
    Set xlWB = Nothing 
    xlApp.Quit 
    Set xlApp = Nothing 
    Set db = Nothing 
End Function 
+0

Konnte DSum() für die ursprünglichen Rohdaten und den Datumsfilter in DSum() verwenden. – June7

+0

@ Juni7 wahr, es scheint jedoch, dass das Kriterium bereits in die gespeicherte Abfrage integriert ist, so schien es einfacher, nur die Abfrage zu verwenden. – MoondogsMaDawg

+1

Auch stimmt. Tho, ich benutze nie dynamisch parametrisierte Abfragen. DSum() kann 1 weniger Abfrageobjekt bedeuten. – June7