|
Ok I know that I have a large number of questions here. Please, I need all the help I can get on this one.
I have an application that is putting data into an Excel spreadsheet. I have also created a mail merge document to read that data into a form letter. How can I do the following?
1. Open Word 2. Open form letter document 3. Merge to the printer 4. Close Word after printing
or
3. Merge to a new document 4. Close the form letter document if a new doc is created
I have the following references in the project: Microsoft.Office.Core Excel Word
Here is what I have so far in code: Dim wordApp As New Word.Application() Dim wordDoc As Word.Document() = wordApp.Documents.Open("[path]\EditReport.doc")
wordApp.ActiveDocument.Merge("[path]\EditReports.xls", )
In the merge method there is a second argument that designates the merge target but I don't know what to put there. I am just shooting in the dark with this whole reporting system, I have never written anything that uses Office. When I run the program in debug mode it locks up when I try to open the document, any ideas?
I have also noticed another problem in the Excel portion of the app. Here is a snippet of the code:
Dim excelApp As New Excel.Application() Dim excelBook As Excel.Workbook = excelApp.Workbooks.Open("[path]\EditReports.xls") Dim excelWorksheet As Excel.Worksheet = CType(excelBook.Worksheets(1), Excel.Worksheet)
'clear the worksheet and repopulate the data
excelBook.Save() excelApp.Quit() excelWorksheet = Nothing excelBook = Nothing excelApp = Nothing
The problem is that even after I quit the app and set all my objects to nothing there is still an Excel process listed in the Task Manager. I can only open EditReports.xls in read only mode because it says that someone else has it opened. After I end the process I am able to open the file. How do I completely release the process?
One last question, where can I find some documentation for the objects in Office and how to use them?
Thank you for your help Michael Dove University of Iowa
|
| MigrationUser 1 Thursday, February 13, 2003 11:08 AM |
I fixed my lock up problem. I set wordApp.Visible = True and ran the program again. There was a dialog box that told me the problem was with the file it was trying to open. That is now fixed. I am still wanting to see how I can automate the mail merge options. I evently want to have this so the user dosen't have to interact with either Excel or Word.
Micahel Dove University of Iowa |
| MigrationUser 1 Thursday, February 13, 2003 11:38 AM |
Ok I have solved all my issues to this point except one. I am going to post my code here for thoes that are looking for a solution like this in the future and then talk about the one hangup left.
-------------------------------------------------------------------------------------------
Private bolOutputPrinter As Boolean = True
Public Sub runEditReport() Dim intFPeriodPKId As Int64 = findFiscalPeriod("Edit Reports") Dim dsReport As New DataSet() Dim daReport As New SqlDataAdapter() Dim conReport As New SqlConnection() Dim cmdReport As New SqlCommand()
Try conReport.ConnectionString = modUser.connectionString cmdReport = New SqlCommand("dbo.USP_RPT_CR_SUMMARY", conReport) cmdReport.CommandType = CommandType.StoredProcedure cmdReport.Parameters.Add("@intFKPeriod", SqlDbType.BigInt).Value = Convert.ToInt64(intFPeriodPKId) daReport.SelectCommand = cmdReport daReport.Fill(dsReport) modUser.CloseConnection(conReport) Catch er As Exception MessageBox.Show("An Exception Occurred in application, Please notify DB Admin of the following message: " & Chr(13) & Chr(13) & er.ToString, "Error in Application") Exit Sub End Try
' Open Excel to dump the data into Dim excelApp As New Excel.Application() Dim excelBook As Excel.Workbook = excelApp.Workbooks.Open("[path]\EditReports.xls") Dim excelWorksheet As Excel.Worksheet = CType(excelBook.Worksheets(1), Excel.Worksheet)
With excelWorksheet .UsedRange.Select() .Cells.Clear() .Columns().ColumnWidth = 15 .Range("A1").Value = "Form" .Range("A1").Font.Bold = True ... continue for the rest of the header row
'Start outputing the data on the second row Dim i As Integer = 2 ' Loop through the Rows collection of the DataSet and write the data ' in each row to the cells in Excel. Dim dr As DataRow For Each dr In dsReport.Tables(0).Rows .Range("A" & i.ToString).Value = dr(0) 'Form Name ' continue for the rest of the columns in the dataset i += 1 Next End With
'done with the data, now save and exit excel in preperation for the mail merge. excelBook.Save() excelBook.Close() excelApp.Quit() excelWorksheet = Nothing excelBook = Nothing excelApp = Nothing
'Open the template file Dim wordApp As New Word.ApplicationClass() wordApp.Visible = True Dim wordDoc As Word.DocumentClass = wordApp.Documents.Open("[path]\EditReport.doc", , True, False)
'Output the Mail Merge to the chosen destination If bolOutputPrinter Then wordDoc.MailMerge.Destination = Word.WdMailMergeDestination.wdSendToPrinter wordDoc.MailMerge.Execute() wordDoc.Close(False) wordApp.Quit(False) Else wordDoc.MailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument wordDoc.MailMerge.Execute() wordDoc.Close(False) End If
End Sub
Private Function findFiscalPeriod(ByVal ReportName As String) As Int64 Dim frmReport As New frmRunReport() ' Get the PKId of the Fiscal Period the user wants to see. frmReport.Text = ReportName frmReport.ShowDialog() bolOutputPrinter = frmReport.rbOutput1.Checked Return Convert.ToInt64(frmReport.txtFPeriodPKId.Text) End Function
<end code>---------------------------------------------------------------------------------------
There is a form (frmRunReport) that the user interfaces with to choose the fiscal year and fiscal period (month) and the method of output (printer or word doc) The forien key for the fiscal period is passed to a stored procedure which then creates a temp table gathering all the various data needed. The same procedure returns the data in the temp table via a select statement. The program them puts the data into a dataset and sends it to an excel spreadsheet. Once the data is in the spreadsheet it is saved and excel is closed. Then we open Word and access a mail merge document that was made for the excel file. If the user chose to send directly to the printer we quit the Word.Application, otherwise we just close the template file.
Ok, now that you know how the system works I still have one problem. Even though I perform the following code there is still an active Excel process until the program closes. This active process keeps me from running the same report or another report until I close the program and restart it.
------------------------------------------------------------------ excelBook.Save() excelBook.Close() excelApp.Quit() excelWorksheet = Nothing excelBook = Nothing excelApp = Nothing <end code>-------------------------------------------------------------
Is there somthing that I am missing?
Michael Dove University of Iowa |
| MigrationUser 1 Thursday, February 13, 2003 3:24 PM |
1. Force a garbage collection:
GC.Collect()
If that doesn't work...
2. Kill Excel yourself:
Dim prc As Process For Each prc In Process.GetProcessesByName("excel") prc.Kill() Next
|
| MigrationUser 1 Thursday, February 13, 2003 3:59 PM |
Josh,
The forcing of garbage collection didn't work and I realy don't like to manualy kill any process of excel that might be running. What if the user had a spreadsheet open while they were running my program. I will kill the one associated with my program as well as the instance that they had open for other reasons. If there was some way of knowing for sure that I killed only the one associated with my program then the kill would be ok.
Any other ideas?
Michael Dove University of Iowa |
| MigrationUser 1 Thursday, February 13, 2003 4:52 PM |
Yea, I'm not really fond of forcing a garbage collection (which ought to work, as long as you've called the ReleaseComObject method), or of killing the process.
The problem is that you're creating "hidden" excel objects as you work with the various methods and properties of Excel, all of which appear innocuous. One alternative is to always EXPLICITLY declare and reference every single Excel object you touch, which is extremely difficult.
I've found that most of these problems just simlpy go away if you download, install, and use the Office PIAs available on the Office web site. Have you gone that route? -- Ken |
| MigrationUser 1 Monday, February 17, 2003 4:33 PM |
Hi There
If you want to do mail merge of Word documents with .NET you can use automation with COM interop. But there is another way which might also work for you. WordReports from www.jisys.com has a mail merge example that creates a Word document without word Automation.
Take a look, they have an evaulation component.
Download WordReports (with mail merge example) : <a href="http://www.jisys.com">www.jisys.com</a>
But if you want Excel as well (like in this example) then you still need to use interop as well.
Hope that helps.
|
| MigrationUser 1 Tuesday, August 12, 2003 7:41 PM |
I have almost an identical problem and when i am trying to use part of your code it gives me a error message! the error message is as follows
---------------------------------<Error message> --------------- An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in WindowsApplication1.exe
Additional information: Old format or invalid type library. ---------------------------------------
I think the error is caused due to the lack of a reference to a specific library. the libraries that i have used for reference are:
1. Microsoft Excel 9.0 Object Library 2. Microsoft Office 9.0 Object Library
is there any other library that i must have reference to? and to i have to refer to the libraries from inside the code or i just add them as a reference and thats all?
Thank you for your help!! Andreas
|
| MigrationUser 1 Tuesday, September 02, 2003 7:33 AM |
I've encountered this same issue of not being able to kill the excel process when my application has finished. Have you found a resolution? Also, on a side note I run many of my excel processes invisible to the user but I haven't figured out how to eliminate the 'Save As' dialouge boxes from displaying when I call the Excel.save method. Any ideas on this one. |
| MigrationUser 1 Friday, October 17, 2003 5:29 PM |
Ken - It appears the Office PIA's that are available work for the Office XP 2002 suite. Is there a set for Office 2000 - Library 9.0 that you know of? Is the 10.0 Library backward compatible? Help I'm a little clueless here... |
| MigrationUser 1 Monday, October 20, 2003 9:26 AM |
Nope. For earlier versions, you simply set a reference, and let VS.NET create a private interop assembly for you. Just beware of memory issues, and look into the ReleaseComObject method call. |
| MigrationUser 1 Monday, October 20, 2003 4:26 PM |
Ken - Thank you so much for the insight. I am hopeful this will also take care of the dialouge boxes that appear and require user input when attempting to delete or save an excel sheet during an application that produces automated excel reports, etc.
Brent
|
| MigrationUser 1 Monday, October 20, 2003 5:28 PM |
Nope, that's the Application.DisplayAlerts property. This is covered in the white paper on <a href="http://msdn.microsoft.com/vstudio/office/default.aspx?pull=/library/en-us/odc_vsto2003_ta/html/excelobj.asp">MSDN</a> on the topic of programming Excel from Visual Studio Tools for Office. I'm pretty sure I mentioned this earlier in the thread, but it's worth downloading and reading if you're just getting started programming Excel from .NET. Although the white paper refers to a demo that requires Office 2003, every single Excel issue covered in the white paper refers to any version of Excel. |
| MigrationUser 1 Tuesday, October 21, 2003 8:29 AM |