Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

bestimmte Zeilen miteinander kombinieren

Begonnen von dave_christopher, Januar 17, 2011, 14:55:14

⏪ vorheriges - nächstes ⏩

dave_christopher

Hallo,

ich habe folgende Problematik:
1 Tabelle in der einigie Zeilen bestimmte identische Werte aufweisen. Bei solchen Treffern sollen die entsprechenden beiden Zeilen miteinander verschmolzen werden.

Praktisch so:

Vorher:
JAHR;NR;BESCH;NR2;NR3;BETRAG1;BETRAG2
2010;1779003;TEST1;4722;0;0;-7.500,00
2010;1779003;TEST1;4722;0;-7.480,00;0

Nacher:
JAHR;NR;BESCH;NR2;NR3;BETRAG1;BETRAG2
2010;1779003;TEST1;4722;0;-7.480,00;-7.500,00

Wie bekomme ich so etwas am besten hin?

Ich bin für jede Hilfe dankbar!

Viele Grüße
Dave

database

Hallo,

ALLES folgende in der Annahme, dass es sich um 2 Duplikate handelt und nicht mehrere Einträge!

Das ALLERERSTE - erstelle eine Kopie deiner DB und arbeite erst mal nur mit dieser Kopie!

Dann erstellst du eine Abfrage, welche dir nach dem Feld 'Nr' sortiert alle Duplikate in deiner Tabelle liefert. (In der Annahme,
dass dieses Feld für die Feststellung von Duplikaten geeignet ist)


Folgende SQL KÖNNTEST du zu diesem Zweck in die SQL-Ansicht des Abfrageentwurfs KOPIEREN:


SELECT Nr, Jahr, BESCH, NR2, NR3, BETRAG1, BETRAG2
FROM DeineTabelle
WHERE (((Nr) In (SELECT [Nr] FROM [DeineTabelle] As Tmp GROUP BY [Nr] HAVING Count(*)>1 )))
ORDER BY Nr;

Speicher die Abfrage und benenne sie 'duplikate'

Dann erstellt  du ein Modul in deiner DB und fügst den folgenden Code ein:


Sub bereinigen()

Dim rst As DAO.Recordset
Dim nummer As String, betrag As Double

Set rst = CurrentDb.OpenRecordset("SELECT * FROM duplikate")
rst.MoveFirst

Do While Not rst.EOF
    If rst!BETRAG1 <> 0 Then
        nummer = rst!Nr
        betrag = rst!BETRAG1
        'Übertragen des Betrags in das richtige Feld
        DoCmd.RunSQL "UPDATE DeineTabelle SET BETRAG1=" & betrag & " WHERE Nr='" & nummer & "' AND BETRAG2 <> 0"
        'Löschen des Duplikats
        DoCmd.RunSQL "DELETE FROM DeineTabelle WHERE Nr='" & nummer & "' AND BETRAG1= 0"
    End If
    rst.MoveNext
Loop

Set rst = Nothing
 
End Sub


Stelle den Cursor in die VBA Prozedur 'Sub bereinigen' und drücke F5 um die Sub abzuarbeiten (F8 um die Sub schrittweise abzuarbeiten)

Es werden nun die Datensätze durchsucht und die Beträge in eine Zeile geschrieben - das Duplikat welches dann im Feld BETRAG2 0,00 stehen hat wird gelöscht.

Wenn das Ergebnis dem entspricht, was du erwartet hast, kannst du die Schritte in deiner Original-DB nachvollziehen.

HTH



dave_christopher

Super! Danke dir für deine Mühe. Ja es handelt sich genau immer um jeweils 2 Dupliakte!

Leider scheint die Abfrage aber nicht ganz korrekt zu sein:
SELECT Nr, Jahr, BESCH, NR2, NR3, BETRAG1, BETRAG2
FROM DeineTabelle
WHERE (((Nr) In (SELECT [Nr] FROM [DeineTabelle] As Tmp GROUP BY [Nr] HAVING Count(*)>1 )))
ORDER BY Nr;


Der Duplikatcheck, müsste noch über das Feld BESCH und NR2 gehen damit das wirklich korrekt für die ganze Tabelle funktioniet.

Also Bedingung für ein Duplikat für das Beispiel ist:
JAHR;NR;BESCH;NR2;NR3;BETRAG1;BETRAG2
2010;1779003;TEST1;4722;0;0;-7.500,00
2010;1779003;TEST1;4722;0;-7.480,00;0

Bedingung: NR(Zeile1)=NR(Zeile2),BESCH(Zeile1)=BESCH(Zeile2),NR2(Zeile1)=NR2(Zeile2)

oma

nichts ist fertig!

database

#4
Hoppala, das solltest du dringend unterlassen!
Mit dem Abfrageassistenten kannst du komfortabel eine entsprechende Duplikatsuche kreieren und statt der von mir vorgeschlagenen einbauen.

EDIT:
Die obige Antwort ist am Handy im Zug entstanden, daher jetzt die Ergänzung:

ZitatBedingung: NR(Zeile1)=NR(Zeile2),BESCH(Zeile1)=BESCH(Zeile2),NR2(Zeile1)=NR2(Zeile2)

