Changing a Word Mail Merge Field in C#

The mail merge fields in Microsoft Word are actually just a specific type of the more general Fields. Fields can be used to make fill-in forms, autogenerated text, dates, etc… They typically are displayed surrounded by funny looking square brackets, like <<first_name>>.

Inside the Word Xml, the Field and the display value are stored separately – the field looks like “ MERGEFIELD User_Title “, then in a separate range, the display of “«User_Title»” is stored.

Using the Word Object Model, Document.MailMerge.Fields contains MailMergeField objects for each instance of a merge field. The .Code member contains the range object, of which the .Text member will contain the field code (aka “ MERGEFIELD User_Title “). If you do a replace on this text field, it will update the merge field, but the display will remain the same.

You next have to call Document.Fields.Update() to get the display matching.

Here is some code:

        private void RenameMergeField(Word.Document doc, string oldName, string newName)
        {
            foreach (Word.MailMergeField field in doc.MailMerge.Fields)
            {
                if (field.Code.Text.Contains(oldName))
                {
                    field.Code.Text = field.Code.Text.Replace(oldName, newName);
                }
            }
            doc.Fields.Update();
        }

The world will end on August 31, 4500 at 11:58 pm

According to Outlook 2010, the world will end on August 31, 4500:

 

image

As you can clearly see, September 1, 4500 will not exist.

 

Additionally, it appears 11:59pm will not exist either, so be sure to get your affairs in order before 11:58pm.

image

 

Consider yourself warned.

Office 2013 isn’t just sluggish and monochromatic

Office 2013 Preview isn’t just sluggish and single-colored to the point of being depressing:

I’m pretty sure this might be the most features removed from a release of Office. Have a look here – it’s downright depressing…

Changes in Office 2013 Preview

Notice the large number of features removed with no compelling reason. At least one feature (broadcasting powerpoint presentations) was removed so they could try to force you to pay for Lync.

Why Microsoft, why?

How to uninstall MSDAIPP (Web Folders) from Windows 7

We had a Windows 7 workstation that was exhibiting “wonky” behavior when opening SharePoint folders in Office 2010 Word (and explorer in general). When it was supposed to open the save-as dialog to a SharePoint folder, it would instead show the default “My Document” folder. You could still enter a SharePoint url, and it would load correctly, but the initial dialog refused to open SharePoint.

Using Fiddler2 I was able see that the problem computer was using a different WebDAV client than the working workstations from the User-Agent in the requests. The first request is identical:

OPTIONS http://sharepointserver/doclib/ HTTP/1.1
User-Agent: Microsoft Office Protocol Discovery
Host: sharepointserver
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

 

But the second request is all kinds of different.

Normal Workstation:

OPTIONS http://sharepointserver/ HTTP/1.1
User-Agent: Microsoft-WebDAV-MiniRedir/6.1.7601
translate: f
Connection: Keep-Alive
Host: sharepointserver

 

Problem Workstation:

OPTIONS http://sharepointserver/ HTTP/1.1
User-Agent:
Microsoft Data Access Internet Publishing Provider Cache Manager
Host: sharepointserver
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache
Cookie: WSS_KeepSessionAuthenticated={164a5252-50a4-4112-9e22-ae36dfsdddc}

 

The next request gets even weirder:

Continue reading

Outlook 2010 Check Names ignores Contacts

After my most recent reinstall of windows, for some reason Outlook 2010 stopped looking in my Contacts when I would hit Check Names. It was only looking in the Global Address Book. I would have to look up the person in my contacts, and Outlook would autocomplete until it was restarted.

Lame.

The solution is here: Outlook 2010: How to change your default Contacts Address Book

I changed mine to be custom so it would look in both the global address book (containing the employee list) AND my contacts. And it’s working.

Now to figure out why the autocomplete gets reset every time I close and reopen…

Paragraph formatting, new lines and bullet lists in Word Rich Text Content Controls

Every since who knows when, Microsoft Word has had Form Fields that allow you to create a fill-in form using Word. Trouble is, unless you protect the document, people rarely end up placing the text in the correct box – or they might delete the field altogether.

So you protect the document. Now spell checking doesn’t work, the arrow keys don’t work right, it is difficult to select text, no formatting, and… well it’s just plain bad.

