Note: I'm using Office Word 2007
I need to replace specific parts of a Word Document with comboboxes, checkboxes, text, etc..
I find "tags" using Regular Expression, and then iterate over regex Matches to get the specific text to replace.
var range = doc.Content; // where doc is current active word document
var matches = GetRegexMatches();
foreach (var match in matches){
if(range.Find.Execute(match.Value)){ // match.Value equals to the "tag" im searching
range.Collapse();
Word.ContentControl checkbox = range.ContentControls.Add(Word.WdContentControlType.wdContentControlCheckbox);
checkbox.Checked = true;
}
}
This code adds some weird box (I guess a ContentControl object, but not of type checkbox). Debugging it didn't help because it just stops the debugger.
I tried following another similar stackoverflow thread, but using a FormField instead of ContentControl just adds a grey checkbox which is disabled by default and unchangeable programatically.
Am I doing something wrong or it cannot be done in this Office version? Or both?
Apparently, if you are working with Office 2010+ and the document you're trying to open has been created in a version previous to the 2010, it gets opened in Compatibility Mode which disables many of the new functionalities in order to not break the file. That includes Comboboxes, Checkboxes, etc.. There's no workaround to this, other than opening the document in new Office version and saving it as newer version.
Related
I am working on a MS-Word addin that reads the content of a document and replaces every occurence of a specific word by a hyperlink.
So far, I came up with this working algorithm.
// Initializes the Find parameters
searchRange.Find.ClearFormatting();
searchRange.Find.Forward = true;
searchRange.Find.Text = "foo";
do
{
searchRange.Find.Execute(Wrap: Word.WdFindWrap.wdFindStop);
if (searchRange.Find.Found)
{
// Creates a Hyperlink at the found location in the current document
this.WordDocument.Hyperlinks.Add(searchRange, externalLink, link, "bar");
}
searchRange.Find.Execute(Wrap: Word.WdFindWrap.wdFindStop);
} while (searchRange.Find.Found);
This code works, however, it can be slow on bigger documents. Thus, instead of adding hyperlinks one by one, I wanted to simply to use the Find.Replacement object and with the WdReplace.ReplaceAllproperty.
However, I cannot manage to replace my search result by a Hyperlink.
Is there a way to replace a piece of text by a hyperlink using the Replacemethod ?
In other words, I'd like to find a way to do this :
Find.Replacement.Text = new Hyperlink(...);
On an other side, I've seen that, by hitting Alt + F9in Word, we can see hyperlinks as code.
The code looks like this :
{ HYPERLINK \l "link" \o "Caption" }
Another solution would be to be able to set the text replacement as that string and make Word interpret it and thus, create the link.
Thanks for reading.
As far as I know, fields can only be inserted programmatically, or by using CTRL-F9. There are two possible reasons for this that I see:
They are not simple text. They have two ranges, the Code and the Result, only one of which is displayed at any time.
How else would a user insert text that looks like a code but is not supposed to be one, unless there was a special mechanism to create one?
I am trying to write an Add-In (VSTO) for Word to add some software requirement-management capabilities to it.
assume a Requirement would follow this convention:
[REQ_<nr>] Specification item title
⌈ Specification item description. ⌋ (REQ_<nr1>, REQ_<nr2>)
Is there anyway to declare this block and name it so, that you can later find all Requriements using OpenXML and c#?
thanks
Word has two basic ways you can identify something in a document: Bookmarks and ContentControls. Both will work for OpenXML and for the Interop (C#).
Each bookmark must have a different name, so you'd use a naming convention with an incrementing counter (Req1, Req2 for example).
ContentControls are specifically designed to allow the same entry for the Title property for multiple controls. The interop command Document.SelectContentControlsByTitle returns an array of all content controls. OpenXML can do the same, of course. This approach is not available for bookmarks in the interop.
Another difference between the two is that content controls can be protected, in case that's important for you.
I have a little C# app that is extracting text from a Microsoft Publisher file via the COM Interop API.
This works fine, but I'm struggling if I have multiple styles in one section. Potentially every character in a word could have a different font, format, etc.
Do I really have to compare character after character? Or is there something that returns me the different style sections? Kinda like I can get the different Paragraphs?
foreach (Microsoft.Office.Interop.Publisher.Shape shp in pg.Shapes)
{
if (shp.HasTextFrame == MsoTriState.msoTrue)
{
text.Append(shp.TextFrame.TextRange.Text);
for(int i = 0; i< shp.TextFrame.TextRange.WordsCount; i++)
{
TextRange range = shp.TextFrame.TextRange.Words(i+1, 1);
string test = range.Text;
}
}
}
Or is there in general a better way to extract the text from a Publisher file? But I have to be able to actually write it back with the same formatting. It's for a translation.
You could consider using the clipboard to copy text sections as RTF which you can later paste back as RTF as with the example below for Word. I am not familiar with Publisher's object model.
string text = wordDocument.Content.Paragraphs[0];
System.Windows.Forms.Clipboard.SetText(text, TextDataFormat.Rtf);
Other than that, I have not found a collection of applied styles when using interop with any of the office products.
We tried an approach were we just compared for every character as many font styles as possible. Not pretty, but works in most cases...
I am working on a word automation project in c# and am using the interop word library to read/write to word. I am currently using bookmarks in a word template doc to find where to write info to in the word doc from c#. One of my bookmarks consists of two highlighted lines in the doc. Based on a boolean value, i have to decide whether to leave that text there and add a new line of text right after it, or delete those existing two lines from the doc.
So here is my pseudo for it:
if (writeToDoc)
{
// leave selected bookmark text intact and press enter to write another line right after
}
else
{
//delete the selected bookmark text
}
Can anyone please show me how to delete existing text as well as do the equivalent of pressing enter and writing another line from c#?
Thanks
EDIT: Here is the code i have (roughly)
foreach (var bookmark in wordDoc.Bookmarks)
{
var bookMarkNameExistsInCode = listOfBookmarks.Contains(wordDoc.Bookmarks[bookmark].Name);
if (bookMarkNameExistsInCode )
{
object oBookMarkName = wordDoc.Bookmarks[bookmark].Name;
rng = wordDoc.Bookmarks.get_Item(ref oBookMarkName).Range;
// at this point i am pointing to the two selected lines labelled as a bookmark in word. How can i deselect and add a new line?
}
}
If the word manipulation is done on DocX files you could use DocX library and use some very simple commands like text.ReplaceText(); and other very easy/intuitive commands. Replacing Interop with DocX if possible should get you up and running in no time :)
I have a VSTO add-in that is able to match against specific codes in the body of a document. The codes themselves are just strings that I syntactically match for validation.
My parsing using StoryRange works fine, but of course, I get the rare exception where a user is doing something funky in their document. I've noticed that some users are introducing bookmarks into the middle of the code string and this throws off my validation match. Instead of of code being '34-RD-345', when you reveal the hidden formatting in Office 2007, you will see something like '34-RID-345'. The bookmark formatting looks similiar to an uppercase i (I) and I can see that a bookmark is present using the bookmark option in the ribbon.
Does anyone know how I might be able to ignore the bookmark when I'm scanning the text?
Maybe an even better alternative maybe to just confine my parsing to [a-Z][0-9]. Is something like that possible?
You can get all bookmarks, then delete them all, then parse the document again.