Word Backward compatibility
Many thanks to RobDog888 for the answer to my earlier question.
Moving along the same lines, the project I'm working on was built with VS 2003 and Office 2003 installed locally. Most of the machines using this program will be Office 2003 based, however there are a few machines that are Office XP (2002) and Office 2000 based. I would like to add backward compatibility into my program to use the Word (Mail Merge) functions so that it is more or less version independent.
I've read some of the info on the Office XP PIA's on microsoft's site, but it's all written from the standpoint of upgrading, that is building an application for that version assuming you are using an older version.
I don't suppose someone could point me in the right direction?
Thanks in advance.
Re: Word Backward compatibility
You will need to use "Late Binding" for all your object variable declarations to ensure backward compatability. Have a search in this forum for that term.
Also, you will need to ensure that you don't call any methods, properties or events that do not exist in prior versions. This can usuall be handled either by error trapping or extensive testing...
Re: Word Backward compatibility
I believe I've correctly modified the code to do late binding on all object types. I also believe that I am not calling any methods that would be unsupported by Office (Word) 2002 (MailMerge). Obviously it's not overly complex code, it just takes some data out of a Microsoft SQL database and calls out to word and merges it.
However when I take the following code to a machine with Office 2002(XP) installed I will get the error that follows the code.
As always pointers, suggestions, help are greatly appreciated. :)
Code:
Public Sub mergeDoc()
Dim docPath As String = "C:\porcupine\docs\"
'Dim wrdApp As New Word.Application
Dim wrdApp As Object
wrdApp = CreateObject("Word.Application")
'Dim wrdDoc As New Word.Document
Dim wrdDoc As Object
wrdDoc = CreateObject("Word.Document")
Dim TemplateFile As String = docPath + TreeView1.SelectedNode.Text & ".doc"
Dim oMissing As New Object
Dim oFile As New Object
Dim oSql As New Object
Dim oFalse = False
Dim oTrue = True
Dim ODCFile As New Object
ODCFile = "C:\Porcupine\memberdata.odc"
oFile = TemplateFile
oMissing = System.Reflection.Missing.Value
wrdApp.Visible = True
wrdDoc = wrdApp.Documents.Open(oFile, oMissing, oTrue, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing)
wrdDoc.Select()
Dim wrdMailMerge = wrdDoc.MailMerge
oSql = "SELECT * FROM MemberData WHERE MBRNAME ='" & ComboBox1.Text & "'"
wrdDoc.MailMerge.OpenDataSource(ODCFile, oMissing, oMissing, oFalse, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oSql, oMissing, oFalse, oMissing)
wrdMailMerge.SuppressBlankLines = True
wrdMailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument
wrdMailMerge.Execute(oFalse)
wrdDoc.Close(oFalse, oMissing, oMissing)
wrdMailMerge = Nothing
wrdDoc = Nothing
wrdApp = Nothing
End Sub
Quote:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.Runtime.InteropServices.COMException (0x80020005): Type mismatch.
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
at VBPorcupineFrontEnd.Form1.mergeDoc()
at VBPorcupineFrontEnd.Form1.Button2_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Re: Word Backward compatibility
Here are the first couple of error fixes...
VB Code:
Dim TemplateFile As String = docPath + TreeView1.SelectedNode.Text & ".doc"
'Should be
Dim TemplateFile As String = docPath [b]&[/b] TreeView1.SelectedNode.Text & ".doc"
Dim ODCFile As New Object
'Should be...
Dim ODCFile As String
ODCFile = "C:\Porcupine\memberdata.odc"
Re: Word Backward compatibility
You should also call the .Quit method instead of just destroying the object variable.
VB Code:
wrdApp.Quit()
wrdApp = Nothing
I think that should just about do it.
Re: Word Backward compatibility
wrdApp.Quit() forces the new document closed, I need the document to stay open so that the user can make changes, additions, deletions etc to the document and then print it - all before closing it. Essentially I want the close control to be a user controlled thing, not something the program forces.
If that makes sense.
Re: Word Backward compatibility
Yes, I see how you need it. ;)
Re: Word Backward compatibility
I knew that technical communication class would pay off! :D
Any thoughts as to why the code won't run against Word 2002 and leave me with the error?
Re: Word Backward compatibility
Your using 2005 I think so the JIT is a bit different.
Looks like the last error is...
Quote:
Type mismatch.
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
Which should correspond to ...
VB Code:
.OpenDataSource
'Or
.Open
'Parameters. Check the type of arguements passed and make sure they are the type they are supossed to be
Re: Word Backward compatibility
Using Visual Studio 2003 actually.
I'm playing with those statements now. It looks like the wrdApp.Open statement was overly complex.
Code:
wrdDoc = wrdApp.Documents.Open(oFile)
That change gets me closer, Word 2002 is now opening the template file at least. Now I'm getting Data Source errors which I am going to guess are a result of the :
Code:
wrdDoc.MailMerge.OpenDataSource(ODCFile, oMissing, oMissing, oFalse, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oSql, oMissing, oFalse, oMissing)
Being overly complicated. Let me see what I come up with.
Re: Word Backward compatibility
I think only the first argument is required.
Re: Word Backward compatibility
Quote:
Originally Posted by RobDog888
I think only the first argument is required.
I will give that a try, but if I remove everything beyond ODCFile it won't know what SQL command to run to get the specific record I need to merge to the document I don't think.
Nope, it just grabs the first record off the database.
Re: Word Backward compatibility
Mostly for the open method but just supply what you need and not all. ;)
Re: Word Backward compatibility
Code:
wrdDoc.MailMerge.OpenDataSource(ODCFile, , , , , , , , , , , , oSql)
I tried to just dumb it down - runs on the 2003 box this way, but still borks out on the 2002 box.
Quote:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.Runtime.InteropServices.COMException (0x800A1722): Word was unable to open the data source.
at Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn)
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
at VBPorcupineFrontEnd.Form1.mergeDoc()
at VBPorcupineFrontEnd.Form1.Button2_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Re: Word Backward compatibility
Getting closer.
Current Code:
Code:
Dim docPath As String = "C:\porcupine\docs\"
'Dim wrdApp As New Word.Application
Dim wrdApp As Object
wrdApp = CreateObject("Word.Application")
'Dim wrdDoc As New Word.Document
Dim wrdDoc As Object
wrdDoc = CreateObject("Word.Document")
Dim TemplateFile As String = docPath + TreeView1.SelectedNode.Text & ".doc"
Dim oMissing As New Object
Dim oFile As New Object
Dim oSql As Object
Dim oFalse As Object
Dim oTrue As Object
Dim ODCFile As String
oMissing = System.Reflection.Missing.Value
oFile = TemplateFile
oSql = "SELECT * FROM MemberData WHERE MBRNAME ='" & ComboBox1.Text & "'"
oFalse = False
oTrue = True
ODCFile = "C:\Porcupine\memberdata.odc"
wrdApp.Visible = True
wrdDoc = wrdApp.Documents.Open(oFile)
wrdDoc.Select()
Dim wrdMailMerge = wrdDoc.MailMerge
'wrdDoc.MailMerge.OpenDataSource(ODCFile, oMissing, oMissing, oFalse, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oSql, oMissing, oFalse, oMissing)
wrdDoc.MailMerge.OpenDataSource(ODCFile)
wrdMailMerge.SuppressBlankLines = True
wrdMailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument
wrdMailMerge.Execute(oFalse)
wrdDoc.Close(oFalse, oMissing, oMissing)
wrdMailMerge = Nothing
wrdDoc = Nothing
wrdApp = Nothing
It is most definitely something in the
Code:
wrdDoc.MailMerge.OpenDataSource(ODCFile
line.
When I reduce it to simply wrdDoc.MailMerge.OpenDataSource(ODCFile) it runs and merges on the 2002 box - however without the SQL statement that is deeper in that line it just grabs the first record, and not the one that should be selected.
I will continue to hack that line apart and throw some different things at it until something sticks.
Re: Word Backward compatibility
VB Code:
Dim oSql As String 'Object
;)
Re: Word Backward compatibility
Woops, fixed that, but still no go.
I am really begining to wonder if the opendatasource call is the same for 2002 as it is for 2003.
I've been working off the premise that it is the same for both:
call ActiveDocument.MailMerge.opendatasource(
Name, _
Format,
ConfirmConversions,
ReadOnly, _
LinkToSource, _
AddToRecentFiles, _
PasswordDocument, _
PassWordTemplate, _
Revert, _
WritePasswordDocument, _
WritePassWordTemplate, _
Connection, _
SQLstatement, _
sqlstatement1)
Re: Word Backward compatibility
Well according to microsoft it appears to be the same:
2002 - http://support.microsoft.com/kb/324378/
Re: Word Backward compatibility
It appears that:
Code:
wrdDoc.MailMerge.OpenDataSource(Name:=ODCFile, SQLStatement:=oSql)
Works on the 2003 box and helps reduce the clutter of the statement. Unfortunately it still causes errors on 2002.
The following seems to be the prevailing error on all of these attempts at working with the OpenDataSource line:
Quote:
************** Exception Text **************
System.Runtime.InteropServices.COMException (0x800A1722): Word was unable to open the data source.
at Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn)
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
at VBPorcupineFrontEnd.Form1.mergeDoc()
at VBPorcupineFrontEnd.Form1.Button2_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Re: Word Backward compatibility
I'm really a bit stuck at this point. If anyone has any other ideas to try I'm all ears. :)
Thanks!