C# to concatenate word documents; problem

G

gretchog

I have a C# program which is designed to concatenate word documents (.docx)
together. I'm receiving no compile or run-time errors, yet the program is not
producing an output document at all. Any help would be appreciated, code
below (there's quite a lot):

using System;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using KeithRull.Utilities.OfficeInterop;

namespace ReportEditorNamespace {

class ReportEditor : Form {

public ReportEditor() {
InitialiseComponent();
}

[STAThread]
public static void Main() {
Application.Run(new ReportEditor());
}

public void InitialiseComponent() {
//Here is the code to setup the window
this.Text = "Report Editing Utility";
this.Size = new System.Drawing.Size(500,350);
this.MaximizeBox = false;
this.MinimizeBox = false;
//First come the instructions to the user
this.instructions1 = new Label();
this.instructions1.AutoSize = true;
this.instructions1.Font = new System.Drawing.Font("Microsoft Sans Serif",
10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((byte)(0)));
this.instructions1.Name = "Instructions1";
this.instructions1.Size = new System.Drawing.Size(139, 20);
this.instructions1.Text = "Please select the sections to create a report
from.";
this.instructions1.Location = new System.Drawing.Point(8, 16);
this.Controls.Add(this.instructions1);
//Next, the CheckedListBox menu which selects the sections
clb = new CheckedListBox();
clb.Parent = this;
clb.Location = new Point(8,70);
clb.Size = new Size(480,170);
clb.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
| AnchorStyles.Bottom;
clb.BorderStyle = BorderStyle.Fixed3D;
clb.ScrollAlwaysVisible = true;
clb.ThreeDCheckBoxes = true;
clb.CheckOnClick = false;
//Next, the button which opens the file browsing window
browse = new Button();
browse.Parent = this;
browse.Text = "Browse...";
browse.Location = new Point(8,40);
browse.Click += new System.EventHandler(browse_Click);
//Clear Button
btnClear = new Button();
btnClear.Parent = this;
btnClear.Text = "Clear All";
btnClear.Size = new Size((int)(Font.Height * .75) *
btnClear.Text.Length, Font.Height + 10);
btnClear.Location = new Point(8,250);
btnClear.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
btnClear.Click += new System.EventHandler(btnClear_Click);
//Create Report Button
btnCreate = new Button();
btnCreate.Parent = this;
btnCreate.Text = "Create Report";
btnCreate.Size = new Size((int)(Font.Height * .75) *
btnCreate.Text.Length, Font.Height + 10);
btnCreate.Location = new Point(8,285);
btnCreate.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
btnCreate.Click += new System.EventHandler(btnCreate_Click);
}

private void browse_Click(object sender, EventArgs e) {
OpenFileDialog dlgOpen = new OpenFileDialog();
dlgOpen.Filter = "Word Documents (*.docx)|*.docx";
dlgOpen.Title = "Select one or more files. To select multiple files,
hold CTRL.";
dlgOpen.ShowReadOnly = true;
dlgOpen.Multiselect = true;
if (dlgOpen.ShowDialog() == DialogResult.OK) {
foreach (string s in dlgOpen.FileNames) {
//Add the files from the appropriate directory to the clb
clb.Items.Add(s);
}
}
}

private void btnClear_Click(object sender, EventArgs e) {
clb.ClearSelected();
for (int i = 0; i <= (clb.Items.Count - 1); i++) {
clb.SetItemChecked(i, false);
}
}

private void btnCreate_Click(object sender, EventArgs e) {
//Opens a form requesting new filename etc.
if(clb.CheckedItems.Count > 0) {
if (cDoc == null || cDoc.IsDisposed) {
string pattern = @".docx";
string file = @"Report Created .docx";
DateTime now = DateTime.Now;
string time = now + @".docx";
cDoc = new CreateDoc(clb);
Regex r = new Regex(pattern);
file = r.Replace(file, time);
cDoc.newfilename.Text = file;
}
cDoc.Show();
cDoc.Activate();
cDoc.Owner = this;
}

else {
MessageBox.Show("Please select at least one item!");
}
}

public Label instructions1;
public Button btnClear, btnCreate, browse;
CheckedListBox clb;
CreateDoc cDoc;
}

public class CreateDoc : Form {

public CreateDoc(CheckedListBox clb) {
cf = clb;
InitialiseComponent();
}

private void InitialiseComponent() {
this.SuspendLayout();
this.Size = new System.Drawing.Size(350,250);
this.Name = "Create New Report";
this.ResumeLayout(false);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.instructions = new Label();
this.instructions.AutoSize = true;
this.instructions.Font = new System.Drawing.Font("Microsoft Sans Serif",
10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((byte)(0)));
this.instructions.Name = "Instructions";
this.instructions.Size = new System.Drawing.Size(139, 20);
this.instructions.Text = "Please choose a name for the report and click
\nOK, or Cancel to return to the main menu.";
this.instructions.Location = new System.Drawing.Point(8, 16);
this.Controls.Add(this.instructions);
this.newfilename = new TextBox();
this.newfilename.AutoSize = true;
this.newfilename.Location = new Point(10, 70);
this.newfilename.Name = "newfilename";
this.newfilename.Text = "";
this.newfilename.Size = new System.Drawing.Size(220,21);
this.Controls.Add(this.newfilename);
ok = new Button();
ok.Parent = this;
ok.AutoSize = true;
ok.Text = "OK";
ok.Location = new Point(10, 170);
ok.Click += new System.EventHandler(ok_Click);
cancel = new Button();
cancel.Parent = this;
cancel.AutoSize = true;
cancel.Text = "Cancel";
cancel.Location = new Point(100, 170);
cancel.Click += new System.EventHandler(cancel_Click);
}

private void ok_Click(object sender, EventArgs e) {
ReportEditor re = (ReportEditor)this.Owner;
//Add the files to be copied to a string array
string newFile = newfilename.Text;
string[] merges = new string[cf.CheckedItems.Count];
int i = 0;
foreach(object itemChecked in cf.CheckedItems){
merges = itemChecked.ToString();
i++;
}
foreach(string merge in merges)
System.Console.WriteLine(merge);
System.Console.WriteLine(newFile);
KeithRull.Utilities.OfficeInterop.MsWord.Merge(merges, newFile, true);
this.Close();
}

private void cancel_Click(object sender, EventArgs e) {
ReportEditor re = (ReportEditor)this.Owner;
this.Close();
}

private Button ok, cancel;
public CheckedListBox cf;
private Label instructions;
public TextBox newfilename;
}
}

using System;
using Word = Microsoft.Office.Interop.Word;
using System.Configuration;

namespace KeithRull.Utilities.OfficeInterop
{
public class MsWord
{
/// <summary>
/// This is the default Word Document Template file. I suggest that
you point this to the location
/// of your Ms Office Normal.dot file which is usually located in
your Ms Office Templates folder.
/// If it does not exist, what you could do is create an empty word
document and save it as Normal.dot.
/// </summary>
private static string defaultWordDocumentTemplate =
@"J:\\eclipse\\Workspace\\C# Files\\Report Editor\\Normal.dot";
/*ConfigurationManager.AppSettings["KeithRull.Utilities.OfficeInterop.DefaultWordTemplate"].ToString();*/

/// <summary>
/// A function that merges Microsoft Word Documents that uses the
default template
/// </summary>
/// <param name="filesToMerge">An array of files that we want to
merge</param>
/// <param name="outputFilename">The filename of the merged
document</param>
/// <param name="insertPageBreaks">Set to true if you want to have
page breaks inserted after each document</param>
public static void Merge(string[] filesToMerge, string
outputFilename, bool insertPageBreaks)
{
Merge(filesToMerge, outputFilename, insertPageBreaks,
defaultWordDocumentTemplate);
}

/// <summary>
/// A function that merges Microsoft Word Documents that uses a
template specified by the user
/// </summary>
/// <param name="filesToMerge">An array of files that we want to
merge</param>
/// <param name="outputFilename">The filename of the merged
document</param>
/// <param name="insertPageBreaks">Set to true if you want to have
page breaks inserted after each document</param>
/// <param name="documentTemplate">The word document you want to use
to serve as the template</param>
public static void Merge(string[] filesToMerge, string
outputFilename, bool insertPageBreaks, string documentTemplate)
{
object defaultTemplate = documentTemplate;
object missing = System.Type.Missing;
object pageBreak = Word.WdBreakType.wdPageBreak;
object outputFile = outputFilename;
System.Console.WriteLine(outputFilename);
System.Console.WriteLine(documentTemplate);

// Create a new Word application
Word._Application wordApplication = new Word.Application();

try
{
// Create a new file based on our template
Word._Document wordDocument = wordApplication.Documents.Add(
ref defaultTemplate
, ref missing
, ref missing
, ref missing);

// Make a Word selection object.
Word.Selection selection = wordApplication.Selection;

//Count the number of documents to insert;
int documentCount = filesToMerge.Length;

//A counter that signals that we shoudn't insert a page
break at the end of document.
int breakStop = 0;

// Loop thru each of the Word documents
foreach (string file in filesToMerge)
{
System.Console.WriteLine(file);
breakStop++;
// Insert the files to our template
selection.InsertFile(
file
, ref missing
, ref missing
, ref missing
, ref missing);

//Do we want page breaks added after each documents?
if (insertPageBreaks && breakStop != documentCount)
{
selection.InsertBreak(ref pageBreak);
}
}

// Save the document to it's output file.
wordDocument.SaveAs(
ref outputFile
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing
, ref missing);

// Clean up!
wordDocument = null;
}
catch (Exception ex)
{
//I didn't include a default error handler so i'm just
throwing the error
throw ex;
}
finally
{
// Finally, Close our Word application
wordApplication.Quit(ref missing, ref missing, ref missing);
}
}
}
}
 
J

Jean-Guy Marcil

gretchog said:
I have a C# program which is designed to concatenate word documents (.docx)
together. I'm receiving no compile or run-time errors, yet the program is not
producing an output document at all. Any help would be appreciated, code
below (there's quite a lot):

This is aVBA group, you may be lucky though... Someone with a few hours to
waste and familiarity with C# may drop by...

Before posting such a tremendous amount of code (Are all those classes and
events even relevant to the problem you experience?), have you tried
debugging step by step to see if each line of code does what you expect it to?
If you find a line that does not behave as expected, and if you cannot
figure out why, then you are about 100% more likely to get help if you do
some of this basic leg work first...
 
G

gretchog

Thanks Marcil, I have tried debugging, including with breakpoints etc. The
problem is, I'm new to the C family (fairly new to programming, faint
background in Java) and especially as I don't know where the problem is
occurring, I wanted to post as much code as possible for checking. As I
mentioned, no errors have appeared either in the compiling or running either,
so I really am confused.

I just hope a C# coder takes pity on me :). Any advice on where I'd be
better to post this? I couldn't find any forums which specifically dealt with
C# and Office...
 
J

Jean-Guy Marcil

gretchog said:
Thanks Marcil, I have tried debugging, including with breakpoints etc. The
problem is, I'm new to the C family (fairly new to programming, faint
background in Java) and especially as I don't know where the problem is
occurring, I wanted to post as much code as possible for checking. As I
mentioned, no errors have appeared either in the compiling or running either,
so I really am confused.

