none
Copy & Paste Word document content with bookmarks for form letter RRS feed

  • Question

  • Hello Everyone,

    So I'm very close to finish my first program in VB but the this last feature gives me a headache. I created a word template where data from my db goes in, after I Select a Daterange in my VB application and hit print it shall open word loads that document and copy paste it so many times as week are selected. And then in every site shall be the data.

    So selekting a daterange that has 3 weeks for example:

    opens up word, loads the template, select all, copy, paste. Load the data for that first week and get it into the first site.

    paste, load data for second week and get it into the second site.

    paste, load data for third week and get it into the thrid site.

    I actually got it halfy working, when I select 3 weeks, it creates 6 sites with that template, but it doesnt copy any bookmarks that I have in the template, where the data shall be filled into.

    So that means, only on the original first site of the template is data, on all the other 5 sites there is only the template but no data.

    I probably made it very complicated and i guess there is a easier way.

    So my question is, how can i get this whole thing to work nicely, I can print out one week without problems, but when I want to print out several weeks, it gives me a hard time to get that to work nicely.

    Screenshot of my template:

    And here the program as a screenshot, selected the weeks there and hit print, but totally messed up, also i only were in october but the date went up to november. :S

    Some Code, what happens when you press on the print button:

     Private Sub btPrint_Click(sender As Object, e As EventArgs) Handles btPrint.Click ' Druckenknopf Funktionen
            Try
                SelectedDate = MonthCalendar_Von.SelectionRange.Start
                myYear = myCalendar.GetYear(SelectedDate)
                week = myCalendar.GetWeekOfYear(SelectedDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday) ' Kalenderwoche aus ausgewähltem Datum bekommen
    
                MonthCalendar_Von.Select()
    
                Monday = GetWeekStartDate(week, myYear)             ' Wochenanfangsdatum der selektierten Woche in die Date-Variable "Monday" speichern
                Tuesday = DateAdd(DateInterval.Day, 1, Monday)      ' Wochenanfangsdatum + 1 Tag in die Date-Variable "Tuesday" speichern
                Wednesday = DateAdd(DateInterval.Day, 2, Monday)    ' Wochenanfangsdatum + 2 Tage in die Date-Variable "Wednesday" speichern
                Thursday = DateAdd(DateInterval.Day, 3, Monday)     ' Wochenanfangsdatum + 3 Tage in die Date-Variable "Thursday" speichern
                Friday = DateAdd(DateInterval.Day, 4, Monday)       ' Wochenanfangsdatum + 4 Tage in die Date-Variable "Friday" speichern
                Saturday = DateAdd(DateInterval.Day, 5, Monday)     ' Wochenanfangsdatum + 5 Tage in die Date-Variable "Saturday" speichern
    
                GesamtWoche = 0                                     ' reseten der Gesamtstunden einer Woche auf 0 wenn der Drucken Knopf betätigt wird
    
                If chkWordDruck.Checked = False Then             ' Übergibt der Variable Worddruck den Wert 1, wenn die Checkbox in der Form aktiv ist
                    DruckForm.Visible = True                        ' Druckform oder Previewform wird geladen - ist benötigt da es die Daten aus der DB lädt.
                    ' Code zum drucken der Formulare hierher: .....
                    DataGridViewPrintLoader.Load()                  ' Lädt die Funktion aus dem vb Modul DataDridViewPrintLoader - Füllt die Druckform mit Daten aus der ausgewählten KW
    
    
                Else
                    Sel_WochenAnzalhRechner()                       ' Ermittelt wie viele Wochen in der Druckkalender Ansicht selektiert wurden
                    word.Visible = True                             ' Öffnet Word
                    doc = word.Documents.Open("C:\NeuerOrdner\AusbildungsnachweisNr.docm", , False, False, , , True) ' Öffnet das Word Template (Erfassungsmaske)
                    Serienbrief.WordSerienbrief()
                    DruckForm.Visible = False                       ' schliesst die Druckform/Druckpreview
                    doc.Activate()                                  ' Setzt das WordDokument als Aktiv
    
                End If
    
    
    
    
    
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub


    Sel_WochenAnzahlRechner() Funktion Code:

    Public Sub Sel_WochenAnzalhRechner()
    
            Dim StartAuswahl As Date = DruckDatumAuswahl.MonthCalendar_Von.SelectionRange.Start
            Dim EndAuswahl As Date = DruckDatumAuswahl.MonthCalendar_Von.SelectionRange.End
            NumOfWeeks = (DateDiff("w", StartAuswahl, EndAuswahl, FirstDayOfWeek.Monday, FirstWeekOfYear.Jan1) + 1)
    
        End Sub
    
    
    End Module

    WordSerienbrief() Function Code:

        Public Sub WordSerienbrief()
    
            word.Selection.WholeStory()
            word.Selection.Copy()
            word.Selection.Collapse()
    
            DruckForm.Visible = True                        ' Öffnet die Druckform/Druckpreview
            DataGridViewPrintLoader.Load()                  ' Läd Daten in die Druckform
            DataGridViewPrintLoader.WordLoader()            ' Zieht Informationen aus der DB und fügt sie in das Word Dokument ein
    
    
    
            For i As Integer = 0 To NumOfWeeks Step 1
                'word.Selection.InsertBreak()
    
                word.Selection.Paste()
    
                week += 1
    
                DruckDatumAuswahl.MonthCalendar_Von.Select()
    
                Monday = DruckDatumAuswahl.GetWeekStartDate(week, myYear)               ' Wochenanfangsdatum der selektierten Woche in die Date-Variable "Monday" speichern
                Tuesday = DateAdd(DateInterval.Day, 1, Monday)                          ' Wochenanfangsdatum + 1 Tag in die Date-Variable "Tuesday" speichern
                Wednesday = DateAdd(DateInterval.Day, 2, Monday)                        ' Wochenanfangsdatum + 2 Tage in die Date-Variable "Wednesday" speichern
                Thursday = DateAdd(DateInterval.Day, 3, Monday)                         ' Wochenanfangsdatum + 3 Tage in die Date-Variable "Thursday" speichern
                Friday = DateAdd(DateInterval.Day, 4, Monday)                           ' Wochenanfangsdatum + 4 Tage in die Date-Variable "Friday" speichern
                Saturday = DateAdd(DateInterval.Day, 5, Monday)                         ' Wochenanfangsdatum + 5 Tage in die Date-Variable "Saturday" speichern
    
                GesamtWoche = 0
    
                DataGridViewPrintLoader.Load()                  ' Läd Daten in die Druckform
                DataGridViewPrintLoader.WordLoader()            ' Zieht Informationen aus der DB und fügt sie in 
    
            Next
    
    
    
        End Sub

    I hope someone can help me.

    Thanks a lot

    Sincerly Yours,

    Patrick V.

    • Moved by KareninstructorMVP Friday, October 3, 2014 9:57 AM Moved from VB.NET forum for better visibility as the bulk of the question is Word automation
    Thursday, October 2, 2014 8:16 AM

