Error when setting FormattedText of Header/Footer ranges with textboxes in Word 2007 and 2010
-
Monday, April 30, 2012 10:11 AM
Hello everyone,
i'm using a Word document and face a COMException when i try to copy content from header/footer from one document to the customited document. For this i go over each section of the document and loop over the HeaderFooter objects and use the FormattedText property of this object to set the value of the source.
In the end its something like this:
private void CopyHeaderFooter(ref Section srcSection, ref Section destSection, bool isHeader, WdHeaderFooterIndex index) { HeaderFooter sourceItem = (isHeader ? srcSection.Headers[index] : srcSection.Footers[index]); if (sourceItem != null) { HeaderFooter destItem = (isHeader ? destSection.Headers[index] : destSection.Footers[index]); destItem.Range.FormattedText = sourceItem.Range.FormattedText; } }That does work properly in MSO2007 using a VSTO 3.0 solution. Yet it does not in MSO2010 with a VSTO 4.0 solution with the very same code. In that scenario an error shows up when the footer content is tried to be copied (header is working):
Message: Ein Problem wurde von Word festgestellt. StackTrace --- at Microsoft.Office.Interop.Word.Range.set_FormattedText(Range prop)
The message is german and just means that an error occured. No further details are given. This error only appears when the header/footers of the document to copy in contain textboxes. Pure textual content does work properly in MSO2010 as well.
I've uploaded the MSO2007 and MSO2010 solutions:
http://www.filefactory.com/file/328r1q815a69/n/OfficeIssues_zip
Does anyone have an idea why this error occurs ? Seems to me the content is copied just fine even with the error message - so in worst case is could just catch the exception and go on. Yet i'd like to know what is happening. The issue arise on both VSTO solutions when using MSO2010 (Issue seems to be caused by MSO2010 Interop).
Here the Office versions i'm using on Win7:
14.0.6112.5000 (32bit)
12.0.6562.5003 SP2Any help would be highly appreciated. Thanks,
OliverThe whole code for ThisDocument.cs. The file copy.docx is part of the mentioned solutions and contains only an empty textbox in header and footer.
using System; using System.Text; using System.Windows.Forms; using Microsoft.Office.Tools.Word; using Microsoft.VisualStudio.Tools.Applications.Runtime; using Office = Microsoft.Office.Core; using Word = Microsoft.Office.Interop.Word; using Microsoft.Office.Interop.Word; using System.Runtime.InteropServices; using System.Collections; using System.IO; namespace WordDocument5 { public partial class ThisDocument { private void ThisDocument_Startup(object sender, System.EventArgs e) { } void ThisDocument_BeforeSave(object sender, SaveEventArgs e) { try { Perform(); e.Cancel = true; MessageBox.Show("Success"); } catch (Exception exc) { MessageBox.Show(exc.Message); } } private void ThisDocument_Shutdown(object sender, System.EventArgs e) { } /// <summary> /// Sets the content of the document /// </summary> /// <param name="data">The content to set</param> public void Perform() { object objFalse = false; object objTrue = true; object objFormat = WdOpenFormat.wdOpenFormatAuto; object missing = System.Type.Missing; Microsoft.Office.Interop.Word.Document destDoc = Globals.ThisDocument.InnerObject; object objFileName = System.IO.Path.Combine(Globals.ThisDocument.Path, "copy.docx"); Microsoft.Office.Interop.Word.Document srcDoc = Globals.ThisDocument.Application.Documents.Open(ref objFileName, ref objFalse, ref objTrue, ref objFalse, ref missing, ref missing, ref missing, ref missing, ref missing, ref objFormat, ref missing, ref objFalse, // visible flag ref missing, ref missing, ref missing, ref missing); // Copy headers and footers manually for (int i = 1; i <= srcDoc.Sections.Count; i++) { Section srcSection = srcDoc.Sections[i]; Section destSection = destDoc.Sections[i]; CopyAllHeadersAndFooters(ref srcSection, ref destSection); } // avoid nasty save dialogs srcDoc.Saved = true; srcDoc.Application.NormalTemplate.Saved = true; object saveChanges = WdSaveOptions.wdDoNotSaveChanges; srcDoc.Close(ref saveChanges, ref missing, ref missing); // release com object Marshal.ReleaseComObject(srcDoc); } /// <summary> /// The header and footer indizes /// </summary> private static readonly WdHeaderFooterIndex[] AllHeaderFooterIndexes = new[] { WdHeaderFooterIndex.wdHeaderFooterPrimary, WdHeaderFooterIndex.wdHeaderFooterFirstPage, WdHeaderFooterIndex.wdHeaderFooterEvenPages }; /// <summary> /// Copies the content of every header/footer within a section /// </summary> /// <param name="srcSection">The source section</param> /// <param name="destSection">The destination section</param> private void CopyAllHeadersAndFooters(ref Section srcSection, ref Section destSection) { foreach (WdHeaderFooterIndex index in AllHeaderFooterIndexes) { foreach (bool isHeader in new[] { true, false }) { CopyHeaderFooter(ref srcSection, ref destSection, isHeader, index); } } } /// <summary> /// Copies the header footer of a section /// </summary> /// <param name="srcSection">The source section</param> /// <param name="destSection">The destination section</param> /// <param name="isHeader">True if its a header</param> /// <param name="index">The header index</param> private void CopyHeaderFooter(ref Section srcSection, ref Section destSection, bool isHeader, WdHeaderFooterIndex index) { HeaderFooter sourceItem = (isHeader ? srcSection.Headers[index] : srcSection.Footers[index]); if (sourceItem != null) { HeaderFooter destItem = (isHeader ? destSection.Headers[index] : destSection.Footers[index]); destItem.Range.FormattedText = sourceItem.Range.FormattedText; } } /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InternalStartup() { this.Startup += new System.EventHandler(ThisDocument_Startup); this.Shutdown += new System.EventHandler(ThisDocument_Shutdown); this.BeforeSave += new SaveEventHandler(ThisDocument_BeforeSave); } } }
All Replies
-
Tuesday, May 01, 2012 6:31 AMModerator
Hi oliver_zx,
Thanks for posting in the MSDN Forum.
This error only appears when the header/footers of the document to copy in contain textboxes.
What's type of your textbox? Rich text content control, plain text content control or a ActiveX control?
Have a good day,
Tom
Tom Xu [MSFT]
MSDN Community Support | Feedback to us
-
Tuesday, May 01, 2012 8:52 AM
Hi Tom,
its a simple textfield (first in the list of textboxes). I also deleted their content so its an empty textbox.
Thanks,
Oliver -
Wednesday, May 02, 2012 5:23 AMModerator
Hi Oliver,
Would you please show me a screen shooting?
Have a good day,
Tom
Tom Xu [MSFT]
MSDN Community Support | Feedback to us
-
Wednesday, May 02, 2012 7:07 AM
Hi Tom,
screenshot - there's not much to show. Just my message box of the catch clause. But you find all the content (inserted document) within the zip file i uploaded and mentioned in my initial post:
http://www.filefactory.com/file/328r1q815a69/n/OfficeIssues_zip
With that you should also be able to reproduce it.
Thanks for the support,
Oliver -
Thursday, May 03, 2012 5:11 AM
Hi, you can check how to set border and footer within C#.NET. That is pretty easy and quite fast way.
Good Luck
-
Thursday, May 03, 2012 7:43 AM
Hi Green,
its not about setting or inserting specific content but to copy the content from one document to another. In the end it does work like this in Word 2003 and 2007. The issue only appears in Word 2010.
Regards,
Oliver -
Thursday, May 03, 2012 9:30 AMModerator
Hi Oliver,
Would you please upload the necessary files to Skydrive? the current location needs to be a site member and login.
btw, Office doesn't support side by side installation, you can only have one version installed.
thanks,
Forrest Guo | MSDN Community Support | Feedback to manager
- Edited by Forrest GuoMicrosoft Employee, Moderator Thursday, May 03, 2012 2:45 PM side by side reminder
-
Thursday, May 03, 2012 3:06 PMModerator
Hi Oliver (and Tom)
Is this "textbox" something you inserted using the Drawing tools? To me, it looks like that kind of textbox (in German Textfeld, ein Mitglied der AutoForms-Gruppe unter Einfügen) in the screen shot.
If it is, then it's a member of the Shapes collection, and it appears that's the only thing in the header?
This kind of situation is notoriously "finicky", especially if the Shape is anchored to the first paragraph.
There are a couple of things I'd test, if this were my project, before I go digging any deeper:
1. Does the problem occur if I test using VBA code. If it does, I know the problem is coming from Word; if it doesn't happen, then the problem is on the .NET side of things.
2. You say the problem occurs in Office 2010 with .NET 4.0: have you created this project with the new option to embed the object model types (the PIAs) in the solution? If yes, this could be the problem. The embedded types don't always work correctly/the same way as the PIAs.
Cindy Meister, VSTO/Word MVP
-
Thursday, May 03, 2012 4:03 PM
Hi Forrest, Hi Cindy,
Would you please upload the necessary files to Skydrive? the current location needs to be a site member and login.
btw, Office doesn't support side by side installation, you can only have one version installed.
you can download the file using the "Slow Download" button on the botton left of the site. Sorry for that. Skydrive does bring errors to me when i use it right now.
And the Office versions are not installed in parrallel. I use two different Win7 machines/VM for these testing purposes.
Is this "textbox" something you inserted using the Drawing tools? To me, it looks like that kind of textbox (in German Textfeld, ein Mitglied der AutoForms-Gruppe unter Einfügen) in the screen shot.
...and it appears that's the only thing in the header?
Yes, thats correct. The textbox is the first of the textfield gallery ("Einfaches Textfeld"/"Simple textfield") within the insert ribbon tab. And its the only thing in the header and footer, right. I just opened a plain new document, went straight into header/footer and inserted such a simple textfield and deleted the text out of it.
Does the problem occur if I test using VBA code. If it does, I know the problem is coming from Word; if it doesn't happen, then the problem is on the .NET side of things.
Hadn't tried that yet. But i use the Interop interfaces to perform my actions. The only VSTO in use the document customization itself and the retrieval of the interop document and appliacation using the Globals class. So i assumed that the VBA would behave the same. But i can try that...
You say the problem occurs in Office 2010 with .NET 4.0: have you created this project with the new option to embed the object model types (the PIAs) in the solution? If yes, this could be the problem. The embedded types don't always work correctly/the same way as the PIAs.
The problem does occur with MSO2010, but not only with .NET 4.0. It also appears when using a VSTO 3.0 document customization with .NET 3.5. The Interop refs were embedded in the VSTO 4.0 case, yes. But even when i dont embed them the issue occurs.
In the next step i'll try the thing with VBA when i find the time.
Thanks for your help and kind regards,
Oliver
-
Monday, May 07, 2012 11:04 AM
Hi,
i tried it with VBA and the same error message appears there when using MSO2010. With MSO2007 it works...
Here's the VBA code:
Sub Perform() Dim srcDoc As Document Set srcDoc = Documents.Open("c:\myfolder\copy.docx") Dim secIdx As Integer Do While secIdx < srcDoc.Sections.Count secIdx = secIdx + 1 Dim srcSec As Section Dim dstSec As Section Set srcSec = srcDoc.Sections(secIdx) Set dstSec = ThisDocument.Sections(secIdx) CopyHeaderFooter srcSec:=srcSec, dstSec:=dstSec, isHeader:=True, index:=wdHeaderFooterPrimary CopyHeaderFooter srcSec:=srcSec, dstSec:=dstSec, isHeader:=False, index:=wdHeaderFooterPrimary Loop srcDoc.Saved = True srcDoc.Close SaveChanges:=False End Sub Sub CopyHeaderFooter(srcSec As Section, dstSec As Section, isHeader As Boolean, index As WdHeaderFooterIndex) Dim sourceItem As HeaderFooter Dim destItem As HeaderFooter If isHeader Then Set sourceItem = srcSec.Headers(index) Set destItem = dstSec.Headers(index) Else Set sourceItem = srcSec.Footers(index) Set destItem = dstSec.Footers(index) End If destItem.Range.FormattedText = sourceItem.Range.FormattedText End Sub
The copy.docx can be found in my test solutions of the initial post. This document just contain an empty, simple textbox in the header and footer - so you can create them yourself if you have issues downloading the solutions file.
Thanks for the help,
Oliver
-
Wednesday, May 09, 2012 6:40 AMModerator
Hi Oliver,
I reproduce the issue with the project you attached. However, I'm afraid that your question falls into the paid support category which requires a more in-depth level of support. Please visit the below link to see the various paid support options that are available to better meet your needs.
http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone
If the issue turns out to be produce defect, you'll not be charged.
best regards,
Forrest Guo | MSDN Community Support | Feedback to manager
-
Monday, June 25, 2012 1:51 PM
Hello again,
just to let you know. After i've created an incident at MS it came up that there exist a hotfix for this. This hotfix is not a public KB yet nor is it part of any SP.
This hotfix solved my issues. You can request it here: http://support.microsoft.com/kb/2596551Additionally i want to add that this issue only arise, when you use a docx that was saved with MSO2007 in MSO2010. It also did not appeared on every MSO2010 version.
So if you face this issue as well, go check out the hotfix.
Regards,
Oliver

