Customize Microsoft Word built-in style with numbering - c#

I have a word document which already defined costumed built-in style. Like image below.
I want to change the style of the predefined built-in style by running the C# code below.
// open document
Object oFilePath = "C://Users/myDoc.docx";
Microsoft.Office.Interop.Word._Document myDoc;
myDoc = wrdApp.Documents.Open(ref oFilePath, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing
);
// Change header2 style
myDoc.Styles[WdBuiltinStyle.wdStyleHeading2].Font.Color = WdColor.wdColorOrange;
//save and close doc
myDoc.Save();
Object oFalse = false;
myDoc.Close(ref oFalse, ref oMissing, ref oMissing);
The code successfully change the color of heading text, but the number before the text still remains green, not affected by the code. Like the following picture.
Please give me some hint to also apply the color change to the numbering of heading.Thank you.

yes you can do that with the API
//To Cancel the numerotation
ListTemplate lt = null;
myDoc.Styles[WdBuiltinStyle.wdStyleHeading2].LinkToListTemplate(lt);
//To add First Level of Numerotation
ListGallery gallery = wrdApp.ListGalleries[WdListGalleryType.wdNumberGallery];
myDoc.Styles[WdBuiltinStyle.wdStyleHeading2].LinkToListTemplate(gallery.ListTemplates[1]);

Related

Convert SharePoint Library XML document to PDF document using C#

