| |
VB.NET - FortgeschritteneSelbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 23.04.17 07:39 |
| Hallo zusammen,
bin grade an nem größeren VB.net Projekt dran. Näheres dazu findet Ihr hier: http://www.vbarchiv.net/forum/id2_i142486t142486_word-vorlage-mit-dat-datei-fuellen-schleifen-tabellen-aktionen.html
da hab ich leider ins falsche Forum gepostet... sorry nochmal ;)
Kurz zusammengefasst. Ich möchte Daten aus einer Kalkulation in eine .dat Datei(aufgebaut wie .csv) schreiben, und damit Wordvorlagen füllen.
Zum stand mit den Dokumenten. Bis jetzt funktionierts eigentlich, aber nicht so wie ich will.
Heißt ich kann im Word meine Textmarken finden, kann diese auch mit den Daten aus der Software füttern.
Hierzu mal der Code:
Imports Word = Microsoft.Office.Interop.Word
Module WordDocWriter
Public Sub DocWriter()
Dim objWordApp As New Word.Application
objWordApp.Visible = True
Dim Anrede As String = Hauptmenue.tbBgFormatA.Text
Dim Zeile As String = "{ADD1.ANREDE};{AUKOPF.DATUM}"
Dim Headlines() As String = Zeile.Split(";")
Dim ZeileDaten As String = "Herr o Frau" & ";" & Hauptmenue.tbDate.Text
Dim Daten() As String = ZeileDaten.Split(";")
' Dokument öffnen.
Dim objDoc As Word.Document = objWordApp.Documents.Add( _
"C:\Users\USERNAME\Desktop\RE-2017.dotx")
objDoc = objWordApp.ActiveDocument
objWordApp.ActiveDocument.SaveAs("RE1101Test.docx")
For i As Integer = 0 To 1
' Textmarken mit Daten ersetzen
objDoc.Content.Find.Execute(FindText:=Headlines(0), _
ReplaceWith:=Daten(0), Replace:=Word.WdReplace.wdReplaceAll)
While objDoc.Content.Find.Execute(FindText:=" ", _
Wrap:=Word.WdFindWrap.wdFindContinue)
objDoc.Content.Find.Execute(FindText:=" ", ReplaceWith:=" ", _
Replace:=Word.WdReplace.wdReplaceAll, _
Wrap:=Word.WdFindWrap.wdFindContinue)
End While
Next
'Dokument speichern und schließen
' objDoc.Save()
' objDoc.Close()
'objDoc = Nothing
'objWordApp.Quit()
'objWordApp = Nothing
' Textmarke aufteilen in Tablename und Columnheader
'Dim StringList As String = "{ADD1.FIRMA}"
'Dim StringArrayList() As String = StringList.Replace("{", "").Replace(
' "}", "").Split(".")
'MessageBox.Show(StringArrayList(0))
'MessageBox.Show(StringArrayList(1))
End Sub
End Module Am Ende sieht man schon den Test die Textmarke zu splitten. Die Textmarken sind so aufgebaut dass immer erst der Tabellenname, dann ein "." und dann die Spaltenüberschrift kommt. Im Word sieht dies dann z.B. so aus: {ADD1.STRASSE}.
Ich kann jetzt also über mein Arry die Textmarken im Word suchen, und durch weiteren Text im zweiten Array ersetzen. Nachteil: Ich durchlauf immer alle Datensätze egal ob vorhanden oder nicht....Gerade wenn ich die Daten wirklich vom SQL Server kommen lass, geht jedes Netzwerk in Traffik unter. Zum anderen hab ich durch die CSV immer ne Kontrolle obs was an der Dokumentvorlage nicht stimmt, oder die Daten nicht aus dem System rauskommen,.....
Deswegen mein Plan: Ich schreibe die Dateien in eine CSV Datei, suche im Word nach den Textmarken, teile Diese, und hab so meine "Adresse" für die CSV Datei um dort die Daten zu holen und Sie dann ins Word zu schreiben.
Und genau da hakts *g*... Zum einen weiß ich nicht wie ich die Daten aus meiner selbsterstellten CSV Datei über die Adressierung rausbekomm. Zum anderen weiß ich nicht wie ich im Word nur nach unbekannten variablen in geschwungenen Klammern suchen kann. Wenn man weiß was drin steht ists einfach ;) Irgend ne Aktion über Stringlänge fällt raus, da die Adressen alle unterschiedlich lang sind.
Achja, zu erwähnen ist, dass alles noch im Aufbau ist,.. deswegen sind da auch teilweise komische Daten wie tbEformatA für die FIRMA drin ;) Also nicht denken, alles noch zum testen *g* | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 23.04.17 07:40 |
| Achja, hier noch der Code mit dem ich meine CSV schreibe:
Imports System.IO.Path
Imports System.IO
Module DATschreiben
Public Sub DATerzeugen()
Dim File As File = Nothing
' Stringvariable bereithalten
Dim strTempPath As String
' TEMP-Verzeichnis ermitteln:
strTempPath = IO.Path.GetTempPath
' Ausgabe ins Konsolenfenster
'MsgBox(strTempPath)
' Tabellen mit Streamwriter erstellen
Dim Writer As StreamWriter
Writer = New StreamWriter(strTempPath & "Gesamt.dat", True, _
Text.Encoding.UTF8)
Writer.WriteLine("[INFO]")
Writer.WriteLine("[ADD1]")
Writer.WriteLine("[FIRMA];" & "[STRASSE];" & "[HAUSNUMMER];" & "[PLZ];" _
& "[ORT];")
Writer.WriteLine(Hauptmenue.tbEformatA.Text & ";" & _
Hauptmenue.tbEformatB.Text & ";" & ";" & ";" & ";")
Writer.WriteLine("[ADD2]")
Writer.WriteLine("[FIRMA];" & "[STRASSE];" & "[HAUSNUMMER];" & "[PLZ];" _
& "[ORT];")
Writer.WriteLine(Hauptmenue.tbEformatA.Text & ";" & _
Hauptmenue.tbEformatB.Text & ";" & ";" & ";" & ";")
Writer.Close()
DocWriter()
End Sub
End Module Vielleicht hat da jemand noch ne elegantere Lösung *g* aber eigentlich so wie es aussehn sollte denk ich. | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 23.04.17 11:48 |
| Naja, es gibt viele Gründe dafür dass ich es so umständlich mache.
Mit dem System werden sämtlichen Dokumente erstellt, also vom Angebot, über die Rechnung, bis hin zum Umlauf- und Lieferschein. In jeder der Vorlagen sind zich Textmarken. Wenn man diese herkönntlich generiert, dauert das ewig ein neues Dokument zu erstellen. Wenn man die umständliche Methode geht, kann man die Textmarke einfach mit {} kennzeichnen, und gibt dort Tabellen- und Spaltenname des Werts an, den man im Dokument haben will. Ohne Word sagen zu müssen, du bist eine Textmarke, und so heißt du *g*
Da aber zudem viel mehr Daten zur Verfügung stehen, als in den einzellnen Dokumenten benötigt wirden,
macht es keinen Sinn, alle Tabellen zu durchlaufen und jeden einzellnen Wert abzufragen. Beim umfangreichen Aufträgen kommt da schon einiges an Daten zusammen.
Deshalb will ich den umständlichen Weg gehen. Wenn eine Textmarke gefunden wird, soll aus dieser der Pfad in die CSV generiert werden, und damit dann aus dieser der Wert ins Excel übergeben.
Zudem besteht bei der herkömmlichen Lösung mit den Textmarken im Word immer das Problem bei Fehlern,..
man weiß erstmal nicht liegts an der Textmarke oder an der Software. Über diese CSV Datei lässt sich leicht kontrollieren ob die Word Vorlage ne macke hat, oder zb irgendwelche Daten im Auftrag vergessen wurden o.ä.....
Für mich also in der Anwendung absolut von Vorteil behaftet. Nur zum Programmieren isses hald schwerer *g*
Beitrag wurde zuletzt am 23.04.17 um 11:50:34 editiert. | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: effeff | Datum: 23.04.17 12:16 |
| Ich finde es einfacher, "richtige" Textmarken zu benutzen.
Dass man mehr Daten zur Verfügung hat, als man benötigt, kenne ich auch. Normalerweise benutzt Du davon ja aber auch nur die, die benötigt werden. Und diese werden dann eben in das Word-Dokument eingefügt.
BTW: Warum übernimmst Du die zu bearbeitenden Daten nicht schlichtweg in DataTables?
//Deshalb will ich den umständlichen Weg gehen. Wenn eine Textmarke gefunden wird, soll aus dieser der Pfad in die CSV generiert werden, und damit dann aus dieser der Wert ins Excel übergeben. //
Wo kommt denn nun auf einmal Excel her? Du wolltest doch eine Word-Datei füllen?
Fehler abzufangen ist die Aufgabe des Programmierers. Also Deine. Du musst prüfen, ob alle Werte vorhanden sind oder ob z. B. Textmarken nicht angesprungen werden können, weil sie nicht vorhanden sind. Wenn Du Fehler abfängst, erkennst Du sofort, woran es hapert.
EALA FREYA FRESENA | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 23.04.17 13:35 |
| Ich hätte doch weiter ausholen sollen ;) Im verlinkten Post wurde das warum etwas besser ausgearbeitet.
Es geht um eine Hausinterne Erweiterung unserer Branchensoftware. Und da läuft es nach dem Prinzip ab. Ich will das ganze jetzt einfach nachprogrammieren, das bis auf die Erweiterung keine großen Erneuerungen aufkommen. Sonst hab ich jede Vorlage doppelt, einmal im System, einmal für die Erweiterung. Und das längere arbeiten mit solchen Vorlagen hat mir gezeigt, dass es oft einfach nur reicht die Textmarke im Word auszuschneiden und wieder einzufügen um Fehler zu beheben.
PS. Das mit Excel war n Ausrutscher, meinte natürlich Word,.. | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: Franki | Datum: 24.04.17 02:27 |
| Hallo,
Zitat: | | Mit dem System werden sämtlichen Dokumente erstellt, also vom
Angebot, über die Rechnung, bis hin zum Umlauf- und Lieferschein. In jeder der Vorlagen sind zich Textmarken. | |
Soweit völlig normal, dafür sind Textmarken ja da, dass sie stellvertretend für die Daten sind die in den jeweiligen Beleg sollen.
ABER:
Zitat: | |
Wenn man diese herkönntlich generiert, dauert das ewig ein
neues Dokument zu erstellen.
| |
Was meinst du jetzt mit neuem Dokument?
Also einen neuen Lieferschein / Rechnung usw. meinst du mit Sicherheit nicht, da brauchen ja nur die Textmarken mit den entsprechenden Daten gefüllt werden, woher auch immer die stammen. Bei solchen Belegen stehen die Textmarken für z.B. Belegnummer, Belegdatum, Kundennummer usw. ja sowieso fest weil sie halt an eine bestimmte Stelle müssen.
Für die anderen Daten wie Artikel die im Beleg aufgeführt sind verwende ich z.B. keine Textmarken. Also wenn der Lieferschein 50 Artikel enthält gibt es in der Vorlage keine 50 Textmarken. So hast du das aber mit Sicherheit auch nicht...
Wenn du einen ganz neuen Beleg erschaffen möchtest den es im Unternehmen noch nicht gibt (z.B. Sammelrechnung, Schönwetterrechnung, Aktionsangebote usw.), mußt du doch auch nur einmalig eine entsprechende Vorlage erstellen die die entsprechenden Textmarken enthält. (Vorhandene kannst du aus anderen Vorlagen kopieren, neue mußt du halt selbst anlegen) Das dauert auch nicht ewig und ist ja auch nur eine einmalige Angelegenheit.
Zitat: | |
Wenn man die umständliche
Methode geht, kann man die Textmarke einfach mit {}
kennzeichnen, und gibt dort Tabellen- und Spaltenname des
Werts an, den man im Dokument haben will. Ohne Word sagen zu
müssen, du bist eine Textmarke, und so heißt du *g*
| |
Aber warum möchte man das machen?
Letztendlich möchtest du ja mit Textmarken arbeiten, also solltest du sie auch verwenden. Was für einen Vorteil soll das bringen Word nicht sagen zu wollen, dass es Textmarken enthält und wie deren Name lautet?
Zitat: | |
Da aber zudem viel mehr Daten zur Verfügung stehen, als in
den einzellnen Dokumenten benötigt wirden,
macht es keinen Sinn, alle Tabellen zu durchlaufen und jeden
einzellnen Wert abzufragen. Beim umfangreichen Aufträgen
kommt da schon einiges an Daten zusammen.
| |
Auch das verstehe ich noch nicht so ganz.
ob ein Lieferschein jetzt 1 oder 1 Mio Artikel enthält oder wie hoch der spätere Rechnungsbetrag ist, hat doch nichts mit der Anzahl der Textmarken zu tun, die ist immer gleich. Also Belegnummer, Kundennummer usw. sind nur einmal vorhanden und müssen gefüllt werden.
Was hat also der Umfang des Auftrags damit zu tun?
Zitat: | |
Zudem besteht bei der herkömmlichen Lösung mit den Textmarken
im Word immer das Problem bei Fehlern,..
man weiß erstmal nicht liegts an der Textmarke oder an der
Software.
Über diese CSV Datei lässt sich leicht
kontrollieren ob die Word Vorlage ne macke hat, oder zb
irgendwelche Daten im Auftrag vergessen wurden o.ä.....
| |
Auch das ist meiner Meinung nach der falsche Ansatz.
Du mußt ja eine Plausibilitätsprüfung in deiner Software machen bevor du die Daten überhaupt an die Word Vorlage schickst. Fehlt bei einer Rechnung z.B. die Rechnungsnummer mußt du das innerhalb deiner Software prüfen und nicht erst später wenn es schon zu spät ist. Also erst wenn alle Pflichtfelder mit plausiblen Daten gefüllt sind (Also z.B. Rechnungsdatum nicht aa.bb.cccc lautet)
Wenn diese Kontrolle erfolgreich durchlaufen wurde dann mußt du natürlich jede Textmarke auf Existenz prüfen und bei einem Fehler abbrechen. (Aber auch hier nur diejenigen die du füllen möchtest)
Zitat: | | Für mich also in der Anwendung absolut von Vorteil behaftet.
Nur zum Programmieren isses hald schwerer *g* | |
Vielleicht solltest du das ganze Konzept mal von Grund auf überdenken. Denn eine *.csv Datei brauchst du nicht um aus einer Software heraus mittels Word Vorlagen für Belege wie z.B. Lieferschein zu erzeugen. Das ist eigentlich ein überflüssiger Schritt bzw. unnötiger Umweg.
Ich arbeite seit über 15 Jahren mit Warenwirtschaftssystemen, Onlineshops usw. aber eine Zwischenschicht mittels *.csv Datei habe ich noch nie gebraucht.
Also beschreiben doch mal genauer (gerne per PM sonst wird es hier OT) warum due die *.csv überhaupt brauchst. Das wäre nur dann irgendwie sinnvoll wenn du externe Daten von Fremdfirmen verarbeiten möchtest, da nutze ich so etwas auch, aber da gab bzw. gibt es vielfältige Formate, damals Datanorm, heute XML wo man den Datenaustausch auch anpassen kann.
Gruß
Frank | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 24.04.17 04:35 |
| Hallo Frank,
mit neuem Dokument mein ich neue Vorlagen. Dies kommt garnicht so selten vor, dass diese neu erstellt werden, da oft z.B. kundenspezifische Lieferscheine, Rechnungen usw gefordert sind.
Für die Artikel, Detailbeschreibungen usw(Mehrzeilige Tabellen) werden in dem Originalsystem Schleifen verwendet. Dafür setzt man einfach ein [WANFANG vor und ein WENDE] hinter die Textmarke/n. Sieht in der Vorlage dann so aus. Würde dort die Textmarken in eine Tabelle setzten um sie zu formatieren, habs mal mit Semikolon getrennt ;).
[WANFANG
{POS1.ARTNR};{POS1.EXTNR};{POS1.BEZ};{POS1.BEZ};
WENDE]
Richtig viele Daten kommen dann bei der Umlaufdokumente für die Produktion.
Da werden sämtliche Materialien, Maschinen, Laufzeiten, Kostenstellen, usw usw abgebildet, zum Teil jeder Arbeitsschritt an jeder Kostenstelle. Da kommen schnell einige hundert Daten zusammen.
Da hat man dann gleich mehrere verschachtelte Schleifen, die erst mehrere Tabellen durchlaufen, und in diesen dann nochmal die Zeilen.
Warum ich diese etwas komplizierte vorgehensweise programmiere. Das ganze hat 2 Hintergründe. Zum einen haben wir ja eine Branchensoftware die genau so arbeitet. Und für diese soll es ja als Erweiterung dienen. Ich greife auf auf die Adress- und Materialdatenbank dieser Software zu. Wenn ich jetzt anfange ein zweites System für die Dokumente zu erstellen, erstell ich in Zukunft jede Vorlage doppelt. Einmal fürs Hauptsystem und einmal für die Erweiterung. Alo selbst wenn man sich mit den umständlichen Textmarken in Word abgefunden hat, erstellt man trotzdem jede Vorlage 2 mal.
Zum anderen find ich das System nicht doof. Wie gesagt, relativ leichtes erstellen von Vorlagen, Übersicht über die verfügbaren Daten in der CSV Datei, die auch der Clientuser einsehen kann. Der weiß ja nicht, welche Daten Ihm das System alle zur Verfügung stellt.
Andererseits bin ich der Meinung dass ich mir so einiges an Laufzeit bzw Performance sparen kann. Mach ich es mit herkömmlichen Textmarken, so muss ich jede möglicherweise vorkommende Marke abfragen, wenn se da ist ersetzen, wenn nicht zur nächsten,... bei wie gesagt einigen hundert wenn nicht gar 1000 Werten einiges an Rechenleistung. Da ist der Ansatz doch gut, erstmal schauen, welche Textmarken hab ich und diese auszulesen. Der Clou dran ist, dass ich, sobald die Marken ausgelesen sind, auch gleich meine Adressierung für die Tabelle hab, in der die Daten stehen. Also ich find die Vorgehensweise erlich gesagt genial. Wenn auch tricky umzusetzen | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 24.04.17 04:51 |
| Auf jeden fall eins der Kernprobleme ;) ^^
Ich hab jetzt mal versuchst in meiner Schleife nach "(<{*}>)", "{(<*>)}", "{(<*>).(<*>)}"
aber irgenwie findet er nichts??? | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: Kuno60 | Datum: 24.04.17 05:53 |
| Hallo,
probiere es mal mit: "{(.+?)};"
bei diesem Text:
[WANFANG
{POS1.ARTNR};{POS1.EXTNR};{POS1.BEZ};{POS1.BEZ};
WENDE]
Dies findet den Inhalt der geschweiften Klammern (POS1.ARTNR)
oder mit: "{(.+?)\.(.+?)};"
Dies findet die beiden Wörter (POS1 und ARTNR).
dies: "\[WANFANG\r\n(.+?)\r\nWENDE\]" findet den gesamten Inhalt der 2. Zeile | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 26.04.17 15:51 |
| Hallo Kuno,
ich probier jetzt schon n paar Tage, aber irgendwie kommt nicht raus,...
hab mich ne kleine Funktion gebastelt um die Regulären Ausdrücke zu testen, aber ich find nix,..
Dim rng As Word.Range = objDoc.Content
Dim intFound As Integer = 0
Dim ausgabe As String = Nothing
rng.Find.ClearFormatting()
rng.Find.Forward = True
rng.Find.Text = "{(.+?)}"
rng.Find.Execute()
Do While rng.Find.Found = True
intFound += 1
rng.Find.Execute()
Loop
MessageBox.Show("Gefundende Strings: " & intFound.ToString()) Wenn ich nach "{(.+?)}" such, bekomm ich 0 Strings,... wenn ich aber nach "{POS1.ARTNR}" suche
find ich was. Habs auch schon mit "\{(.+?)\.(.+?)\}","\{(.+?)\}" und einigen anderen Kombis versucht,... | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: Kuno60 | Datum: 26.04.17 17:28 |
| Hallo,
ich weiß nicht, ob Word direkt reguläre Ausdrücke unterstützt, aber mit RegEx kann man z.B. so suchen:
For Each m As Match In Regex.Matches(Dokumenttext, "{(.+?)}")
Dim g1 = m.Groups(1)
Dim text = g1.Value
Dim index = g1.Index
Dim länge = g1.Length
Next Dokumenttext ist der gesamte Text, der durchsucht werden soll und in der Schleife werden alle Übereinstimmungen gefunden, mit Index und Länge. | |
Re: Selbsterstellte .CSV auslesen/Word Datei füllen | | | Autor: StereotypMonoton | Datum: 28.04.17 06:35 |
| Hallo Kuno,
also vorweg muss ich erstmal n großes DANKE ausprechen. Echt super wie ihr einem hier weiterhelft.
Also kurzum, funzt ;) Hehe, mit .value von der Matchgruppe bekomm ich sogar gleich meine Adresse für die CSV Datei,...
hier mal der Code, sollen ja Andere auch was von haben ;)
Try
For Each DataMatch As Match In Regex.Matches(objDoc.Content.Text, _
"{(.+?)}")
Dim g1 = DataMatch.Groups(1)
Dim text = g1.Value
Dim DataAddy = g1.Value
MessageBox.Show("Zellenadresse: " & DataAddy)
Next
Catch
MessageBox.Show("Satz mit x")
End Try OK, also Zwischenstand: CSV Datei wird erstellt, Textmarken in Word werden gefunden, können ersetzt und ausgelesen werden. Jetzt muss das ganze noch verheiratet werden ;) ^^
Also, ich hab die Textmarke {ADD1.STRASSE} in meine Word dokument. Die Software findet diese, gibt mir ADD1.STRASSE zurück. Jetzt stell ich mir vor dass es so ne Art WVERWEIS SVERWEIS wie im Excel geben müsste. Dem ich sag, ADD1 = Tablename, STRASSE = Columnname und mir dann sagt was drunter steht ?? Den Wert nehm ich dann und ersetz dann via Replace meine Textmarke im Word....
Frage is nur, wie komm ich dran *g* | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevZIP40 Pro DLL
Zippen und Unzippen wie die Profis!
Mit nur wenigen Zeilen Code statten Sie Ihre Anwendungen ab sofort mit schnellen Zip- und Unzip-Funktionen aus. Hierbei lassen sich entweder einzelnen Dateien oder auch gesamte Ordner zippen bzw. entpacken. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|