range 對象應用(上)

range 對象 應用(上)

.net技術 2010-09-16 12:01:53 閱讀47 評論0   字號: 訂閱

毫無疑問,Range對象是Excel對象模型中最重要的對象,幾乎所有與工作表有關的實質性操作都涉及到Range對象,可以說,熟悉並熟練運用Range對象是掌握Excel VBA編程的關鍵。下面,讓我們逐步瞭解、熟悉並開始使用Range對象吧。
在VBA代碼中引用或選擇Excel工作表的單元格或單元格區域
在使用Excel VBA編程時,我們通常需要頻繁地引用單元格區域,然後再使用相應的屬性和方法對區域進行操作。所謂單元格區域,指的是單個的單元格、或者包含連續或非連續的多個單元格組成的區域、或者是整行、整列、甚至是三維單元格區域等。
[應用1]引用當前工作表中的單個單元格(例如引用單元格C3)
可以使用下面列舉的任一方式引用當前工作表中的單元格(C3):
(1)Range(”C3″)
(2)[C3]
(3)Cells(3, 3)
(4)Cells(3, “C”)
(5)Range(”C4″).Offset(-1)
Range(”D3″).Offset(, -1)
Range(”A1″).Offset(2, 2)
(6)若C3爲當前單元格,則可使用:ActiveCell
(7)若將C3單元格命名爲“Range1”,則可使用:Range(”Range1″)或[Range1]
(8)Cells(4, 3).Offset(-1)
(9)Range(”A1″).Range(”C3″)
此外,可以使用下面的代碼選擇當前工作表中的單元格D5:
ActiveSheet.Cells(5, 4).Select
或:ActiveSheet.Range(”D5″).Select
[應用2]引用當前工作表中的B2:D6單元格區域
可以使用下面列舉的任一方式引用當前工作表中的單元格區域B2:D6:
(1)Range(“B2:D6”)
(2)Range(”B2″, “D6″)
(3)[B2:D6]
(4)Range(Range(”B2″), Range(”D6″))
(5)Range(Cells(2, 2), Cells(6, 4))
(6)若將B2:D6區域命名爲“MyRange”,則又可以使用下面的語句引用該區域:
① Range(”MyRange”)
② [MyRange]
(7)Range(”B2″).Resize(5, 3)
(8)Range(”A1:C5″).Offset(1, 1)
(9)若單元格B2爲當前單元格,則可使用語句:Range(ActiveCell, ActiveCell.Offset(4, 2))
(10)若單元格D6爲當前單元格,則可使用語句:Range(”B2″, ActiveCell)
下面的過程將單元格區域 A1:D5 的字體設置爲加粗。
Sub FormatRange() Workbooks("Book1").Sheets("Sheet1").Range("A1:D5") _ .Font.Bold = True End Sub 
Range(”A:A”)代表當前工作表中的A 列,Range(”1:1″)代表當前工作表中的第一行,Range(”A:C”)代表當前工作表中從 A 列到 C 列的區域,Range(”1:5″)代表當前工作表中從第一行到第五行的區域,Range(”1:1,3:3,8:8″)代表當前工作表中第 1、3 和 8 行,Range(”A:A,C:C,F:F”)代表當前工作表中的第A、C和F 列。
下面是給單元格賦值的幾個例子。
示例1:
Sub test1() Worksheets("Sheet1").Range("A5").Value = 22 MsgBox "工作表Sheet1內單元格A5中的值爲" _ & Worksheets("Sheet1").Range("A5").Value End Sub 
示例2:
Sub test2() Worksheets("Sheet1").Range("A1").Value = _ Worksheets("Sheet1").Range("A5").Value MsgBox "現在A1單元格中的值也爲" & _ Worksheets("Sheet1").Range("A5").Value End Sub 
示例3:
Sub test3() MsgBox "用公式填充單元格,本例爲隨機數公式" Range("A1:H8").Formula = "=Rand()" End Sub 
示例4:
Sub test4() Worksheets(1).Cells(1, 1).Value = 24 MsgBox "現在單元格A1的值爲24" End Sub 
示例5:
Sub test5() MsgBox "給單元格設置公式,求B2至B5單元格區域之和" ActiveSheet.Cells(2, 1).Formula = "=Sum(B1:B5)" End Sub 
示例6:
Sub test6() MsgBox "設置單元格C5中的公式." Worksheets(1).Range("C5:C10").Cells(1, 1).Formula = "=Rand()" End Sub 
示例7:
Sub test7() MsgBox "給命名區域賦值." ActiveSheet.Range("MyCell").Value = 1 End Sub 
其中,MyCell爲單元格區域的名稱。
[應用3]引用當前工作表中不確定的單元格區域
有時,我們需要在代碼中依次獲取工作表中特定區域內的單元格,這通常可以採取下面的幾種方式:
(1)Range(”A” & i)
(2)Range(”A” & i & “:C” & i)
(3)Cells(i,1)
(4)Cells(i,j)
其中,i、j爲變量,在循環語句中指定i和j的範圍後,依次獲取相應單元格。
在下例中,Cells(6,1)返回Sheet1上的單元格A6,然後將Value屬性設置爲 10。
Sub EnterValue() Worksheets("Sheet1").Cells(6, 1).Value = 10 End Sub 
因爲可以用變量替代編號,所以Cells屬性非常適合於在單元格區域中循環,如下例中所示。
Sub CycleThrough() Dim Counter As Integer For Counter = 1 To 20 Worksheets("Sheet1").Cells(Counter, 3).Value = Counter Next Counter End Sub 
如果要同時更改某個區域中所有單元格的屬性(或將方法應用於該區域中的所有單元格),建議使用Range屬性。
[應用4]擴展引用當前工作表中的單元格區域
可以使用Resize屬性,例如:
(1)ActiveCell.Resize(4, 4),表示自當前單元格開始創建一個4行4列的區域。
(2)Range(”B2″).Resize(2, 2),表示創建B2:C3單元格區域。
(3)Range(”B2″).Resize(2),表示創建B2:B3單元格區域。
(4)Range(”B2″).Resize(, 2),表示創建B2:C2單元格區域。
如果是在一個單元格區域(如B3:E6),或者一個命名區域中(如將單元格區域B3:E6命名爲“MyRange”)使用Resize屬性,則只是相對於單元格區域左上角單元格擴展區域,例如:
代碼Range(”C3:E6″).Resize(, 2),表示單元格區域C3:D6,並且擴展的單元格區域可以不在原單元格區域內。
因此,可以知道Resize屬性是相對於當前活動單元格或某單元格區域中左上角單元格按指定的行數或列數擴展單元格區域。
再舉一些例子。
例1:要選擇當前工作表中名爲“Database”區域,然後將該區域向下擴展5行,可以使用下面的代碼:
Range("Database").Select Selection.Resize(Selection.Rows.Count + 5, Selection.Columns.Count).Select 
例2:選擇名爲“Database”區域下方4行右側3列的一個區域,然後擴展2行和1列,可以使用下面的代碼:
Range("Database").Select Selection.Offset(4, 3).Resize(Selection.Rows.Count + 2, Selection.Columns.Count + 1).Select 
[應用5]在當前工作表中基於當前單元格區域或指定單元格區域處理其它單元格區域
可以使用Offset屬性,例如:
(1)Range(”A1″).Offset(2, 2),表示單元格C3。
(2)ActiveCell.Offset(, 1),表示當前單元格下一列的單元格。
(3)ActiveCell.Offset(1),表示當前單元格下一行的單元格。
(4)Range(”C3:D5″).Offset(, 1),表示單元格區域D3:E5,即將整個區域偏移一列。
從上面的代碼示例可知,Offset屬性從所指定的單元格開始按指定的行數和列數偏移,從而到達目的單元格,但偏移的行數和列數不包括指定單元格本身。正值表示向下和向右,負值表示向上和向左,零值則是指當前單元格。
例如,要選擇距當前單元格下面5行左側4列的單元格,可以使用下面的代碼:
ActiveCell.Offset(5, -4).Select 
要選擇距當前單元格上方2行右側3列的單元格,可以使用下面的代碼:
ActiveCell.Offset(-2, 3).Select 
注意:一定要保證當前單元格與所選單元格之間的距離在工作表範圍內,否則會出錯。
又如,要選擇距單元格C7下方5行右側4列的單元格,可以使用下面的代碼:
ActiveSheet.Cells(7, 3).Offset(5, 4).Select 
或:
ActiveSheet.Range("C7").Offset(5, 4).Select 
再舉一些例子。
例如,要選擇與名爲“Test”的區域大小相同但在該區域下方4行右側3列的一個區域,可以使用下面的代碼:
ActiveSheet.Range("Test").Offset(4, 3).Select 
如果該命名區域不在當前工作表中,可以先激活該工作表,然後再選擇,如下面的代碼:
Sheets("Sheet3").Activate ActiveSheet.Range("Test").Offset(4, 3).Select 
下面的例子計算移動平均值:
Sub MovingAvg() Dim rng As Range Dim lngRow As Long Set rng = Range("B1:B3") For lngRow = 3 To 12 Cells(lngRow, "C").Value = WorksheetFunction.Sum(rng) / 3 Set rng = rng.Offset(1, 0) Next lngRow End Sub 
上述代碼首先將B列中的前3個單元格設置爲一個單元格區域,計算其平均值,並放置在單元格C3中。接着,Offset屬性將單元格區域下移一行但仍在B列,計算單元格區域B2:B4的平均值,並將結果放置到單元格C4。代碼重複上述過程直到單元格B12。
[應用6]在當前工作表中引用交叉區域
可以使用Intersect方法,例如:
Intersect(Range("C3:E6"), Range("D5:F8"))
表示單元格區域D5:E6,即單元格區域C3:E6與D5:F8相重迭的區域。
又如,要選擇名爲“Test”和“Sample”的兩個區域的交叉區域,可以使用下面的代碼:
Application.Intersect(Range("Test"), Range("Sample")).Select 
注意,兩個區域必須在同一工作表中。
注意,如果兩個區域不存在交叉,那麼該方法返回Nothing。
例如,下面的代碼選擇兩個命名區域的交叉部分,如果不存在交叉,則顯示一條消息。
Sub IntersectSample() Worksheets("Sheet1").Activate Set Intersect = Application.Intersect(Range("rng1"), Range("rng2")) If Intersect Is Nothing Then MsgBox "不存在交叉區域." Else Intersect.Select End If End Sub 
[應用7]在當前工作表中引用多個區域
(1)可以使用Union方法,將多個區域組合到一個Range對象中。例如:
Union(Range("C3:D4"), Range("E5:F6"))
表示單元格區域C3:D4和E5:F6所組成的區域。
Union方法可以將多個非連續區域連接起來成爲一個區域,從而可以實現對多個非連續區域一起進行操作。
(2)也可以使用下面的代碼,即通過在兩個或多個引用之間插入逗號,可使用Range屬性引用多個區域:
Range("C3:D4, E5:F6")
[C3:D4, E5:F6]
注意:Range(”C3:D4″, “F5:G6″),表示單元格區域C3:G6,即將兩個區域以第一個區域左上角單元格爲起點,以第二個區域右下角單元格爲終點連接成一個新區域。
同時,在引用區域後使用Rows屬性和Columns屬性時,注意下面代碼的區別:
①Range(”C3:D4″, “F8:G10″).Rows.Count,返回的值爲8;
②Range(”C3:D4,F8:G10″).Rows.Count,返回的值爲2,即只計算第一個單元格區域。
(3)可用Areas屬性引用選定的單元格區域或多塊選定區域中的區域集合。
例1:以下示例清除了 Sheet1 上三個區域的內容。
Sub ClearRanges() Worksheets("Sheet1").Range("C5:D9,G9:H16,B14:D18"). _ ClearContents End Sub 
命名區域使得用Range屬性處理多個區域更加容易。以下示例可在所有這三個命名區域處於同一工作表時運行。
Sub ClearNamed() Range("MyRange, YourRange, HisRange").ClearContents End Sub 
例2:爲了同時選擇名爲“Test”和“Sample”的兩個區域,可以使用下面的代碼:
Application.Union(Range("Test"), Range("Sample")).Select 
注意,這兩個區域須在同一工作表中,如下面的代碼:
Set y = Application.Union(Range("Sheet1!A1:B2"), Range("Sheet1!C3:D4"))
但Union方法不能處理不同工作表中的區域,可下面的代碼:
Set y = Application.Union(Range("Sheet1!A1:B2"), Range("Sheet2!C3:D4"))
將會出錯。
例3:以下示例創建了名爲 myMultipleRange 的 Range 對象,並將其定義爲區域 A1:B2 和 C3:D4 的組合,然後將該組合區域的字體設置爲加粗。
Sub MultipleRange() Dim r1, r2, myMultipleRange As Range Set r1 = Sheets("Sheet1").Range("A1:B2") Set r2 = Sheets("Sheet1").Range("C3:D4") Set myMultipleRange = Union(r1, r2) myMultipleRange.Font.Bold = True End Sub 
例4:下述過程計算選定區域中的塊數目,如果有多個塊,就顯示一則警告消息。
Sub FindMultiple() If Selection.Areas.Count > 1 Then MsgBox "不能對多個選區進行操作." End If End Sub 
[應用8]引用當前工作表中活動單元格或指定單元格所在的區域(當前區域)
可以使用CurrentRegion屬性,例如:
(1)ActiveCell.CurrentRegion,表示活動單元格所在的當前區域。
(2)Range(”D5″).CurrentRegion,表示單元格D5所在的當前區域。
當前區域是指周圍由空行或空列所圍成的區域。
下面的示例將當前工作表當前區域的值複製到剪貼板,然後將這些值插入到新工作表:
Sub CopyCurrentRegionValue() Range("D5").Activate ActiveCell.CurrentRegion.Select Selection.Copy Sheets.Add After:=Sheets(Sheets.Count) Sheets(Sheets.Count).Name = "Sample" Sheets("Sample").Select Range("D5").Activate ActiveSheet.Paste End Sub 
[應用9]引用當前工作表中已使用的區域
可以使用UsedRange屬性,例如:
(1)Activesheet.UsedRange,表示當前工作表中已使用的區域。
(2)Worksheets(”sheet1″).UsedRange,表示工作表sheet1中已使用的區域。
與CurrentRegion屬性不同的是,該屬性代表工作表中已使用的單元格區域,包括顯示爲空行,但已進行過格式的單元格區域。
'選取當前工作表中已使用的單元格區域 Sub SelectUsedRange() MsgBox "選取當前工作表中已使用的單元格區域" _ & vbCrLf & "並顯示其地址" ActiveSheet.UsedRange.Select MsgBox ActiveSheet.UsedRange.Address End Sub 
[應用10]在單元格區域內指定特定的單元格
可以使用Item屬性,例如:
(1)Range(”A1:B10″).Item(5,3)指定單元格C5,這個單元格處於以區域中左上角單元格A1(即區域中第1行第1列的單元格)爲起點的第5行第3列。因爲Item屬性爲默認屬性,因此也可以簡寫爲:Range(”A1:B10″)(5,3)。
如果將A1:B10區域命名爲”MyRange”,那麼Range(”MyRange”)(5,3)也指定單元格C5。
(2)Range(”A1:B10″)(12,13)指定單元格M12,即用這種方式引用單元格,該單元格不必一定要包含在區域內。
同時,也不需要索引數值是正值,例如:
① Range(”D4:F6″)(0,0)代表單元格C3;
② Range(”D4:F6″)(-1,-2)代表單元格A2。
而Range(”D4:F6″)(1,1)代表單元格D4。
(3)也可以在單元格區域中循環,例如:
Range(”D4:F6″)(2,2)(3,4)代表單元格H7,即該單元格位於作爲左上角單元格E5的第3行第4列(因爲E5是開始於區域中左上角單元格D4起的第2行第2列)。
(4)也能使用一個單個的索引數值進行引用。計數方式爲從左向右,即在區域中的第一行開始從左向右計數,第一行結束後,然後從第二行開始從左到右接着計數,依次類推。(注:從區域中第一行第一個單元格開始計數,當第一行結束時,轉入第二行最左邊的單元格,這樣按一行一行從左向右依次計數。以單元格區域中第1個單元格開始,按上述規則依次爲第2個單元格、第3個單元格….等等),例如:
Range(”A1:B2″)(1) 代表單元格A1;
Range(”A1:B2″)(2) 代表單元格B1;
Range(”A1:B2″)(3) 代表單元格A2;
Range(”A1:B2″)(4) 代表單元格B2。
這種方法可在工作表中連續向下引用單元格(即不一定是在單元格區域內,但在遵循相同的規律),例如:
Range(”A1:B2″)(5)代表單元格A3;
Range(”A1:B2″)(14)代表單元格B7,等等。
也可以使用單個的負數索引值。
這種使用單個索引值的方法對遍歷列是有用的,例如,Range(”D4″)(1)代表單元格D4,Range(”D4″)(2)代表單元格D5,Range (”D4″)(11)代表單元格D14,等等。
同理,稍作調整後也可遍歷行,例如:
Range(”D4″).Columns(2)代表單元格E4,Range(”D4″).Columns(5)指定單元格H4,等等。
(5)當與對象變量配合使用時,Item屬性能提供簡潔並有效的代碼,例如:
Set rng = Worksheets(1).[A1]
定義了對象變量後,像單元格方法一樣,Item屬性允許使用兩個索引數值引用工作表中的任一單元格,例如,rng(3,4)指定單元格D3。
[應用11]引用當前工作表中的整行或整列
見下面的示例代碼:
(1)Range(”C:C”).Select,表示選擇C列。
Range(”C:E”).Select,表示選擇C列至E列。
(2)Range(”1:1″).Select,表示選擇第一行。
Range(”1:3″).Select,表示選擇第1行至第3行。
(3)Range(”C:C”).EntireColumn,表示C列;
Range(”D1″).EntireColumn,表示D列。
同樣的方式,也可以選擇整行,然後可以使用如AutoFit方法對整列或整行進行調整。
此外,可用Rows屬性或Columns屬性來處理整行或整列。這兩個屬性返回代表單元格區域的Range對象。在下例中,Rows(1)返回Sheet1上的第一行,然後將區域字體加粗。
Sub RowBold() Worksheets("Sheet1").Rows(1).Font.Bold = True End Sub 
另,Rows(1)代表當前工作表中的第一行,Rows代表當前工作表中的所有的行,Columns(1)代表當前工作表中的第一列,Columns(”A”)代表當前工作表中的第一列,Columns代表當前工作表中所有的列。
若要同時處理若干行或列,可創建一個對象變量並使用Union方法,將對Rows屬性或Columns屬性的多個調用組合起來。下例將活動工作簿中第一張工作表上的第一行、第三行和第五行的字體設置爲加粗。
Sub SeveralRows() Worksheets("Sheet1").Activate Dim myUnion As Range Set myUnion = Union(Rows(1), Rows(3), Rows(5)) myUnion.Font.Bold = True End Sub 
[應用12]引用當前工作表中的所有單元格
可以使用下面的代碼:
(1)Cells,表示當前工作表中的所有單元格。
(2)Range(Cells(1, 1), Cells(Cells.Rows.Count, Cells. Columns.Count)),其中Cells.Rows表示工作表所有行,Cells. Columns表示工作表所有列。
下面的過程清除活動工作簿中Sheet1上所有單元格的內容。
Sub ClearSheet() Worksheets("Sheet1").Cells.ClearContents End Sub 
[應用13]引用工作表中的特定單元格區域
在工作表中,您可能使用過“定位條件”對話框。可以通過選擇菜單“編輯——定位”,單擊“定位”對話框中的“定位條件”按鈕顯示該對話框。這個對話框可以允許用戶選擇特定的單元格。例如:
(1)Worksheets(”sheet1″).Cells.SpecialCells(xlCellTypeAllFormatConditions),表示工作表sheet1中由帶有條件格式的單元格所組成的區域。
(2)ActiveCell.CurrentRegion.SpecialCells(xlCellTypeBlanks),表示當前工作表中活動單元格所在區域中所有空白單元格所組成的區域。
(3)選擇所有公式單元格
Sub SelectSpecialCells() MsgBox "選擇當前工作表中所有公式單元格" ActiveSheet.Cells.SpecialCells(xlCellTypeFormulas).Select End Sub 
當然,還有很多常量和值的組合,可以讓您實現特定單元格的查找並引用。
[應用14]引用命名區域
使用名稱比使用A1樣式記號更容易標識單元格區域。若要命名選定的單元格區域,請單擊編輯欄左端的名稱框,鍵入名稱,再按回車鍵。
例1:要選擇當前工作表中名爲“Test”的區域,可以使用下面的代碼:
Range("Test").Select 
或:
Application.Goto "Test" 
例2:選擇同一工作簿中另一工作表上名爲“Test”的區域,可使用下面的代碼:
Application.Goto Sheets("Sheet1").Range("Test")
也可以先激活工作表,再選擇:
Sheets("Sheet1").Activate Range("Test").Select 
例3:要選擇不同工作簿中工作表上名爲“Test”的區域,可使用下面的代碼:
Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet2").Range("Test")
也可以先激活工作表,再選擇:
Workbooks("BOOK2.XLS").Sheets("Sheet2").Activate Range("Test").Select 
例4:以下示例引用名爲“MyBook.xls”的工作簿中名爲“MyRange”的區域,並將該區域的字體設置爲斜體:
Sub FormatRange() Range("MyBook.xls!MyRange").Font.Italic = True End Sub 
例5:以下示例引用名爲“Report.xls”的工作簿中特定工作表的區域“Sheet1!Sales”,並添加邊框線:
Sub FormatSales() Range("[Report.xls]Sheet1!Sales").BorderAround Weight:=xlThin End Sub 
例6:要選定命名區域,可以使用GoTo方法。該方法將激活工作簿和工作表,然後選定該區域。
Sub ClearRange() Application.Goto Reference:="MyBook.xls!MyRange" Selection.ClearContents End Sub 
以下示例顯示對於活動工作簿將如何編寫與上例相同的過程。
Sub ClearRange() Application.Goto Reference:="MyRange" Selection.ClearContents End Sub 
例7:下例用For Each…Next循環語句在命名區域中的每一個單元格上循環。如果該區域中的任一單元格的值超過limit的值,就將該單元格的顏色更改爲黃色。
Sub ApplyColor() Const Limit As Integer = 25 For Each c In Range("MyRange") If c.Value > Limit Then c.Interior.ColorIndex = 27 End If Next c End Sub 
[應用15]選擇特別指定的單元格或單元格區域
下面的示例使用瞭如下圖1所示的工作表。

