• How to insert a logo using VBA (Office XP, Word 2002 SP-2)

    Home » Forums » AskWoody support » Productivity software by function » MS Word and word processing help » How to insert a logo using VBA (Office XP, Word 2002 SP-2)

    Author
    Topic
    #390466

    Our templates contain a company logo. The company changes logo now and then (unfortunately) and would like to be able to insert a new logo (picture/.gif, .tif file) by e. g. using a command placed in a user form. the file representing the logo should be placed in the …Workgroup-templates folder on the C-drive.

    I think it should be done by placing a “field code” representing the place on the document where I want the logo to be placed. So how can I make this possible in VBA?

    Thanks in advance.

    regards
    Bjorn

    Viewing 0 reply threads
    Author
    Replies
    • #693679

      What you could do is place the logo in the template by Insert | Picture | From File…, browse to the logo file, then click the dropdown arrow next to the Insert button and click Insert and Link. Next, select Edit | Links… and lock the link, so that it won’t be updated. Since the logo has been inserted, it will be available even on computers on which the logo file is not available.

      When you need to update the logo, replace the original logo with a file of the same name. Use code to unlock the link, update it and lock it again. For example:

      With ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.Fields(1)
      .Locked = False
      .Update
      .Locked = True
      End With

      You will have to adapt this to your situation.

      • #693874

        Thanks HansV

        I will try this asap.

        It is amazing how often companies change their logo now adays.

        Bjorn

        • #693882

          Bjorn,

          Just to clarify: do you need to update the logos in the templates only (Hans’ method should do fine), or do you need to give the user the option to update an existing logo in some existing documents? – the latter scenario would take more doing.

          Gary

          • #693910

            Thanks Gary,

            Yes I do; Our documents has a logo inserted to day. I plan to make a new template such that the logo will be inserted (automatically) when I create a new document. Then the logo is placed in the document and can be viewed on any computer.

            If the company logo is changed at a later time the user should be able to insert (click a button) the new logo and thus replace the old one at the same place.
            I would very much appreciate a code to do so!!

            Bjorn

            • #693913

              Bjorn,

              I think you can use the method I proposed for this: if you insert the logo with Insert and Link, the image will be stored in the document itself, so that it can be viewed and printed on any computer, but it still “knows” where the original file was, so that it can be updated if needed.

              You could put the code snippet I posted to get the up-to-date logo into a macro in a general module in the template.

              You can call this macro in the Document_New macro in the ThisDocument module of the template, so that a new document always gets the current logo.
              You could also make the macro available through a custom toolbar button, keyboard shortcut and/or custom menu item (all stored in the template), so that the user can update an existing document if needed.

              If you need to move the logo file to another folder, this won’t work. Take a look at macropod’s Star Post Update paths in INCLUDETEXT et al. (Word 2000/XP) for a way to update the path of a linked image.

            • #693923

              Thanks HansV,

              I will try this out as soon as I get some time free. Though I’m not sure how the insert macro knows where to put the new logo? Or does it know through the code?

              bjorn

            • #693948

              Bjorn,

              My idea was to place the logo in the template where you want it (probably in a header or footer) “by hand”. After that, it would only be updated by the macro I proposed, not deleted and inserted anew. You would have to modify ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.Fields(1) to make the macro update the correct field – in this example, it is the first field in the first-page header in the first section; change this according to your situation.

            • #693960

              Thanks HansV,
              Correct I have my logo in the Header.

              As I understand it, it is the term Fields(1) that “knows” where the picture/object is located and which picture/object it is and thus can replace it.
              I also understand that logos in other sections are controlled through the term Sections(1).

              What if I have another logo/picture in the text?

              How can I know which number the logo/picture has got, if there are several pictures?

              Thanks for quick answers!!!

              Bjorn

            • #693981

              Bjorn,

              If you have several fields in the header, you can loop through them and test if they are of type msoIncludePicture (the type of field inserted when you link a picture):

              Dim i As Long
              Dim rng As Range
              Set rng = ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range
              For i = 1 To rng.Fields.Count
              If rng.Fields(i).Type = wdFieldIncludePicture Then

              End If
              Next i

              You’d have to repeat this for other headers and other sections if necessary; you can loop through them if you like.

            • #693985

              Thanks Hans,

              I shall try this.

              Here it is the end of the day and I will be on work tomorrow again.

              Thanks a lot for very good help!!!

              Regards
              Bjorn

      • #694320

        Hi,

        I have tried this, but the update function does not work. I get the link unlocked and locked again when running through the code but nothing happens with the .UPDATE

        My code is as follows:

        Private Sub UpdateLogo()
        With ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.Fields(1)
        .Locked = False
        .Update
        .Locked = True
        End With
        End Sub

        What am I missing?

        bjorn

        • #694343

          Hello Bjorn,

          The code that I posted earlier was just an example. As it is, it looks at a field in the first page header. Does the first section in your document have a “different first page” header? Check this in File | Page Setup…, Layout tab. If you just have a single header, use wdHeaderFooterPrimary instead of wdHeaderFooterFirstPage.
          Also, did you insert the logo with Insert and Link?

          If I change the picture file and then run the macro in my test document, the logo in the header does get updated, so the code itself is OK…

          • #694454

            Hi,
            I have “different first page” header. Have tried with both “wdHeaderFooterFirstPage” and “wdHeaderFooterPrimery”. Have also tried after I made a section continuous break.

            I inserted with Insert/Picture/From File and then used “Insert and Link”. Then I did as you said; opened Edit/Links… , Locked it and “OK”.
            I replaced the picture file with a different picture with the same name.

            I can watch that the link for the picture is being unlocked and locked again, but the picture is not updated.

            I’ll try more this night and see what I can come up with.

            Thanks Hans, you’re a patient person!

            Bjorn

          • #694479

            Hi Hans,

            I have tried more and now it looks as it will work. It is a matter of choosing “FistPage” or “Primary” or rather the correct property.

            I had to use FirstPage for the first page section 1 which is defined as “different first page”.

            Anyway, hope I have the principles ready for a real trial tomorrow on the documents that need to be supplied with a new logo.

            Thanks a lot for your help!

            Regards
            Bjorn

          • #695259

            Hi Hans,

            I have forgotten to say that my template contains several CustomProperties, but only two are with a logo of type “INCLUDEPICTURE” or wdFieldIncludePicture. According to “Fields.Count” the template has 37 fields. They are not all different but repeated on the next page. Some, like PAGE and NUMPAGES are of the Builtin type.

            I have tried and it looks as the code will function OK until one field does not exist. Then I get an error and I cannot find out how to get further when a field does not exist. I get “Run time Error 4951; The requested member of the collection does not exist”.

            I presume that if I delete a field, say no. 4, the reult is only that the Fields.Count is one less, totaly.

            My code is now like this (the LOCK/UNLOCK is remmed out (disabled) for testing reasons):

            Private Sub UpdateLogo()
            Dim sec As Section
            Dim i As Integer
            Dim j As Integer
            Dim rng1 As Range
            Dim rng2 As Range
            Dim AmountFields As Integer
            Dim EndOfFields As Boolean

            For i = 1 To Fields.Count
            Set rng1 = ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range

            ‘ Looking in the first page header when “Different first page” is set and no section exist:
            With ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.Fields ‘(1)
            If rng1.Fields(i).Type = wdFieldIncludePicture Then
            ‘ MsgBox “nr. ” & i & ” is a linked picture logo”
            ‘ .Locked = False
            ‘ ‘ .Update
            ‘ .Locked = True
            End If
            On Error GoTo LastField
            End With
            Next

            LastField:
            MsgBox “This field is the last field in this section or first page: ” & i
            Err.Clear

            For i = 1 To Fields.Count
            Set rng2 = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range

            ‘ Looking in the next page header when “Different first page” is set and no section exist:
            With ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range.Fields ‘(1)

            On Error GoTo LastField2
            If rng2.Fields(i).Type = wdFieldIncludePicture Then ‘ here the error message pops up when the next field does not exist
            MsgBox “nr. ” & i & ” is a linked picture logo”
            ‘ .Locked = False
            ‘ ‘ .Update
            ‘ .Locked = True
            End If
            On Error GoTo LastField3
            End With
            LastField2:
            Next
            LastField3:
            Err.Clear
            End Sub

            When the running comes to the field which do not exist the code “On Error GoTo LastField2” does not respond. Neither does “On Error Resume Next”.

            So I can’t find out how to test whether a field exist or not in order to jump over the non existing field. It works for the first section, it jumps over when there are no more fields on the first page.

            Any code I can use to come across this problem?

            regards a hopefull
            bjorn

            • #695261

              Hi Bjorn,

              You can’t do this:

              For i = 1 To Fields.Count
              Set rng2 = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range

              If rng2.Fields(i).Type

              A Word document consists of several parts, each of which has its own Fields collection. The main document is one of them, and if you use Fields without further qualification, you get the Fields collection of the main document. But each header and footer of each section has its own collection of fields; they are not counted in the collection of fields of the main document. So you are trying to loop through the fields in the header using the count of the fields in the main document.

              Instead, you must do something like the following:

              Dim sec As Section
              Dim hdr As Header
              Dim rng As Range
              Dim i As Integer

              For Each sec In ActiveDocument.Sections
              For Each hdr In sec.Headers
              Set rng = hdr.Range
              For i = 1 To rng.Fields.Count

              Next i
              Next hdr
              Next sec

            • #695305

              Thanks Hans

              This works much better though I probably have to recode the With sentence(?). My code then looks like:

              For Each sec In ActiveDocument.Sections
              For Each hdr In sec.Headers
              Set rng = hdr.Range
              For i = 1 To rng.Fields.Count
              If rng.Fields(i).Type = wdFieldIncludePicture Then
              ‘ MsgBox “nr. ” & i & ” is a linked picture logo”
              With ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.Fields ‘ This may be wrong
              .Locked = False
              .Update ‘ This does not function
              .Locked = True ‘ checking Edit/Links show that only the first one is unlocked and locked
              End With
              End If
              Next i
              Next hdr
              Next sec

              As I can see, my document does not have any sections and therefore the With sentence may have to change.

              Bjorn

            • #695327

              Bjorn,

              Your statement “my document does not have any sections” is not quite true – a document always has at least one section. The code might be simplified a bit for that case, but on the other hand, keeping the For Each sec In ActiveDocument.Sections doesn’t generate a lot of overhead if there is just one section, and it will make your code easier to re-use in multi-section documents in the future. Here is the revised code, using the rng.Fields collection instead of explicitly referring to the first section in the loop:

              For Each sec In ActiveDocument.Sections
              For Each hdr In sec.Headers
              Set rng = hdr.Range
              For i = 1 To rng.Fields.Count
              With rng.Fields(i)
              If .Type = wdFieldIncludePicture Then
              ‘ MsgBox “nr. ” & i & ” is a linked picture logo”
              .Locked = False
              .Update
              .Locked = True
              End If
              End With
              Next i
              Next hdr
              Next sec

            • #695336

              Thanks again,

              I can check that the links are unlocked and locked again, so that means the correct field codes are found, but the Update does not work.

              My code is now like:

              For Each sec In ActiveDocument.Sections
              For Each hdr In sec.Headers
              Set rng = hdr.Range
              For i = 1 To rng.Fields.Count
              With rng.Fields(i)
              If .Type = wdFieldIncludePicture Then
              .Locked = False
              .Update
              .Locked = True
              End If
              End With
              Next i
              Next hdr
              Next sec

              I have checked the path and name of the logo file and it is exactly the same with the logo that shall replace the “old” ones.

              (Why do not the indented code lines show as indented in the Post?)

              Bjorn

            • #695344

              Bjorn,

              I am very sorry but I don’t know what goes wrong. It works for me, I just tested it again to make absolutely sure. I copied the code from this thread into a new macro in the Visual Basic Editor, and only added declarations (I have Option Explicit, so I must declare all variables). I put some pictures into the header with Insert and Link, and locked them. Then I replaced the pictures on disk with different ones having the same name. Running the macro replaced the old pictures in the header with the new ones…

            • #695362

              I hope I’m not driving you crazy!!

              (I also use Option Explicit)

              I’m using F8 to step through every line and it looks like the Update works, but …

              The field with the link looks like this:

              {INCLUDEPICTURE “../Program Files/OfficeTemplates/Word/Workgroup-templates/LogoBWA4PortrLong.tif” * MERGEFORMATINET}

              (The logo is replaced with a logo with colors, but I have given it the same name, so it should not be anything wrong with the link.
              The character is inserted by Windows when a name contains a space )

              The procedure is placed in ThisDocument.

              Well, I have to look for any small differences that might not be easy to see.

              My code now looks like this:

              Sub UpdateLogo()
              Dim sec As Section
              Dim hdr As HeaderFooter ‘ Had to dim it as HeaderFooter
              Dim i As Integer

              Dim rng As Range

              For Each sec In ActiveDocument.Sections
              For Each hdr In sec.Headers
              Set rng = hdr.Range
              For i = 1 To rng.Fields.Count
              With rng.Fields(i)
              If .Type = wdFieldIncludePicture Then
              MsgBox rng.Fields(i)
              .Locked = False
              .Update
              .Locked = True
              End If
              End With
              Next i
              Next hdr
              Next sec
              End Sub

              Thanks Hans

            • #695368

              Ah! You’ve given away a valuable clue! In my own test document, I used the absolute path to the images, while you use a relative path. I can’t explain why, but the macro doesn’t update the images for me either when I use a relative path. Would it be very annoying for you to use absolute paths?

              Note: in an absolute path, you must use double backslashes as separators; Word will put these in automatically if you insert an image that is not in a path directly related to the current one, but if you change the field codes yourself (for examply by search and replace), you must take that into account. Example:

              { INCLUDEPICTURE “C:PicturesLogo.tif” } or { INCLUDEPICTURE “serversharefolderLogo.tif” }

            • #695373

              Well,

              In my template the link looks like this:
              {INCLUDEPICTURE “C:Program FilesOfficeTemplatesWordWorkgroup-templatesLogoBWA4PortrLong.tif” * MERGEFORMATINET}

              but in the document I have made with the template it looks like this:
              INCLUDEPICTURE “../Program Files/OfficeTemplates/Word/Workgroup-templates/LogoBWA4PortrLong.tif” * MERGEFORMATINET

              Why that occurs I don’t know. The document is located in a test-folder.

              I read something about updating links the other day, but can’t recall where.

              Bjorn

            • #695376

              If I save the document in the same directory as where the template is located, the Update functions OK. The link then looks like this:
              {INCLUDEPICTURE “../Word/Workgroup-templates/LogoBWA4PortrLong.tif” * MERGEFORMATINET}

              The difference I can see is that the whole path from ../Program Files/OfficeTemplates are not shown here.

              May be the link must be updated before unlocking or Update (??)

              Bjorn

            • #695380

              I don’t think you would want to store the documents in the same folder as the template except in a test environment. What happens if you put the pictures in a path that is not directly related to that of the template, for instance on another drive?

            • #695383

              You’r right,

              The document I create from the template can be stored anywhere and specially in our company it will be sstored in SharePoint and that I haven’t deared to test yet.

              The fact is that when creating a document the link will not be an absolute path even it is locked???
              May be it must be inserted another way?

              Bjorn

            • #695385

              In my test (template somewhere on C:, logo files somewhere on a network drive named F:), the path in the INCLUDEPICTURE field isn’t altered when I create a document based on the template, and the macro (stored in the template) works as it should in the document. So the main point seems to be that you must avoid placing the logo files in a path that can be converted to a relative path with respect to the template.

            • #695387

              Seems you have found the reason, but

              “avoid placing the logo files in a path that can be converted to a relative path”

              where could that be? what type of places cannot be converted to a relative path?
              I have stored the logo-files in the same director as the template, on C:Program FilesOfficeTemplatesWordWorkgroup-templates as you have seen in the links.

              Bjorn

            • #695390

              Bjorn, would it be possible to store the logo files on a network drive?

            • #695401

              Yes,

              I located the logos on a common drive and saved the document on C: and it worked. The link looks like:
              INCLUDEPICTURE “S-osl-23-0004FTemplates.TESTWorkgroup-templatesLogoBWA4PortrLong.tif” * MERGEFORMAT

              which is the same as saving the document in SharePoint, also shows that the locked link changes to:
              {INCLUDEPICTURE “S-osl-23-0004FTemplates.TESTWorkgroup-templatesLogoBWA4PortrLong.tif” * MERGEFORMAT}

              which again is the same as in the template, which looks like this:
              INCLUDEPICTURE “S-osl-23-0004FTemplates.TESTWorkgroup-templatesLogoBWA4PortrLong.tif” * MERGEFORMAT

              Looks as the problem is solved so far! I shall do other tests tomorrow to be quite sure.
              Now its late (17:29) and time to go home.

              Thanks Hans
              You have done a tremendously good Work, I really do appreciate this!!
              Saved me many hours!
              Thanks again.

              Best regards
              Bjorn
              (Bj

            • #696750

              Hi,
              A got a new challenge:

              I want make it possible to toggle between hide and show the picture.

              How can I get hold of the INCLUDEPICTURE field and hide it such that it is not visible on the screen/printout?

              Bjorn

            • #696757

              Format it as hidden. something like this (you may have to finetune it)

              Sub ToggleLogos()
              Dim sec As Section
              Dim hdr As HeaderFooter
              Dim fld As Field
              Dim rng As Range

              For Each sec In ActiveDocument.Sections
              For Each hdr In sec.Headers
              Set rng = hdr.Range
              For Each fld In rng.Fields
              If fld.Type = wdFieldIncludePicture Then
              With .InLineShape.Range.Font
              .Hidden = Not .Hidden
              End With
              End If
              Next fld
              Next hdr
              Next sec

              Set fld = Nothing
              Set rng = Nothing
              Set hdr = Nothing
              Set sec = Nothing
              End Sub

            • #696794

              Thanks a lot Hans,
              I may be able to test it during the week end (?)

              As you understand I’m not an experienced programmer, rather an amateur.

              If I get this working it solves a lot of problems.

              Again thanks!

              Bjorn

            • #697489

              Hi,

              Thanks again for great help. Here, just for your information (F.Y.I) my code ended this way:

              Sub ToggleLogosOnOffNo()
                  Dim cmdToggleLogosText As String
                  Dim sec As Section
                  Dim hdr As HeaderFooter
                  Dim fld As Field
                  Dim rng As Range
              
                  For Each sec In ActiveDocument.Sections
                      For Each hdr In sec.Headers
                          Set rng = hdr.Range
                          For Each fld In rng.Fields
                              If fld.Type = wdFieldIncludePicture Then
                                  With fld.InlineShape.Range.Font
                                      .Hidden = Not .Hidden
                                  End With
                              End If
                          Next fld
                      Next hdr
                  Next sec
                      If cmdToggleLogosOnOff.Caption = "Gjem Logoer" Then
                              cmdToggleLogosOnOff.Caption = "Vis Logoer"
                              ActiveDocument.CustomDocumentProperties("LOGOSVISIBLE") = False
                          Else
                          cmdToggleLogosOnOff.Caption = "Gjem Logoer"
                          ActiveDocument.CustomDocumentProperties("LOGOSVISIBLE") = True
                      End If
              
                  Set fld = Nothing
                  Set rng = Nothing
                  Set hdr = Nothing
                  Set sec = Nothing
              End Sub
              

              The only adjustment was to write “fld.InlineShape.Range.Font”, i.e. I had to add fld.

              Also have added a command button that changes according to status of the visuability of the logo.

              (Hope the pre-tagging works. Got a message to change if lines are too long. It looks OK)

              Have an effective day

              Bjorn

            • #695406

              [indent]


              (Why do not the indented code lines show as indented in the Post?)


              [/indent]If you use pre tags in your post, the formatting (indenting) will be preserved. i.e. use

              then all your VBA text & then 

              Cheers,

            • #695407

              Thanks Phil1
              I will do so next time.

              Regards
              Bjorn

    Viewing 0 reply threads
    Reply To: Reply #696750 in How to insert a logo using VBA (Office XP, Word 2002 SP-2)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information:




    Cancel