As of Word 2007 and Word 2010, there is a better solution called Content Controls – accessed from the Developer tab. The Rich Text content countrol allows for formatted text without messing up the surrounding document, and (if you do it right) supports spell checking. The trick is to use grouping instead of document protection. (Create your document, select everything, and group it from the developer tab. The document cannot be edited, except for the content controls)

This is great, but we ran into a mystifying problem with the Rich Text content control – in our existing document, it was not creating new lines when you pressed the return / enter key. You could hold shift-enter to get a new line, but then you could not create bulleted lists. We tried creating a new word document and adding a rich text control, and it worked fine – it seemed to be a problem with our existing document.

The solution: The rich text control does not allow sub-paragraphs when it is not the only thing in a paragraph. Place the content control in it’s own paragraph in the word document, and it will allow bulleted lists, new paragraphs, formatting, etc.

Office 2010 Backstage OnShow callback contextObject

The signature for the Office 2010 backstage OnShow callback looks like so:

void Backstage_OnShow(object contextObject)

But I cannot find anywhere that documents what the contextObject is.

Well I can tell you – it’s the Window object that is hosting the backstage as shown. I’m guessing it’s an object because it will be the equivalent Window object in whichever Office application happens to be running.

Undocumented Office Ribbon Callback functionality

I just stumbled on an undocumented feature of the getImage callback for the Office 2010 Ribbon (well, backstage actually)

The “official” callback signature is

Public System.Drawing.Bitmap GetImage(Office.IRibbonControl control) {}

Or sometimes

Public stdole.IPictureDisp GetImage(Office.IRibbonControl control) {}

I don’t know which is “best”, but if you return a Bitmap it sure is easier to work with.

Now back in Office 2007 there are a couple controls with a GetImageMso callback that allows you to provide an Office Control ID for a built-in image. This is lacking from any 2010 backstage controls.

Whilst doing some unpleasant native debugging to try to “figure out” what office expects in these callback delegates, I tried creating a GetImage callback that returned a string.

<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
  <backstage>
    <tab id="MyTabShare" label="Testing">
      <firstColumn>
        <group id="MyGroup">
          <topItems>
            <imageControl id="imageControl1" getImage="GetImage"/>
          </topItems>
        </group>
      </firstColumn>
    </tab>
  </backstage>
</customUI>
        public string GetImage(Office.IRibbonControl control)
        {
            return "hello world";
        }

I was really hoping for an error about a bad callback signature, possible including an exception in MSO.DLL that I could dig into…

Instead, I got this:

Really… So when GetImage returns a string, Office interprets it as an ImageMso? I had to try:

        public string GetImage(Office.IRibbonControl control)
        {
            return "WindowKeepOnTop";
        }

The result: SUCCESS!

So, at least for the Office 2010 backstage ribbon, the getImage callback has an alternate signature:

string GetImage(IRibbonControl control)

Where string is an Office Image Id (or the value you would place statically in imageMso).

Definitive complete list of Office Ribbon Callback Signatures for 2007 and 2010

Microsoft’s documentation for programming the Office Ribbon is pretty sparse at best. There are two pages you can get Callback signatures:
1. Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)
2. Introduction to the Office 2010 Backstage View for Developers

Notice that neither of these documents sound like where you would expect callback signatures “part 3 of 3”, and “introduction to the…” Also, the backstage introduction article contains rehashes of most of the office 2007 callbacks in a painfully verbose fashion.

I am here to help.
How about an excel spreadsheet containing the callbacks, associated control, source (2007 vs 2010) and the signatures in 4 different languages? Did I mention the data is already in a table and sorted by callback name?

Here you go:
Full Office Ribbon Callback List
Update: I have uploaded this file to a public SkyDrive so it can be viewed online, since I have needed to make some changes:
Office Ribbon Callbacks

This document is not a control -> callback mapping. The typical use case is:
I am building Office customizations using xml.
I need to implement X callback, but do not know the signature.
I look up the callback by name, then make sure it is the correct one for my control.

Also, I didn’t quite finish reconciling some discrepencies between the 2010 and 2007 documentation – for example, in 2007 the getImage is supposed to return an IPictureDisp – which is a real pain in the butt. My experience showed that returning a bitmap worked anyway, and now the 2010 documentation says getImage returns System.Drawing.Bitmap. I have switched to using Bitmap because it is so much cleaner, but I figured I should leave them both in there.

I am open to suggestions – just trying to fill what I consider a documentation gap.