圖1:示例數據
例1:選擇連續數據列中的最後一個單元格
要選擇一個列A中最後一個單元格,可以使用下面的代碼:
ActiveSheet.Range("A1").End(xlDown).Select 
在圖1所示的工作表中運行上述代碼,將選擇單元格A4。
'選取最下方的單元格 Sub SelectEndCell() MsgBox "選取當前單元格區域內最下方的單元格" ActiveCell.End(xlDown).Select End Sub 
可以改變參數xlDown以選取最左邊、最右邊、最上方的單元格。
例2:選擇連續數據列底部的空單元格
要選擇連續單元格區域下面的空單元格,可以使用下面的代碼:
ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Select 
在圖1所示的工作表中運行上述代碼,將選擇單元格A5。
例3:選擇某列中連續數據單元格區域
要選擇列A中連續數據單元格區域,可以使用下面的代碼:
ActiveSheet.Range("A1", ActiveSheet.Range("A1").End(xlDown)).Select 
或:
ActiveSheet.Range("A1:" & ActiveSheet.Range("A1").End(xlDown).Address).Select 
在圖1所示的工作表中運行上述代碼,將選擇單元格區域A1:A4。
例4:選擇某列中非連續數據單元格區域
要選擇某列中非連續數據單元格區域,可以使用下面的代碼:
ActiveSheet.Range("A1", ActiveSheet.Range("A65536").End(xlUp)).Select 
或:
ActiveSheet.Range("A1:" & ActiveSheet.Range("A1").End(xlDown).Address).Select 
在圖1所示的工作表中運行上述代碼,將選擇單元格區域A1:A6。
例5:選擇一個矩形(規則的)單元格區域
要選擇圍繞某單元格的一個矩形區域,可以使用CurrentRegion屬性。CurrentRegion屬性將選擇四周被空行和空列圍繞的區域,如下面的代碼:
ActiveSheet.Range("A1").CurrentRegion.Select 
在圖1所示的工作表中運行上述代碼,將選擇單元格區域A1:C4。也可以使用下面的代碼:
ActiveSheet.Range("A1", ActiveSheet.Range("A1").End(xlDown).End(xlToRight)).Select 
或:
ActiveSheet.Range("A1:" & ActiveSheet.Range("A1").End(xlDown).End(xlToRight).Address).Select 
若想選擇單元格區域A1:C6,可使用下面的代碼:
lastCol = ActiveSheet.Range("A1").End(xlToRight).Column lastRow = ActiveSheet.Cells(65536, lastCol).End(xlUp).Row ActiveSheet.Range("A1", ActiveSheet.Cells(lastRow, lastCol)).Select 
或:
lastCol = ActiveSheet.Range("A1").End(xlToRight).Column lastRow = ActiveSheet.Cells(65536, lastCol).End(xlUp).Row ActiveSheet.Range("A1:" & ActiveSheet.Cells(lastRow, lastCol).Address).Select 
[應用16]選擇多個不同長度的非連續列
例如,有如下圖2所示的工作表:

