BCB使用Variant和Automation对象操作Word

BCB使用Variant和Automation对象操作Word
 最近,我需要在基于BCB开发的程序上增加导出Word报表功能,由于之前使用Variant和Automation对象操作过Excel,于是放弃了使用Office2k的TWordApplication控件的方式,直接使用Variant就开始了。期间,我在网上搜索资料,发现会的人还真是少,当然了,除了“OLE专业户”妖哥了,在此表示感谢。通过这几天的努力,我还真收获了不少,特别是如何将VBA语言转换为BCB语言。想起这几天网上搜资料的辛苦,于是我决定把心得写下来,希望能帮到自己和其他有需要的人。
--By OYYJ

一、 基础概念
Word对象代表一个Word 的元素,如文档(Documents)、段落(Paragraphs)、表格(Tables)书签或单个的字符。
集合是用来存储Word中的一组对象。每一个集合将有两个使它有用的关键资源:Count属性和Item方法。Count属性说明在集合中有多少对象。Item方法则用于取得对一个请求项的引用,或者通过数字或者通过名字(如果该对象有一个的话)。例如,一个集合对象中可包含文档中的所有书签对象。通过使用属性和方法,可以修改单个的对象,也可修改整个的对象集合。属性是对象的一个特性或者该对象操作的一个方面。例如文档属性包含名称、内容、保存状态,以及是否启用修订。要更改一个对象的属性,可以修改属性的值。方法是对象可以进行的动作。
Variant使得使用Automation非常简单,在得到和操作Automation对象时最有用的方法是:
CreateObject()
GetActiveObject()
OleFunction()
OleProcedure()
OlePropertyGet()
OlePropertySet()
OleFunction()、OleProcedure()、OlePropertyGet()、OlePropertySet()本质上是对Exec()方法的包装器。Exec()由BCB使用以便执行一个进程或函数或者以取出或设置一个属性值。要做到这个,它依赖于如下四个类来访问想要的Automation功能:
Function()
Procedure()
PropertyGet()
PropertySet()
两种不同的使用方法见如下代码:
创建一个新的应用程序,放置一个Button在窗体上,命名它为Button_LaunchWord,标题为Launch Word。加入如下代码到该Button的OnClick事件中。
void __fastcall TForm_Automation::Button_LaunchWordClick(TObject *Sender)
{
    Variant word_app;
    Variant word_docs;
Variant word_select;

    word_app = Variant::CreateObject("word.application");
    word_docs = word_app.OlePropertyGet("Documents");
    word_docs.OleProcedure("Add");

    word_app.OlePropertySet("Visible", (Variant)true);
}
 使用Exec()建立相同的代码如下:
void __fastcall TForm_Automation::Button_WordExecClick(TObject *Sender)
{
    Variant word_app;
    Variant word_docs;

    Function Documents("Documents");//--Define the Documents funciton
    Function AddDocument("Add");//--Define the add documents function
    PropertySet Visibility("Visible");//--Define the visibility property

    word_app = Variant::CreateObject("word.application");
    word_docs = word_app.Exec(Documents);
    word_docs.Exec(AddDocument);
    Visibility << true;
    word_app.Exec(Visibility);
}
二、 VBA转BCB对比
1、 在Word中插入表格的VBA如下:
ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=15, NumColumns:=4,        DefaultTableBehavior:=wdWord9TableBehavior,AutoFitBehavior:=wdAutoFitFixed
 翻译成BCB如下:
word_select = word_app.OlePropertyGet("Selection");
word_app.OlePropertyGet("ActiveDocument").OlePropertyGet("Tables").
         OleProcedure("Add", word_select.OlePropertyGet("Range"), nRowCount, nColCount, 1, 0);
其中VBA的Selection为BCB中Word应用的选中word_app.OlePropertyGet("Selection")。
2、 选中Word中的表1,使表格文字均居中显示的VBA如下:
Selection.Tables(1).Select
Selection.SelectCell
Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
翻译成BCB如下:
word_table = word_app.OlePropertyGet("ActiveDocument").OlePropertyGet("Tables").
                      OleFunction("Item", 1);//Tables(1)
word_table.OleFunction("Select");//Tables(1).Select
word_select.OleFunction("SelectCell");//Selection.SelectCell
word_select.OlePropertyGet("ParagraphFormat").
            OlePropertySet("Alignment", wdAlignParagraphCenter);
             //Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
   //使用wdAlignParagraphCenter 需要#include "Word_2K_SRVR.h"
 word_select.OlePropertyGet("Cells").
             OlePropertySet("VerticalAlignment", wdCellAlignVerticalCenter);
             //Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
 至此,你是否找到了一些规律了呢?更多的就需要自己去尝试了。
