Data Watch - Einsatz am Limit

Union-Statement automatisch erzeugen

Im Gegensatz zur Möglichkeit der manuellen Union-Abfrage (Listing 4) wird hier der SQL-Text per VBA erzeugt. Diese Konstruktion ist durchaus mit Vorsicht zu genießen, denn das SQL-Statement kann sehr lang werden. Je Datensatz im Ergebnis, also je Abfrage zur Analyse, wird ein Befehl wie folgt nötig sein:

SELECT "STOP" As QTyp, "Xyz" As QName, 99 As QAnzahl FROM [qrySTOPxyz] UNION …

Statt "Xyz" wird dort in Wirklichkeit ein Abfragename mit etwa 20 Zeichen stehen, das ergibt mit den übrigen 70 Zeichen jeweils einen knapp 90 Zeichen langen SQL-Befehl. Daher wird auch die Ermittlung des Namens ohne die ersten sieben Zeichen und die Anzahl der Datensätze bereits vorher per VBA vorgenommen und nur das (kürzere) Ergebnis eingetragen, was hier durch die Zahl 99 symbolisiert wird.

Da ein SQL-Befehl von Abfragen in Access auch über 32.000 Zeichen lang sein darf, können Sie mehr als 320 Analysen aneinander hängen, bevor es eng wird. Das sollte ausreichen.

Nicht in Tabelle zwischenspeichern

Die Alternative dazu wäre, die Namen und Ergebnisse in einer eigenen Tabelle zwischenzuspeichern. Das ist nicht nur wegen des umfangreichen Löschens und Neuschreibens langsamer, sondern erzwingt deswegen auch regelmäßiges Komprimieren der Datenbank.

Der Code ändert sich nun also wie in Listing 7, um die Union-Abfrage zu erzeugen. Das letzte UNION dabei ist übrig und wird durch ein Semikolon ersetzt, durch welches jeder SQL-Befehl abgeschlossen werden sollte.

Sub GrenzwerteMitUNION()
Dim qryJede As QueryDef
Dim strSQL As String
Dim lngAnzahl As Long
For Each qryJede In CurrentDb.QueryDefs
Select Case LCase(Left(qryJede.Name, 7))
Case "qryinfo", "qrymldg", "qrystop"
lngAnzahl = DCount("*", qryJede.Name)
If lngAnzahl > 0 Then
strSQL = strSQL & _
"SELECT """ & Mid(qryJede.Name, 4, 4) & _
""" As QTyp, """ & Mid(qryJede.Name, 8) & _
""" As QName, " & lngAnzahl & " As QAnzahl " & _
"FROM [" & qryJede.Name & "] UNION" & vbCrLf
End If
End Select
Next
Set qryJede = CurrentDb.QueryDefs("qryUNION")
qryJede.SQL = Left(strSQL, Len(strSQL) - Len("UNION" & vbCrLf))
End Sub

Der Code setzt übrigens voraus, dass bereits eine Abfrage qryUNION existiert. Da deren Inhalt ohnehin überschrieben wird, können Sie sie vor dem ersten Aufruf einfach als umbenannte Kopie einer anderen Abfrage bereitstellen.

Bild 3: Tabellarisches Formular mit Abfrageergebnissen.
Bild 3: Tabellarisches Formular mit Abfrageergebnissen.
Bild 4: Abfragen mit Beschreibung.
Bild 4: Abfragen mit Beschreibung.

Dargestellt wird jetzt eine sortierte Übersicht der wichtigsten Analysen, die jeden Benutzer zufrieden stellen sollte (Bild 3).