Hallo zusammen,
ich habe eine Abfrage, die folgende vereinfachte Struktur besitzt:
Bezeichnung Art Größe Baujahr Alter Wert ...
Gebäude1 Whs 650 1965 58 1300
Gebäude2 BG 1520 1970 53 850
Gebäude3 GA 30 1965 58 450
Nun möchte ich eine Abfrage regenerieren, die folgendes Ergebnis besitzt:
Gebäude1 Gebäude2 Gebäude3
Art Whs BG GA
Größe 650 1520 30
Baujahr 1965 1970 1965
Alter 58 53 58
Wert 1300 850 450
...
Da diese Abfrage dann in ein Worddokument eingefügt werden soll,
soll diese direkt nach Word exportiert werden.
Ich habe gelesen, dass das mit einer Kreuztabellenabfrage funktionieren soll.
Aber ich bin an diesem Assistenten bisher immer gescheitert.
Weiß jemand wie das geht, so dass der Export nach Word auch funktioniert?
Das ist keine Abfrageaufgabe. Solches Transponieren kann man mit VBA vollziehen. Oder Du bringst die Tabelle nach Excel, weil es dort bereits einige Hausmethoden zu Transpose gibt.
Zitatich habe eine Abfrage
Persönlich verlasse ich mich nicht gern auf Abfragen anderer, insbesondere auf Abfragen von Ungeübten. Da würde ich mich lieber auf die Tabellen direkt und das bekannte Datenmodell beziehen.
Hallo Eberhard,
hast Du vielleicht ein VBA-Beispiel zur Hand?
Gruß
Max
Dutzende.
Trage in die Suchleiste einer Maschine eigener Wahl "ms access excel tabelle transponieren" ein.
Hallo Max,
es gibt das Statement CreateTable. Lese deine Eingabetabelle Zeile für Zeile und bau den SQL-String mit den Inhalten der Spalte Bezeichnung als Spaltennamen zusammen. Bedenke aber, dass Access nur 255 Spalten kann. Im zweiten Schritt erzeugst Du in der neuen Tabelle pro Feldnamen deiner Ausgangstabelle einen Datensatz. Im dritten Schritt sind dann die passenden Werte an der passenden Stelle einzutragen.
Der Rest ist VBA üben ;-)
@ Eberhard
Wenn es geht, würde ich gerne auf Excel verzichten. Mir reicht schon das hoprige Zusammenspiel zwischen Access und Word.
@ andyfau
Da ich weder SQL- noch VBA-Experte bin, kann ich mit Deiner Beschreibung leider nicht viel anfangen. Kannst Du mir das bitte etwas detailierter schildern?
Gruß
Max
Hallo Max,
ich hab da mal was zum üben zusammengeklöppelt:
(geht sicher auch noch eleganter, funzt aber)
Sub AufrufTabConvert()
TabConvert "Gebaeude", "Gebaeudetransform"
End Sub
Public Sub TabConvert(InTab As String, AusTab As String)
' Tabelle transformieren (Zeilen/Spalten tauschen)
' Ausgabetabelle hat nur Stringfelder, weil Access nur Datensaetze kennt und keine Spalten, in denen verschieden Datentypen stehen koennen.
' Die Eingabetabelle darf nur max. 255 Saetze haben, weil eine Accesstabelle nur 255 Felder pro Datensatz (Excelleute würden Spalten sagen) haben kann.
' Enthalten Feldname der Eingabetabelle Leerzeichen oder Sonderzeichen, so sind beim Aufbau des CREATE-SQL-Strings diese in Hochkomma (') zu setzen.
' Keine Feldnamen verwenden, die SQL-Befehlen entsprechen. Zum Beispiel ALTER auf AlterJahre ändern.
' Feldname "Bezeichnung" wurde als Feldname für "Spalte 1" beibehalten.
Dim db As Database
Dim rs As Recordset
Dim rst As Recordset
Dim sqlstr As String
Dim x As Integer
Dim t2s As Integer 'spalte Tab2
Dim t1z As Integer 'zeile Tab1
Dim t2z As Integer 'zeile Tab2
Dim t1s As Integer 'spalte Tab1
If DCount("Bezeichnung", InTab) > 255 Then
MsgBox "Es können aufgrund der Spaltenbegrenzung von Access nur max. 255 Sätze verarbeitet werden!", vbCritical, "Fehler"
Exit Sub
End If
If fctTabExists(AusTab) = True Then 'falls vorhanden Austab löschen
DoCmd.DeleteObject acTable, AusTab
End If
Set db = CurrentDb
Set rs = db.OpenRecordset(InTab, dbOpenDynaset)
sqlstr = "CREATE TABLE " & AusTab & " (Bezeichnung CHAR"
rs.MoveFirst
Do Until rs.EOF
sqlstr = sqlstr & ", " & rs!Bezeichnung & " CHAR"
rs.MoveNext
Loop
sqlstr = sqlstr & ");"
db.Execute sqlstr
Set rst = db.OpenRecordset(AusTab, dbOpenDynaset)
For x = 1 To db.TableDefs(InTab).Fields.Count - 1
rst.AddNew
rst!Bezeichnung = db.TableDefs(InTab).Fields(x).Name
rst.Update
Next
t2s = 1 'spalte Tab2
t1z = 1 'zeile Tab1
t2z = 1 'zeile Tab2
t1s = 1 'spalte Tab1
rs.MoveFirst
Do Until rs.EOF
rst.MoveFirst
Do Until rst.EOF
rst.Edit
rst.Fields(t2s) = rs.Fields(t1s)
rst.Update
rst.MoveNext
t1s = t1s + 1
Loop
rs.MoveNext
t2s = t2s + 1
t1s = 1
Loop
Set db = Nothing
Set rs = Nothing
Set rst = Nothing
End Sub
Public Function fctTabExists(strTabName As String) As Boolean
fctTabExists = IsNull(DLookup("[Name]", "MSysObjects", "[Name] = '" & strTabName & "' AND (Type = 1 Or Type = 6)")) = False
End Function
Hallo andyfau,
habe Deinen Code gerade mal ausprobiert. Er funktioniert. Echt irre!
Das hätte ich nicht ansatzweise hinbekommen.
Ich müsste nur noch irgendwie die Einheiten der Zahlen (Jahre, €, €/m², etc.) unterbringen.
In den Feldnamen der Ausgangstabelle werden bei mir Leerzeichen und Sonderzeichen akzeptiert.
Etwas nervig sind die hunderte Leerzeichen hinter den Werten.
Ich gehe mal davon aus, dass das Ganze nicht mit einer Abfrage funktioniert, oder?
Aber erst einmal vielen Dank für Deine Mühe!!
Gruß
Max
Hi,
ersetze im Code "CHAR" durch "VARCHAR". Dann gibt es keine Folgeleerstellen mehr.
Nach der Zeile :
rst!Bezeichnung = db.TableDefs(InTab).Fields(x).Name
vor
rst.Update
kannst Du die Bezeichnung ja um "Jahre," "€", "€/m²", etc. ergänzen. z. B. mit einer Select Anweisung:
select case rst!Bezeichnung
case "Wert"
rst!Bezeichnung = rst!Bezeichnung & "€"
case "AlterJahre"
rst!Bezeichnung = rst!Bezeichnung & "Jahre"
end select
Beste Grüße
Andreas