2015-04-15 60 views
0

當考慮@Crouzilles問題:Assigning range to array in VBA我意識到,無論是否明確使用ActiveWorkbook.ActiveSheet來定義範圍,它都很重要。例如:將範圍分配給數組時,顯式和隱式使用ActiveSheet

Dim arr1() As Variant 
Dim arr2() As Variant 

arr1 = Range("A1:B2") 
arr2 = ActiveWorkbook.ActiveSheet.Range("A1:B2")    'Type mismatch 

我曾假定兩個右手側將返回Range對象,這將被鑄造成的變體的陣列;然而,第二行產生一個類型不匹配錯誤:

Run-time error '13': Type mismatch 

爲確保兩個語句的確返回數組我查TypeName()

Debug.Print TypeName(Range("A1:B2"))       'Range 
Debug.Print TypeName(ActiveWorkbook.ActiveSheet.Range("A1:B2")) 'Range 

我還檢查Range("A1:B1").Worksheet.Name屬性,以確保Range("A1:B2")是的確引用了ActiveWorkbook.ActiveSheet.references

然後我試着將Range().Value賦值給這兩個變量,它們的執行都是正確的:

arr1 = Range("A1:B2").Value 
arr2 = ActiveWorkbook.ActiveSheet.Range("A1:B2").Value   'No error 

這是有意義的爲一.ValueRange對象轉換爲變體的陣列....相同類型arr1arr2

Debug.Print TypeName(Range("A1:B2").Value)      'Variant() 
Debug.Print TypeName(ActiveWorkbook.ActiveSheet.Range("A1:B2").Value) 'Variant() 

要添加到我的混亂,明確地分配兩個變化到Range引用允許兩個陣列被分配:

Dim rng1 As Range 
Dim rng2 As Range 

Set rng1 = Range("A1:B2") 
Set rng2 = ActiveWorkbook.ActiveSheet.Range("A1:B2") 

arr1 = rng1 
arr2 = rng2              'No error 

任何人都可以解釋爲什麼一個RangeRange("A1:B2")引用的對象可以隱式轉換爲一組變體,而ActiveWorkbook.ActiveSheet.Range("A1:B2")不能?

回答

4

這是關於綁定和使用默認屬性。 Activesheet返回一個Object,而不是Worksheet,所以之後的所有內容都是後期限制,而Range(...)實際上是Application.Range的縮寫,因此它是早期綁定的。如果你聲明一個工作表變量並賦予ActiveSheet到它的代碼也將工作:

Dim ws As Worksheet 
Set ws = ActiveWorkbook.ActiveSheet 
arr2 = ws.Range("A1:B2") ' works 

聲明的變量爲Variant,而不是Variant()也會起作用。

道德故事:總是指定你的意思!

從VBA語言規範:

5.6.2.3默認成員遞歸限制

評價的對象,其默認屬性獲取或默認函數返回另一個對象可以導致遞歸評價處理返回的對象是否有其他默認成員。如果評估爲簡單數據值並且每個默認成員都有一個空參數列表,則通過這個默認成員鏈的遞歸可能是隱含的,或者如果指定了特定參數化每個默認成員的索引表達式,那麼遞歸通過默認成員鏈可能是隱含的

一個實現可以定義這種遞歸默認成員評估何時有效的限制。限制可能取決於諸如遞歸的深度,空參數列表的隱式或顯式指定,成員是否返回特定類與返回對象或變體,缺省成員是函數還是屬性獲取以及表達式出現在賦值的左側。 實施可能會確定此類評估爲靜態無效,或者可能會在運行時評估期間引發錯誤9(下標超出範圍)或13(類型不匹配)

+0

這很有意義,謝謝!有沒有辦法顯示對象是以編程方式延遲綁定的?我可以看到'Dim obj As Object'顯然很明顯,但直觀上我期望'ActiveWorksheet'返回一個'Worksheet'並確實'TypeName(ActiveWorksheet)'也會提示這一點。 – stucharo

+1

但它不是'ActiveWorksheet',它是'ActiveSheet',並且該工作表可能是Chart工作表(甚至是宏工作表) - 這就是爲什麼它返回一個Object而不是'Worksheet'。對象瀏覽器將顯示返回類型。 – Rory

+0

@stucharo - 如果你輸入「。之後並沒有在Intellesense上獲得成員名單。 – Comintern

相關問題