Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Images and Mailmerge

Status
Not open for further replies.

Remou

Technical User
Sep 30, 2002
13,030
BE
I am not quite sure if this is a question, in that someone may well suggest something much better, or a helpful hint, in that it seems to work.

Code:
Option Compare Database
Option Explicit

'The problem with putting images in a mailmerge from Access is that you
'have to update each image after the mailmerge has run, which is tedious.
'I needed to include pictures in textboxes for identity cards, which
'was even more tedious to update, so I found some code in various
'places in Tek-Tips. In addition, I used:
'Mail merge includepicture doesn't work!
'thread68-1275181
'when setting up the document.

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function ShowWindow Lib "user32" _
    (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function GetWindow Lib "user32" _
    (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
    (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Public Const SW_SHOW = 5
Public Const GW_HWNDNEXT = 2

Sub TestIt()
Dim strPath As String
Dim strDataFile  As String
Dim strWordFile  As String
    strPath = "C:\CertTemplates\"
    strDataFile = "Data.txt"
    strWordFile = "Doc.doc"
    RunMailmerge strPath, strDataFile, strWordFile
End Sub

Public Sub RunMailmerge(MergePath As String, MergeDataFile As String, MergeDocFile As String)
'This is a very much cut down version of PSeale's code, which can be found in full
'here:
'Native' mailmerge reports - as painless as possible
'faq181-5088
'I hope I will be forgiven.

On Error GoTo Sub_Error
    Dim objWordDoc As Object
    Dim objWordDocX As Object
    Dim strDir As String

    Set objWordDoc = GetObject(MergePath & MergeDocFile, "Word.Document")
    
    objWordDoc.Application.Visible = True
    
    'Format:=0 '0 = wdOpenFormatAuto
    objWordDoc.MailMerge.OpenDataSource _
        Name:=MergePath & MergeDataFile, ConfirmConversions:=False, _
        ReadOnly:=False, LinkToSource:=True, AddToRecentFiles:=False, _
        PasswordDocument:="", PasswordTemplate:="", WritePasswordDocument:="", _
        WritePasswordTemplate:="", Revert:=False, Format:=0, _
        Connection:="", SQLStatement:="", SQLStatement1:=""

    With objWordDoc
        .MailMerge.Destination = 0 '0 = wdSendToNewDocument
        .MailMerge.Execute
        FindFormLetters
    End With

Sub_Exit:
On Error Resume Next
    'Word pops up a messagebox to confirm saving the document,
    'even if specifically set it to "wdDoNotSaveChanges".
    'Therefore first save the document, then close it.
    objWordDoc.Save
    objWordDoc.Close SaveChanges:=-1 '-1 = wdSaveChanges
    
    Set objWordDoc = Nothing
    'attempt to delete file, silently fail on errors.
    'FileSystem.Kill strMailmergeDataFilename
    
    Exit Sub
    
Sub_Error:
    If Err.Number = 432 Then
        MsgBox "ERROR: Invalid filename provided: '" & MergeDataFile & "' or " & _
        "'" & MergePath & MergeDocFile & "'."
    Else
        MsgBox Err.Description
    End If
    Resume Sub_Exit
End Sub

Sub FindFormLetters()
Dim WinHandle As Long
Dim astrWindows As Variant
Dim varLetterNo
Dim i, j
Dim objWordDoc As Object
Dim SH

'This is all a bit shaky
'First, how many letters have been run
astrWindows = Split(FindWindowPartial("Form Letters"), "|")

'Get the most recent (this will only work up to 9)
varLetterNo = 0
For i = 0 To UBound(astrWindows)
    If Mid(astrWindows(i), 13, 1) > varLetterNo Then
        varLetterNo = Mid(astrWindows(i), 13, 1)
        j = 1
    End If
Next

'I am sure this could be tidied up
'Return the handle ...
WinHandle = FindWindow(vbNullString, astrWindows(j))
    
'and use it ...
ShowWindow WinHandle, SW_SHOW

'to get the word document.
Set objWordDoc = GetObject(, "Word.Application")

With objWordDoc
'Print View
    If .ActiveWindow.View.SplitSpecial = 0 Then '0=wdPaneNone
        .ActiveWindow.ActivePane.View.Type = 3 '3=wdPrintView
    Else
        .ActiveWindow.View.Type = 3 '3=wdPrintView
    End If

'The code is modified fro SkipVought's post in:
'Replace not working in VBA - Word 2000
'thread68-794360
'Search though the textboxes in the document updating the pictures
   For Each SH In .ActiveDocument.Shapes
        SH.Select
        With .Selection.Find
            .Text = "^g"
            .Forward = True
            .Wrap = 1 '1=wdFindContinue
            .Format = False
            .MatchCase = False
            .MatchWholeWord = False
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False
        End With
        .Selection.Find.Execute 'Replace:=wdReplaceAll
        .Selection.Fields.Update
    Next
End With

Set objWordDoc = Nothing
End Sub

Function FindWindowPartial(ByVal Title As String) As String
'The code is modified from Hypetia's post in:
'Find Handle - Class/Window Name Changes
'thread711-710383

    Dim hWndThis As Long
    hWndThis = FindWindow(vbNullString, vbNullString)
    While hWndThis
        Dim sTitle As String, sClass As String
        sTitle = Space$(255)
        sTitle = Left$(sTitle, GetWindowText(hWndThis, sTitle, Len(sTitle)))
        If InStr(sTitle, Title) > 0 Then
            FindWindowPartial = sTitle & "|" & FindWindowPartial
        End If
        hWndThis = GetWindow(hWndThis, GW_HWNDNEXT)
    Wend
End Function
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top