VC下怎么用VBA

tankbattle 2003-04-29 04:07:20
VC下怎么用VBA?是否要SDK?那里去找?
...全文
182 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
ern 2003-05-02
  • 打赏
  • 举报
回复
目录之后贴出了用mfc开发的方法,另外和你相关的就是前一节——用C++开发。你如果想要的话说一声。因为这个论坛的原因,有些格式有很大问题,将就吧。我用这个方法开发outlook addin的时候是没有问题的。
ern 2003-05-02
  • 打赏
  • 举报
回复
Modify the SaveAs method so that you are passing it a Filename with an invalid path:
oActiveDoc.SaveAs(COleVariant("c:\\badpath\\doc1.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);

COM is able to invoke the SaveAs method because, as far as COM is concerned, it has the correct DISPID, the correct argument types, and so forth. However, the SaveAs method itself fails because of the invalid path. Build and run the application. When the SaveAs method is invoked, the method fails and generates a COleDispatchException and the exception handler kicks in to display the error:



Note that the server's Quit method is called after the catch handlers. Using this layout, when an exception occurs, the Quit method is still called. If the Quit method were in the try block instead, it might not be invoked if an exception occurs and you could risk leaving the server in memory when the procedure ends.

ern 2003-05-02
  • 打赏
  • 举报
回复
Exception Handling
MFC provides two classes for handling exceptions with your Automation code: COleException and COleDispatchException. Both of these classes are derived from the CException base class and can be used with try blocks and catch handlers.

You use COleException to handle general failures with COM calls and COleDispatchException to handle errors that occur on the server's end.

Exercise 7: Implement exception handling in your automation client
This exercise implements exception handling in the MFC Automation client you created in the previous exercise, and then breaks the Automation code so that you can see the exception handler in action.

Modify CExercise6Dlg::OnRun to implement exception handling:

//Commonly used variants.
COleVariant vTrue((short)TRUE),
vFalse((short)FALSE),
vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

//Start a new instance of Microsoft Word
_Application oWordApp;
if (!oWordApp.CreateDispatch("Word.Application", NULL))
{
AfxMessageBox("CreateDispatch failed.",
MB_OK | MB_SETFOREGROUND);
return;
}

try
{

//Create a new document
Documents oDocs;
_Document oDoc;
oDocs = oWordApp.GetDocuments();
oDoc = oDocs.Add(vOpt, vOpt);
//Note for Word 2000: The Add method has 4 arguments in Word 2000.
//If you wrapped the classes from the Word type library
//(msword9.olb),modify the Add method to provide 4 optional
//arguments:
// oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);

//Add text to the document
Selection oSel;
oSel = oWordApp.GetSelection();
oSel.TypeText("one");
oSel.TypeParagraph();
oSel.TypeText("two");
oSel.TypeParagraph();
oSel.TypeText("three");

//Save the document
_Document oActiveDoc;
oActiveDoc = oWordApp.GetActiveDocument();
oActiveDoc.SaveAs(COleVariant("c:\\ doc1.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);
}

catch(COleException *e)
{
LPVOID lpMsg;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e->m_sc,
MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT),(LPTSTR) &lpMsg,
0, NULL);
::MessageBox(NULL, (LPCTSTR)lpMsg, "COM Error",
MB_OK | MB_SETFOREGROUND);
::LocalFree( lpMsg );
}

catch(COleDispatchException *e)
{
char msg[512];
sprintf(msg, "Run-time error '%d':\n\n%s",
e->m_scError & 0x0000FFFF, e->m_strDescription);
::MessageBox(NULL, msg, "Server Error",
MB_OK | MB_SETFOREGROUND);
}


//Quit the application
oWordApp.Quit(vFalse, vOpt, vOpt);

Build and run the application. Everything should work as expected and no exceptions should occur.
Modify the SaveAs method so that you are passing it a COleVariant of type VT_I4 for the first argument, the Filename argument:
oActiveDoc.SaveAs(COleVariant((long)5)),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);

SaveAs expects a string for the Filename argument, so you expect modifying the SaveAs method to generate an error. Build and run the application. When you click the button, the code generates a COleException when invoking the SaveAs method due to a type mismatch for the Filename argument. The exception handler displays a message box:
ern 2003-05-02
  • 打赏
  • 举报
回复
Build and run the application. Click the button to run the Automation code. Confirm that your Automation client created C:\Doc1.doc and that the document contains the text that you expect.
There are some important points to observe about the Automation code in this exercise:

When you call a member function for a wrapper class, you must provide all arguments to the function. You can omit optional arguments by passing a COleVariant with the type code VT_ERROR and the scode DISP_E_PARAMNOTFOUND.
When calling member functions that return a pointer to an IDispatch interface (type LPDISPATCH), you can directly assign the return value to a COleDispatchDriver derived class to attach it to the returned IDispatch pointer:
Documents oDocs;
_Document oDoc;
oDocs = oWordApp.GetDocuments();
oDoc = oDocs.Add(vOpt, vOpt);

This is essentially the same as:

Documents oDocs;
_Document oDoc;
oDocs.AttachDispatch(oWordApp.GetDocuments());
oDoc.AttachDispatch(oDocs.Add(vOpt, vOpt));

You did not directly call COleDispatchDriver::ReleaseDispatch() to release the objects and decrement reference counts. COleDispatchDriver has a data member, m_bAutoRelease, which is set to True when it is constructed. When m_bAutoRelease is True, the object is released when it is destroyed. Because all of the COleDispatchDriver-derived classes in your client have procedure-level scope, the objects are all released automatically when the procedure ends.
In this particular example, you did not use the Document object Doc that was returned from Documents::Add(), but you assigned the return value anyway. Documents::Add() effectively increases the reference count for the Document object when it requests a pointer to its IDispatch interface. This reference count is properly decremented when the procedure ends and the Document object variable Doc loses scope. If you had ignored the returned LPDISPATCH, you might have encountered a problem with the object's reference count and the server might have remained in memory even after your Automation client ended. You should be aware of return values, especially those of type LPDISPATCH.
ern 2003-05-02
  • 打赏
  • 举报
回复
Add the following code to CExercise6App::InitInstance in Exercise6.cpp so that COM services are enabled when your application is initialized:
if(!AfxOleInit())
{
AfxMessageBox("Could not initialize COM services");
return FALSE;
}

Next, select the dialog resource IDD_EXERCISE6_DIALOG. Add a button to the dialog box and name the button IDC_RUN. Add the following code to the button handler:


COleVariant vTrue((short)TRUE),
vFalse((short)FALSE),
vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

//Start a new instance of Microsoft Word
_Application oWordApp;
if (!oWordApp.CreateDispatch("Word.Application", NULL))
{
AfxMessageBox("CreateDispatch failed.", MB_OK | MB_SETFOREGROUND);
return;
}

//Create a new document
Documents oDocs;
_Document oDoc;
oDocs = oWordApp.GetDocuments();
oDoc = oDocs.Add(vOpt, vOpt);
//Note for Word 2000: The Add method has 4 arguments in Word 2000. If
//you wrapped the classes from the Word type library (msword9.olb),
//modify the Add method to provide 4 optional arguments:
// oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);

//Add text to the document
Selection oSel;
oSel = oWordApp.GetSelection();
oSel.TypeText("one");
oSel.TypeParagraph();
oSel.TypeText("two");
oSel.TypeParagraph();
oSel.TypeText("three");

//Save the document
_Document oActiveDoc;
oActiveDoc = oWordApp.GetActiveDocument();
oActiveDoc.SaveAs(COleVariant("c:\\doc1.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);

//Quit the application
oWordApp.Quit(vOpt, vOpt, vOpt);

Note The Documents::Add method in the type library for Microsoft Word 2000 has four arguments, whereas Microsoft Word 97 only has two. If you added wrappers using the Word 2000 type library (Msword9.olb) in step 2, modify the Add method in the code so that it has four arguments, for example:
oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);


Add the directive to include Msword8.h in Exercise6Dlg.cpp:
#include "msword8.h" //or "msword9.h" for Word 2000

Note Add this include directive after the include directive for "stdafx.h." Otherwise, you might receive compile errors.
ern 2003-05-02
  • 打赏
  • 举报
回复
In VBA, the property or method is called… And its equivalent ClassWizard-generated member function is…
Documents property of the Application object LPDISPATCH _Application::GetDocuments()



Add method of the Documents Collection object LPDISPATCH Documents::Add(VARIANT* Template,
VARIANT* NewTemplate)



Selection property of the Application object LPDISPATCH__Application::GetSelection()



TypeText method of the Selection object void Selection::TypeText(LPCTSTR Text)



TypeParagraph method of the Selection object void Selection::TypeParagraph()



ActiveDocument property of the Application object LPDISPATCH _Application::GetActiveDocument()



SaveAs method of the Document object void _Document::SaveAs(VARIANT* FileName,
VARIANT* FileFormat,
VARIANT* LockComments,

VARIANT* Password,
VARIANT* AddToRecentFiles,

VARIANT* WritePassword,

VARIANT* ReadOnlyRecommended,

VARIANT* EmbedTrueTypeFonts,

VARIANT* SaveNativePictureFormat,

VARIANT* SaveFormsData,
VARIANT* SaveAsAOCELetter)

ern 2003-05-02
  • 打赏
  • 举报
回复
On the Project Workspace window, click the ClassView tab. Expand "Exercise6 Classes" to display all the classes that the ClassWizard generated from the Word type library. Double-click the _Application class to display its definition in the Text Editor window. Note that the _Application class is derived from COleDispatchDriver:
// _Application wrapper class

class _Application : public COleDispatchDriver
{

. . .

}

Expand the _Application class on the ClassView tab to display all of its member functions. Double-click GetDocuments() to display its definition in the Text Editor window:
LPDISPATCH _Application::GetDocuments()
{
LPDISPATCH result;
InvokeHelper(0x6, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result,
NULL);
return result;
}


The definition of Application::GetDocuments tells you that it makes a call to COleDispatchDriver::InvokeHelper to invoke the Documents property (DISPATCH_PROPERTYGET) using the DISPID 0x6. _Application::GetDocuments() returns an IDispatch pointer to the Documents class.

Note In VBA, this function is called the Documents property, but the ClassWizard names this function GetDocuments. The ClassWizard names a function based on the context in which the function is invoked.
If the function is a … ClassWizard generates a member function named…
Property that returns a value (DISPATCH_PROPERTYGET) GetFunction
Property that sets a value (DISPATCH_PROPERTYPUT) SetFunction
Method (DISPATCH_METHOD) Function

With ClassView, examine the equivalent member functions for all the objects, properties, and methods that the recorded Word macro used. Compare the member function to its VBA equivalent in the Object Model documentation and you can see a definite correlation. The documentation provides you with a description of the function's purpose, a description of each argument, and the function's return value.

ern 2003-05-02
  • 打赏
  • 举报
回复
COleDispatchDriver::CreateDispatch() Starts a new instance of the server and attaches the COleDispatchDriver object to the server's IDispatch interface
COleDispatchDriver::AttachDispatch() Attaches an IDispatch connection to the COleDispatchDriver object
COleDispatchDriver::DetachDispatch() Detaches a COleDispatchDriver object from an IDispatch interface but does not release it
COleDispatchDriver::ReleaseDispatch() Releases an IDispatch interface
COleDispatchDriver::InvokeHelper() Invokes properties and methods

COleDispatchDriver also has a data member m_lpDispatch, which, as its name implies, is the pointer to the IDispatch interface and is type LPDISPATCH. This data member is often useful when you need to package a VARIANT of type VT_DISPATCH as an argument to an invoked function.

Exercise 6: Creating an automation client with MFC
In this exercise, you will create a MFC Automation client with the same functionality as your C/C++ Automation client. As you progress through the exercise, you might notice that the code has a much clearer one-to-one correlation with the recorded Word macro. This is the attraction of writing Automation code with MFC and the wrapper classes that ClassWizard generates for you.

In Visual Studio, start a new dialog-based MFC AppWizard(EXE) project named Exercise6.
On the View menu, click ClassWizard, and go to the Automation tab. Click Add Class and choose From A Type Library. Browse to the Microsoft Word 97 type library Msword8.olb (or Msword9.olb if you are using Word 2000) and click OK. Select all of the classes the ClassWizard presents and click OK.


Figure 9. Use the ClassWizard to create wrapper functions from a type library.

This process generates two new files in your project: Msword8.cpp and Msword8.h. These files make up the wrapper classes for all the classes and class member functions that the Word type library exposes. Next, examine one of the properties that you will use in your code: the Documents property. As you might recall from your examination of the Object model documentation, Documents is a property of the Application object and returns a Documents collection object that represents all the open documents.

ern 2003-05-02
  • 打赏
  • 举报
回复
Creating an Automation Client with MFC
Now that you have created your Automation client with straight C++, you can see how MFC simplifies this task for you and cuts down the amount of code you write.

The COleDispatchDriver Class
MFC provides a COleDispatchDriver class for handling IDispatch interfaces of Automation objects. You can use the Visual C++ ClassWizard to automatically generate wrapper classes from a Microsoft Office type library. All the classes in the type library that implement IDispatch are wrapped into a new class that is derived from COleDispatchDriver. The ClassWizard also creates member functions that map to all the properties and methods that a class exposes.

These wrapper classes provide several benefits to the MFC programmer:

ClassWizard sets up the call to invoke the function and provides the DISPID, context, parameters, and return value. Thus, you rarely need to make COM calls directly to retrieve function DISPIDs or to invoke functions.
COleDispatchDriver handles reference counts.
ClassWizard generates a member function in such a way that you can pass the function arguments without building a DISPPARAMS structure.
The COleVariant class encapsulates the VARIANT data type. With MFC, you can use COleVariants for your parameters and return values for the wrapped functions.
COleDispatchDriver supports several functions for communicating with Automation servers. The following list describes the ones you are most likely to use.

ern 2003-05-02
  • 打赏
  • 举报
回复
Lori Turner
Microsoft Corporation

March 2000

Summary: This article provides the fundamentals for understanding how to automate Microsoft Office 97 and Microsoft Office 2000 applications. This article starts with the basics and walks you through creating a variety of fully functional Automation clients. It is structured as a tutorial with a large assortment of code samples and provides tips throughout that will facilitate development of your Automation clients. Exercises and sample code are presented for Microsoft Visual Basic, Microsoft Visual C/C++, and Microsoft Foundation Classes (MFC) developers. However, much of the information is generic (not language-specific), so you can apply it regardless of the development language you use. (123 printed pages)

Download the OffAutmn.exe from the MSDN Code Center.

Contents
Introduction
Office Object Models
How an Object Exposes Its Methods and Properties
Creating an Automation Client with Visual Basic
Creating an Automation Client with C++
Creating an Automation Client with MFC
Improving the Performance of Your Automation Code
Handling Events in the Automation Server
Automating Embedded and Linked Office Documents
Sample Code for Automating Microsoft Office Applications
Troubleshooting Common Problems
For More Information


你先看看要哪方面的,上面是目录。实在太长了,如果不全要,就说一声。
Janely 2003-05-02
  • 打赏
  • 举报
回复
贴出来吧,共赏,谢谢!
ern 2003-05-02
  • 打赏
  • 举报
回复
赫赫,这可不是一个问题——用vc要麻烦的多。看看msdn下面一篇文章(我好像引用很多次,骗分数的好文章:) )
ms-help://MS.MSDNQTR.2002APR.1033/dno2kta/html/offaut.htm
200204版的
如果你没有,我可以贴出来
tankbattle 2003-04-29
  • 打赏
  • 举报
回复
我要在VC下操作WORD,怎么办??
ern 2003-04-29
  • 打赏
  • 举报
回复
什么意思?vc调用vba的程序?

5,138

社区成员

发帖
与我相关
我的任务
社区描述
其他开发语言 Office开发/ VBA
社区管理员
  • Office开发/ VBA社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