3
votes

For my VSTO Word solution, I need to programatically "compare" two documents side-by-side. In other words I need to, from code, perform the equivalent of clicking the View > Show Side by Side button.

I tried using the CompareSideBySideWith method after loading two documents. An exception is thrown: "The requested member of the collection does not exist". I am not the first to encounter this; see Microsoft's (boilerplate, not particularly helpful) replies in this thread. The MS rep ended up scratching her head and giving up.

I even tried opening two blank documents and comparing them. This time no exception, but the compare didn't happen and CompareSideBySideWith() returned false.

        Document doc1 = this.word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
        object doc2 = this.word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
        doc1.Windows.CompareSideBySideWith(ref doc2);

Has anyone discovered a workaround for this? It seem a pretty basic piece of functionality to have a in a custom solution.

Note: We need to call the actual "Side by Side" compare, not just arrange the windows via Windows.Arrange(). This is partly because our ribbon contains an alias for the View Side by Side button, which won't be turned on (pressed in) unless the actual Side by Side command is called successfully.


Update: The exception was still thrown in the above example involving two new documents; Word swallowed the exception because I tried it outside of my try-catch block.

Per Otaku below I tried calling doc2.Windows.Compare(ref doc1) instead, and this worked for blank documents as well as test documents saved as .docx and .rtf from Word 2007.

However, we need to compare documents saved as RTF from another RTF editor. When I load one of our documents, it fails. To reproduce my error, try loading RTF documents saved from WordPad--these fail as well. I've tried tinkering with the Encoding and Format parameters of Documents.Open() to no avail. It would be nice to avoid having to convert and save the temp file as .docx, particularly for larger documents! Also note that I can click View Side by Side after opening the WordPad-saved RTF files manually, and it works.

Also, it only seems to matter what format the compare document (the document being passed as parameter to Windows.CompareSideBySideWith() is in. For example, if we are doing doc2.Windows.CompareSideBySideWith(ref doc1) as in Otaku's example, it works when doc1 is a regular docx but not when it's an RTF saved from WordPad. (Regardless of where doc2 came from).


Update 2: As usual, one line of code resolves several days of chasing one's tail:

doc1.Convert(); // Updates the document to the newest object model (i.e. DOCX)

Can now compare side-by-side without a problem.

1
Did you try to activate doc1 first? Like: doc1.Activate. Then do the CompareSideBySideWith()...code4life
Why is doc2 an object instead of a Document?Todd Main
@Otaku: It's an idiosyncrasy in the Word object model, you have to use ref object in many parameters.System.Cats.Lol
Gotcha. I used to VB.NET where this kind of stuff isn't needed. See answer below.Todd Main

1 Answers

3
votes

Reverse the compares of your documents and it should be fine:

For new documents

Document doc1 = this.word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
Document doc2 = this.word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
object o = doc1;
doc2.Windows.CompareSideBySideWith(ref o);

For existing documents

object missing = System.Reflection.Missing.Value;
object newFilename1 = "C:\\Test\\Test1.docx";
Document doc1 = this.word.Documents.Open(ref newFilename1, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

object newFilename2 = "C:\\Test\\Test2.docx";
Document doc2 = this.word.Documents.Open(ref newFilename2, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
object o = doc1;
doc2.Windows.CompareSideBySideWith(ref o);

If your app isn't visible or you are launching a new instance of Word, you should set this.word.Visible = true; before running the opening of documents as CompareSideBySideWith is a UI routine.