Answers

  • The problem you're having is due to the fact that a bookmark can only exist in one location in a document. So, when you copy the page multiple times, the bookmark doesn't get copied - it stays on the first page only. Perhaps the simplest solution is to either:
    a) update the bookmarks for the first day, replicate the page to make the second page (e.g. via .FormattedText), repeating the process until all are done, then delete the first page; or
    b) create a separate document for each day, update the bookmarks for that document, then combine all the documents when you're done.

    Another approach would be to use content controls, via their titles in place of the bookmarks. You could then replicate the page as many times as you need, then refer to the content controls via the SelectContentControlsByTitle method.For example, in VBA:
    ActiveDocument.SelectContentControlsByTitle("Control1").Item(1).Range.Text = "Page 1 text"
    would update the content trol with the title 'Control1' on the first page and:
    ActiveDocument.SelectContentControlsByTitle("Control1").Item(2).Range.Text = "Page 2 text"
    would update the content trol with the title 'Control1' on the second page


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Friday, October 3, 2014 10:37 AM

All replies

  • You are having trouble getting the bookmarks form words?

    IMO this forum http://social.msdn.microsoft.com/Forums/en-US/home?forum=worddev may be helpful, and you'd better separate it to the one how to get bookmarks from word selection.


    remember make the reply as answer and vote the reply as helpful if it helps.

    Friday, October 3, 2014 9:50 AM
  • The problem you're having is due to the fact that a bookmark can only exist in one location in a document. So, when you copy the page multiple times, the bookmark doesn't get copied - it stays on the first page only. Perhaps the simplest solution is to either:
    a) update the bookmarks for the first day, replicate the page to make the second page (e.g. via .FormattedText), repeating the process until all are done, then delete the first page; or
    b) create a separate document for each day, update the bookmarks for that document, then combine all the documents when you're done.

    Another approach would be to use content controls, via their titles in place of the bookmarks. You could then replicate the page as many times as you need, then refer to the content controls via the SelectContentControlsByTitle method.For example, in VBA:
    ActiveDocument.SelectContentControlsByTitle("Control1").Item(1).Range.Text = "Page 1 text"
    would update the content trol with the title 'Control1' on the first page and:
    ActiveDocument.SelectContentControlsByTitle("Control1").Item(2).Range.Text = "Page 2 text"
    would update the content trol with the title 'Control1' on the second page


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Friday, October 3, 2014 10:37 AM
  • I have had similar problem some years ago, when I had to create a report where one page contained complex set of data, related to one order. Then in case of several orders this page should have been repeated for each order.

    I prepared a template for the order report page and created bookmarks where the data would be placed.  Then I wanted to fill this report programmatically with data. I was using VBA at the time to populate the word template. I have had similar issue as you - the bookmarks disappeared after the second page has been added.

    At about the same time I evaluated some toolkits for merging templates and data in Word, trying to find a solution for my order report. At the end I chose Docentric toolkit mainly because of their support which was very helpful in advising me how to prepare a template and how to fill it up with data in C# application (or VB.NET if necessary).

    SO WHAT I HAD TO DO?

    1. I created a VisualStudio 2010 project where I created a class which represented view model for the report. This class represents data object, which would be bound to the report template at runtime.
    2. I filled this view model with data from the database.
    3. I prepared a console application with command line parameters which represent criteria for the data selection and input template and output document file names. In this console application I called the method for document generation. This method actually does the merging and output document creation.
    4. I prepared a visual layout of template. That was easy, because I already had a template from previous application. I only had to remove bookmarks.
    5. Next I inserted Docentric content placeholders (elements). The first one was list element, which contained entire page and would be repeated for each record on a new page. The order layout was then included in this list element.
    6. I inserted field elements for every database data field. This was similar to placing bookmarks in the old system, except that field elements are visible on the template.
    7. Data in one-to-many relationships - like order items - are placed in nested tables (again via list elements).

    that was all that needed to be done. It took me a couple of days to set it up and running and there were absolutely no issues with it later.

    In the mean time we upgraded from Office 2007 to Office 2010 and now some users are using Office 2013. The original templates still work without any modifications.

    The things that I like in this toolkit are:
    - simple Word Add-in for template generation
    - based on OpenXML so it can run on the server and doesn't need Word installed on the server
    - supports images, tables and data-bound graphs
    - allows conditional elements in templates
    - placeholders can be placed in headers and footers
    - very fast final document generation.

    The things that still need some improvement are some visual styling issues (checkboxes on templates could look more intuitive, cell widths in tables with field placeholders are sized on placeholder element name width until runtime, pdf output is not yet supported for all elements).

    Our newly developed applications are now using reports prepared in this way with great success.









    Tuesday, December 16, 2014 7:51 PM