圖2:示例數據
要同時選擇A列和C列中的數據,即單元格區域A1:A3和C1:C6,可使用下面的代碼:
StartRange = "A1" EndRange = "C1" Set a = Range(StartRange, Range(StartRange).End(xlDown)) Set b = Range(EndRange, Range(EndRange).End(xlDown)) Union(a, b).Select 
[應用17]設置當前單元格的前一個單元格和後一個單元格的值
Sub SetCellValue() MsgBox "將當前單元格中前面的單元格值設爲""我前面的單元格""" & vbCrLf _ & "後面的單元格值設爲""我後面的單元格""" ActiveCell.Previous.Value = "我前面的單元格" ActiveCell.Next.Value = "我後面的單元格" End Sub 
[應用18]引用其它工作表或其它工作簿中的單元格區域
要引用其它工作表或其它工作簿中的單元格區域,只需在單元格對象前加上相應的引用對象即可,例如:
(1)Worksheets(”Sheet3″).Range(”C3:D5″),表示引用工作表sheet3中的單元格區域C3:D5。
(2)Workbooks(”MyBook.xls”).Worksheets(”sheet1″).Range(”B2″),表示引用MyBook工作簿中工作表Sheet1上的單元格B2。
此外,要選擇同一工作簿中另一工作表上的單元格E6,可以使用下面的代碼:
Application.Goto ActiveWorkbook.Sheets("Sheet2").Cells(6, 5)
或:
Application.Goto (ActiveWorkbook.Sheets("Sheet2").Range("E6"))
也可以先激活該工作表,然後再選擇:
Sheets("Sheet2").Activate ActiveSheet.Cells(6, 5).Select 
同樣,例如要選擇另一工作簿中某工作表上的單元格F7,可以使用下面的代碼:
Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Cells(7, 6)
或:
Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Range("F7")
也可以先激活該工作簿中的工作表,然後再選擇:
Workbooks("BOOK2.XLS").Sheets("Sheet1").Activate ActiveSheet.Cells(7, 6).Select 
又如,要選擇同一工作簿中另一工作表上的單元格區域D3:E11,可以使用下面的代碼:
Application.Goto ActiveWorkbook.Sheets("Sheet3").Range("D3:E11")
或:
Application.Goto ActiveWorkbook.Sheets("Sheet3").Range("D3", "E11")
也可以先激活該工作表,然後再選擇:
Sheets("Sheet3").Activate ActiveSheet.Range(Cells(3, 4), Cells(11, 5)).Select 
要選擇另一工作簿中某工作表上的單元格區域E4:F12,可以使用下面的代碼:
Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Range("E4:F12")
或:
Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Range("E4", "F12")
也可以先激活該工作表,然後再選擇:
Workbooks("BOOK2.XLS").Sheets("Sheet1").Activate ActiveSheet.Range(Cells(4, 5), Cells(12, 6)).Select 
說明:使用Application.Goto方法,如果指定另一工作表(不是當前工作表)中的指定區域,在Range屬性中使用兩個Cells屬性時,則必須包括Sheets對象,如:
Application.Goto Sheets("Sheet1").Range(Sheets("Sheet1").Range(Sheets("Sheet1").Cells(2, 3), Sheets("Sheet1").Cells(4, 5)))
[應用19]處理三維區域
如果要處理若干工作表上相同位置的單元格區域,可用Array函數選定兩張或多張工作表。下例設置三維單元格區域的邊框格式。
Sub FormatSheets() Sheets(Array("Sheet2", "Sheet3", "Sheet5")).Select Range("A1:H1").Select Selection.Borders(xlBottom).LineStyle = xlDouble End Sub 
下例應用FillAcrossSheets方法,將Sheet2上區域中的格式和所有數據傳送到活動工作簿中所有工作表上的相應區域。
Sub FillAll() Worksheets("Sheet2").Range("A1:H1") _ .Borders(xlBottom).LineStyle = xlDouble Worksheets.FillAcrossSheets (Worksheets("Sheet2") _ .Range("A1:H1")) End Sub 
[應用20]使用Range對象變量引用單元格
如果將對象變量設置爲Range對象,即可以使用變量名輕鬆地操作單元格區域。
以下過程將創建對象變量myRange,然後將活動工作簿中Sheet1上的區域A1:D5賦予該變量。隨後的語句用該變量名稱代替Range對象,以修改該區域的屬性。
Sub Random() Dim myRange As Range Set myRange = Worksheets("Sheet1").Range("A1:D5") myRange.Formula = "=RAND()" myRange.Font.Bold = True End Sub 
[應用21]其它的引用方式
對於Excel 2007以前的版本來說:
(1)Cells(15),表示單元格O1,即可在Cells屬性中指定單元格數字來選擇單元格,其計數順序爲自左至右、從上到下,又如Cells(257),表示單元格B1。
(2)Cells(, 256),表示單元格IV1,但是如果Cells(, 257),則會返回錯誤。
Excel 2007中增加了工作表列數和行數,因此上述限制相應改變。
說明:上面的一些代碼在選擇單元格或單元格區域時,先激活工作表後選擇,這只是爲了說明的方便。實際上,在操作單元格時,只要引用了相應的單元格或單元格區域,不必先激活工作表。
小結:我們使用VBA對Excel進行處理,一般是對其工作表中的數據進行處理,因此,引用單元格區域是ExcelVBA編程中最基本的操作之一,只有確定了所處理的單元格區域,才能使用相應的屬性和方法進行下一步的操作。
上面列舉了一些引用單元格區域的情形和方式,可以看出,引用單元格區域有很多方式,有一些可能不常用,可以根據工作表的所處的環境和個人編程習慣進行選擇使用。
當然,在編寫程序時,也可能會將上面的一些屬性聯合使用,以達到選取特定操作對象的目的,例如Offset屬性、Resize屬性、CurrentRegion屬性、UsedRange屬性等的組合。
下面對Range對象的一些常用屬性和方法進行簡單的小結。
1、Activate與Select
試驗下面的過程:
Sub SelectAndActivate() Range("B3:E10").Select Range("C5").Activate End Sub 
其結果如下圖所示:

