前一篇文章介紹了Excel中的菜單系統,在創建完菜單和工具欄之後,就要著手進行功能的開發了。不論您采用何種方式來開發Excel應用程序,了解Excel對象模型尤其重要,這些對象是您與Excel進行交互的基石。據不完全統計,Excel的對象模型中有270多個對象及超過5000多個屬性和方法。通過這些對象及方法,您可以充分利用Excel來定制化您的插件。
Excel的所有對象,事件,方法和屬性在這裡不可能全部介紹完。本文簡要介紹一下Excel的整體文檔對象模型,以及一些比較重要的,平常開發中需要頻繁接觸到的對象,屬性,事件及方法,如Application,Range對象等,使您對Excel的整個結構有一個簡單的了解。後面在編程中遇到問題了,您可以快速定位知道需要設置或者調用哪個對象及其方法,然後根據關鍵字到Google或者MSDN上方便查找。本文大部分內容參照MSDN上的這篇文章Understanding the Excel Object Model from a .NET Developer's Perspective 如果您對英文沒有問題,建議您直接去MSDN看原文。
在與Excel進行交互之前,了解Excel對象模型的整體結構非常重要,這使得我們對Excel有一種更整體全面的了解。下圖是Excel的對象模型的整個層級結構。
Application是根對象,代表著Excel應用程序本身,一切Excel中的其他對象都有它直接或者間接創建。 您可以回想到前面我們在Shared Add-in項目中創建Excel菜單和工具條時接觸到的對象。我們首先是在Connect方法中保存了 application對象,然後在該對象上創建了MenuBar和Toolbar。Application對象有一些熟悉,事件和方法,在我們編程中經常會用到,現在就稍微講一下:
Application中控制Excel狀態和顯示的方法和屬性有很多,表一中列出了常用的幾個屬性。有一個屬性是需要重新啟用後才可以生效的。
屬性
類型
說明
Cursor
XlMousePointer 枚舉
獲取或者設置鼠標手勢的形狀
EditDirectlyInCell
Boolean
獲取或者設置是否可以直接在單元格裡面對數據進行編輯,如果為false,則只能在公示欄中對數據進行編輯
Interactive
Boolean
獲取或者設置用戶是否可以通過鼠標或者鍵盤與Excel進行交互
MoveAfterReturnDirection
xlDirection枚舉
設置當用戶敲回車時,在 MoveAfterReturn屬性設置為true的情況下,下一個單元格移動的位置,默認為向下。
ScreenUpdating
Boolean
設置屏幕刷新屬性,當設置為True時,每一個單元格的刷新時都會刷新整個屏幕,一般地在編程時,為了提升速度,在代碼處理的過程中禁止屏幕刷新,待數據填充完成之後,再開啟屏幕刷新.
StandardFont
String
獲取或者設置Excel中顯示的默認字體,重啟後生效。
StandardFontSize
Long
獲取或者設置Excel默認顯示的字體大小,重啟後生效。
StartupPath (read-only
String
返回Excel外接插件啟動項的加載目錄.
TemplatesPath (read-only)
String
返回Excel模板加載的路徑,通常為Windows的特殊目錄.
DisplayAlerts
Boolean
如果設置為true,在某些情況下,比如我們的代碼刪除一個sheet頁,Excel會彈出提示框提醒用戶。如果設置為false,則不顯示提示框,Excel默認選擇默認項。
上面列出的屬性中,最可能用到的是ScreenUpdating屬性,正確使用該屬性能夠大幅提高應用程序的性能。默認的,該屬性為true,即每一次修改就會刷新整個界面,這會使得應用程序變慢,尤其是在往單元格填充大量數據的時候。所以一般的做法是,在填充數據之前保存ScreenUpdating屬性,然後將ScreenUpdating屬性設置為false,禁止屏幕刷新,然後填充數據,最後將之前保存的ScreenUpdating屬性賦值回來。下面的代碼演示了這一做法:
oldScreenUpdate = .Application.ScreenUpdating; { .Application.ScreenUpdating = ; } { .Application.ScreenUpdating = oldScreenUpdate; }
從Application對象中可以獲取很多有用的對象。如ActiveCell返回當前活動的單元格;ActiveChart,返回當前選中的活動的圖表;ActiveSheet、ActiveWindows分別返回活動的Sheet頁和窗口;Selection屬性返回當前選中的對象,可能是Range,Worksheet或者是一個窗體;Workbooks,Sheets,Charts返回當前Excel中所有工作簿,工作表,圖表的集合。
通常,我們接觸最多的是Application對象的Workbooks屬性,該對象是當前Excel打開的所有的工作簿文件。一個Workbook就是一個.xls或者.xlsx文件。下面簡單講解Workbooks對象。
Excel.wb = .Application.Workbooks.Add(.Missing);
.Application.Workbooks.Close();
Excel.wbOpenExistFile = .Application.Workbooks.Open( , .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing);
這些操作可以通過OpenText,OpenDatabase,OpenXml方法來實現,方法參數可能需要您詳細指定。
有時候我們可能需要從當前的工作簿文件中,找到指定的工作簿文件進行操作。一般的我們可以通過Workbooks屬性通過索引器傳入index來返回,或者通過工作簿名稱來返回。需要注意的是,工作簿沒有保存前,不需要後綴,保存後需要帶上後綴來進行訪問,代碼如下:
Excel.wbFind = .Application.Workbooks[1]; wbFind = .Application.Workbooks[]; wbFind = .Application.Workbooks[];
Application對象提供了一些方法,包括單元格的重新計算,撤銷操作等。
.Application.Calculate(); .Application.Calculate(); .Application.get_Range(, ).Calculate();
Office.dlg = .Application.get_FileDialog( Office..msoFileDialogOpen); dlg.Filters.Clear(); dlg.Filters.Add(, , .Missing); dlg.Filters.Add(, , .Missing); (dlg.Show() != 0) dlg.Execute();
Application中還有一些其他有用的對象,如WorksheetFunction,該對象包括了一系列靜態或者共享方法,這些方法都是對Excel內置函數的包裝。
Excel.ws = (Excel.).Application.ActiveSheet; Excel.rng = ws.get_Range(, .Missing); System.rnd = System.(); (i = 1; i <= 20; i++) ws.Cells[i, 2] = rnd.Next(100); rng.Sort(rng, Excel..xlAscending, .Missing, .Missing, Excel..xlAscending, .Missing, Excel..xlAscending, Excel..xlNo, .Missing, .Missing, Excel..xlSortColumns, Excel..xlPinYin, Excel..xlSortNormal, Excel..xlSortNormal, Excel..xlSortNormal); Excel.wsf = .Application.WorksheetFunction; ws.get_Range(, .Missing).Value2 = wsf.Min(rng, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing);
.Application.Windows.Arrange( Excel..xlArrangeStyleTiled, .Missing, .Missing, .Missing);
Excel.nm = .Application.Names.Add( , , .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing);
後面使用該名稱即可找到該名稱代表的Range對象:
.Application.get_Range(, .Missing).Value2 = ;
Application對象除了上面講解的一些有用的方法和屬性之外,還有一些事件。這些事件大致分為Sheet行為相關的事件、Window行為相關事件Workbook管理相關的事件。下面簡要介紹這些事件的作用。
Sheet相關事件:
以上application上的事件在Workbook類上也存在。application上的事件對所有的工作簿都有效,而Workbook上的這些事件僅對該Workbook有效。
Windows行為相關事件:
Workbook行為相關事件:
Workbook對象也有很多屬性和方法,下面僅介紹一些比較常用的方法和屬性。
Workbook屬性
文檔屬性
Excel文檔允許用戶將一些信息保存到文件屬性中。Excel提供了一些列內置的屬性,我們也可以添加自己的屬性。
一般地,我們可以將一些和文檔相關的信息或者臨時數據保存到自定義信息中。
文檔樣式
在Excel開發中,我們經常要對單元格進行格式化,這時,我們可能需要自定義一些樣式,然後給其命名,然後下次直接按照名稱賦給樣式即可。
工作表對象
Workbook的Sheets屬性返回該工作簿包含的所有工作表對象。這些對象可以是工作表也可以是Chart對象,下面的代碼列出了當前工作簿中的所有對象。
ListSheets() { i = 0; Excel.rng = .Application.get_Range(, .Missing); (Excel.sh .Application.ActiveWorkbook.Sheets) { rng.get_Offset(i, 0).Value2 = sh.Name; i = i + 1; } }
WorkSheet有一些很有用的屬性和方法:
HideTheSheet() { ((Excel.).Application.ActiveWorkbook.Sheets[1]).Visible = Excel..xlSheetVeryHidden; }
Excel.sh = .Application.Sheets.Add( .Missing, .Missing, .Missing, .Missing);
((Excel.) .Application.ActiveWorkbook.Sheets[1]). Copy(.Missing, .Application.ActiveWorkbook.Sheets[3]);
.Application.ActiveWorkbook.Sheets.FillAcrossSheets( .Application.get_Range(, .Missing), Excel..xlFillWithAll);
Excel.shts = .Application.ActiveWorkbook.Sheets; ((Excel.)shts[1]).Move(.Missing, shts[shts.Count]);
((Excel.).Application.ActiveWorkbook.Sheets[1]). PrintOut(1, 1, 2, , .Missing, .Missing, .Missing, .Missing);
Workbook類的方法
Workbook代表一個工作簿,他也提供了很多方法,其中一些方法用來處理一些非常特殊的場景。和前面介紹其他對象一樣,這裡僅介紹我們在開發中會經常使用到的屬性和方法。
((Excel.).Application.Workbooks[1]).Activate();
.Application.Workbooks[1].Close(,.Missing, .Missing);
.Application.Workbooks[1].Protect(, .Missing, .Missing);
(Excel.wb .Application.Workbooks) { wb.Save(); }
.Application.ActiveWorkbook.SaveAs(, Excel..xlXMLSpreadsheet, .Missing, .Missing, .Missing, .Missing, Excel..xlNoChange, .Missing, .Missing, .Missing, .Missing, .Missing);
.Application.ActiveWorkbook.SaveCopyAs();
雖然Worksheet類也提供了大量的屬性方法和事件,但是大部分的屬性和方法和Application和Workbook類現相似,這部分重點介紹Worksheet中之前的對象中沒有講到過的,且經常會用到的屬性和方法。
沒有Sheet類
雖然Workbook對象有一個Sheets集合類,但是並不存在一個所謂的Sheet類,Sheets集合中的類要不是Worksheet元素,要麼是Chart對象。可以認為Worksheet和Chart對象是Sheet類對象的實例,雖然公共的對象中並沒有看到有Sheet類。
文檔保護
通常Excel會對工作簿或者工作表提供一些保護特性,以不允許用戶修改工作表中的隊形。一旦我們開啟了對工作表進行保護,除非進行取消保護,否則用戶不能編輯或者修改工作表。在用戶界面上,您可以通過菜單審閱-> 保護工作表菜單開啟,我們可以設置保護密碼。默認情況下,會對所有的工作表中的單元格進行保護。如果您要對特定范圍的單元格進行保護,可能需要使用 審閱->允許用戶編輯區域實現。
下面是一個使用Protect方法對工作表進行保護的例子,該方法設置了保護密碼,並僅允許對數據進行排序:
((Excel.).Application.Sheets[1]).Protect( , .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, , .Missing, .Missing);
要取消保護,直接調用unprotect方法即可。
Object屬性
Worksheet對象還有幾個返回Object類型的屬性。
Worksheet類提供了Comments屬性,該屬性返回一個Comments對象,該對象是一個集合,您可以便利該集合中的對象,Comment類提供的屬性很少,用的最多的是Visible屬性,用來顯示或者隱藏注釋;在一個就是Delete屬性,用來刪除注釋,最後Text屬性可以用來添加或者修改現有的注釋。
添加完成注釋之後,我們可能希望在工作表中顯示注釋。下面就是在當前活動工作表中顯示或者隱藏注釋的代碼。
ShowOrHideComments(show) { Excel.ws = (Excel.).Application.Sheets[]; (i = 1; i <= ws.Comments.Count; i++) { ws.Comments[i].Visible = show; } }
Range對象是在Excel開發中用的最多的隊形,在我們對Excel進行操作之前,我們需要獲取我們要進行操作的對象。幾乎我們對工作表中的內容操作都會涉及到Range對象。Range對象是對工作表中內容的一種抽象,他可以表示一個單元格,一行數據,一列數據,一個選擇的單元格區間,或者在不同工作表中的一系列對象。下圖是Range的簡要對象模型圖:
上面的代碼會使得用戶當前的選擇區域丟失。如果之前只有一個單元格被選中,那麼在運行上面的代碼之後,整個連續的單元格都回被選中了。除非我們的目的就是這樣,要選擇整個Range返回內的單元格,一個更好的方法可能是:
.Application.ActiveCell.CurrentRegion.ClearContents();
之前的代碼通常是使用宏錄制獲得的,一般情況下,宏錄制其會錄制好用戶的選擇,然後對用戶的選擇進行修改。當我們對單個單元格或者多個單元格進行操作的時候,一般應該使用Range對象來表示我們操作的對象,而不是通過修改選中的對象來進行操作。如果確實需要修改用戶的選擇對象,可以使用Range.Select 方法。
在代碼中引用Range對象
在開發中,Range對象的使用范圍非常廣泛和靈活。有時候Range對象表示單個的對象,有時候也表示一個集合。即使一個Range對象只表示一個對象,它也有Item和Count屬性,所以我們要注意在有些情況下該如何更好地使用Range對象。
Excel.ws = (Excel.).Application.Worksheets[1]; Excel.rng1, rng2; rng1 = .Application.ActiveCell;
rng = ws.get_Range(, .Missing); rng = ws.get_Range(, .Missing);
rng = (Excel.)ws.Cells[1, 1];
rng = ws.get_Range(, ); rng = ws.get_Range(, ).Cells; rng = ws.get_Range(, ).Rows; rng = ws.get_Range(, ).Columns;
rng = .Application.get_Range(, .Missing);
rng = (Excel.)ws.Rows[1, .Missing]; rng = (Excel.)ws.Rows[, .Missing]; rng = (Excel.)ws.Columns[3, .Missing];
rng = .Application.get_Range(, .Missing); rng1 = .Application.get_Range(, ); rng2 = .Application.get_Range(, ); rng = .Application.Union(rng1, rng2, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing);
rng = .Application.get_Range(, .Missing); rng1 = .Application.get_Range(, ); rng2 = .Application.get_Range(, ); rng = .Application.Intersect(rng1, rng2, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing, .Missing);
rng = (Excel.)ws.Cells[1, 1]; (i = 1; i <= 5; i++) { rng.get_Offset(i, 0).Value2 = i.ToString(); }
Excel.rngLeft, rngRight, rngUp, rngDown; rng = (Excel.).Application.Selection; rngRight = rng.get_End(Excel..xlToRight); rngLeft = rng.get_End(Excel..xlToLeft); rngUp = rng.get_End(Excel..xlUp); rngDown = rng.get_End(Excel..xlDown);
操作Range對象
獲得了Range對象之後,我們就可以對Range對象進行各種操作了。
AutoFill() { Excel.rng = .Application.get_Range(, .Missing); rng.AutoFill(.Application.get_Range(, .Missing), Excel..xlFillDays); rng = .Application.get_Range(, .Missing); rng.AutoFill(.Application.get_Range(, .Missing), Excel..xlFillMonths); rng = .Application.get_Range(, .Missing); rng.AutoFill(.Application.get_Range(, .Missing), Excel..xlFillYears); rng = .Application.get_Range(, .Missing); rng.AutoFill(.Application.get_Range(, .Missing), Excel..xlFillSeries); }
要進行Excel開發,繞不開對Excel中對象模型的理解, 本文簡要介紹了Excel中的對象模型,介紹了這些對象中比較重要的幾個對象,Application,Workbook,Worksheet,Range對象,這些對象不論在何種Excel開發方式中,只要需要對Excel進行交互,都會使用的到,本文介紹了這四個對象中的一些常用的屬性,方法及事件。他們之間有很多對象都有相同的屬性方法或者事件,這篇文章主要是想讓大家對Excel對象模型有一個簡單的認識,具體全部的對象模型,大家可以直接到MSDN或者Google上面去查找,下一篇文章將會介紹Excel中比較核心的功能:自定義函數。
希望本文對大家理解Excel對象模型有所幫助。