Daten an Word



  • Hallo C#-ler,

    folgende Probleme bei mir:

    (1) In meiner Datenbank speichere ich Bilder im Blob Format ab. Diese sollen nun bei Auswahl der zugehörigen ID auf der C#-Form in ein Word Dokument übergeben werden. Wie?

    (2) Bei Auswahl der ID auf der C#-Form werden auch entsprechend zugehörige Datensätze ausgelesen. Diese sollen ebenfalls an Word übergeben werden. Dies können aber manchmal nur 2 Datensätze sein, manchmal auch 10. Wie mache ich dies dynamisch?

    Um einfach Daten zu übergeben verwende ich bisher folgendes Vorgehen:

    string[,] uaIDarray = new string[50, 3];
    
                    Object oMissing = System.Reflection.Missing.Value;
                    Object oTrue = true;
                    Object oFalse = false;
    
                    Word.Application oWord = new Word.Application();
                    Word.Document oWordDoc = new Word.Document();
    
                    oWord.Visible = true;
                    Object oTemplatePath = @"C:\Datenbanken\Vorlagen\Kontrolle.dot";
                    oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
    
                    int iTotalFields = 0;
    
                    foreach (Word.Field myMergeField in oWordDoc.Fields)
                    {
                        iTotalFields++;
                        Word.Range rngFieldCode = myMergeField.Code;
                        String fieldText = rngFieldCode.Text;
    
                        if (fieldText.StartsWith(" MERGEFIELD"))
                        {
                            Int32 endMerge = fieldText.IndexOf("\\");
                            Int32 fieldNameLength = fieldText.Length - endMerge;
                            String fieldName = fieldText.Substring(11, endMerge - 11);
    
                            fieldName = fieldName.Trim();
    
                            if (fieldName == "ID")
                            {
                                myMergeField.Select();
                                oWord.Selection.TypeText(selectedID);
                            }
    ...
    }
    }
    


  • WolfgangSchwarz schrieb:

    (1) In meiner Datenbank speichere ich Bilder im Blob Format ab. Diese sollen nun bei Auswahl der zugehörigen ID auf der C#-Form in ein Word Dokument übergeben werden. Wie?

    Bilder in der Datenbank? Was haben sie dort zu suchen? Die Datenbank aufblähen, unnötig verlangsamen, oder beides?

    Zur Frage: Ist Word (welche Version) auf dem System, auf dem das Programm laufen soll, installiert?

    WolfgangSchwarz schrieb:

    (2) Bei Auswahl der ID auf der C#-Form werden auch entsprechend zugehörige Datensätze ausgelesen. Diese sollen ebenfalls an Word übergeben werden. Dies können aber manchmal nur 2 Datensätze sein, manchmal auch 10. Wie mache ich dies dynamisch?

    Du könntest deine Datensätze zur Weiterverarbeitung an die List(Of T)-Klasse verfüttern ...

    Einfacher (und wirtschaftlicher) erscheint die Aufgabe, wenn man sie mit Word-Makros (Stichwort: VBA Programmierung) direkt angeht.



  • Bilder in der Datenbank? Was haben sie dort zu suchen? Die Datenbank aufblähen, unnötig verlangsamen, oder beides?

    Da stimme ich Dir zu! Allerdings wurde das schon vor meiner Zeit verbrochen, d.h. ich muss auf den bestehenden Sachen aufbauen ...

    Ja, Word wäre installiert ...
    Wie würden dann die Word Makros von C# raus zum Füllen angesprochen werden?

    Meine Vorstellung war eine Tabelle, die dann dynamisch erweitert werden soll ...



  • Meine Empfehlung wäre gewesen, die gesamte Anforderung per Word-Makro zu lösen. Ohne jegliche C#-Fernsteuerkrücke.

    Aber wenn's wirklich nicht anders geht: schau hier 😉



  • Super! Vielen Dank für den Link!
    Über Textmarken kann ich so meine Daten einfügen - das hat schonmal funktioniert.

    Problem ist nun noch die Bilder (Blob in MySQL-DB) nach Word zu bekommen ...
    Hast Du dazu vielleicht noch einen Tipp oder sollte ich mich da besser bei VBA-Foren umschauen?



  • Nun taucht leider doch eine Fehlermeldung auf - in der Zeile mit dem MySQLCommand:
    Ungültiger Textmarkenname

    Funktioniert diese Art des Füllens gar nicht?

    C#-Code:

    object oMissing = System.Reflection.Missing.Value;
    
                    Word.ApplicationClass oWord = new Word.ApplicationClass();
                    oWord.Visible = true;
    
                    Word.Documents oDocs = oWord.Documents;
                    object oFile = "P:\\Datenbanken\\Vorlagen\\Dok1.doc";
                    Word._Document oDoc = oDocs.Open(ref oFile, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
    
                    conn.Open();
                    MySqlCommand cmd = new MySqlCommand("SELECT id, anzahl, einheit FROM endkontrolle WHERE hauptid = '" + selectedArtikel + "'", conn);
                    dr = cmd.ExecuteReader();
    
                    while (dr.Read())
                    {
                        RunMacro(oWord, new Object[] { "TextmarkeEinfuegen", "TM-" + dr.GetString(0) });
                        RunMacro(oWord, new Object[] { "AufrufTextmarke", "TM-" + dr.GetString(0), dr.GetString(0) });
                    }
                    conn.Close();
    

    VBA-Code:

    Sub TextmarkeEinfuegen(strTextmarke As String)
    ActiveDocument.Bookmarks.Add Name:=strTextmarke, Range:=Selection.Range
    End Sub
    
    'Display a message box that displays the application name.
    Public Sub AufrufTextmarke(tm As String, inhalt As String)
    fktReplaceBookmarkText ActiveDocument, tm, inhalt
    End Sub
    
    Function fktReplaceBookmarkText(ThisDocument As Document, strTextmarke As String, strVar As String)
       Dim rng As Range
       If ThisDocument.Bookmarks.Exists(strTextmarke) Then
        Set rng = ThisDocument.Bookmarks(strTextmarke).Range
        rng.Text = strVar
        ThisDocument.Bookmarks.Add strTextmarke, rng
        Set rng = Nothing
       End If
    End Function
    


  • Sorry, die Fehlermeldung kommt beim ersten RunMacro

    Dazu hier noch der Code:

    private void RunMacro(object oApp, object[] oRunArgs)
            {
                oApp.GetType().InvokeMember("Run", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.InvokeMethod, null, oApp, oRunArgs);
            }
    


  • Problem gelöst: Der - als Bezeichnung für eine Textmarke verursacht die Fehlermeldung. Wenn ich den weglasse, funktioniert es! 🙂



  • Ich möchte keinen neuen Beitrag erstellen, da es sich noch quasi um das selbe Thema bzw. noch den selben Code handelt.
    Hoffe ihr könnt mir helfen, auch wenn ich nicht genau weiß, ob mein Problem (Denkfehler) grad bei C# oder bei VBA liegt:

    Hier mein C#-Code

    conn.Open();
                    MySqlCommand cmd = new MySqlCommand("SELECT id, anzahl, einheit FROM endkontrolle WHERE hauptid = '" + selectedArtikel + "'", conn);
                    dr = cmd.ExecuteReader();
    while (dr.Read())
                    {
                        string strWert = dr.GetString(0);
                        strWert = strWert.Replace(" ", "");
                        RunMacro(oWord, new Object[] { "TextmarkeEinfuegen", "TM" + dr.GetString(0), "TM" + dr.GetString(1), "TM" + dr.GetString(2) });
    
                        RunMacro(oWord, new Object[] { "AufrufTextmarke", "TM" + dr.GetString(0), dr.GetString(0) });
                        RunMacro(oWord, new Object[] { "AufrufTextmarke", "TM" + dr.GetString(1), dr.GetString(1) });
                        RunMacro(oWord, new Object[] { "AufrufTextmarke", "TM" + dr.GetString(2), dr.GetString(2) });
                    }
    

    Und hier VBA:
    Textmarke einfügen

    Sub TextmarkeEinfuegen(strTMArtNr As String, strTMAnz As String, strTMEinheit As String)
        Dim rng As Word.Range
    
        If ActiveDocument.Bookmarks.Exists("Hauptartikelnummer") Then
        Set rng = ActiveDocument.Bookmarks("Hauptartikelnummer").Range
        rng.Collapse wdCollapseEnd
        rng.MoveStart Unit:=wdParagraph, Count:=1
        rng.Bookmarks.Add Name:=strTMArtNr, Range:=rng
        'Textmarke für Anzahl
        rng.InsertAfter vbTab
        rng.Bookmarks.Add Name:=strTMAnz, Range:=rng
        'Textmarke für Einheit
        rng.InsertAfter vbTab
        rng.Bookmarks.Add Name:=strTMEinheit, Range:=rng
    
        rng.InsertAfter vbNewLine
        rng.InsertAfter vbNewLine
    
        End If
    End Sub
    

    Füllen der Textmarke

    Function fktReplaceBookmarkText(ThisDocument As Document, strTextmarke As String, strVar As String)
       Dim rng As Range
       If ThisDocument.Bookmarks.Exists(strTextmarke) Then
        Set rng = ThisDocument.Bookmarks(strTextmarke).Range
        rng.Text = strVar
        ThisDocument.Bookmarks.Add strTextmarke, rng
        Set rng = Nothing
       End If
    End Function
    

    Für jede Spalte aus der Tabelle soll eine Textmarke angelegt werden, für den nächsten Datensatz soll ein Zeilenumbruch bzw. eine Leerzeile kommen.
    Anschließend soll alles gefüllt werden.

    Wenn ich nur dit Textmarken anlegen lasse (also die Funktion nicht ausführen lasse), dann werden auch alle Textmarken richtig angelegt.
    Lass ich diese nun aber befüllen, dann wird nur jeweils die letzte Spalte aus der Tabelle auf dem Worddokument ausgegeben.

    Ich hoffe, ihr versteht das Problem und könnt mir helfen.



  • Oft mag es sinnvoll sein das Dokument selber zu erstellen - sofern es nicht zu komplex ist. WordML ist für wenig komplexe Dokumente ziemlich praktisch. Wir verwenden regelmäßig das pendant von Excel zur Generierung von xls Dateien...



  • Danke für den Tipp! Gut zu wissen, was es noch gibt.
    Möchte es aber vorerst doch noch über VBA bzw. Word versuchen.

    Kann mir da vielleicht doch jemand helfen und sagen, warum, wenn ich die folgenden beiden Code ausführe

    RunMacro(oWord, new Object[] { "AufrufTextmarke", "TM" + dr.GetString(1), dr.GetString(1) });
                        RunMacro(oWord, new Object[] { "AufrufTextmarke", "TM" + dr.GetString(2), dr.GetString(2) });
    

    nur jeweils die letzte eingefügte Textmarke des Datensatzes gefüllt wird bzw. noch im Dokument vorhanden ist?

    Kommentiere ich die beiden Zeilen aus, enthält mein Dokument alle Textmarken und jeweils die ID des Datensatzes.


Anmelden zum Antworten