圖3:Select與Activate
即選取單元格區域B3:E10並將單元格C5選中。
Selection指單元格區域B3:E10,而ActiveCell則是單元格C5;ActiveCell代表單個的單元格,而Selection則可以代表單個單元格,也可以代表單元格區域。
2、Range屬性
可以使用Application對象的Range屬性引用Range對象,如
Application.Range("B2") '代表當前工作表中的單元格B2
若引用當前工作表中的單元格,也可以忽略前面的Application對象。
Range("A1:D10") '代表當前工作表中的單元格區域A1:D10 Range("A1:A10,C1:C10,E1:E10") '代表當前工作表中非連續的三個區域組成的單元格區域
Range屬性也接受指向單元格區域對角的兩個參數,如:
Range("A1","D10") '代表單元格區域A1:D10
當然,Range屬性也接受單元格區域名稱,如:
Range("Data") '代表名爲Data的數據區域
Range屬性的參數可以是對象也可以是字符串,如:
Range("A1",Range("LastCell"))
3、單元格引用的快捷方式
可以在引用區域兩側加上方括號來快速引用單元格區域,如:
[B2]
[A1:D10]
[A1:A10,C1:C10,E1:E10]
[Data]
但其引用的是絕對區域。
4、Cells屬性
可以使用Cells屬性來引用Range對象。如:
ActiveSheet.Cells Application.Cells '引用當前工作表中的所有單元格 Cell(2,2) Cell(2,"B") '引用單元格B2 Range(Cells(1,1),Cells(10,5)) '引用單元格區域A1:E10
若想在一個單元格區域中循環時,使用Cells屬性是很方便的。
也可以使用Cells屬性進行相對引用,如:
Range("D10:G20").Cells(2,3) '表示引用單元格區域D10:G20中第2行第3列的單元格,即單元格F11
也可使用語句:Range(”D10″).Cells(2,3)達到同樣的引用效果。
5、Offset屬性
Offset屬性基於當前單元格按所給參數進行偏移,與Cells屬性不同的是,它基於0即基準單元格爲0,如:
Range(”A10″).Cells(1,1)和Range(”A10″).Offset(0,0)都表示單元格A10
當想引用於基準單元格區域同樣大小的單元格區域時,則Offset屬性是有用的。
6、Resize屬性
可使用Resize屬性獲取相對於原單元格區域左上角單元格指定大小的區域。
7、SpecialCells方法
SpecialCells方法對應於“定位條件”對話框,如圖05-02所示:
圖4:“定位條件”對話框
8、CurrentRegion屬性
使用CurrentRegion屬性可以選取當前單元格所在區域,即周圍是空行和空列所圍成的矩形區域,等價於“Ctrl+Shift+*”快捷鍵。
9、End屬性
End屬性所代表的操作等價於“Ctrl+方向箭”的操作,使用常量xlUp、xlDown、xlToLeft和xlToRight分別代表上、下、左、右箭。
例如,下面的代碼彙總活動單元格下方列的值:
Sub SumBelow() Dim rng As Range '彙總活動單元格下方單元格的值  With ActiveCell Set rng = Range(.Offset(1), .Offset(1).End(xlDown)) .Formula = "=SUM(" & _ rng.Address(RowAbsolute:=False, ColumnAbsolute:=False) & ")" .Copy Destination:=Range(.Cells(1), .Offset(1).End(xlToRight).Offset(-1)) End With End Sub 
10、Columns屬性和Rows屬性
Columns屬性和Rows屬性分別返回單元格區域中的所有列和所有行。
11、Areas集合
在多個非連續的單元格區域中使用Columns屬性和Rows屬性時,只是返回第一個區域的行或列,如:
Range("A1:B5,C6:D10,E11:F15").Rows.Count
將返回5。
此時應使用Areas集合來返回區域中每個塊的地址,如:
For Each rng In Range("A1:B5,C6:D10,E11:F15").Areas MsgBox rng.Address Next rng
12、Union方法和Intersect方法
當想從兩個或多個單元格區域中生成一個單元格區域時,使用Union方法;當找到兩個或多個單元格區域共同擁有的單元格區域時,使用Intersect方法。
當然,操作單元格或單元格區域有很多有用的技巧,這需要在實踐中總結和歸納。接下來的文章,我們將對Range對象的常用屬性和方法進行詳解。
 
