WdInformation.wdVerticalPositionRelativeToPage gives different values in VBA vs C# - com

I am translating a piece of code written in VBA to C# using Microsoft.Office.Interop.Word
What I observe that
p.Range.Information[WdInformation.wdVerticalPositionRelativeToPage]
in C# gives a different value vs. when used in VBA
p.Range.Information(wdVerticalPositionRelativeToPage) where p is the Paragraph object.
This happens whenever a shape is present on the page of Word document. I was wondering why this is happening? Is there something different in rendering of documents when document is opened via C# vs VBA?
PS - in both cases, word visibility is set to false.
Edit: Update - I tried to set visibility to true and I do observe differences in document rendering when Document is launched using C# vs using VBA. How do I fix this?

So I figured out the problem. My code was trying to access header section like this
foreach (Section sect in objDoc.Sections)
{
foreach (HeaderFooter hf in sect.Headers)
{
someFunction(hf.Range.Paragraphs, false, false);
if (hf.Shapes.Count > 0) // to handle shapes in Headers
{
someFunction(hf.Shapes);
}
}
}
For some reason, accessing headers changes the position of paragraphs in rendering causing the different values. To fix this, I now access headers as the last piece in my code. Hope this helps somebody.

Related

Word - Conditional Text

I'm having to convert some documents which had been built in OpenOffice over to word, and one thing which seems overly complicated in Word is conditional text. OO had some features which made this a breeze, but I'm thinking I'm missing something in Word.
For more simple pieces of text I've used the {IF {DOCVARIABLE xxxx} = ...} method which seems to work well with single lines of text.
For longer blocks of text I've tried using a similar method but inserting an Autotext block. This works well if the content is static, but if the content I'm inserting needs to be edited, updating the document ends up replacing any changes with the Autotext block. So this method won't work for parts of my document.
Most of the search results I'm seeing use some variation of the two methods above. Is there something else I can use which allows blocks of text, possibly including tables, to be conditionally inserted or hidden and also editable?
Macros are okay since this is how I'm setting various DOCVARIABLE parameters in the document.
I'm using Word 2016 on Windows 7.
After doing more experimenting, it looks like I can use bookmarks to do what I need.
I can select the block of text I want to conditionally show/hide, then create a bookmark for the selection.
Then in my macro I can hide the section when necessary with:
ActiveDocument.Bookmarks("MyBookmarkName").Range.Font.Hidden = True
or show it again using False instead of True. This seems to hide tables and other things within that block of text. I'd love it if the Word developers would add some of the features for this type of thing which are in OpenOffice.

VBA Macro for MS Word to Ignore Spelling Errors in Selected Block of Text

VBA Noob here. I take my python programming notes in a word document since I can import images into it and align/format text quickly. Any code pasted into this document comes up as a spelling error. I'm trying to find a way to ignore spelling errors within a selected text area so I don't have to deal with ignoring each spelling error line of code individually. I don't want to turn off spell check in the document.
Ideally, I'd able to write a macro that read:
Selection.ShowSpellingErrors = True
but ShowSpellingErrors() can only be used with ActiveDocument. I was able to a record a macro that ignored spelling errors with:
Selection.LanguageID = wdEnglishUS
Selection.NoProofing = True
However, any new text I type into this also doesn't get proofed, which is something I don't want. I want to be able to write new text and see any errors I make. Thanks for any help!
Not a VBA Macro, but I think this answer may be relevant to your problem anyway.
Try creating a style for code which does not include spell check. Anything with this style does not get spell checked, while the rest of the document does. Sometimes I find the code shows the red underline, but if you run spell check it should just disappear without needing to be 'fixed'.
Create a new style, in the modify formatting dialog, go to Format > Language:
Tick the 'Do not check spelling or grammar' checkbox:
Highlight your code and use the new style. Any text not in this style will still be spellchecked:

Open XML SDK 2.5 document validation: The 'smtClean' attribute is not declared