三、 例程
在如上创建的工程中,操作Word插入两个表格,一个为15X4的,一个为8X4的,均带
表头。
void __fastcall TForm_Automation::Button_LaunchWordClick(TObject *Sender)
{
    Variant word_app;
    Variant word_docs;
    Variant word_activedoc;
    Variant word_select;
    Variant word_table;
    Variant word_paras;
    Variant word_para;
    Variant start_cell;
    Variant end_cell;
    Variant my_cell;
   
    int nRowCount;
    int nColCount;
    AnsiString filename;

    try
    {
        try
        {
            word_app = Variant::CreateObject("Word.Application");
        }
        catch (...)
        {
            ShowMessage("运行Word出错,请确认安装了Office!");
            word_app = Unassigned;
            return;
        }

        if (!DirectoryExists(ExtractFilePath(Application->ExeName) + "文件夹WordFile不存在
        {   //创建文件夹WordFile
            if (!CreateDir(ExtractFilePath(Application->ExeName) + "\\WordFile"))
                throw Exception("无法创建文件夹WordFile");
            else
            {
                SaveDialog_Word->InitialDir = (ExtractFilePath(Application->ExeName) + "WordFile").c_str();
                SaveDialog_Word->FileName = (ExtractFilePath(Application->ExeName) + "WordFile\\BCTS-1报表.doc").c_str();
            }
        }
        //文件夹WordFile存在
        else
        {
            SaveDialog_Word->InitialDir = (ExtractFilePath(Application->ExeName) + "WordFile").c_str();
            SaveDialog_Word->FileName = (ExtractFilePath(Application->ExeName) + "WordFile\\BCTS-1报表.doc").c_str();
        }

        if (SaveDialog_Word->Execute())
        {

            filename = SaveDialog_Word->FileName;
            Form_Automation->Enabled = false;
        }
        else
        {
            Form_Automation->Enabled = true;
            return;
        }

        try
        {

            word_app.OlePropertySet("Visible", (Variant)false);

            //新建一个文档并保存
            word_docs = word_app.OlePropertyGet("Documents");
            word_docs.OleProcedure("Add");
            word_activedoc = word_app.OlePropertyGet("ActiveDocument");
            word_activedoc.OleFunction("SaveAs", filename.c_str());
            //
            word_select = word_app.OlePropertyGet("Selection");
            //添加标题
            word_select.OlePropertyGet("Font").OlePropertySet("Size", 20);
            word_select.OlePropertyGet("Font").OlePropertySet("Name", "黑体");
            word_select.OlePropertyGet("ParagraphFormat").
                        OlePropertySet("Alignment", wdAlignParagraphCenter);
            word_select.OleProcedure("TypeText", "BCTS-1报表\n");
            //添加段落
            word_select.OlePropertyGet("Font").OlePropertySet("Size", 10);
            word_select.OlePropertyGet("Font").OlePropertySet("Name", "宋体");
            Procedure AddText("TypeText");
            word_select.Exec(AddText << WideString("\n"));
            //插入表格1--分、合闸时间测量
            nRowCount = 15;
            nColCount = 4;
            word_activedoc.OlePropertyGet("Tables").OleProcedure("Add", word_select.OlePropertyGet("Range"), nRowCount, nColCount, 1, 0);
                //使表格1中文字居中
            word_table = word_activedoc.OlePropertyGet("Tables").OleFunction("Item", 1);//Tables(1)
            word_table.OleFunction("Select");//Tables(1).Select
            word_select.OleFunction("SelectCell");//Selection.SelectCell
            word_select.OlePropertyGet("ParagraphFormat").
                        OlePropertySet("Alignment", wdAlignParagraphCenter);
                        //Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
            word_select.OlePropertyGet("Cells").
                        OlePropertySet("VerticalAlignment", wdCellAlignVerticalCenter);
                        //Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
                //合并单元格 做表头
                    //(1, 1)-(1, 4)合并为(1, 1)
            start_cell = word_table.OleFunction("Cell", (Variant)1, (Variant)1);
            end_cell = word_table.OleFunction("Cell", (Variant)1, (Variant)4);
            start_cell.OleProcedure("Merge", end_cell);
            start_cell.OlePropertySet("Range", "一、分、合闸时间测量");
            start_cell.OleFunction("Select");
            word_select.OlePropertyGet("ParagraphFormat").OlePropertySet("Alignment", wdAlignParagraphLeft);
                    //(2, 1)-(2, 2)合并为(2, 1)
            start_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)1);
            end_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)2);
            start_cell.OleProcedure("Merge", end_cell);
            start_cell.OlePropertySet("Range", "合闸时间");
                //注意前面已经合并的(2, 1)-(2, 2)变成了新的(2, 1)
            start_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)2);
            end_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)3);
            start_cell.OleProcedure("Merge", end_cell);
            start_cell.OlePropertySet("Range", "分闸时间");
                //
            my_cell = word_table.OleFunction("Cell", (Variant)3, (Variant)1);
            my_cell.OlePropertySet("Range", "标准值(ms)");
            my_cell = word_table.OleFunction("Cell", (Variant)3, (Variant)2);
            my_cell.OlePropertySet("Range", "指示值(ms)");
            my_cell = word_table.OleFunction("Cell", (Variant)3, (Variant)3);
            my_cell.OlePropertySet("Range", "标准值(ms)");
            my_cell = word_table.OleFunction("Cell", (Variant)3, (Variant)4);
            my_cell.OlePropertySet("Range", "指示值(ms)");
            /*//往表格中填入数据
            for (int i = 0; i < 12; i++)
            {
                my_cell = word_table.OleFunction("Cell", (Variant)(4+i), (Variant)1);
                my_cell.OlePropertySet("Range", StringGrid1->Cells[1][i+1].c_str());
                my_cell = word_table.OleFunction("Cell", (Variant)(4+i), (Variant)3);
                my_cell.OlePropertySet("Range", StringGrid1->Cells[4][i+1].c_str());
            }
            */

            //添加段落
            word_paras = word_activedoc.OlePropertyGet("Paragraphs");
            word_paras.OleFunction("Add");
            word_paras.OleFunction("Add");
            word_para = word_paras.OleFunction("Item", 74);

            //插入表格2--弹跳时间测量
            nRowCount = 8;
            nColCount = 4;
            word_activedoc.OlePropertyGet("Tables").OleProcedure("Add", word_para.OlePropertyGet("Range"), nRowCount, nColCount, 1, 0);
            //操作表格
            word_table = word_activedoc.OleFunction("Range").OlePropertyGet("Tables").OleFunction("Item", 2);
            word_table.OleFunction("Select");
            word_select.OleFunction("SelectCell");
            word_select.OlePropertyGet("ParagraphFormat").OlePropertySet("Alignment", wdAlignParagraphCenter);
            word_select.OlePropertyGet("Cells").OlePropertySet("VerticalAlignment", wdCellAlignVerticalCenter);
            //合并单元格
                //(1, 1)-(1, 4)
            start_cell = word_table.OleFunction("Cell", (Variant)1, (Variant)1);
            end_cell = word_table.OleFunction("Cell", (Variant)1, (Variant)4);
            start_cell.OleProcedure("Merge", end_cell);
            start_cell.OlePropertySet("Range", "二、弹跳时间测量");
            start_cell.OleFunction("Select");
            word_select.OlePropertyGet("ParagraphFormat").OlePropertySet("Alignment", wdAlignParagraphLeft);
            //
            my_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)1);
            my_cell.OlePropertySet("Range", "标准值(ms)");
            my_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)2);
            my_cell.OlePropertySet("Range", "指示值(ms)");
            my_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)3);
            my_cell.OlePropertySet("Range", "标准值(ms)");
            my_cell = word_table.OleFunction("Cell", (Variant)2, (Variant)4);
            my_cell.OlePropertySet("Range", "指示值(ms)");
            /*
            for (int i = 0; i < 6; i++)
            {
                my_cell = word_table.OleFunction("Cell", (Variant)(3+i), (Variant)1);
                my_cell.OlePropertySet("Range", StringGrid1->Cells[3][i+1].c_str());
                my_cell = word_table.OleFunction("Cell", (Variant)(3+i), (Variant)3);
                my_cell.OlePropertySet("Range", StringGrid1->Cells[3][i+1+6].c_str());
            }
            */
            //将光标移到文档结尾
            word_select.OleProcedure("EndKey", 6);
        }
        __finally
        {
            word_activedoc.OleProcedure("Save");
            word_activedoc = Unassigned;
        }
    }
     __finally
     {
        word_app.OleProcedure("Quit");
        word_app = Unassigned;
     }
     ShowMessage("导出报表完毕!");
     Form_Automation->Enabled = true;
}
                               

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值