...sollte eigentlich mit folgender SQL abgedeckt werden können


SELECT DeineTabelle.[NR], DeineTabelle.[BESCH], DeineTabelle.[NR2], DeineTabelle.[Jahr], DeineTabelle.[NR3], DeineTabelle.[BETRAG1], DeineTabelle.[BETRAG2]
FROM DeineTabelle
WHERE (((DeineTabelle.[NR]) In (SELECT [NR] FROM [DeineTabelle] As Tmp GROUP BY [NR],[BESCH],[NR2] HAVING Count(*)>1  And [BESCH] = [DeineTabelle].[BESCH] And [NR2] = [DeineTabelle].[NR2])))
ORDER BY DeineTabelle.[NR], DeineTabelle.[BESCH], DeineTabelle.[NR2];


Führ mal diese Abfrage auf deine Tabelle aus und wenn das so passt schmeißt du die alte Abfrage in den Mist und nimmst diese hier - umbenennen auf 'duplikate' nicht vergessen!

HTH

dave_christopher

Hallo,

leider habe ich noch ein Problem mit dem folgenden VBA-Code:

Sub bereinigen()

Dim rst As DAO.Recordset
Dim nummer As String, betrag As Double

Set rst = CurrentDb.OpenRecordset("SELECT * FROM duplikate")
rst.MoveFirst

Do While Not rst.EOF
    If rst!BETRAG1 <> 0 Then
        nummer = rst!Nr
        betrag = rst!BETRAG1
        'Übertragen des Betrags in das richtige Feld
        DoCmd.RunSQL "UPDATE DeineTabelle SET BETRAG1=" & betrag & " WHERE Nr='" & nummer & "' AND BETRAG2 <> 0"
        'Löschen des Duplikats
        DoCmd.RunSQL "DELETE FROM DeineTabelle WHERE Nr='" & nummer & "' AND BETRAG1= 0"
    End If
    rst.MoveNext
Loop

Set rst = Nothing
 
End Sub


In der Zeile DoCmd.RunSQL "UPDATE DeineTabelle SET BETRAG1=" & betrag & " WHERE Nr='" & nummer & "' AND BETRAG2 <> 0" erscheint der Fehler: Laufzeit 3464 Datentypen in Kriterienausdruck unverträglich.

Hast du da noch eine Idee?

Aber schonmal soweit vielen lieben Dank für deine Mühe!!! Du hast mir hier schon sehr weitergeholfen. :)

@oma Sry, sollte damit meine Chancen erhöhen. Kommt nicht wieder vor!

Viele Grüße
Dave

oma

Hallo dave,

DoCmd.RunSQL "UPDATE DeineTabelle SET BETRAG1=" & betrag & " WHERE Nr='" & nummer & "' AND BETRAG2 <> 0"

müsste so sein:

DoCmd.RunSQL "UPDATE DeineTabelle SET BETRAG1=" & betrag & " WHERE Nr='"  & nummer & " ' " & " AND BETRAG2 <> 0"

Gruß Oma
nichts ist fertig!

dave_christopher

Hallo oma,

leider immer noch selber Fehler.

Dave

oma

Hallo.

Deine Tabelle heißt wirklich "DeineTabelle" wie im Code angegeben;  Betrag ist Double; nummer ist String - das ist ok.
was ist denn Betrag2 -  muss auch Zahl sein


Gruß Oma
nichts ist fertig!

DF6GL

Hallo,


DoCmd.RunSQL "UPDATE DeineTabelle SET BETRAG1=" & STR(betrag) & " WHERE Nr='" & nummer & "' AND BETRAG2 <> 0"

wenn BETRAG1 vom Datentyp Double ist und in "betrag" ein Wert mit Nachlommastellen vorkommt.

database

Hallo,

in Ermangelung der Kenntnis um die tatsächlichen Felddatentypen habe ich ein wenig phantansiert und für meinen Vorschlag 'nummer' als Text und BETRAG1 / BETRAG2 als Double mit 2 Kommastellen (Festkommazahl) deklariert, Jahr als Zahl und alle anderen Felder ebenfalls Text.

@oma
Die Codes in meinen Antworten sind getestet, Hochkommasetzung und anderer Firlefanz sind korrekt.

Möglicherweise ist 'nummer' im Original eine LongInteger und sträubt sich deswegen sich vergleichen zu lassen?

Ich habe leider im Moment keinen Zugriff auf mein Antwortbeispiel - ich häng das Viech morgen am Vormittag da rein.


oma

Hallo,

@Peter: ja eigentlich war mein Versuch Firlefanz, es muss ja an die Datentypen liegen

Gruß Oma
nichts ist fertig!

database

Hallo,

@oma
So wollte ich das nicht verstanden wissen  ;) ;D  Firlefanz bezog sich eigentlich auf den Rest ausserhalb der Abfrage ...   :D

Wie gestern angesprochen im Anhang das Beispiel-File mit Tabelle, der alten Abfrage, der neuen Abfrage mit den erweiterten Kriterien und das Modul mit der Sub zur Umsetzeung.

HTH

[Anhang gelöscht durch Administrator]