Hallo zusamm,
ich brauche eure Hilfe da ich nicht so recht weiterkomme.
Was möchte ich machen:
Ich möchte gerne eine Stückliste in Tabellenform aus einem Datensatz welcher in Zeilenform vorliegt umwandeln.
Beispiel:
Ausgangslage: Ich habe eine Tabelle in der meine Datensätze mit den einzelnen Bauteilen stehen:
tblStueliBauteile
stueliID zbSachnmmer Bauteil_1 Bauteil_2 Bauteil_3 Bauteil_n
1 7 654 321 Teil 1 Teil 2 Teil 3 Teil n
2 9 876 543 Teil 6 Teil 8 Teil n
3 7 654 321 Teil 1 Teil 9
Ziel:
Jetzt möchte ich die Datensätze gerne in einer Abfrage untereinander geschrieben haben. Die leeren Felder aus der Tabelle sollen ignoriert werden.
qryStueliBauteile_untereinander
stueliID zbSachnmmer Bauteil
1 7 654 321 Teil_1
1 7 654 321 Teil_2
1 7 654 321 Teil_3
1 7 654 321 Teil_n
2 9 876 543 Teil_6
2 9 876 543 Teil_8
2 9 876 543 Teil_n
3 7 654 321 Teil_1
3 7 654 321 Teil_9
Wie kann ich das umsetzen? Geht das mit einer Kreuztabelle? Ich habe es leider nicht hinbekommen.
Vielen Dank schon mal im Voraus für eure Hilfe!
ZitatGeht das mit einer Kreuztabelle?
Eine Kreuztabellenabfrage könnte aus aus Deinem Ziel (Liste) eine Kreuztabelle (Pivottabelle) erzeugen, aber nicht umgedreht.
Da siehst Du schon mal aus dem Praktischen heraus, dass Deine Ausgangstabelle nicht datenbankkonform ist, von Normalisierung mal ganz zu schweigen.
Eine Umformung kannst Du per UNION-Abfrage vornehmen (für jede Bauteil-Spalte ein SELECT). Das kann sehr umfangreich werden, wenn es dann viele n-Spalten sind.
Am Ende würde man die Abfrage per VBA zusammensetzen.
Effektiver ist eine Umformung der Pivottabelle in eine Liste (mit anschließender Beseitigung der Pivottabelle).
Sub beisielaufruf_PivotToList()
Dim bRet As Boolean
bRet = PivotToList("Pivottabelle", "Listtabelle", 4, "Art", "Betrag", dbLong)
If bRet Then Debug.Print "Die Tabellenerstellung sollte geklappt haben."
End Sub
Public Function PivotToList(ByVal NamePivotTable As String, _
ByVal NameListTable As String, _
ByVal NumberFirstMatrixField As Byte, _
ByVal NameTitleField As String, _
ByVal NameValueField As String, _
ByVal TypeValuefield As DataTypeEnum, _
Optional ByVal UseNullValues As Boolean = False) As Boolean
On Error GoTo ErrHandler
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim sSQL As String
Dim sConstantFields As String
Dim i As Long
Set dbs = CurrentDb
If TableExistsDAO(dbs, NameListTable) Then dbs.TableDefs.Delete NameListTable
Set rst = dbs.OpenRecordset(NamePivotTable, dbOpenSnapshot)
With rst
' Listtabelle neu erstellen
Set tdf = dbs.CreateTableDef(NameListTable)
For i = 0 To NumberFirstMatrixField - 2
Set fld = tdf.CreateField(.Fields(i).Name, .Fields(i).Type)
tdf.Fields.Append fld
sConstantFields = sConstantFields & "[" & .Fields(i).Name & "], "
Next
Set fld = tdf.CreateField(NameTitleField, dbText)
tdf.Fields.Append fld
Set fld = tdf.CreateField(NameValueField, TypeValuefield)
tdf.Fields.Append fld
dbs.TableDefs.Append tdf
RefreshDatabaseWindow
' Inhalte übertragen
For i = NumberFirstMatrixField To .Fields.Count - 1
sSQL = "INSERT INTO " & NameListTable & " (" & sConstantFields & "[" & _
NameTitleField & "], [" & NameValueField & "])" & _
" SELECT " & sConstantFields & "'" & .Fields(i).Name & "', [" & _
.Fields(i).Name & "] FROM " & NamePivotTable
If Not UseNullValues Then
sSQL = sSQL & " WHERE [" & .Fields(i).Name & "] IS NOT NULL"
End If
dbs.Execute sSQL, dbFailOnError
Next
.Close
End With
' ' Beispiel für ein Setzen eines zusammengesetzten Index
' sSQL = "CREATE INDEX NameVorname ON Listtabelle([Name], Vorname)"
' dbs.Execute sSQL, dbFailOnError
Set rst = Nothing
Set dbs = Nothing
PivotToList = True
Exit_Function:
Exit Function
ErrHandler:
MsgBox "Fehler: " & vTab & Err.Number & vbCrLf & Err.Description
Resume Exit_Function
End Function
Public Function TableExistsDAO(pDb As DAO.Database, _
ByVal psName As String) As Boolean
Dim s As String
On Error Resume Next
s = pDb.TableDefs(psName).Name
TableExistsDAO = (Err.Number = 0)
End Function
Danke für die flotte und ausführliche Anwort :)
Dann werde ich mir das mal in Ruhe anschauen und ausprobieren. Ich bin zur Zeit eh gerade noch beim probieren und aufbauen der Stückliste.
Also werde ich es wie Du es gesagt hast angehen...das wird dann das sinnvollste sein. Ich gebe dann noch mal ne kurze Rückmeldung wenn alles steht.
Danke und Gruß
GWPapst
Einzelkomponenten einer Stückliste sollten nebenbei auch eine Mengenangabe sowie einen Verweis auf eine Einheiten-Tabelle aufweisen.
Hallo Lachtaube,
ja da hast Du recht!
Ich habe für jedes Bauteil eine separate Tabelle (tblBauteil_1, usw.) mit den Mengeneinheiten und weiteren Informationen (Länge, Gewicht, etc.) angelegt.
Dieses werden dann auf die tblStueliBauteile referenziert.
In die Stückliste sollen dann auch noch die Gewichte, Mengen und ein Bemerkungsfeld mi rein. Muss mal überöegen wie das evtl auch über eine extra Abfrage mit einbringe.
Ich werde wohl im ersten Ansatz versuchen die Stückliste über die vorgeschlagenen UNION-Abfrage zu erstellen. Könnte mir vorstellen das das ganz gut klappt.
Ich werde berichten sobald ich was brauchbares habe :)
Falls jemand noch alternative Vorschläge/Ideen hat, immer her damit.
Hallo,
ZitatIch habe für jedes Bauteil eine separate Tabelle (tblBauteil_1, usw.) mit den Mengeneinheiten und weiteren Informationen (Länge, Gewicht, etc.) angelegt.
falscher Ansatz, alle Bauteile müssen in eine Tabelle.
In
Zitatdie Stückliste sollen dann auch noch die Gewichte, Mengen und ein Bemerkungsfeld mi rein. Muss mal überöegen wie das evtl auch über eine extra Abfrage mit einbringe.
In die Stückliste kommt nur die Menge und ev. das Bemerkungsfeld. Das Gewicht ist ein Attribut des Bauteils und kommt in die Tabelle mit allen Bauteilen. Außerdem kann eine Abfrage nur berechnete Felder anlegen, alle Felder die Eingabedaten erfassen benötigen Tabellenfelder.
Danke Klaus für den Hinweis...werde ich beim Umsetzen berücksichtien!