顯示具有 OLE 標籤的文章。 顯示所有文章
顯示具有 OLE 標籤的文章。 顯示所有文章

2018年7月1日 星期日

BCB OLE操作EXCEL(3)

在用 OLE 操作 Excel 時
有可能會遇到剪貼簿裡的資料過大
導致關閉 Excel 時跳出視窗警告
"是否放棄剪貼簿裡的資料"

要避開的話通常會用關閉 DisplayAlert 的方法來避免
但我常常失敗,原因不明。

所以給失敗的朋友另一個辦法
在 Excel 關閉前複製一格 避免剪貼簿裡資料過多跳出視窗


void __fastcall Excel::Close_2(){
    Exc.Range = Exc.WorkSheet.OlePropertyGet("Cells", 1, 1);
    Exc.Range.OleFunction("Copy");
    Exc.WorkBook.OleFunction("Close", false);
    Exc.App.Exec(Procedure("Quit"));
}

上一篇:
BCB OLE操作EXCEL (2)

2018年5月1日 星期二

BCB OLE操作EXCEL(2)

BCB 操作 EXCEL、WORD ( OLE的應用 )


有時候再操作 EXCEL 和 WORD 的時候,有可能會要應用到 MultiProcess 的概念
但真正需要的地方很少,我自己是用偷懶的方式來避開,
因為互相搶奪導致資料錯誤出現的機率微乎其微。
下面介紹一些我常碰到的錯誤
bool __fastcall JunYe_Word::getDataTable(int index){
    Variant Range;
    bool flag = true;
    try{
        Range = Wd.DataDoc.OlePropertyGet("Tables").OleFunction("Item",index).OlePropertyGet("Range");
    }catch(EOleSysError *e){
        BugReport(L"Ranging Fail !! This Word doesn't have No."+IntToStr(index)+" Table.");
        flag = false;
    }
    if(flag){
        Range.OlePropertyGet("Rows").OleFunction("Item",1).OleFunction("Delete");
        Range.OleFunction("Copy");
    }
    return flag;
}
有時候要 Range 但 FAIL,有可能資料錯誤或跳錯誤訊息,且造成程式當掉的機會很大
這時候就會用 Try and Catch 如上面的程式碼來避免
String __fastcall Excel::getCellValue(int row, int column){
    String data;
    Variant temp;
    try{
        temp = Exc.WorkSheet.OlePropertyGet("Cells", row, column).OlePropertyGet("Value");
        if(VarType(temp) != varError){
            data = temp;
        }
    }catch(EOleSysError *e){
        BugReport(L"The Cell Can't transmit to OleStr");
    }
    return data;
}
這個段程式是防止吃 EXCEL CELL的值時,會導致 Can't transmit to OleStr 的狀況, 不是吃錯值,而是格子可能是#FFFFFF之類的東西,你直接用上述的data(String)去接會錯 Try and Catch 也擋不了( 我自己試擋不了 ),這時我用多了一層判斷, 用 VarType 去檢查 CELL 值是否能轉 OleStr。

上一篇:
BCB OLE操作EXCEL (1)
下一篇:

2018年4月1日 星期日

BCB OLE操作EXCEL(1)

BCB 操作 EXCEL、WORD ( OLE的應用 )


之前有講工作關係需要彙整報告,報告不外乎 WORD、EXCEL、PDF檔

程式要操作 WORD、EXCEL 可以靠微軟的
COM(Component Object Model)或 .NET Framework.
照理說應該要用 .NET Framework ( 比較潮?? ) 但是公司前輩使用的是 COM
新人啥都不懂乖乖跟著學就對了,其實也不知道兩者實際差異
因為從來沒試過另外一種XD

在 COM 的基礎下,OLE ( Object Linking and Embedding )就是我們要用的技術
簡單來說就是把應用程式 ( EXCEL、WORD ) 物件化後給軟體使用
所以在這基礎下達到操作 EXCEL、WORD 和兩者間的溝通操作

這裡使用的 IDE 是 BCB10 拿 EXCEL 作範例

#include "Comobj.hpp" //操作EXCEL
struct _Excel
{
        Variant App;
        Variant WorkBooks;
        Variant WorkBook;
        Variant WorkSheets;
        Variant WorkSheet;
};
首先宣告 Variant 去承接OLE的EXCEL物件
Excel::Excel(){
        Exc.App = CreateOleObject("Excel.Application");
        Exc.App.OlePropertySet("Visible", true);
        Exc.WorkBooks = Exc.App.OlePropertyGet("Workbooks");
}
void __fastcall Excel::Open(AnsiString path){
        Exc.WorkBook = Exc.WorkBooks.OleFunction("Open", OleStr(path));
        Exc.WorkSheets = Exc.WorkBook.OlePropertyGet("Worksheets");
        Exc.WorkSheet = Exc.WorkSheets.OlePropertyGet("Item", 1);
}
void __fastcall Excel::Close(){
        Exc.WorkBook.OleFunction("Close", true);
        Exc.App.Exec(Procedure("Quit"));
}
這裡我分三個FUNCTION 來模擬平時操作EXCEL的狀態( 對我來說直觀好理解 )
constructor 產生EXCEL物件,並開啟工作簿集合( 工作簿想像是EXCEL的外框 )
open            開啟路徑的EXCEL,並在工作表集合要編號為"1"的工作表
close            關閉工作簿,這裡第一行 CODE 代表意義是不儲存就關閉

這裡有個重要東西先講
OLE 物件吃的是 Wide String,這裡用的是萬能的 OleStr() 轉成 Wide String
我從 BCB10 的 UnicodeString 轉過去吃盡苦頭
這時去問了那個唯一可以問的前輩才知道有這個函式,那時真覺得他是活菩薩。
關於 Wide String 和 UnicodeString 的轉換以後再寫一篇

( PS 以下是我的體感,有錯我道歉
關於 OLE 網路上的資源並沒很多
第一個 BCB10 沒人用 (沒有當初BCB6那麼猛),要用都用 Visual C++ 去寫
第二個 OLE 也是一個快被替換的東西
所以用 BCB10 去寫這東西,上網查都是 BCB6 的CODE
所以要注意的是 BCB6 跟 BCB10 字串的差異 )


下一篇:
BCB OLE操作EXCEL (2)

參考來源:
1. http://skybow.pixnet.net/blog/post/98858843-%5Bbcb%5D%E7%94%A8c%2B%2B-builder%E6%8E%A7%E5%88%B6excel%E6%AA%94%E6%A1%88%E8%AE%80%E5%8F%96
2. https://zh.wikipedia.org/wiki/%E7%BB%84%E4%BB%B6%E5%AF%B9%E8%B1%A1%E6%A8%A1%E5%9E%8B
3. https://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1%E9%93%BE%E6%8E%A5%E4%B8%8E%E5%B5%8C%E5%85%A5

Popular Posts