PDA

Vollständige Version anzeigen : Tabelle aktualisieren


shs
02.05.2011, 08:48
Hallo zusammen,


suche eine Lösung für die folgende Aufgabe:

ich möchte die Adressdaten in einer Access Tabelle über eine externe Datei (.CSV Format) über die Funktion Datenimport , die in einem Formular über ein Butten aktiviert wird, aktualisieren.
Die Import Datei kann sowohl neue Liefernummer als auch Adressänderungen von bereits vorhandene Lieferanten in der Access Tabelle beinhalten.
Beim Einlesen der Datei sollen die Adressdaten von bereits vorhandene Lieferanten aktualisiert werden und neue Lieferanten angefügt werden.
Die Liefernummer ist eindeutig.

Die Tabelle hat die folgende Struktur:

Liefernummer
Name
Strasse
PLZ
Ort

Kann jemand mir weiterhelfen.

Vielen Dank.

Aram

Atrus2711
02.05.2011, 08:58
Hi und willkommen im Forum :hands:,

grundsätzlich ist das machbar. Der grobe Ablauf wirs etwa so sein:

Import oder Verknüpfung der Textdatei -> Lesbare Tabelle in Access
Auslesen der Änderungen oder (je nach Anliegen) Neu-Normalisierung der Daten mittels Anfügeabfragen (ggf. als Inkonsistenzabfragen: "welche Anbieter haben wir noch nicht")
Das ganze ist möglich z.B. bei ButtonClick durch Ausführen der Abfragen mittels Currentdb.Execute oder Varianten davon.


Das Schwierige wird eher sein, die Änderungen zu erkennen. Wenn ein Lieferant seine Adresse ändert, was bleibt dann noch, um ihn wiederzuerkennen? Wenn ein Lieferant seine Firma ändert, was bleibt dann noch, um ihn wiederzuerkennen? Und wenn beides auf einmal wechselt?

Im übrigen siehe auch hier: http://ms-office-forum.de/forum/showthread.php?t=277554

shs
02.05.2011, 09:37
Hallo Martin,

Vielen Dank für die Antwort.
Deine Anmerkungen sind berechtigt, aber in diesem Fall gelten immer die aktuellen Adressdaten in der Tabelle. Die alten Daten sind nicht mehr interssant.
Ich würde gerne wissen. wie der Update Befehl in VBA-Code aussieht. Durch diesen Befehl sollen Name, Strasse, PLZ und Ort von dem bereits vorhandenen Lieferant in der Tabelle aktualisiert werden.

Danke.

Aram

Atrus2711
02.05.2011, 09:46
Hi,

Updates kannst du in VBA grundsätzlich folgendermaßen ausführen:

Dim db as dao.database
Set db = CurrentDb
With db
.execute "SQL oder Name der Änderungsabfrage", dbFailOnError
End With
Set db = Nothing

Die Änderungsabfrage kannst du also als ganz normale Abfrage vorbereiten und abspeichern.

Angenommen, die Tabellen heißen (demohalber) Daten und Importe, dann wäre die Abfrage etwa so möglich:
UPDATE Daten INNER JOIN Importe ON Daten.[Name] = Importe.[Name]
SET Daten.Strasse = Importe.Strasse, Daten.PLZ = Importe.PLZ, Daten.Ort = Importe.Ort
Diese Abfrage "findet" alte und neue Lieferanten aber ausschließlich anhand des Namens. Eine Meier GmbH kann es aber durchaus öfter geben. Und daher meine Mahnung zur Vorsicht: "alt und neu" anzugleichen, kann nach hinten losgehen, wenn man nicht sicher sein kann, dass der neue Wert wirklich der neue Wert von diesem alten ist. Wenn ein Meier umzieht, zieht nicht jeder Meier um. Diese Erkennung ist oft schwieriger als gedacht, aber ein leichtfertiges Update kann viele Daten verhunzen.

Es ist außerdem erforderlich, dass Daten und Importe "gleich schnell ticken". Ein Satz in Daten sollte also auch (maximal) einem Satz in Importe entsprechen. Wenn es mehrere Neuwerte zu einem Altwert gibt, ist nicht gut entscheidbar, welcher davon sich "durchsetzt".

ebs17
02.05.2011, 09:56
Die Liefernummer ist eindeutig.
Dann kann man wohl davon ausgehen, dass diese Liefernummer als Schlüssel zur Verknüpfung von zusammen gehörenden Datensätzen verwendet werden kann. Die Abfragen lauten dann etwa ...
' Aktualisierung bestehender Datensätze
UPDATE Zieltabelle Z INNER JOIN Quelltabelle Q
ON Z.Liefernummer = Q.Liefernummer
SET Z.Name = Q.Name, Z.Strasse = Q.Strasse,
Z.PLZ = Q.PLZ, Z.Ort = Q.Ort

' Anfügen nur neuer Datensätze
INSERT INTO Zieltabelle (Liefernummer, Name, Strasse, PLZ, Ort)
SELECT Q.Liefernummer, Q.Name, Q.Strasse, Q.PLZ, Q.Ort
FROM Quelltabelle Q
WHERE NOT EXISTS
(SELECT Null FROM Zieltabelle Z
WHERE Z.Liefernummer = Q.Liefernummer)

Atrus2711
02.05.2011, 10:00
Kommt drauf an, wo und wann sie vergeben wird. Wenn die Importdaten "jedesmal" andere Werte vergeben, sind sie auch eindeutig, finden sich aber in den alten Daten nicht wieder. Eindeutigkeit alleine genügt nicht.

shs
02.05.2011, 10:02
Hello,

vielen herzlichen Dank für eure Hilfe.
Ich werde das ausprobieren.

Aram.

