要在 Excel 里創(chuàng)建一些自定義應(yīng)用程序,需要一些常用對(duì)象或者對(duì)象集合的工作知識(shí),例如 Range,Workbook (Workbooks),Worksheet (Worksheets),Window (Windows) 和 Application。在前面部分,你開(kāi)拓了學(xué)習(xí) VB 的許多方法。這里有一個(gè)總結(jié)關(guān)于什么時(shí)候使用什么工具:
當(dāng)你在一個(gè)現(xiàn)行 VBA 過(guò)程,對(duì)對(duì)象、屬性或方法有疑義時(shí)按 F1 打開(kāi)在線幫助,如果你需要快速列出每個(gè)可用對(duì)象的屬性和方法時(shí),或者查找一個(gè)很難找到的過(guò)程時(shí),使用對(duì)象瀏覽器。如果你想要測(cè)試VBA并且立即查看VBA命令的結(jié)果時(shí),激活立即窗口。
圖2-25 Excel 對(duì)象模型里的 Range 對(duì)象
電子表格單元格操作
當(dāng)你已經(jīng)準(zhǔn)備好編寫你自己的 VBA 過(guò)程,將電子表格任務(wù)自動(dòng)化的時(shí)候,你很可能是從尋求操作電子表格單元格的指令開(kāi)始的。你需要知道如何選擇單元格,如果在單元格輸入數(shù)據(jù),如何給單元格區(qū)域命名,如何設(shè)置單元格格式,以及如何移動(dòng),復(fù)制和刪除單元格。雖然這些任務(wù)可以通過(guò)鼠標(biāo)或鍵盤輕易執(zhí)行,掌握VBA這些方面的技術(shù)需要一些練習(xí)。你必須使用Range 對(duì)象來(lái)引用單個(gè)單元格,單元格區(qū)域,行或列。如果你看了 Excel 對(duì)象模型,你會(huì)注意到Range 對(duì)象是另外一個(gè)大對(duì)象——Worksheet 對(duì)象——的一部分。有三種屬性讓你訪問(wèn)Range 對(duì)象:Range 屬性,Cells 屬性和 Offset 屬性。
使用Range屬性
Range 屬性返回一個(gè)單元格或者單元格區(qū)域。引用必須是 A1 在引號(hào)里的樣式(例如:”A1”)引用可以包括區(qū)域運(yùn)算符冒號(hào)(例如:”A1:B2”)或者聯(lián)合運(yùn)算符逗號(hào)(例如:”A”,”B12”)
使用 Cells 屬性
當(dāng)你要選擇一個(gè)確定的單元格時(shí),Cells 屬性要求兩個(gè)自變量,第一個(gè)是行號(hào),第二個(gè)是列號(hào)或者列字母。自變量輸入在括號(hào)中。如果忽略自變量,Excel 將會(huì)選擇當(dāng)前工作表的所有單元格。
注意,在上面的例子中,你如何結(jié)合使用 Range 和 Cells 屬性:
Range(Cells(6, 1), Cells(10, 1)).Select
在上面的例子里,第一個(gè) Cells 屬性返回單元格 A6,而第二個(gè)返回單元格 A10。Cells 屬性返回的單元格之后又當(dāng)做 Range 對(duì)象的參數(shù)。結(jié)果 Excel 就選擇了上面單元格為第一個(gè) Cells 屬性返回的結(jié)果和下面為第二個(gè) Cells 屬性返回單元格的區(qū)域了。
工作表是單元格的集合,你也可以使用只帶一個(gè)自變量的 Cells 屬性來(lái)表示單元格在工作表所有單元集合中的位置。Excel 按下列方式給單元格編號(hào):?jiǎn)卧?A1 是工作表中的第一個(gè)單元格,B1 是第二個(gè),C1 是第三個(gè),等等。Cell256 是第一行中的最后一個(gè)單元格。你也許會(huì)想起 Excel 只有 256 列。
注意,Item 是返回一個(gè)集合成員的屬性。因?yàn)?Item 是一個(gè)集合的默認(rèn)成員,你可以直接引用工作表單元格,而不必明確地使用 Item 屬性。現(xiàn)在你發(fā)現(xiàn)了兩種方法選擇單元格(Range 屬性和 Cells 屬性),你也許很迷惑為什么要使用更復(fù)雜的 Cells 屬性呢?很明顯 Range 屬性更具有可讀性,畢竟,你遠(yuǎn)在決定學(xué)習(xí) VBA 之前就在 Excel 公式和
函數(shù)里面使用了 Range 引用。然而,當(dāng)需要將單元格當(dāng)做集合操作的時(shí)候,Cells 屬性則使用更方便。使用這個(gè)屬性去訪問(wèn)單元格集合中的所有單元格或者單個(gè)單元格。
使用 Offset 屬性
另外一個(gè)引用工作表單元格非常靈活的方法是使用 Offset 屬性。當(dāng)工作表任務(wù)自動(dòng)化時(shí),你也許不知道某個(gè)單元格的確切地址。你如何能夠選擇一個(gè)你根本不知道地址的單元格?你可以讓 Excel 基于當(dāng)前選擇的單元格來(lái)選擇一個(gè)位置。Offset 屬性通過(guò)計(jì)算從開(kāi)始選擇的單元格向下或向上移動(dòng)的具體行數(shù),來(lái)得到新的區(qū)域。同樣也可以從當(dāng)前選擇的單元格區(qū)域向右或向左移動(dòng)具體的列數(shù)。
Offset 屬性使用兩個(gè)自變量來(lái)獲得新單元格區(qū)域的地址。第一個(gè)自變量表示行偏移,第二個(gè)自變量則表示列偏移。我們來(lái)測(cè)試一下幾個(gè)例子:
上面的第一個(gè)例子里,Excel 選擇的時(shí)單元格 D2。一旦你輸入了第二個(gè)例子,Excel選 擇了單元格 C13。如果單元格 A1 和 D15 已經(jīng)被選中了,你也可以將上面的兩個(gè)例子改寫為這樣:
Selection.Offset(1, 3).Select
Selection.Offset(-2, -1).Select
注意,上面第三個(gè)例子里的第二個(gè)自變量是 0,第一個(gè)或第二個(gè)自變量為 0 時(shí),Offset 屬性相應(yīng)表示當(dāng)前行或當(dāng)前列。如果當(dāng)前活動(dòng)單元格在第一行,那么指令 ActiveCell.Offset(-1, 0).Select 會(huì)導(dǎo)致錯(cuò)誤。
當(dāng)使用 Offset 屬性時(shí),你可能有時(shí)需要改變選擇區(qū)域的大小。假設(shè)開(kāi)始選擇的區(qū)域是A5:A10,如何將選擇區(qū)域向下移動(dòng)兩行,向右移動(dòng)兩列,然后再改變新選擇區(qū)域的大小呢?假設(shè)新的選擇區(qū)域應(yīng)該是 C7:C8。Offest 屬性只能完成前面部分,后面部分要求另外一個(gè)屬性來(lái)完成。Excel 有個(gè)專門的 Resize 屬性,你可以結(jié)合 Offset 屬性和 Resize 屬性來(lái)回到上面的問(wèn)題。在你結(jié)合這兩個(gè)屬性之前,我們先來(lái)看看如何獨(dú)立地使用它們:
1.將 Excel 窗口和 VB 窗口并排顯示
2.激活立即窗口,并且輸入下述指令:
Range('A5:A10').Select
Selection.Offset(2, 2).Select
Selection.Resize(2, 4).Select
上面的第一條指令選擇區(qū)域 A5:A10,當(dāng)前活動(dòng)單元格是 A5。第二條指令將選區(qū)偏移到C7:C12。單元格 C7 處于活動(dòng)單元格A5的向下兩行和向右兩列?,F(xiàn)在,活動(dòng)單元格是 C7。最后一條指令將當(dāng)前選區(qū)改變大小,單元格區(qū)域 C7:C8 被選中了,而不再是 C7:C12。象Offset 屬性一樣,Resize 屬性也需要兩個(gè)自變量。第一個(gè)是你要選取的行數(shù),第二個(gè)則是要選取的具體列數(shù)因此,指令
Selection.Resize(2, 4).Select 將當(dāng)前選擇區(qū)域改為兩行和四列
后面兩行指令可以結(jié)合成下面方式:
Selection.Offset(2, 2).Resize(2, 4).Select
上面的例子,先是 Offset 屬性計(jì)算得到新區(qū)域的起始點(diǎn)(譯者:選區(qū)左上角的單元格),接著是 Resize 屬性決定新選區(qū)的大小,然后是 Select 方法選取具體的單元格區(qū)域。
技巧:錄制單元格的選擇
宏錄制器默認(rèn)地使用 Range 屬性錄制選擇單元格。如果你打開(kāi)宏錄制器,并且選擇單元格A2,輸入“text”,再選擇單元格A5,你將在 VB 編輯器窗口里得到下述代碼:
Range('A2').Select
ActiveCell.FormulaR1C1 = 'text'
Range('A5').Select
如果你使用相對(duì)引用方式,宏錄制器會(huì)使用 Offset 屬性。你可以在錄制前,點(diǎn)擊宏錄制工具條上的相對(duì)引用按鈕。宏錄制器將得到如下代碼:
ActiveCell.Offset(-3, 0).Range('A1').Select
ActiveCell.FormulaR1C1 = 'text'
ActiveCell.Offset(3, 0).Range('A1').Select
當(dāng)你使用相對(duì)引用方式錄制宏時(shí),過(guò)程總是會(huì)選擇相對(duì)于當(dāng)前活動(dòng)單元格的單元格。注意,上面指令中的第一和第三行的引用單元格 A1,即使我們沒(méi)有涉及到 A1 的任何東西。你可能記得,在第一章中,宏錄制器用它自己的方式將事情搞定。為了將上面的指令變簡(jiǎn)單一些,你可以刪除對(duì)單元格 A1 的引用:
ActiveCell.Offset(-3, 0).Select
ActiveCell.FormulaR1C1 = 'text'
ActiveCell.Offset(3, 0).Select
使用相對(duì)引用來(lái)錄制過(guò)程后,不要忘記再次點(diǎn)擊這個(gè)按鈕,如果下次錄制一個(gè)非相對(duì)地址的過(guò)程。
選擇單元格的其它方法
如果你經(jīng)常需要訪問(wèn)你工作表里某些遙遠(yuǎn)的單元格,你可能已經(jīng)對(duì)下面的鍵盤快捷鍵很熟悉:End+上箭頭, End+下箭頭, End+左箭頭和End+右箭頭。在 VBA 中,你可以使用 End 屬性快速地移動(dòng)到遙遠(yuǎn)的單元格。
注意,End 屬性要求一個(gè)自變量來(lái)表示你要移動(dòng)的方向。使用下列 Excel 內(nèi)置的常數(shù)來(lái)跳到具體的方向:xlright, xlleft, xlup, xldown。
在新版本(2010版本之后)的office中xlright和xlleft需要替換為xltoleft和xltoright。
選擇行和列
Excel 使用 EntireRow 和 EntireColumn 屬性來(lái)選擇整行或整列。
你選擇了一個(gè)單元格區(qū)域,你也許想要知道選區(qū)包括多少行,多少列。我們來(lái)讓 Excel 計(jì)算區(qū)域 A1:D15 中的行數(shù)和列數(shù):
1. 在立即窗口里輸入下述 VBA 語(yǔ)句
Range('A1:D15').Select
如果 Excel 窗口可見(jiàn),當(dāng)你按回車后,VBA 會(huì)選中區(qū)域 A1:D15
2.輸入下列語(yǔ)句來(lái)得到選區(qū)的行數(shù)
?Selection.Rows.Count
一旦你回車,VBA 在下一行顯示結(jié)果。你的選擇包括 15 行
3.輸入下列語(yǔ)句來(lái)得到選區(qū)的列數(shù)
?Selection.Columns.Count
現(xiàn)在 VBA 告訴你,選中的區(qū)域 A1:D15 占據(jù)了四列的寬度。
4.將光標(biāo)放在關(guān)鍵字 Rows 或 Columns 中的任意位置,并且按下 F1,獲取這些有用屬性的更多信息。
獲取工作表信息
Excel 工作表有多大?它有多少單元格,列和行?即使你忘記了這些細(xì)節(jié),使用 Count 屬性。
Excel 2002工作表里有16,777216個(gè)單元格,65,536行和256列。
往工作表輸入數(shù)據(jù)
輸入工作表里的信息可以是文本,數(shù)字或者公式。你可以使用 Range 對(duì)象的兩種屬性之一來(lái)往單元格或單元格區(qū)域里輸入數(shù)據(jù):Value 屬性或者 Formula 屬性。
Value 屬性:
ActiveSheet.Range('A1:C4').Value = '=4 * 25'
Formula 屬性:
ActiveSheet.Range('A1:C4').Formula = '=4 * 25'
上面兩種例子,A1 單元格都顯示 4 乘 25 的結(jié)果 100。
返回工作表中的信息
毫無(wú)疑問(wèn),你在某些 VB 過(guò)程中可能需要返回單元格或者單元格區(qū)域的內(nèi)容。雖然你既可以使用 Value 屬性也可以使用 Formula 屬性,但是,這次,Range 對(duì)象的這兩個(gè)屬性是不可互用的。
Value 屬性顯示具體單元格中公式的結(jié)果。例如,如果 A1 中含有公式“= 4 * 25”,那么指令 ?Range('A1').Value 將會(huì)返回值 100
如果你想要顯示公式,而不是結(jié)果,那么你必須使用 Formula 屬性:?Range('A1').Formula。
Excel 將會(huì)顯示公式“= 4 * 25”而不是結(jié)果 100。