Warum das überhaupt?
Weil Du jeden Tag dieselbe Frage hast:
„Was steht in diesem PDF – und wohin gehört es im System?“
Access kann Dir das nicht alleine beantworten.
Aber mit OCR, GPT und ein bisschen JSON schon.
Ich zeig Dir, wie Du aus PDF-Dateien automatisch strukturierte Auftragsdaten bekommst.
Auftragskopf. Positionen. Fertig zum Import.
Was Du brauchst
- Tesseract OCR oder Azure OCR für Texterkennung
- OpenAI GPT (oder Azure OpenAI) für das Parsing
- PDF-Datei (z. B. E-Mail-Anhang)
- Access mit VBA
- Tabellen für Kopf, Position, Fehlerprotokoll
Tabellenstruktur (Beispiel)
Tabelle | Zweck |
---|---|
tblImportPDF | Quelldateien + OCR-Text |
tblAuftraege | Auftragskopf (Kunde, Datum…) |
tblPositionen | Einzelpositionen |
tblImportFehler | Parsing- oder OCR-Fehler |
Schritt 1: Text aus PDF extrahieren (per Tesseract)
Sub OCR_PDF(pfad As String)
Dim cmd As String
Dim tempTxt As String
tempTxt = Environ("TEMP") & "\ocr_output.txt"
cmd = "tesseract """ & pfad & """ """ & Replace(tempTxt, ".txt", "") & """ -l deu pdf"
Shell cmd, vbHide
Application.Wait Now + TimeValue("00:00:05")
Dim txt As String
txt = LadeTextdatei(tempTxt)
CurrentDb.Execute "INSERT INTO tblImportPDF (Dateipfad, OCRText, Zeitstempel) VALUES ('" & _
Replace(pfad, "'", "''") & "', '" & Replace(txt, "'", "''") & "', Now())"
End Sub
Hilfsfunktion: Textdatei laden
Function LadeTextdatei(pfad As String) As String
Dim f As Integer
Dim inhalt As String
f = FreeFile
Open pfad For Input As #f
inhalt = Input$(LOF(f), f)
Close f
LadeTextdatei = inhalt
End Function
Schritt 2: Text per GPT zerlegen lassen
Du gibst dem Modell den OCR-Text und sagst:
„Bitte extrahiere mir den Auftragskopf und alle Positionen als JSON.“
Prompt-Vorlage
Lies den folgenden Text aus einem PDF-Auftrag.
Extrahiere den Auftragskopf (z. B. Kundennummer, Bestellnummer, Lieferdatum)
und die Positionen (Menge, Artikelnummer, Beschreibung, Preis)
als JSON mit zwei Objekten: "kopf" und "positionen".
TEXT:
[...OCR-Text...]
API-Aufruf aus Access
Function RufeParsingGPT(ocrText As String) As String
Dim http As Object
Dim apiKey As String
Dim prompt As String
Dim json As String
apiKey = "DEIN_API_KEY"
prompt = "Lies folgenden Auftrag und gib Kopf- und Positionsdaten als JSON zurück:" & vbCrLf & ocrText
json = "{" & _
"""model"":""gpt-4""," & _
"""messages"":[{""role"":""user"",""content"":""" & Replace(prompt, """", "\""") & """}]" & _
"}"
Set http = CreateObject("MSXML2.ServerXMLHTTP")
http.Open "POST", "https://api.openai.com/v1/chat/completions", False
http.setRequestHeader "Content-Type", "application/json"
http.setRequestHeader "Authorization", "Bearer " & apiKey
http.Send json
RufeParsingGPT = http.responseText
End Function
JSON auslesen
Function ParseKopfUndPositionen(json As String) As Boolean
Dim sc As Object
Dim kopf As String
Dim positionen As String
Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
sc.AddCode "function kopf(j){return JSON.parse(JSON.parse(j).choices[0].message.content).kopf;}"
sc.AddCode "function pos(j){return JSON.parse(JSON.parse(j).choices[0].message.content).positionen;}"
kopf = sc.Run("kopf", json)
positionen = sc.Run("pos", json)
Call SpeichereKopf(kopf)
Call SpeicherePositionen(positionen)
ParseKopfUndPositionen = True
End Function
Schritt 3: Daten speichern
Auftragskopf
Sub SpeichereKopf(json As String)
' Beispielhafte Umsetzung, musst Du konkret parsen
' Angenommen: json = {"kundennummer":"4711", "bestellnummer":"A123", "lieferdatum":"2025-06-01"}
Dim sc As Object
Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
sc.AddCode "function parse(j){var d=JSON.parse(j); return d.kundennummer + '|' + d.bestellnummer + '|' + d.lieferdatum;}"
Dim teile() As String
teile = Split(sc.Run("parse", json), "|")
CurrentDb.Execute "INSERT INTO tblAuftraege (Kundennummer, Bestellnummer, Lieferdatum) VALUES ('" & teile(0) & "', '" & teile(1) & "', #" & teile(2) & "#)"
End Sub
Positionen
Sub SpeicherePositionen(jsonArray As String)
' jsonArray = [{"menge":5,"artikelnummer":"12345","text":"Dichtung","preis":12.50}, {...}]
Dim sc As Object
Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
sc.AddCode "function parse(j){var arr=JSON.parse(j);var r='';for(var i=0;i<arr.length;i++){r+=arr[i].menge+'|'+arr[i].artikelnummer+'|'+arr[i].text+'|'+arr[i].preis+'\n';}return r;}"
Dim zeilen() As String
Dim teile() As String
Dim i As Long
zeilen = Split(sc.Run("parse", jsonArray), vbLf)
For i = 0 To UBound(zeilen)
If Trim(zeilen(i)) <> "" Then
teile = Split(zeilen(i), "|")
If UBound(teile) = 3 Then
CurrentDb.Execute "INSERT INTO tblPositionen (Menge, Artikelnummer, Beschreibung, Einzelpreis) VALUES (" & _
teile(0) & ", '" & teile(1) & "', '" & Replace(teile(2), "'", "''") & "', " & teile(3) & ")"
End If
End If
Next i
End Sub
Fehlerbehandlung
Falls GPT Mist liefert – loggen. Nicht raten.
Sub LogFehler(pfad As String, fehlertext As String)
CurrentDb.Execute "INSERT INTO tblImportFehler (Dateipfad, Fehlertext, Zeitstempel) VALUES ('" & _
Replace(pfad, "'", "''") & "', '" & Replace(fehlertext, "'", "''") & "', Now())"
End Sub
Was Du beachten musst
- OCR ist nie perfekt → Eingabequalität zählt
- GPT kann mal halluzinieren → bei Auftragsnummern auf Plausibilität achten
- API-Limits und Laufzeiten beachten (Timeouts)
- Ggf. Zwischenprüfung per Vorschau vor dem Import
„Was vorher Chaos war, wird jetzt strukturierter Auftrag – mit Access als Dirigent.“
Wenn Du’s ernst meinst mit automatischem Auftragseingang:
Meld Dich. Ich bau Dir das robust.
Nicht fancy. Aber funktionierend.
No responses yet