ebs17
02.05.2011, 10:18
Bezogen auf Adressdaten von Lieferanten wäre sicher eine Lieferantennummer sinniger als eine Liefernummer, also eine Nummer, die den Lieferanten selber identifiziert und nicht eine seiner Leistungen.

shs
09.05.2011, 11:18
Hallo,

kannst Du mir den exakten Befehl für Insert der neuen Datensätze beschreiben. Dieser Code habe ich verschiedens probiert, funktioniert leider nicht. Ich bekomme immer Syntax Fehler.

Code:

'' Anfügen nur neuer Datensätze
INSERT INTO Zieltabelle (Liefernummer, Name, Strasse, PLZ, Ort)
SELECT Q.Liefernummer, Q.Name, Q.Strasse, Q.PLZ, Q.Ort
FROM Quelltabelle Q
WHERE NOT EXISTS
(SELECT Null FROM Zieltabelle Z
WHERE Z.Liefernummer = Q.Liefernummer)

Vielen Dank.
Aram

ebs17
09.05.2011, 11:27
Syntaxproblem? Das würde ich hier zuerst in der Verwendung des reservierten Wortes "Name" vermuten.

Ansonsten ist das eine Abfrage, einzutragen in die SQL-Ansicht (http://www.ardiman.de/datenbanken/grundlagen/abfragen.html#SEC2), und der Kommentar ist natürlich wegzulassen. Kommentare in Jet-SQL gibt es nicht.

shs
09.05.2011, 16:12
Hallo,

ich brauche eure Hilfe.
was ist in diesem Statement falsch:

DoCmd.RunSQL "INSERT INTO Ziel_Tab_GSC Z (Liefnr, Name, Strasse, PLZ, Ort )" & _
"SELECT Q.Liefnr, Q.Name, Q.Strasse, Q.PLZ, Q.Ort FROM Quell_Tab_GSC Q WHERE Not EXISTS" & _
"SELECT Null FROM Ziel_Tab_GSC Z WHERE Z.Liefnr= Q.Liefnr", _
dbFailOnError

Danke.

maikek
09.05.2011, 16:29
Hallo,
ersetze DoCmd.RunSQL durch CurrentDB.Execute. Dann wird dir dbFailOnError die meisten Fehler schon mitteilen ;) .
Mach' aus dem SQL-Statement eine String-Variable und lass' dir die per Debug.Print im Direktfenster ausgeben. Da sieht man (Syntax-)fehler sehr viel schneller.
maike

Thomas Möller
09.05.2011, 16:55
Hallo!

was ist in diesem Statement falsch:

in Deinem Statement fehlen auf jeden Fall ein paar Leerzeichen. Füg mal jeweils ein Leerzeichen am Ende der ersten und zweiten Zeile ein.

CU

ebs17
09.05.2011, 17:12
... und die Klammern um die Unterabfrage sollte man auch nicht einfach weglassen:
Dim sSQL = "INSERT INTO Ziel_Tab_GSC Z (Liefnr, Name, Strasse, PLZ, Ort)" & _
" SELECT Q.Liefnr, Q.Name, Q.Strasse, Q.PLZ, Q.Ort" & _
" FROM Quell_Tab_GSC Q WHERE Not EXISTS" & _
" (SELECT Null FROM Ziel_Tab_GSC Z WHERE Z.Liefnr= Q.Liefnr)"
' Kontrollausgabe
Debug.Print sSQL
CurrentDb.Execute sSQL, dbFailOnError
Wenn Du die Leerzeichen für die VBA-Zeilentrennung des SQL-Strings immer am Anfang der Zeile setzt, hast eine bessere Übersicht.

shs
10.05.2011, 07:43
Hallo,

leider klappt das nicht. Der Kompiller erwartet ein Anweisungsende.

Private Sub Befehl71_Click()

Dim sSQL = "INSERT INTO Ziel_Tab_GSC Z (Liefnr, Name, Strasse, PLZ, Ort)" & _
" SELECT Q.Liefnr, Q.Name, Q.Strasse, Q.PLZ, Q.Ort" & _
" FROM Quell_Tab_GSC Q WHERE Not EXISTS" & _
" (SELECT Null FROM Ziel_Tab_GSC Z WHERE Z.Liefnr = Q.Liefnr)"
' Kontrollausgabe
Debug.Print sSQL
CurrentDb.Execute sSQL, dbFailOnError

End Sub

Aram

Atrus2711
10.05.2011, 08:01
Hi,

trenne Dimensionierung und Wertvergabe:

Private Sub Befehl71_Click()

Dim sSQL AS String
sSQL = "INSERT INTO Ziel_Tab_GSC Z (Liefnr, Name, Strasse, PLZ, Ort)" & _
" SELECT Q.Liefnr, Q.Name, Q.Strasse, Q.PLZ, Q.Ort" & _
" FROM Quell_Tab_GSC Q WHERE Not EXISTS" & _
" (SELECT Null FROM Ziel_Tab_GSC Z WHERE Z.Liefnr = Q.Liefnr)"
' Kontrollausgabe
Debug.Print sSQL
CurrentDb.Execute sSQL, dbFailOnError

End Sub

ebs17
10.05.2011, 10:32
Dim sSQL = "INSERT INTO Ziel_Tab_GSC Z (Liefnr, ..."
Hab ich das so geschrieben? Sorry, da war das Schreiben (von Zeilen) deutlich langsamer als der Gedanke.

Das Z als Alias in dieser Zeile ist allerdings Deine Idee. Das ist überflüssig und evtl. sogar störend.

shs
10.05.2011, 12:18
Hallo zusammen,

Vielen Dank für Eure Hilfe.
Das hat wunderbar funktioniert.

Aram.