在Excel中,如果想使用VBA在工作表的最後一行輸入數據,則必須先找到最後一行的位置,而在有些情況下,已輸入的數據中可能有隱藏的行,也可能最後一行的數據沒有顯示,也可能最後一行沒有數據但存在格式。此時,該如何有效地找到最後一行呢?又如,如果想找到最後一個公式所在的行,又該如何查找?還有一些情況,比如,在第一行和最後一行之間存在着空行;各列的最後一行不相同,在工作表無數據區域中雖沒有數據但已設置了格式……等等。
當然,在Excel中,有許多可以用來查找最後一行的方法,比如End(xlUp)屬性、UsedRange屬性、CurrentRegion屬性、SpecialCells方法、以及Find方法等,這些方法可以在不同的情形下使用。但正如前面所講述的,關鍵是要清楚Excel將“已使用範圍”、“當前區域”、和一些常量如xlCellTypeLastCell在工作表中代表什麼區域,以及您是在什麼情形下查找最後一行,然後選用合適的方法,以確保找到正確的最後一行,否則,可能所找到的並不是您所想要的最後一行。
“最後一行”可能的情形
在查找最後一行時,可能是查找以下情形單元格所在的“最後一行”,即:
  • 含有公式的單元格
  • 格式化的單元格
  • 含有顏色的單元格
  • 包含數據有效性的單元格
  • 包含批註的單元格
  • 直接輸入數據(文本和/或數字)的單元格
  • 由公式生成數據(文本和/或數字)的單元格
  • 直接輸入數據(文本和/或數字)或者由公式生成數據(文本和/或數字)的單元格
  • 直接輸入數字的單元格
  • 由公式生成數字的單元格
  • 直接輸入數字或由公式生成數字的單元格
  • 直接輸入文本的單元格
  • 由公式生成文本的單元格
  • 直接輸入文本或由公式生成文本的單元格
  • 其它情形
  • 包含上述所有情形的單元格
