locked
Howto: Easily change a Date field in the Header RRS feed

  • General discussion

  • I've became real fond of Word 2010 and I'm totally amazed at the things I can do using VBA. As such I decided to share another of my findings, hoping that it might be able to help someone.

     

    So; I've designed a template (backed up with VBA macro's obviously) which can be used to create standard letters, offers and bills. Not sure if this phenomenon is known in other countries; but if a sent bill gets 'revoked' (either because the customer doesn't want the product anymore or something else has changed) its custom here to sent out a so called "Credit note". Basically a "counter-bill"; proof for both administrations (the customers and yours) that the previous sent bill is no longer valid and doesn't need to be paid.

    The beauty here is that documents which are made using a template remain 'linked' to it (and its containing vba code). SO it was only logical (IMO) to add a procedure which could change a bill into a "credit note" (after all; its basically the same bill with a disclaimer explaining the refund or the no longer existing obligation to pay). Thus you open the original document, press the key combo and presto: its changed.

    One problem: the date field. Obviously the original date field is set to reflect the document's create date in order to prevent accidental updates. But since a 'credit note' is basically a new document we need this field to reflect the current date yet without risking future updates since this too will become an official document.

    One solution that I came across online was to use the .select method on the field, then insert a new field using the .InsertDateTime method (optionally supplying a date layout as well). Because this also changes Word's view (when in print view) it was followed by "ActiveWindow.View.Type = wdPrintView" which would reset the view back to the original Print view.

    It works, but I didn't like it ;-)

    Here's what I came up with...

    The first thing to realize is that a Date field is basically a small piece of "template code". Select a field, press alt-f9 (or use the pop-up menu to change the "field view") which will show it. The beauty here is that we can access this "template code" from within VBA as well!

    So...  Open up the VBA editor (alt-f11), go to the (invaluable) 'direct' window (control-g) and try it yourself:

    print ActiveDocument.Sections.First.Headers(1).Range.Fields(1).Code

    This will print the code of the first field in the header, so in my case:

     CREATEDATE  \@ "dd MMM yyyy"  \* MERGEFORMAT

    Notice the "date layout template" which makes sure that the date gets shown as (in this example) "08 Nov 2011".

    Now, what I want to do is to turn this 'create date' into the current date and then prevent it from updating while retaining the current layout. While I could try to split the code manually I decided to keep it simple and change the date and supply the required format as well (because I always use this specific format):

    ActiveDocument.Sections.First.Headers(1).Range.fields(1).Code.Text = "TIME \@ DD\ MMM\ YYYY"

    Take special note of the \'s here. These are so called escape characters. Used to tell the VBA interpreter to ignore the next character as far as parsing is concerned. In other words: use the next character in its literal form. As such it will know that the @ and the spaces are all still part of the field code. While the VBA editor will recognize that the String hasn't ended (due to the not-yet-encountered " character) the Date field will have no such knowledge and won't be able to grok the first space. Just try it yourself by removing the \'s, see what happens.

    What's that?  "NO error what so ever, what's the problem mate?"

    Simple, for that you need the next step..  After changing the code of a Field this change won't become visible right away. You need to update it, like so:

    ActiveDocument.Sections.First.Headers(1).Range.fields(1).Update

    Now you'll either see the current date, or you'll see an incomplete date or maybe even an error if you started playing with the \ characters.

    What we basically did here was change the field which displayed the documents create date into a field which displays the current time. Obviously this is going to pose a problem if you open this document again after a few days (I know; not if you don't update the field. But would you risk that?).

    So the final step here is to unlink the time field which we created. This will basically change the field into the static text which is currently displays. That can be done like this:

    ActiveDocument.Sections.First.Headers(1).Range.fields(1).Unlink

    And now we're done. We changed the CREATEDATE field into a TIME field, updated it so that it would display our changes and then made those changes permanent by unlinking it.

    Right...  Long story, hope it might be helpful to someone. Of course I did search the forum prior to posting this and couldn't find anything specific like it, so here you go.

     


    With kind regards, Peter
    Wednesday, November 9, 2011 4:13 AM

All replies

  • Thank you very much for the sharing!


    Sincerely,

    Max Meng
    Forum Support


    Come back and mark the replies as answers if they help and unmark them if they provide no help.
    If you have any feedback on our support, please contact tnmff@microsoft.com.

    Thursday, November 10, 2011 8:44 AM