Our current work project involves opening a Microsoft PowerPoint file (.pptx format), changing some text and chart values, and then presenting the edited version to the end user.
This works rather well so far, but I'm puzzled by what happens when I try to validate the document afterwards. Using the DocumentFormat.OpenXml.Validation.OpenXmlValidator class, I run the Validate function with the PresentationDocument passed in as the only parameter.
Dim document As PresentationDocument = PresentationDocument.Open(templateFilePath, True)
Dim validator As OpenXmlValidator = New OpenXmlValidator()
Dim errors = validator.Validate(document)
For Each errInfo As ValidationErrorInfo In errors
Debug.Print("Error: """ & errInfo .Description & """")
Debug.Print("XPath: " & errInfo .Path.XPath)
Next
Validate() returns an array filled with instances of ValidationErrorInfo. Just about all of these give the same error description when debugging:
The 'smtClean' attribute is not declared.
The XPath for each error looks like this (numbers vary; there appears to be one error per piece of text):
/p:sldLayout[1]/p:cSld[1]/p:spTree[1]/p:sp[4]/p:txBody[1]/a:p[1]/a:fld[1]/a:rPr[1]
Every TableCell has a Paragraph, with child element Run, and this Run has child elements RunProperties and Text. I modify the Text in my scripts, but I do not touch anything else.
Searching for 'smtClean' gave me an MSDN entry for RunProperties which shows 'smtClean' as one of the possible values to be set, but if I create a new instance of DocumentFormat.OpenXml.Presentation.Drawing.RunProperties the 'smtClean' attribute is not available.
Looking around, I found threads where people mentioned merged documents to be one possible cause, but these errors occur even in an unmodified presentation with only a single slide and table in it. Using the Open XML SDK 2.5 Productivity Tool to Validate the base document, I get the same result.
The errors also occur no matter which format I ask the Validator to test for - both the 2007, 2010 and 2013 version of the PowerPoint format return the same amount of errors.
Finally: The file itself works just fine in PowerPoint, even after being modified. I am curious about why the validator returns so many errors, however.
Thanks in advance for any help.
we process Office Documents and remove this Attribute in all Types (Word, Powerpoint, Excel) without Side-Effects. Eric White has identified this as Bug: smtpClean attribute not supported
It is fixed in the current OpenXml SDK on Branch Office2016: https://github.com/OfficeDev/Open-XML-SDK/tree/Office2016
Regards...
Smart tags were deprecated in Office 2010, and the SDK v2.5 validator doesn't support smart tag elements and therefore marks them as invalid.
Please see this MSDN article for more information.
The current developer of the productivity tool says in this thread that the smtClean validation error was a bug in some situations and has been fixed in v3 of the tool.
v3 (the Office 2016 productivity tool) can be found here, however I'm not sure how compatible it is with older versions of Office.

MS Word building block not inserted in its own page

I defined a building block (QuickPart) to "Insert in its own page". I insert it in code (C# Word Interop) like this:
range =
_doc.get_AttachedTemplate()
.BuildingBlockEntries[blockName]
.Insert(Where: _selection.Range, RichText: true);
_doc is _word.Documents.Add(...), _selection is _doc.ActiveWindow.Selection (nothing is selected) and _word is the Application object.
Based on the definition of the building block, I expect a page break to be automatically inserted before the building block but that is not happening. How do I make BuildingBlock.Insert honor the building block definition?
It appears that the object model does not honor that setting. Apparently, only inserting the Building Block from the UI will trigger it.
My recommendation would be to:
Format the first paragraph of the Buidling Block entry with "Page
break before" paragraph formatting.
Then include a PageBreak (Ctrl+Enter) at the end of the entry.
Select it, including the page break and re-create the Building
Block.
In this way, the entire entry will always appear on a separate page from the rest of the text in the document.

Look for Style Changes in Word

Is there any way when programming MS Word to list the points in the text where a change in character style occurs?
I'm programmatically trying to analyze a paragraph to retrieve all the contiguous blocks of text that have the same style - in other words, split the paragraph at the points where the text style changes. At the moment the way I'm doing it is to take each character and compare its style with the previous character - if the name of the style is different, I know I've found a point to split the results at. That works but is horrendously inefficient (for every character, you have to do a full string comparison of the style name). I'm wondering if there's a way in the Word object model to solve this problem without comparing every character?
The approximate code I'm currently using is as follows (It's C# code: I'm using COM Interop against Word 2003, but I'd be equally happy with a solution in VBA since once I know in principle how to do it, converting to C# should be easy. )
// used to store the results as we go
StringBuilder currentText = new StringBuilder();
string currentStyle = null;
// range contains the Range I want to split up
foreach (Range charRng in range.Characters)
{
string style = charRng.get_Style().NameLocal;
if (style == currentStyle)
{
currentText.Append(charRng.Text);
}
else
{
AddTextBlockToMyResults(currentStyle, currentText.ToString());
currentText = new StringBuilder(charRng.Text);
currentStyle = style;
}
}
AddTextBlockToMyResults(currentStyle, currentText.ToString());
What version(s) of Office were used to create the Word docs?
If it's Office 2007 or later (or, you can convert the docs to that format) then an office document is really just a .zip archive. If you open a .docx file with an archive utility like WinRAR, you'll see that it has a directory structure like:
_rels
customXml
docProps
word
|_ document.xml
That document.xml is an Open Office XML file that contains all the text and reference to styles in your Word doc. I bet you could parse that XML a heck of a lot faster than doing what you're doing now.