此外,還需要考慮工作表中的最後一行是否被隱藏了,而哪些方法忽略隱藏的行?最後一行的單元格中的數據是否顯示?這些都會影響到您是否能查找到正確的最後一行。
下面,我們來討論查找最後一行的方法以及可能出現的一些情況。
找到最後一行的一些方法探討
使用End屬性
在Excel VBA中,使用End(xlUp)查找最後一行是最常使用且最爲簡單的方法,它假設有一列總會包含有數據(數字、文本和公式等),並且在該列中最後輸入數據的單元格的下一行不會包含數據,因此不必擔心會覆蓋掉已有數據。但該方法有兩個缺點:
(1)僅侷限於查找指定列的最後一行。
(2)如果該列中最後一行被隱藏,那麼該隱藏行將被視作最後一行。因此,在最後一行被隱藏時,其數據可能會被覆蓋。但該列中間的隱藏行不會影響查找的結果。
[示例代碼01]
Sub EndxlUp_OneColLastRow() If Range("A" & Rows.Count).End(xlUp) = Empty Then GoTo Finish '獲取最後一行 MsgBox "最後一行是第" & Range("A" & Rows.Count).End(xlUp).Row & "行." Exit Sub Finish: MsgBox "沒有發現公式或數據! " End Sub 
[示例代碼02]
Sub NextRowInColumnUsedAsSub() '包含所有數據和公式,忽略隱藏的最後一行 Range("A" & Range("A" & Rows.Count).End(xlUp).Row + 1).Select End Sub 
[示例代碼03]
Sub NextRowInColumnUsedAsFunction() '包含所有數據和公式,忽略隱藏的最後一行 Range("A" & LastRowInColumn("A") + 1).Select End Sub  Public Function LastRowInColumn(Column As String) As Long LastRowInColumn = Range(Column & Rows.Count).End(xlUp).Row End Function 
注意,要輸入新數據的列可能與我們所查找最後一行時所使用的列不同,例如,在上例中,我們可以修改爲在B列中查找該列的最後一行,而在A列相應行的下一行中輸入新的數據。
使用Find方法
Find方法在當前工作表數據中進行查找,不需要指定列,也可以確保不會意外地覆蓋掉已有數據。其中,參數LookIn指定所查找的類型,有三個常量可供選擇,即xlValues、xlFormulas和xlComments。
(1) 常量xlFormulas將包含零值的單元格作爲有數據的單元格。(當設置零值不顯示時,該單元格看起來爲空,但該參數仍將該單元格視爲有數據的單元格)
(2) 常量xlValues將包含零值的單元格(如果設置零值不顯示時)作爲空白單元格,此時,若該單元格在最後一行,則Find方法會認爲該單元格所在的行爲空行,因此,該單元格中的內容可能會被新數據所覆蓋。
[注:在Excel中,選擇菜單“工具”——“選項”,在打開的“選項”對話框中,選擇“視圖”選項卡,將其中的“零值”前的複選框取消選中,則工作表中的零值都不會顯示]
如果在參數LookIn中使用常量xlValues的話,還存在一個問題是:如果您將最後一行隱藏,則Find方法會認爲倒數第二行是最後一行,此時您在最後一行的下一行輸入數據,則會將實際的最後一行的數據覆蓋。
您可以在隱藏最後一行與不隱藏最後一行,或者是最後一行顯示零值與不顯示零值時,運行下面的示例代碼04,看看所得的結果有什麼不同。
[示例代碼04]
Sub Find_LastRowxlValues() On Error GoTo Finish '獲取最後一行 MsgBox "最後一行是第" & Cells.Find("*", _ SearchOrder:=xlByRows, LookIn:=xlValues, _ SearchDirection:=xlPrevious).EntireRow.Row & "行" Exit Sub Finish: MsgBox "沒有發現數值!" End Sub 
因此,在使用Find方法時,您應該考慮所選參數設置的常量,以及工作表最後一行是否有可能被隱藏或不顯示零值。如果您忽視這些情況,很可能得不到您想要的結果,或者是覆蓋掉已有數據。使用常量xlFormulas可以避免這個問題,如下面的示例代碼05所示。
[示例代碼05]
Sub Find_LastRowxlFormulas() On Error GoTo Finish '獲取最後一行 MsgBox "最後一行是第" & Cells.Find("*", _ SearchOrder:=xlByRows, LookIn:=xlFormulas, _ SearchDirection:=xlPrevious).EntireRow.Row & "行" Exit Sub Finish: MsgBox "沒發現數值或公式!" End Sub 
下面再列舉幾個示例代碼。
[示例代碼06]
Sub NextRowUsedAsSub() '選取最後一行的下一行 Range("A" & Cells.Find("*", LookIn:=xlFormulas, SearchDirection:=xlPrevious).Row + 1).Select End Sub 
[示例代碼07]
Sub NextRowUsedAsFunction() '選取最後一行的下一行(調用函數) Range("A" & LastRow + 1).Select End Sub  Public Function LastRow() As Long '本代碼包含隱藏行  '使用常量xlFormulas,因爲常量xlValues會忽略隱藏的最後一行 LastRow = Cells.Find("*", LookIn:=xlFormulas, SearchDirection:=xlPrevious).Row End Function 
注:Find方法中,參數LookIn的默認值爲xlFormulas。
使用SpecialCells方法
SpecialCells方法用於查找指定類型的值,其語法爲SpecialCells(Type,Value),有兩種主要的使用方式:
(1)若參數Type僅考慮常量,則在查找時會忽略和覆蓋由公式生成的任何數據,如示例代碼08所示。
(2)若參數Type僅考慮由公式生成的數據,則在查找時會忽略和覆蓋任何常量數據,如示例代碼09所示。
如果參數Type是xlCellTypeConstants或者是xlCellTypeFormulas,則Value參數可使用常量決定哪種類型的單元格將被包含在結果中,這些常量值能組合而返回多個類型,其缺省設置是選擇所有的常量或公式,而不管是何類型,可使用下面四個可選的常量:
1)xlTextValues(包含文本) 2)xlNumbers(包含數字)
3)xlErrors(包含錯誤值) 4)xlLogical(包含邏輯值)
自已在工作表輸入一些含有數值和公式的數據,隱藏或不隱藏最後一行或公式所在的行,體驗下面的兩段示例代碼。
[示例代碼08]
'當最後一行爲公式或隱藏了最後行時,會忽略,即認爲倒數第二行爲最後一行 Sub NextConstantRowFunction() Range("A" & LastConstantRow(True, True, True, True) + 1).Select End Sub  Public Function LastConstantRow(Optional IncludeText As Boolean, _ Optional IncludeNumbers As Boolean, _ Optional IncludeErrors As Boolean, _ Optional IncludeLogicals As Boolean) As Long Dim Text As Long, Numbers As Long, Errors As Long Dim Logical As Long, AllTypes As Long If IncludeText Then Text = xlTextValues Else Text = 0 If IncludeNumbers Then Numbers = xlNumbers Else Numbers = 0 If IncludeErrors Then Errors = xlErrors Else Errors = 0 If IncludeLogicals Then Logical = xlLogical Else Logical = 0 AllTypes = Text + Numbers + Errors + Logical On Error GoTo Finish LastConstantRow = Split(Cells.SpecialCells(xlCellTypeConstants, AllTypes).Address, "$") _ (UBound(Split(Cells.SpecialCells(xlCellTypeConstants, AllTypes).Address, "$"))) Exit Function Finish: MsgBox "沒有發現數據!" End Function 
[示例代碼09]
'查找含有公式的單元格所在的行,忽略該行以後的常量和隱藏的行 Sub NextFormulaRowFunction() Range("A" & LastFormulaRow(True, True, True, True) + 1).Select End Sub  Public Function LastFormulaRow(Optional IncludeText As Boolean, _ Optional IncludeNumbers As Boolean, _ Optional IncludeErrors As Boolean, _ Optional IncludeLogicals As Boolean) As Long Dim Text As Long, Numbers As Long, Errors As Long Dim Logical As Long, AllTypes As Long If IncludeText Then Text = xlTextValues Else Text = 0 If IncludeNumbers Then Numbers = xlNumbers Else Numbers = 0 If IncludeErrors Then Errors = xlErrors Else Errors = 0 If IncludeLogicals Then Logical = xlLogical Else Logical = 0 AllTypes = Text + Numbers + Errors + Logical On Error GoTo Finish LastFormulaRow = Split(Cells.SpecialCells(xlCellTypeFormulas, AllTypes).Address, "$") _ (UBound(Split(Cells.SpecialCells(xlCellTypeFormulas, AllTypes).Address, "$"))) Exit Function Finish: MsgBox "沒有發現數據!" End Function 
下面的示例代碼10忽略最後一行帶有公式的單元格,即當最後一行的單元格中含有公式時,將倒數第二行作爲最後一行,即只考慮直接輸入到工作表中的數據。當最後一行沒有公式但被隱藏時,並不影響該方法的判斷。
[示例代碼10]
Sub SpecialCells_LastRowxlCellTypeConstants() Dim MyRow As Range On Error GoTo Finish Set MyRow = Intersect([A:A], Cells. _ SpecialCells(xlCellTypeConstants).EntireRow).EntireRow '獲取最後一行 MsgBox "最後一行是第" & Split(MyRow.Address, "$") _ (UBound(Split(MyRow.Address, "$"))) & "行" Set MyRow = Nothing Exit Sub Finish: MsgBox "沒有發現數據!" End Sub 
注:因爲上述代碼使用了“Split函數”,故只適合於Office2000及以上的版本。
該方法也允許我們指定單個數據類型,諸如數字數據或文本數據,如下所示。
下面,我們查找的最後一行是僅在行中有數字(而不包含公式)的單元格的最後一行。
[示例代碼11]
Sub SpecialCells_LastRowxlCellTypeNumberConstants() Dim MyRow As Range On Error GoTo Finish Set MyRow = Intersect([A:A], Cells. _ SpecialCells(xlCellTypeConstants, xlNumbers).EntireRow) '獲取最後一行 MsgBox "最後一行是第" & Split(MyRow.Address, "$") _ (UBound(Split(MyRow.Address, "$"))) & "行" Set MyRow = Nothing Exit Sub Finish: MsgBox "沒有發現數據!" End Sub 
下面,我們查找的最後一行是僅在行中有文本(而不包含公式)的單元格的最後一行。
[示例代碼12]
Sub SpecialCells_LastRowxlCellTypeTextConstants() Dim MyRow As Range On Error GoTo Finish Set MyRow = Intersect([A:A], Cells. _ SpecialCells(xlCellTypeConstants, xlTextValues).EntireRow) '獲取最後一行 MsgBox "最後一行是第" & Split(MyRow.Address, "$") _ (UBound(Split(MyRow.Address, "$"))) & "行" Set MyRow = Nothing Exit Sub Finish: MsgBox "沒有發現數據!" End Sub 
下面,我們查找的最後一行是僅在行中有公式的單元格的最後一行。
[示例代碼13]
Sub SpecialCells_LastRowxlCellTypeFormulas() Dim MyRow As Range On Error GoTo Finish Set MyRow = Intersect([A:A], Cells. _ SpecialCells(xlCellTypeFormulas).EntireRow).EntireRow '獲取最後一行 MsgBox "最後一行是第" & Split(MyRow.Address, "$") _ (UBound(Split(MyRow.Address, "$"))) & "行" Set MyRow = Nothing Exit Sub Finish: MsgBox "沒有發現數據!" End Sub 
同上面所講述的一樣,我們也能使用SpecailCells方法去找到其它特定類型的單元格所在的最後一行,下面是這些常量的完整列表:
XlCellTypeAllFormatConditions (任何格式的單元格)
XlCellTypeAllValidation (帶有數據有效性的單元格)
XlCellTypeBlanks (所使用區域中的空白單元格)
XlCellTypeComments (包含有批註的單元格)
XlCellTypeConstants (包含有常量的單元格)
XlCellTypeFormulas (包含有公式的單元格)
XlCellTypeLastCell (已使用區域中的最後一個單元格(看下面))
XlCellTypeSameFormatConditions (有相同格式的單元格)
XlCellTypeSameValidation (有相同數據有效性條件的單元格)
XlCellTypeVisible (工作表中所有可見的單元格)
使用UsedRange屬性(及SpecialCells方法)
UsedRange方法可用於在工作表中已使用區域查找最後一行,該區域包括可能以前使用過的任何單元格,但現在其中的數據被刪除了,比如目前的工作表中只有第1行至第5行共5行,其它行都無數據,但在第6行中有些單元格以前使用過(可能僅僅格式化或內容清除了,總之該行現在不含有數據),那麼第6行也包含在該已使用的區域中。此外,如果最後一行被隱藏,那麼使用該方法查找最後一行是無規律且不可靠的,它通常可能會得到預料不到的結果。
有時,與UsedRange屬性相似的技術也能用SpecialCells方法實現,其常量xlCellTypeLastCell代表在“已使用區域”中的最後一個單元格,與UsedRange屬性稍有不同的是,當您在最後一行中輸入數據後,又將其刪除,則此數據所在的單元格也包含在已使用的區域中,並且如果最後的行被隱藏,則將可見行的最後一行當作最後一行。下面有兩段代碼您可以在工作表中進行調試,看看其特點。
[示例代碼14]
Sub NextUsedRowSub() ' 選取可見的最後一行的下一行 Range("A" & Cells.SpecialCells(xlCellTypeLastCell).Row + 1).Select End Sub 
[示例代碼15]
Sub NextUsedRowFunction() Range("A" & LastUsedRow + 1).Select End Sub  Public Function LastUsedRow() As Long LastUsedRow = Cells.SpecialCells(xlCellTypeLastCell).Row End Function 
使用這裏介紹的兩種技術時,您一定要清楚工作表當前的狀態,以找到正確的最後一行。
使用CurrentRegion屬性
CurrentRegion屬性返回代表單元格所在的當前區域,即四周有空行的獨立區域,因此,可使用此屬性查找當前區域的最後一行。但是使用其查找最後一行的一個缺點是,必須首先選取當前區域,然後進行查找。
交叉參考
在《在彙總工作表中合併多個工作表中的數據》和《將多個工作簿中的數據合併到一個工作簿》中也有查找最後一個單元格、最後一行或最後一列的優秀代碼示例。
小結
正如開始所講述的一樣,使用各種方法來查找最後一行都有其優缺點,並且都能找到您想要的最後一行,關鍵是您要了解各種方法的特性,以及工作表的狀態,以便於選擇所使用的方法來找到您需要的最後一行。
上述內容可能有不準確的地方,也可能有遺漏之處,您也可以在調試中體會和改進。
CurrentRegion屬性代表什麼
您可能經常在程序代碼中看到CurrentRegion屬性,它是一個非常有用的屬性,返回活動單元格所在的周圍由空行和空列組成的單元格區域(即通常所說的當前區域),如圖1所示。

