Neuigkeiten:

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

Mobiles Hauptmenü

Import aus PDF / Aufbau entsprechender Abfragen

Begonnen von Mr. Ahnungslos, Januar 28, 2014, 20:06:05

⏪ vorheriges - nächstes ⏩

Mr. Ahnungslos

Hallo Access-Gemeinde,

ich stehe vor einer Herausforderung bzgl. des Imports von Daten. Die zu verarbeitenden Daten befinden sich leider in einer PDF-Datei in Tabellenform. Ich habe bislang keine andere Möglichkeit gefunden, als über Paste-und-Copy die Daten in Excel zu kopieren und dann weiter zu bearbeiten (über die Funktionen rechts, links und Teil muss ich diverse Zellinhalte erst mal in die einzelnen Felder aufteilen.

Soweit so gut. Ich habe also nun eine Excel-Datei, die schon fast brauchbare Daten enthält. Die sind u.a. eine Kundennummer, der Kundenname sowie der Ertrag der Kundenverbindung (zum Zeitpunkt der PDF-Erstellung). In Access habe ich eine Tabelle für die Kunden und eine Tabelle für die Erträge (Ertrag/Währung; per/Datum; Kunde/Zahl – Fremdschlüssel zu Tabelle Kunden) erstellt.

Nun zu meinem Problem. Ich habe keinen Einfluss auf die Form der Ursprungs-PDF.  Zu jedem Abfragezeitpunkt wird mein komplettes Kundenportfolio entsprechend zusammengefasst und ausgewertet. Wie gehe ich am besten vor, wenn ich folgende Problemstellungen möglichst in einer Routine lösen möchte?

1.   Aktualisiere den Datenbestand an Kundenverbindungen, falls seit der letzten PDF-Erstellung weitere Kundenverbindungen hinzugekommen sind. (Anfügeabfrage? Duplikatsuche? Duplikate löschen – aber wie?)
2.   Übertrage die  jeweiligen Erträge aus der Excel-Datei in die Tabelle ,,Erträge", wobei ein Fremdschlüssel eingefügt werden soll, der die Verbindung zur entsprechenden Kundenverbindung herstellt.

Ich hoffe meine Fragestellung wurde klar und Ihr könnt mir weiterhelfen.

Besten Dank im Voraus

Michael

ebs17

#1
Ich würde nach Möglichkeit das ursprüngliche Dokument (PDF) verwenden und darauf einen automatisierten Import aufbauen:
1) Plaintext aus PDF extrahieren
Damit sollte der Inhalt des PDF in eine Textdatei überführt werden, nach Möglichkeit in eine Texttabelle, die dann per SQL auswertbar wäre.
Ansonsten müsste man etwas aufbereiten.
2) SQL ist leicht (4) - Aktualisierung einer Tabelle
Mittels der Texttabelle werden Zieltabellen aktualisiert.

Falls das bei Dir nicht gleichlautend funktioniert (wegen anderer Strukturen), müsstest Du etwas mehr zeigen.
Mit freundlichem Glück Auf!

Eberhard

Mr. Ahnungslos

Hallo Eberhard,

vielen Dank für Deine Antwort.

Zu 1) Eine .exe-Datei ins Firmennetzwerk zu laden funktioniert bei uns aus Sicherheitsgründen nicht, daher werde ich wohl bei Paste & Copy bleiben müssen

Zu 2) die Links sind Super, es ist genau das was ich suche, nur mit dem individuellen umformulieren des sql-Codes tue ich mich leider immer etwas schwer, vielleicht kannst Du mir hier nochmal behilflich sein?

Ich glaube der Code hier wäre das, was an meine Bedürfnisse angepasst werden müsste:


Sub Import()
   Dim db As DAO.Database
   Dim sSQL As String
   Set db = CurrentDb

   ' Externe Tabelle verlinken statt importieren: Gewährleistet den gleichen Zugriff
   ' auf die Daten und verhindert Datenmüll in der eigenen Datenbank (Gefahr des
   ' Aufblähens der Datenbank)
   ' Beispiel Exceltabelle
   'DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel8 _
         , "tblTemp", "x:\irgendwo\eine.xls", True

   ' Wenn man Daten auf mehrere Tabellen verteilen möchte, beginnt man mit den Tabellen,
   ' in denen ein Primärschlüssel erzeugt wird oder vorhanden ist, der dann später als
   ' Fremdschlüssel in einer weiteren Tabelle benötigt wird, also immer in der
   ' Reihenfolge 1-Tabelle vor n-Tabelle
   
   ' ### 1. Schritt ###
   ' Füllen der 1-(Master-)Tabelle mit den Werten, die neu sind
   
   sSQL = "INSERT INTO tblGruppen (Gruppe)" & _
         " SELECT DISTINCT Gruppe FROM tblTemp T WHERE NOT EXISTS" & _
         " (SELECT Null FROM tblGruppen G WHERE G.Gruppe = T.Gruppe)"
   db.Execute sSQL, dbFailOnError

   sSQL = "INSERT INTO tblBenutzer (Benutzer)" & _
         " SELECT DISTINCT Benutzer FROM tblTemp T WHERE NOT EXISTS" & _
         " (SELECT Null FROM tblBenutzer B WHERE B.Benutzer = T.Benutzer)"
   db.Execute sSQL, dbFailOnError

   ' ### 2. Schritt ###
   ' Füllen der n-(Detail-)Tabelle, dabei Ermitteln der Primärschlüssel der zugehörigen
   ' 1-Tabelle(n) und Eintragen als Fremdschlüssel. Hier gibt es nun viele
   ' Gestaltungsmöglichkeiten, abhängig davon, wie man die Zwischentabelle definiert.
   
'   ' 2a: Einfaches Anfügen der Kombinationen mit zusätzlichem Zeitstempel
'   sSQL = "INSERT INTO tblGruppen_Benutzer (fID_Gruppe, fID_Benutzer, Zeitstempel)" & _
'         " SELECT G.ID_Gruppe, B.ID_Benutzer, Now() AS Zeitstempel FROM tblGruppen G" & _
'         " INNER JOIN (tblBenutzer B INNER JOIN tblTemp T ON B.Benutzer = T.Benutzer)" & _
'         " ON G.Gruppe = T.Gruppe"
'   db.Execute sSQL, dbFailOnError
   
   ' 2b: Anfügen nur neuer Kombinationen mit zusätzlichem Zeitstempel
   sSQL = "INSERT INTO tblGruppen_Benutzer (fID_Gruppe, fID_Benutzer, Zeitstempel)" & _
         " SELECT Q.ID_Gruppe, Q.ID_Benutzer, Q.Zeitstempel FROM" & _
         " (SELECT G.ID_Gruppe, B.ID_Benutzer, Now() AS Zeitstempel FROM tblGruppen G" & _
         " INNER JOIN (tblBenutzer B INNER JOIN tblTemp T ON B.Benutzer = T.Benutzer)" & _
         " ON G.Gruppe = T.Gruppe) Q WHERE NOT EXISTS" & _
         " (SELECT Null FROM tblGruppen_Benutzer Z WHERE Q.ID_Gruppe = Z.fID_Gruppe" & _
         " AND Q.ID_Benutzer = Z.fID_Benutzer)"
   db.Execute sSQL, dbFailOnError

   ' verknüpfte Tabelle entsorgen
   'DoCmd.DeleteObject acTable, "tblTemp"
   
   Set db = Nothing
End Sub


Ich habe eine verknüpfte Tabelle ,,ExcelErtrag" mit den Feldern ,,Filiale", ,,Kundennummer", ,,Bezeichnung", ,,Ertrag", ,,per"und ,,Jahr". Diese enthällt alle Daten, die in die Tabellen ,,Kunden" (1-Tabelle – Master) und in die Tabelle ,,Erträge" (n-Tabelle) aufgeteilt werden sollen.

Die Felder Filiale, Kundennummer und Bezeichung sind die Felder der Kunden-Tabelle, der Rest gehört in die Tabelle ,,Erträge" sowie halt zusätzlich der Fremdschlüssel, der auf die Kundentabelle zeigt. Zukünftig sollen nur dann neue Kunden in der Kundentabelle angelegt werden, sofern diese noch nicht angelegt sind. Erträge der Kundenverbindungen sollen jedoch dauerhaft erhalten bleiben und zukünftig nur hinzukommen.

