Footer still active after reading it (rtf formular file) - c#

An rtf document is generated by a data base application, with information from this data base. I have created a software (C#, net framework 4.5), to pick up data, then to record it into Excel file.
I have to read the footer of the rtf file, thing I can do.
But, when software access to footer, the document view is the same when footer/header are active (the same effect when you double click on header/footer to access it when you are under Word. This action action adds a carriage return on header (Word add this to enter something), and this \r causes to have additional page.
Here the code :
Sections oSection = cGlobalVar.varWordApp.ActiveDocument.Sections;
HeaderFooter oFooter = oSection[1].Footers[WdHeaderFooterIndex.wdHeaderFooterFirstPage];
Range oRange = oFooter.Range.Tables[1].Range;//<= at this point, footer is accessible, the empty header of original document has a\r character, causing 2nd page to document that I don't want
strBuffer = oRange.Text;//<= information I need
oRange = oSection[1].Range.Tables[1].Range;//<= try to affect something else to oRange
oFooter = null;//<= try to null the object
oSection = null;//<= same as above
//cGlobalVar.varWordDoc.ActiveWindow.View.Type = WdViewType.wdPrintView;//<= try to use this to return to a normal state
I have tried to manipulate Word to find something to get back to my original document (one page), but without any success.

Nulling the object won't clear its content. If you want to clear it, change the text of the range object
oFooter.Range.Text = "";
oSection.Range.Text = "";
Note: These objects have a reference type. This means that the variable points to the actual object, which is somewhere else. If you set the variable to null, you are just loosing the link to the object, but you are not changing the object. See my answer to the SO question Setting a type reference type to null doesn't affect copied type?
UPDATE
I made an experiment in Word, using a VBA macro that reads the table range of the footer as you did above. It does not change the view type of word.
Sub Macro1()
Dim oSection As Sections
Dim oFooter As HeaderFooter
Dim oRange As Range
Dim strBuffer As String
Set oSection = Application.ActiveDocument.Sections
Set oFooter = oSection(1).Footers(WdHeaderFooterIndex.wdHeaderFooterPrimary)
Set oRange = oFooter.Range.Tables(1).Range
strBuffer = oRange.Text
Debug.Print strBuffer
End Sub

Related

How to get location of comments from word file in c#

I have tried Microsoft.Office.Interop.Word. In that, I have tried Range property. But not getting a result.
Application application = new Application();
Document document = application.Documents.Open("D:\\Files\\Meeting Agenda.doc");
var commentRange = document.Comments[1].Range;
I misunderstood exactly what you wanted.
It is the "Scope" property of the "Comment" object that you need - it is a range & you can obtain the location of the comment from that (Start/End are 0 based offset from start of document). So use :
var commentRange = document.Comments[1].Scope;
The "Range" property is the comment itself (Start/End properties appear to be offsets in a list of comments).
The documentation states the "Reference" property indicates the location of the comment but the Start and End properties are always 1 apart & seem to be the end of the comment & the Text property is always null.

PDFClown Find and replace page

Using pdfclown,
I was wondering the best practice to find a page in a Existing PDF doc, and replace with a page from another PDF doc.
I have the bookmark and pagelabel of both pages.
A simple example for replacing pages can be derived from the PageManager cli examples:
string inputA = #"A.pdf";
string inputB = #"B.pdf";
string output = #"A-withPage1FromB-simple.pdf";
org.pdfclown.files.File fileA = new org.pdfclown.files.File(inputA);
org.pdfclown.files.File fileB = new org.pdfclown.files.File(inputB);
// replace page 0 in fileA by page 0 from fileB
Document mainDocument = fileA.Document;
Bookmarks bookmarks = mainDocument.Bookmarks;
PageManager manager = new PageManager(mainDocument);
manager.Remove(0, 1);
manager.Add(0, fileB.Document.Pages.GetSlice(0, 1));
fileA.Save(output, SerializationModeEnum.Standard);
This indeed replaces the first page in A.pdf by the first page in B.pdf and saves the result as A-withPage1FromB-simple.pdf.
Unfortunately, though, the PageManager does not update bookmarks. In the result of the code above, therefore, there still is a bookmarks which used to point to the original first page; as this page is not there, anymore, it now points nowhere anymore. And the bookmark pointing to the first page in fileB, is ignored completely.
Other document level, page related properties also are not transferred, e.g. the page label. In case of the page labels, though, the original label for the first page remains associated to the first page after replacement. This is due to a different kind of reference (by page number, not by object).

Is there a way to check the validity of internal hyperlinks/Cross references added via a bookmark inside an active word document?

I'am trying to build an ms word add-in in which ,
I wanted to check for a particular scenario,i.e say a user inserts a bookmark and later in the document adds a cross reference to this bookmark.But he then deletes the bookmark and forgets to update his document, now upon pressing ctrl+click (to follow the link) takes me to the start of the document, instead I wanted to know if we can display a specific message to the user telling him to update his document or even remove the cross reference by any chance .
Please let me know how I can go about this ,I know how to test for invalid links with respect to toc. But this scenario is confusing.Any help is much much appreciated.Thanks in advance :)
I solved the problem by using the following logic
Dim doc As Word.Document
Dim fld As Word.Field
Dim rng As Word.Range
Dim str As String
Set doc = ActiveDocument
For Each fld In doc.Fields
If fld.Type = wdFieldRef Then
str = fld.Code
str = Replace(str, "REF ", "")
str = Replace(str, "\h", "")
str = Trim(str)
‘need handle the error if the bookmark has been deleted.
Set rng = doc.Bookmarks(str).Range
End If
Next
if you want to further delete the cross reference to an invalid bookmark you can use Field.Result.Delete

MS Word Interop to C# - Inserting multiple files at a bookmark

I have one master document into which I want to insert a number of files. These should be inserted into the file one after another at a certain point in the middle of the document.
So I have created a bookmark at this point called "TESTS", since this seems to be the easiest way of programatically finding the point.
I am able to insert a single file using this code:
Microsoft.Office.Interop.Word.Application oWord = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document oWordDoc = oWord.Documents.Open(#"C:\master.doc");
oWordDoc.Bookmarks.Cast<Bookmark>().First(b => b.Name == "TESTS").Range.InsertFile(#"C:\test1.doc");
But this removes the bookmark, making it impossible to insert a second file at the same point. I don't mind losing the bookmark, but only once I have inserted all files.
Can this be done? I am guessing that the above code replaces the range with the bookmark so finding the location just before or after and then deleting the bookmark range would be best - but I just can't find the code for it. Everything I have tried seems to replace the whole document.
Alternatively, is there any way to do this without the Interop (i.e. by parsing the file - no touching MS Word at all)?
There must be something particular about the way your document is set up and the exact range of the the bookmark because I am able to get this to work without losing the bookmark. According to this MVP article Inserting text at a bookmark without deleting the bookmark, adding Text to a bookmarked range should delete the bookmark; maybe you are running into similar issue with InsertFile.
Try their suggestion of storing the bookmark's range into a variable ie MyRange and then calling Bookmarks.Add "mybookmark", MyRange
Dim BMRange As Range
Set BMRange = ActiveDocument.Bookmarks("MyBookmark").Range
BMRange.Text = "Hello world"
ActiveDocument.Bookmarks.Add "MyBookmark", BMRange

Editing the Text of Word Document Range removes paragraph formatting

I'm using Office Interop with MS Word (Microsoft.Office.Interop.Word) and Microsoft.Office.Tools.Word to modify a word document in a Word Add-in. I have a Range which contains specific text I want to edit.
When I update the Text object, the paragraph formatting of the Range is reset, specifically the Alignment and the LeftIndent. I can save the Alignment and LeftIndent in temp variables and reset them, but this is not ideal. Is there a way to stop the ParagraphFormat from being reset and if not, are there any other properties that I may be forgetting that I need to save (I just realized the before and after paragraph spacing also gets reset...).
Microsoft.Office.Interop.Word.Range range = myObject.range;
var oldAlignment = range.ParagraphFormat.Alignment;
var oldLeftIndent = range.ParagraphFormat.LeftIndent;
range.Text = "new text";
range.ParagraphFormat.Alignment = oldAlignment;
range.ParagraphFormat.LeftIndent = oldLeftIndent;
Edit: I just tried saving the ParagraphFormat as a temp variable and then resetting the formatting with that, but the temp variable loses its formatting as well.
oldParagraphFormat = range.ParagraphFormat;
range.Text = "new text";
range.ParagraphFormat = oldParagraphFormat; // oldParagraphFormat's objects are reset
Try creating a duplicate of the Range.ParagraphFormat object prior to changing the text. You can do this via the ParagraphFormat.Duplicate object. This will retain the old ParagraphFormat value. After you change a range's text and its ParagraphFormat resets, you can restore the value from the duplicate.
// Get current value of ParagraphFormat.
Microsoft.Office.Interop.Word.Range range = myObject.range;
var oldParagraphFormat = myObject.range.ParagraphFormat.Duplicate;
// Change the range's text. This will reset ParagraphFormat, so reapply the previous value.
range.Text = "new text";
range.ParagraphFormat = oldParagraphFormat;
Some background as to what's going on: Changing Range.Text essentially resets the Range object because a Range is text + formatting. So changing the text without including any formatting information will cause all previous formatting to be lost. (Much like how changing an HTML tag's innerText property causes that tag to lose all child tags.)
If duplicating the ParagraphFormat doesn't help then you may want to look into setting the Range.FormattedText property instead of Range.Text.

Categories