Background
I have a SharePoint 2013 (SP2013) environment (env) where the Word Automation Services (WAS) has stopped working, so my application has be failing to convert XML documents to PDF.
Previous Status
I use OpenXML SDK to convert the XML InfoPath document to Word document (works as expected). Then convert the Word document to PDF using WAS on SP.
Current Status
The WAS stopped working. My application converts the XML to Word but never converts to PDF. As a stop gap I am using a C# code snippet (shown below) to try converting to PDF but I keep getting the error "Object reference not set to an instance of an object."
...
using Word = Microsoft.Office.Interop.Word;
...
string fileName = generatedDoc; //generatedDoc is Word doc converted from XML
string pdfFileName = fileName.Replace("docx", "pdf");
string sourceUrl = siteUrl + "/DocLibMemo/" + fileName;
string destUrl = siteUrl + "/ApprovedMemoPDF/" + pdfFileName;
Convert(sourceUrl, destUrl, Word.WdSaveFormat.wdFormatPDF);
public static void Convert(string input, string output, Word.WdSaveFormat format)
{
// Create an instance of Word.exe
Word._Application oWord = new Word.Application();
// Make this instance of word invisible (Can still see it in the taskmgr).
oWord.Visible = false;
oWord.ScreenUpdating = false;
// Interop requires objects.
object oMissing = System.Reflection.Missing.Value;
object isVisible = false;
object readOnly = false;
object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;
object oInput = input;
object oOutput = output;
object oFormat = format;
// Load a document into our instance of word.exe
Word._Document oDoc = oWord.Documents.Open(
ref oInput, ref oMissing, ref readOnly,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref isVisible, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
// Make this document the active document.
oDoc.Activate(); // The execption is hit here
// Save this document using Word
oDoc.SaveAs(ref oOutput, ref oFormat, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing);
// Always close Word.exe.
oWord.Quit(ref oMissing, ref oMissing, ref doNotSaveChanges);
}
The above snippet worked when I tested it using a console application and the Word files was on my C drive. However now that the Word files are on a SP library It doesn't convert to PDF.
I have encountered with the same problem. SharePoint library is a network drive which doesn't have a physical location. The files of SharePoint are indeed saved in database, so that is the reason why we cannot write and save files in SharePoint library. MS Office has a different approach of saving files to SP Library, it actually upload files instead of saving them directly.
Solution for the problem is to take a local copy of the Word file and make changes to the local copy and upload(i.e Copy) it to the same location in the SharePoint library.
Hope this helps.
Thanks.

How to change excel filename

My question is how to we change the excel filename without we manual changing by our own?
Example , i get a list of naming from excel format from vendor and he will put on the specified location . I need to run a program which using this file to generate a cancellation progress with a specific format of excel in MMYYSP15.
Here my code and i wish to add on the function as i need . Kindly advise
object oMissing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.ApplicationClass xl = new Microsoft.Office.Interop.Excel.ApplicationClass();
Microsoft.Office.Interop.Excel.Workbook xlBook;
Microsoft.Office.Interop.Excel.Worksheet xlSheet;
//System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;
string laPath = System.IO.Path.GetFullPath("D:\\New & Renewal Summary Report 201409.xls");
xlBook = (Microsoft.Office.Interop.Excel.Workbook)xl.Workbooks.Open(laPath, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
xlSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlBook.Worksheets.get_Item(1);
xlSheet.Name = "Sheet 1";
xlBook.Save();
xl.Application.Workbooks.Close();
You have to call xlBook.SaveAs. You can't change the current file's name.
xlBook.SaveAs(Filename: yourFileName);
If you do not intend to do anything with the Excel workbook itself, a simple File.Move would do.
File.Move(fromFileName, toFileName);

How to grammatically parse sentences using Microsoft Word Automation

I have written some code that parses sentences from a Microsoft Word document based on the suggestions found at the following URLs:
Open Word document using C#
Using VBA to parse text in an MS Word document
How to Automate Microsoft Word using C#
I wrote a small function that reads in a document and outputs its sentences via debug statements:
using Microsoft.Office.Interop.Word;
private void button2_Click(object sender, EventArgs e)
{
oWord.Visible = true;
object filename = textBox1.Text;
oDoc = oWord.Documents.Open(filename, ref oMissing, true, false, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
Sentences sentences;
sentences = oDoc.Sentences;
Debug.WriteLine("sentences=" + sentences.ToString());
foreach (Range r in sentences)
{
Debug.WriteLine("range.Text=" + r.Text);
}
}
It does just about as good of a job as I have done previously using the Mid function on strings. I was expecting it to do much better, considering MS Word has grammar check capabilities. Is there some way to make use of MS Word's grammar abilities in order to get it to be smarter about sentence parsing?

Office Word intertop heading styles not showing in table of contents

I am building a word document using Office's Word interop. I am settings heading styles via code. The content is getting styled correctly, however, one opening the created word document, the style is not selected for the selection in the header. This is causing the table of contents to not find the heading.
object oMissing = Missing.Value;
//Start Word and create a new document.
var application = new Application();
application.Visible = true;
var document = application.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
foreach (var member in assembly.Members)
{
//Insert a paragraph at the beginning of the document
var paragraph = document.Content.Paragraphs.Add(ref oMissing);
paragraph.set_Style(WdBuiltinStyle.wdStyleHeading1);
paragraph.Range.Text = member.MemberName;
paragraph.Range.InsertParagraphAfter();
}
document.TablesOfContents.Add(document.Content, true /*use heading styles*/, oMissing, oMissing, oMissing,
oMissing, oMissing, oMissing, oMissing, oMissing,
oMissing, oMissing);
document.SaveAs(#"C:\test.docx", oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
document.Close();
application.Quit();
This example causes the table of contents to display "No entries found".
Note that the content is correctly styled with the heading style. However, when I open the document manually and select "Heading 1", then the table of contents finds the entry correctly.
Any ideas why this would happen? I am callign set_Style with a built in style name. Why does it apply the style but not actually get treated as the style (in this case, a heading)?
UPDATE
Adding the following code seems to make only the first heading recognized as a heading in Word.
foreach (var member in assembly.Members)
{
document.ActiveWindow.Selection.set_Style(WdBuiltinStyle.wdStyleHeading1);
//Insert a paragraph at the beginning of the document
var paragraph = document.Content.Paragraphs.Add(ref oMissing);
paragraph.set_Style(WdBuiltinStyle.wdStyleHeading1);
paragraph.Range.Text = member.MemberName;
paragraph.Range.InsertParagraphAfter();
}
I have noticed difference in the order of the operations
Follow code will not generate real header, it is only looks like header
/*1*/ paragraph.set_Style(WdBuiltinStyle.wdStyleHeading1);
/*2*/ paragraph.Range.Text = "Head";
/*3*/ paragraph.Range.InsertParagraphAfter();
To solve propblem you should use this code
/*1*/ paragraph.Range.Text = "Head";
/*2*/ paragraph.set_Style(WdBuiltinStyle.wdStyleHeading1);
/*3*/ paragraph.Range.InsertParagraphAfter();
After Adding the Paragraph select the paragraph it might work .
paragraph.Range().Select()
I had to do something similar, but the paragraph was not getting the style...
I used then TypeText instead, and then worked...I used a Word.Selection too. I´m merging documents, but I guess your code should be something like this:
(after the line: var document = application.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing)).I´m using Word = Microsoft.Office.Interop.Word on the usings, so that "Word" before the selection is realated to that.
Word.Selection selection = application.Selection;
foreach (var member in assembly.Members)
{
selection.TypeText(member.MerberName);
selection.set_Style(WdBuiltinStyle.wdStyleHeading1);
selection.TypeParagraph();
}
That worked here and the TOC is getting filled.

Getting word message box contents using c#

I have a c# application that is opening a word document, running a .bas macro, and closing word. All of that works fine. The macro generates 2 message box dialogs with the result of the macro. I want to communicate these messages to my c# application. How can I do this?
Here is my code:
// Object for missing (or optional) arguments.
object oMissing = System.Reflection.Missing.Value;
// Create an instance of Word, make it visible,
// and open Doc1.doc.
Word.Application oWord = new Word.Application();
oWord.Visible = true;
Word.Documents oDocs = oWord.Documents;
object oFile = #"c:\\Macro.docm";
// Open the file.
Word._Document oDoc = oDocs.Open(ref oFile, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing);
// Run the macro.
oWord.GetType().InvokeMember("Run",
System.Reflection.BindingFlags.Default |
System.Reflection.BindingFlags.InvokeMethod,
null, oWord, new Object[] { "MyMacro" });
// Quit Word and clean up.
oDoc.Close(ref oMissing, ref oMissing, ref oMissing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDoc);
oDoc = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDocs);
oDocs = null;
oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWord);
oWord = null;
return "all done!";
The solution I've used in the past for this is not for the faint of heart. It basically involves using good old fashioned Windows API calls to find the message box then to enumerate through its "windows" (controls) until you find the control with the text you are after.
If the message box always has the same title, you should be able to locate the window using the API call FindWindowEx. Once you have its window handle you can use EnumChildWindows to run through its controls until you find the one you are after. You can usually qualify the right control with either GetWindowText or GetClassName or a combination of both. Generally the text of a control should be available with GetWindowText, but I dont know what control MS used for this particular window.
Good luck!
FindWindowEx example
EnumChildWindows example

Categories