天天看點

如何用C#制作Excel AddIn

AddIn 中文翻譯為插件,有時候也叫Plug In,我的了解是,根據程式開發商提供的接口,讓程式加載自定義的代碼片段以完成某種功能。

這個需求源自于一個朋友的要求,他向我陳述了産生需求的原因。

朋友所在工廠的品質部每天需要檢測大量的産品零部件,并且要把檢測的資料制作成報表,這是QC測量員的日常工作。由于最近公司的訂單增多,生産任務的增多也導緻測量員每天需要檢測大量的産品零件,産生大量的測量資料。QC測量員還需要把這些資料整理成規定格式的報表,送出給組長稽核。訂單的增多,會導緻QC測量員工作量增加。他詢問我,是否有辦法可以減少QC測量員的工作量,提高工作效率。

從他的描述中看出,有兩件工作是不斷重複進行的:測量零件和制作報表。對于測量零件,我也沒有辦法去提高效率,除非規定隻檢測部分零件,而不是全部檢測。在工廠規定必須全部檢測的情況下,第一道工序很難優化。對于第二道工序,把測量的資料制作成報表。這一步似乎可以用程式來提高效率。因為要求制作的報表的格式是規定的,隻需要把測量的結果資料導入到規定格式的報表中去,第二步就順利完成。

報表采用EXCEL格式,每行每列的版面已經确定。隻需要把指定的資料放到相應的列位置即可。如圖

如何用C#制作Excel AddIn

Item列是零件名稱,Mean列是對應零件的測量資料。

測量機器導出的零件的資料格式支援常用的CSV,XML和TXT格式,導出的資料用EXCEL看起來是這樣的

如何用C#制作Excel AddIn

我選擇把測量資料導出為csv格式,這種格式容易檢視,也容易分析。如果選用XML格式,大多資料員工都看不懂,而且檢視起來不友善。對于這類的平面結構(相對于層次結構)的資料,導出為CSV是首選。

接下來就是分析一下,如何快速的把測量資料制作成報表。

大部分EXCEL使用者對公式比較熟悉,制作報表也相當專業和快速。我先嘗試直接用公式解決。

這個需求用公式描述是,在指定的區域中找值,然後傳回指定的值到相應的資料列中。

EXCEL的VLOOKUP函數可以達到我的目的。如下的解釋:VLOOKUP(C1,A:B,2,) 這個公式,意思是要在A列到B列查找C1這個資料,并顯示與其對應的B列的資料

但是有個問題,報表和測量資料是分别放在兩在檔案中的,而且測量資料是不允許被放到報表所在的檔案中。使用者需要先把測量資料添加到報表檔案中,然後使用上面的公式,去找到比對值,做完之後再把測量資料所在的worksheet删掉。如果有很多這樣的報表要做,使用者要反複的添加和删除worksheet,雖然可以解決問題,有點不完美,使用者操作起來不友善。這個方案可以解決問題,但不完美,

嘗試用VBA的方法,網上關于VBA的資料相當多。VBA就相當于程式的方式。我的思路是先讀取測量資料檔案,把它放到一個類似于字典的結構中(Hashtable,Dictionary),然後循環讀取報表中需要資料的零件,取出它對應的測量資料并賦給相應的單元格。沒研究過VBA,不知道怎樣入手。用關鍵詞“VBA如何讀取一個檔案”在網上找了搜尋了很久也沒有找到相關内容,這個方案不會程式設計實作,隻好放棄。

考慮用VSTO。VS 2005/2008預設都會安裝這個元件,它相當于托管版本的VBA。而且VSTO支援C#語言,可以用最熟悉的技術解決這個問題。在C#裡面,讀取一個檔案相當容易,一個StreamReader就可以搞定讀取檔案的問題。

打開VS2008,建立一個Excel 2003的Workbook項目。

如何用C#制作Excel AddIn

向導會建立一個類,它的主體代碼如下

public partial class ThisAddIn

{

private void ThisAddIn_Startup(object sender, System.EventArgs e){       }

private void ThisAddIn_Shutdown(object sender, System.EventArgs e)   {       }

}

看不懂可以猜測,根據名字,猜測Startup和Shutdown是插件被加載和關閉時執行的事件

在ThisAddIn_Startup中,加載界面。

可以添加一個菜單,也可以添加一個工具按鈕。添加菜單的效果如下

如何用C#制作Excel AddIn

具體代碼的寫法是