I just hope a C# coder takes pity on me :). Any advice on where I'd be
better to post this? I couldn't find any forums which specifically dealt with
C# and Office...

Try the MSDN forums on VSTO
http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=16&SiteID=1
On the Forum home page
(http://forums.microsoft.com/MSDN/default.aspx?SiteID=1) you will find a few
forums dealing specifically with C#.
 
C

Cindy M.

Hi =?Utf-8?B?Z3JldGNob2c=?=,

Which version of Word are you targeting? And which version are you testing
against on your development machine?
I have a C# program which is designed to concatenate word documents (.docx)
together. I'm receiving no compile or run-time errors, yet the program is not
producing an output document at all. Any help would be appreciated, code
below (there's quite a lot):
Any code manipulating Office should be in Try...Catch blocks. The COM
application may otherwise not return error information to the managed code and
will fail silently. I recommend using a MessageBox.show(ex.Message) in the Catch
block so that you see the message immediately.

From the look of it, the optimal place to put a break point would be in the
MsWord class, fairly close to the beginning (Merge, maybe). Once it hits the
break point, use F11 to step through. Check the values of the variables being
passed into the class, as you go, to make sure they contain the values you
expect. (For example, if the Length of filesToMerge is 0 you've got a problem.)

Also, for debugging purposes, make the Word Application instance visible. This
can give you an idea about what's happening as you step through.

At the end, since you're quitting the Word application, you may want to Close
the wordDocument before assigning it "null". Otherwise, you risk creating a
memory leak.

The links Jean Guy gave you aren't necessarily the best places to ask this. The
VSTO forum technically doesn't support WinForms, Console and ASP.NET
applications, as VSTO is a particular technology that runs within the Office
application interface. The folks in the C# forums aren't really "into" Office
automation. The most appropriate place to go with this would be the
office.developer.automation newsgroup, although you may not find much more help
there. There just aren't a lot of C# people with in-depth experience sharing
their knowledge about working with Office apps.
Http://www.microsoft.com/office/community/en-us/default.mspx?
dg=microsoft.public.office.developer.automation&lang=en&cr=US

I can very much recommend two books if you're going to be doing much with Office
and C#:

.NET Development for Office by Andrew Whitechapel
Visual Studio Tools for Office Using C# by Eric Carter and Eric Lippert

The first is a "must have" for you. Even though you (currently) aren't using
VSTO, the second book provides a lot of information about working with the
Office object models.

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 17 2005)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or reply
in the newsgroup and not by e-mail :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top