圖1
具體地說,當前區域即活動單元格所在的矩形區域,該矩形區域的每一行和每一列中至少包含有一個數據,其周圍是空行和空列,圖1中列舉了其中的4種情形(見藍色陰影區域)。在當前區域範圍內,不管活動單元格是哪一個單元格,其所在的當前區域均爲同一區域,如上例中的B5:D7區域,活動單元格B5的當前區域爲B5:D7,當活動單元格爲C6時,其當前區域仍爲B5:D7。
使用CurrentRegion屬性相當於在Excel工作表中選擇菜單“編輯——定位”命令,在彈出的“定位”對話框中單擊“定位條件”按鈕,然後在“定位條件”對話框中選中“當前區域”選項按鈕,或者相當於使用Ctrl+Shift+*組合鍵。
CurrentRegion屬性的一些基本應用
CurrentRegion屬性可用於很多操作,下面通過如圖2所示的工作表示例講解該屬性的應用。

圖2
(1)返回指定(或活動)單元格所在區域中標題行的行數
Worksheets("sheet1").Range("H2").Value = _ Worksheets("sheet1").Range("A1").CurrentRegion.ListHeaderRows
上述代碼在示例工作表中運行後,將返回“1”,即單元格A1所在區域的標題行的行數爲1。
(2)返回指定(或活動)單元格所在區域的行數
Worksheets("sheet1").Range("H3").Value = _ Worksheets("sheet1").Range("A1").CurrentRegion.Rows.Count
上述代碼在示例工作表中運行後,將返回“11”,即單元格A1所在區域的行數爲11。
(3)返回指定(或活動)單元格所在區域的列數
Worksheets("sheet1").Range("H4").Value = _ Worksheets("sheet1").Range("A1").CurrentRegion.Columns.Count
上述代碼在示例工作表中運行後,將返回“4”,即單元格A1所在區域的列數爲4。
(4)返回指定(或活動)單元格所在區域的單元格數
Worksheets("sheet1").Range("H5").Value = _ Worksheets("sheet1").Range("A1").CurrentRegion.Cells.Count
上述代碼在示例工作表中運行後,將返回“44”,即單元格A1所在區域的單元格數爲44。
(5)在指定(或活動)單元格所在區域中選取除標題行以外的數據區域
Worksheets("sheet1").Range("A1").CurrentRegion.Resize( _ Worksheets("sheet1").Range("A1").CurrentRegion.Rows.Count - Worksheets("sheet1"). _ Range("A1").CurrentRegion.ListHeaderRows, Worksheets("sheet1").Range("A1").CurrentRegion. _ Columns.Count).Offset(1, 0).Select 
上述代碼在示例工作表中運行後,將選取單元格A1所在區域中除標題行外的數據區域,即單元格區域A2:D11。
下面,將上述代碼綜合成一個完整的示例以演示CurrentRegion屬性的一些用法。程序代碼如下:
Sub testCurrentRegion() Dim rng As Range, ws As Worksheet Set ws = ActiveWorkbook.Worksheets("sheet1") Set rng = ws.Range("A1").CurrentRegion ws.Range("G2") = "當前區域標題行數" ws.Range("H2").Value = rng.ListHeaderRows ws.Range("G3") = "當前區域的行數" ws.Range("H3").Value = rng.Rows.Count ws.Range("G4") = "當前區域的列數" ws.Range("H4").Value = rng.Columns.Count ws.Range("G5").Value = "當前區域的單元格數" ws.Range("H5").Value = rng.Cells.Count ws.Columns("G:G").EntireColumn.AutoFit MsgBox "選取當前區域中除標題行以外的區域" rng.Resize(rng.Rows.Count - rng.ListHeaderRows, rng.Columns.Count).Offset(1, 0).Select End Sub 
運行後的結果如下圖3所示,示例文檔見:


圖3
(6)複製當前區域的數據到另一位置
Sub CopyCurrentRegion() Sheets("sheet1").Range("A1").CurrentRegion.Copy Sheets("sheet2").Range("A1") End Sub 
上述代碼將工作表Sheet1中單元格A1所在的區域複製到工作表sheet2中以單元格A1開始的單元格區域中。
(7)格式化當前區域中的數據
Sub FormatCurrentRegion() With ActiveCell.CurrentRegion .Font.Bold = True .Font.ColorIndex = 3 End With End Sub 
上述代碼將工作表中活動單元格所在區域數據加粗且設置爲紅色。
(8)在當前區域中自動套用格式
Sub testAutoFormatCurrentRegion() Worksheets("sheet1").Range("A1").CurrentRegion.AutoFormat End Sub 
上述代碼將在工作表sheet1中單元格A1所在區域自動套用默認的格式,當然,您可以設置所需套用的格式,默認值爲xlRangeAutoFormatClassic1。
一些示例
[示例1]在當前區域中查找空白單元格並填充
如下圖4所示的工作表,現在要使用空白單元格上方的有數據的單元格中的數據來填充空白單元格。

圖4
可以編寫如下的代碼:
Sub FillBlankCells() Worksheets("sheet1").Range("A1").CurrentRegion.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C" Worksheets("sheet1").Range("A1").CurrentRegion.Value = Worksheets("sheet1").Range("A1").CurrentRegion.Value End Sub 
運行代碼後,工作表中單元格A1所在區域中的空白單元格被相應數據填充,如圖5所示。

圖5
示例下載:

[示例2] 一個排序的簡單示例
如圖6所示的工作表,現在對第3列進行排序,按降序排列。

圖6
編寫的代碼如下:
Sub testSort() Dim rng As Range Set rng = Worksheets("sheet1").Cells(1, 1).CurrentRegion rng.Sort Key1:=rng.Cells(1, 3), Order1:=xlDescending, Header:=xlYes End Sub 
運行代碼後,工作表中的數據將按照第3列的數據從大到小進行排列,如圖7所示。

圖7
示例下載:

小結
1、CurrentRegion屬性的基本語法爲:
<單元格對象>.CurrentRegion
2、可以先使用CurrentRegion屬性返回指定單元格或者活動單元格所在的區域,然後使用其它的屬性對該區域的數據進行操作。
本文出自 51CTO.COM技術博
發佈了10 篇原創文章 · 獲贊 3 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章