EDIT2: Ohne das Feld: "Sum(RabattBetrag) AS Rabatt" tritt der Fehler nicht auf.
EDIT: habe einen SQL-String mit fast 1400 Zeichen erfolgreich ausgeführt, kann also nicht an der Länge liegen.
Guten Tag
Heute ist echt der Wurm drin, oder ich stosse gegen eine mir nicht bekannt Grenze von Access:
Ich habe eine Verschachtelte SQL-Abfrage("sqlRabattpreise") als String gespeichert. (ca 924 Zeichen, mehrere Unterabfragen und auch UNION-Klauseln)
Diese Abfrage funktioniert so und kann ausgeführt werden.
Versuche ich nun eine weitere Aggregation draufzupacken, stürzt mein Access ab, sobald die Abfrage ausgeführt werden soll. Die Gesamtlänge von sqlRabatt ist nun 1033 Zeichen:
sqlRabatt = "SELECT PositionID, Sum(RabattBetrag) AS Rabatt " & _
"FROM (" & sqlRabattpreise & ") AS Rabattpreise " & _
"GROUP BY PositionID"
CurrentDb.QueryDefs("qryRabatt").sql = sqlRabatt
Interessant: Die Länge von sqlRabattpreise ist variabel. Bei kürzeren Varianten funktioniert der Code. Auch funktioniert es wenn ich sqlRabattpreise in einer Abfrage speichere und dann basierend auf dieser Abfrage die Aggregation mache.
https://www.ms-office-forum.net/forum/showthread.php?t=129167#:~:text=Der%20SQL%20String%20wird%20dabei,3500%20Zeichen%20lang%20und%20l%C3%A4nger. (https://www.ms-office-forum.net/forum/showthread.php?t=129167#:~:text=Der%20SQL%20String%20wird%20dabei,3500%20Zeichen%20lang%20und%20l%C3%A4nger.)
Laut der Aussage unter diesem Link beträgt die maximale Zeichenzahl eines SQL-Strings 64'000 Zeichen.
Die maximale Länge in einer Zelle im Abfragentwurf-Bereich beträgt 1024 Zeichen.
Ich benutze die Zellen im Abfrageentwurf-Bereich nicht, trotzdem beschleicht mich das Gefühl, dass es irgendetwas mit der Anzahl der Zeichen zu tun hat.
Wenn ich nach dem Absturz die Access neu öffne, dann finde ich, dass Access eine neue Abfrage mit einem kryptischen Namen erstellt hat, welche allerdings leer ist:
qryRabatt_7AD614424B4A44C2B77A66E3E1B7D67F
Weiss jemand, was die Ursache dieses Problems ist und wie man es beheben kann?
Vielen Dank und freundliche Grüsse
Mino
UNION und Gruppieren/Aggregieren zusammen wäre für mich ein Ausnahmezustand, unabhängig davon, ob es manchmal irgendwie funktioniert. GUT funktionieren kann das nicht.
Beheben?
=> Datenmodellierung überprüfen. UNION ist im Großteil der Fälle eine Folge von unzureichender Strukturplanung.
=> Abfrage anders formulieren. Für eine Rabattsumme pro Position eine Abfrage der Länge von über 1.000 Zeichen in den Ring zu werfen - mit dem 40-Tonner fährt man auch, um seine zwei Frühstücksbrötchen aus der Innenstadt zu holen ...?
Sowie:
Zitatstürzt mein Access ab, sobald die Abfrage ausgeführt werden soll
Wie äußert sich das genau? Gelber Rauch, lila Sternchen, Selbstauflösung der Festplatte?
Oder einfach gefühlte Untätigkeit, weil man dem Rechner eine Rechentätigkeit übergeben hat, an der er eine Weile zu tun hat?
Guten Tag
Erstmal danke für die Hinweise.
Der Absturz geht wie folgt von statten:
- Access versucht zu rechnen (Sanduhrsymbol) für ca. 2 Sekunde
- Access schliesst sich selber komplett.
- Access startet sich wieder und öffnet ein Fenster um ein Backup zu speichern
- Danach wird die Datei wieder geöffnet und die Abfrage mit dem komischen Namen wurde hinzugefügt
Der ganze Vorgang dauert nur etwa 10 Sekunden. Ein Fenster um den Fehler an Microsoft zu senden, wie ich es sonst von Windows kenne erscheint nicht.
Gibt es eigentlich irgendwo eine Log-Datei wo man mehr über die Fehlerursache herausfinden kann?
Freundliche Grüsse
Hallo,
-- Prüfe, ob in JEDEM Modulkopf Option Explicit steht.
-- Kompiliere, nachdem das korrigiert wurde, die DB nochmal (VBA-Editor/Debuggen/Kompilieren). Auftretende Fehler allesamt eliminieren.
-- Zeige die SQL-Strings aller beteiligter Abfragen und den vollständigen Code, der am Zusammenbau oder der Verwendung der SQL-Strings beteiligt ist.
-- Lade ansonsten die DB (soweit datenreduziert, als dass die Situation weiterhin auftaucht) gezippt hier hoch.
Hallo
Vielen Dank für die Hinweise.
Da es mit dem Zwischenspeichern von SQL-Strings in Abfragen läuft, ist das Problem nicht dringlich. Ich werde mich zu einem späteren Zeitpunkt wieder dem Problem annehmen und gegebenenfalls die DB hochladen.
Habe den gesamten Code mit SQL-Strings, Kommentaren und dem auskommentierten Block der für den Absturz verantwortlich ist angefügt.
Ich werde das Thema trotzdem als gelöst bezeichnen, da ich nicht unnötig eure Zeit in Anspruch nehmen möchte.
Vielen Dank.
'SQL-Abfrage für Aufstellung Rechnung
Private Function Aufstellung()
Dim sqlNetto As String
Dim sqlNettopreis As String
Dim sqlRabatt As String
Dim sqlRabattKondition As String
Dim sqlRabattpreise As String
Dim sqlAufstellung As String
Dim sqlTotal As String
'BruttoNetto prüfen # getestet:gut
If Me.BruttoNetto Then
sqlNettopreis = "Einzelpreis/(1+[MWST-Satz])"
Else
sqlNettopreis = "Einzelpreis"
End If
'Nettopreise berechnen # getestet: gut
sqlNetto = "SELECT PositionID, Bezeichnung AS Objekt, Menge, " & sqlNettopreis & " AS Nettopreis, Nettopreis*Menge AS NettoBetrag, [MWST-Satz] " & _
"FROM tblObjekt INNER JOIN (tblMenge INNER JOIN (tblPosition INNER JOIN tblPreis ON tblPosition.PositionID = tblPreis.Position_F)" & _
" ON tblMenge.Position_F = tblPosition.PositionID) ON tblObjekt.ObjektID = tblMenge.Objekt_F " & _
"WHERE tblPosition.Liste_F = " & Me.subStueckliste.Form!ListeID
CurrentDb.QueryDefs("qryNetto").sql = sqlNetto
'Rabatt-Konditionen Abfrage erstellen # getestet: gut
sqlRabattKondition = "SELECT Position_F, Kondition, EinschraenkungPosition, Frist, Ermaessigung " & _
"FROM tblKondition INNER JOIN tblPosition ON tblPosition.PositionID = tblKondition.Position_F " & _
"WHERE Liste_F = " & Me.subZahlungskonditionen.Form!ListeID & " AND Typ = ""Rabatt"";"
CurrentDb.QueryDefs("qryRabattKondition").sql = sqlRabattKondition
'Rabatt-Konditionen auslesen und SQL-String erzeugen # getestet: gut
Dim dbsCurrentDB As DAO.Database
Set dbsCurrentDB = CurrentDb()
Dim rstKondition As DAO.Recordset
Set rstKondition = dbsCurrentDB.OpenRecordset(sqlRabattKondition, dbOpenSnapshot, dbReadOnly)
'Prüfen ob Abfrage Datensätze enthält
If rstKondition.BOF = False Then
sqlRabattpreise = "SELECT PositionID, RabattBetrag FROM ("
Do Until rstKondition.EOF
sqlRabattpreise = sqlRabattpreise & "SELECT PositionID, NettoBetrag*" & rstKondition!Ermaessigung & " AS RabattBetrag " & _
"FROM (" & sqlNetto & ") AS Netto"
If Not IsNull(rstKondition!EinschraenkungPosition) Then
sqlRabattpreise = sqlRabattpreise & " WHERE PositionID " & rstKondition!EinschraenkungPosition
End If
sqlRabattpreise = sqlRabattpreise & " UNION ALL "
rstKondition.MoveNext
Loop
'Letzte 10 Zeichen aus String entfernen, Alias vergeben und Klammer setzen
sqlRabattpreise = Left(sqlRabattpreise, Len(sqlRabattpreise) - 10) & ") AS Nettopreise"
Else
sqlRabattpreise = "SELECT PositionID, 0 AS RabattBetrag " & _
"FROM (" & sqlNetto & ")"
End If
'DAO-Objekte schliessen
rstKondition.Close
dbsCurrentDB.Close
Set dbsCurrentDB = Nothing
Set rstKondition = Nothing
CurrentDb.QueryDefs("qryRabattpreise").sql = sqlRabattpreise
'Auskommentiert aufgrund Absturz
'' Rabatte Gruppieren # getestet: gut, Test UNION-Abfrage hängig
' sqlRabatt = "SELECT PositionID, Sum(RabattBetrag) AS Rabatt " & _
' "FROM (" & sqlRabattpreise & ") AS Rabattpreise " & _
' "GROUP BY PositionID"
' CurrentDb.QueryDefs("qryRabatt").sql = sqlRabatt
sqlRabatt = "SELECT PositionID, Sum(RabattBetrag) AS Rabatt " & _
"FROM qryRabattpreise AS Rabattpreise " & _
"GROUP BY PositionID"
CurrentDb.QueryDefs("qryRabatt").sql = sqlRabatt
'Skonto auslesen # getestet: gut
Dim Skonto As Variant
Skonto = CDec(DLookup("[Ermaessigung]", "tblKondition", "[Position_F]=" & Me.cboSkonto_F))
'Tabellen Netto und Rabatt zusammenfügen # getestet: gut
sqlAufstellung = "SELECT Netto.PositionID, Objekt, Menge, Nettopreis, [MWST-Satz], NettoBetrag, Rabatt AS RabattBetrag, Nettobetrag*" & Skonto & " AS SkontoBetrag, " & _
"NettoBetrag-RabattBetrag-SkontoBetrag AS NettoNetto, [MWST-Satz]*NettoNetto AS MWSTBetrag, NettoNetto+MWSTBetrag AS BruttoBetrag " & _
"FROM (" & sqlRabatt & ") AS Rabatt INNER JOIN (" & sqlNetto & ") AS Netto ON Rabatt.PositionID = Netto.PositionID"
CurrentDb.QueryDefs("qryAufstellung").sql = sqlAufstellung
'Aggregationen bilden # getestet: gut
sqlTotal = "SELECT Sum(NettoBetrag) AS NettoSumme, Sum(RabattBetrag) AS RabattSumme, Sum(SkontoBetrag) AS SkontoSumme, Sum(NettoNetto) AS NettoNettoSumme, " & _
"Sum(MWSTBetrag) AS Summe_MWST, Sum(BruttoBetrag) AS SummteTotal " & _
"FROM (" & sqlAufstellung & ") AS Aufstellung;"
CurrentDb.QueryDefs("qryTotal").sql = sqlTotal
'Aufstellung aktualisieren
Me!subAufstellung.Form.RecordSource = sqlTotal
Me.subAufstellung.Form.Requery
End Function
Hallo,
naja,
Du könntest ja noch den Inhalt von "sqlRabatt" mit Debug.Print in das Direktfenster schreiben und hier mit C&P posten...