private void ThisAddIn_Startup(object sender, System.EventArgs e)

       {

           #region VSTO generated code

           this.Application = (Excel.Application)Microsoft.Office.Tools.Excel.ExcelLocale1033Proxy.Wrap(typeof(Excel.Application), this.Application);

           #endregion         

           this.AddMenu();

       }

Office.CommandBarControl menuTop;

Office.CommandBarControl menuCreateMail = null;

private void AddMenu()

Office.CommandBar bar = this.Application.CommandBars.ActiveMenuBar;

menuTop.Caption = "YiHu Tools";

Office.CommandBarPopup commandBarPopupTmp = menuTop.Control as Office.CommandBarPopup;

menuCreateMail.Caption = "Import Data";

Office.CommandBarButton buttonMenu = menuCreateMail as Office.CommandBarButton;

buttonMenu.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(buttonMenu_Click);

這裡有一個技巧。如果menuTop或menuCreateMail 在AddMenu方法中定義,會導緻EXCEL打開後,多次點選按鈕事件,它隻執行一次。除非你重新啟動EXCEL。

點選菜單“Import Data”的事件代碼如下

void buttonMenu_Click(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)

{

//分析CSV檔案,設定指定報表列的值

代碼比較長。首先是彈出對話框,選擇要導入的包含測量資料的檔案,分析并導入值。

導入值的代碼涉及到操作EXCEL,代碼如下

Excel.Worksheet sheet = (Excel.Worksheet)Application.ActiveWorkbook.ActiveSheet;                  

               int rowIndex = 10; int maxIndex = 300;

               for (rowIndex = 10; rowIndex < maxIndex;rowIndex++ )

               {

                   Excel.Range source = sheet.get_Range("A" + rowIndex, "A" + rowIndex);

                   Excel.Range target = sheet.get_Range("F" + rowIndex, "F" + rowIndex);

                   if (String.IsNullOrEmpty(source.Value2.ToString()))

                       continue;

                   else

                   {

                       string hashkey = source.Value2.ToString();

                       if (table.Contains(hashkey))

                           target.Value2 = table[hashkey].ToString();

                   }

               }

table的類型是Hashtable,它以零件名作鍵名,零件的測量資料為值。

讀取檔案的代碼也有點技巧。我的機器是XP SP2英文版,EXCEL是2003的英文标準版。如果以COM Interop API讀取資料檔案,把資料檔案當作EXCEL檔案來讀取,會經常出現亂碼,如果是以文本檔案的方式讀取資料檔案,則沒有任何問題。這個問題我一直找不到原因。

下面說一下怎樣部署這個插件 以下幾個步驟是必須的,而且要以管理者身份才能執行以下步驟

1 在目标機器上,安裝 .Net Framework 2.0 http://www.microsoft.com/downloads/details.aspx?FamilyID=0856EACB-4362-4B0D-8EDD-AAB15C5E04F5&displaylang=en

2 安裝Office 2007 PIAs

http://www.microsoft.com/downloads/details.aspx?familyid=59DAEBAA-BED4-4282-A28C-B864D8BFA513&displaylang=en

3 安裝 VSTO Runtime 2.0:

http://www.microsoft.com/downloads/details.aspx?FamilyId=4468D8CB-B43E-4B09-82F6-8BA3F7B5E935&displaylang=en#filelist

4 確定EXCEL 2003已經打上了SP2更新檔,否則請安裝SP2更新檔

如何用C#制作Excel AddIn

5  編譯安裝項目,并執行,完成插件的安裝。

如何用C#制作Excel AddIn

6  到安裝插件的目錄,執行指令行工具,設定程式集的權限(程式集名字為QCExcelAddIn)

caspol -machine –addfulltrust  QCExcelAddIn.dll

經過這幾步,打開EXCEL,應該可以看到插件的菜單。如果仍然看不到菜單,看是不是插件被EXCEL禁用. 在DisalbeItems中把插件激活。

如何用C#制作Excel AddIn

至此,這個問題圓滿解決。經過一段時間的使用,測量員要求修改一下測量資料的檔案格式,如下圖

如何用C#制作Excel AddIn

解析這種格式的代碼比較簡單,直接用正則式分解字元串即可,而上面的那個版本的格式還需要判斷是奇數行還是偶數行,奇數行取零件名稱,偶數行讀取測量資料。

關于這個插件的注冊資訊,在系統資料庫中有相應的鍵值對說明

插件所在的系統資料庫鍵的路徑是

如何用C#制作Excel AddIn

值如下圖所示

如何用C#制作Excel AddIn

也許這個辦法也不是最優化的辦法,歡迎提供您的思路供大家參考學習。

繼續閱讀