Ich hoffe, das sind ausreichende Details um den Code entsprechend anpassen zu können.

Danke!!!!

Michael

ebs17

ZitatIch hoffe, das sind ausreichende Details
Nö.
ZitatZukünftig sollen nur dann neue Kunden in der Kundentabelle angelegt werden
Woran würde man einen gleichen Kunden identifizieren?

Zitatum den Code entsprechend anpassen zu können
Feld- und Tabellenbezeichnungen austauschen kannst Du nicht?
Mit freundlichem Glück Auf!

Eberhard

Mr. Ahnungslos

nunja, woran erkennt man eine Kundenverbindung? Evtl. an einer Kundennummer?!

Das reine austauschen von Tabellen und Feldern ist ja nicht da Problem, aber der Code liest doch immer nur ein Feld aus der verknüpften Ursprungstabelle aus und fügt dieses in den beiden Tabellen an. Wie mache ich das denn nun richtig, wenn ich aus der Ursprungstabelle jeweils 2-3 Felder in die beiden Tabellen importieren möchte?

Mr. Ahnungslos

Hallo Access-Gemeinde,

ich hoffe weiterhin auf Hilfe.

Teil 1 des folgenden Codes funktioniert, aber in Teil 2 kommt die Fehlermeldung, dass 3 Parameter erwartet wurden, aber zu wenig übergeben wird. Wieso 3? Es sollen in die Tabelle Erträge doch 4 Felder eingetragen werden (Ertrag, per, Jahr und die ID aus der Tabelle Stammnummern als Fremdschlüssel). Wer kann mir verraten was ich falsch mache? Ich versuche mit der VBA-Hilfe weiterzukommen, aber meiner Meinung nach müsste der Aufbau doch korrekt sein?????

Private Sub Btn_Import_Click()

   Dim db As DAO.Database
   Dim sSQL, iSQL As String
   Set db = CurrentDb

   
   ' Wenn man Daten auf mehrere Tabellen verteilen möchte, beginnt man mit den Tabellen,
   ' in denen ein Primärschlüssel erzeugt wird oder vorhanden ist, der dann später als
   ' Fremdschlüssel in einer weiteren Tabelle benötigt wird, also immer in der
   ' Reihenfolge 1-Tabelle vor n-Tabelle
   
   ' ### 1. Schritt ###
   ' Füllen der 1-(Master-)Tabelle mit den Werten, die neu sind
   
   sSQL = "INSERT INTO Stammnummern (Filiale, Stammnummer, Bezeichnung)" & _
         " SELECT DISTINCT Filiale, Stammnummer, Bezeichnung FROM VerknExcelErträge T WHERE NOT EXISTS" & _
         " (SELECT Null FROM Stammnummern G WHERE G.Stammnummer = T.Stammnummer)"
   db.Execute sSQL, dbFailOnError


   ' ### 2. Schritt ###
   ' Füllen der n-(Detail-)Tabelle, dabei Ermitteln der Primärschlüssel der zugehörigen
   ' 1-Tabelle(n) und Eintragen als Fremdschlüssel. Hier gibt es nun viele
   ' Gestaltungsmöglichkeiten, abhängig davon, wie man die Zwischentabelle definiert.
   
'   ' 2a: Einfaches Anfügen der Kombinationen
   iSQL = "INSERT INTO Erträge (Ertrag, per, Jahr, Kunde)" & _
         " SELECT VerknExcelErtäge.Ertrag, VerknExcelErtäge.per, VerknExcelErtäge.Jahr, Stammnummern.ID FROM Stammnummern" & _
         " INNER JOIN VerknExcelErträge ON Stammnummern.Stammnummer = VerknExcelErträge.Stammnummer"
   db.Execute iSQL, dbFailOnError
   
   Set db = Nothing



End Sub

ebs17

SELECT VerknExcelErtäge.Ertrag

Unbekannte weil neue Bezeichnungen werden mit einer Parameternachfrage behandelt, um darüber evtl. zu einer funktionsfähigen Anweisung zu kommen.
Mit freundlichem Glück Auf!

Eberhard

Mr. Ahnungslos