2014-09-18 81 views
2

在VBA中,爲什麼會出現下列問題?在VBA中的工作表中指定Excel範圍

Dim rng as Range rng = Range("Sheet1:Sheet3!A1")

它拋出一個HRESULT異常。有沒有另一種方法來構建VB​​A中的這個範圍?請注意,您可以輸入一個工作表函數,如= SUM(Sheet1:Sheet3!A1),它工作正常。

回答

3

A 範圍對象僅限於一個工作表。畢竟,它只能有一個父母。

= SUM()函數可以對一組範圍進行操作。 (這是真實的許多工作表函數)

編輯#1

我一直在尋找,因爲Janauary的解決方案:

UDF Syntax

我一直在使用範圍數組。不是一個很好的解決方案。

+0

簡單問題,對於第一部分簡單的答案。例如,我想知道是否有一種方法可以在VBA中構建Range對象,例如給出一個引用像「Sheet1:Sheet3!A1」或「'Foo 1:Bar'!A3:C4」之類的3D範圍的輸入字符串,例如。 – OfficeAddinDev 2014-09-19 10:48:23

+0

@Ryan請參閱我的**編輯#1 ** – 2014-09-19 11:15:38

+0

所以,簡而言之,答案就是它無法完成。 – OfficeAddinDev 2014-09-19 19:34:29

2

就發展Gary的回答(如果你要接受一個答案,接受他:):

使用Range變量:

Sub SumTest1() 

    Dim rSheet1  As Range 
    Dim rSheet2  As Range 
    Dim rSheet3  As Range 
    Dim dSum  As Double 

    With ThisWorkbook 
     Set rSheet1 = .Sheets("Sheet1").Range("A1") 
     Set rSheet2 = .Sheets("Sheet2").Range("A1") 
     Set rSheet3 = .Sheets("Sheet3").Range("A1") 
    End With 

    dSum = WorksheetFunction.Sum(rSheet1, rSheet2, rSheet3) 
    Debug.Print CStr(dSum) 

End Sub 

使用Variant變量:

Sub SumTest2() 

    Dim vArray  As Variant 
    Dim dSum  As Double 

    With ThisWorkbook 
     vArray = Array(.Sheets("Sheet1").Range("A1"), .Sheets("Sheet2").Range("A1"), .Sheets("Sheet3").Range("A1")) 
    End With 

    dSum = WorksheetFunction.Sum(vArray) 
    Debug.Print CStr(dSum) 

End Sub 

使用無變量:

Sub SumTest3() 

    Dim dSum  As Double 

    With ThisWorkbook 
     dSum = WorksheetFunction.Sum(Array(.Sheets("Sheet1").Range("A1"), .Sheets("Sheet2").Range("A1"), .Sheets("Sheet3").Range("A1"))) 
    End With 

    Debug.Print CStr(dSum) 

End Sub 
+0

我有興趣從描述我的問題中顯示的範圍的字符串返回Range對象,而不是範圍的總和。但是,如果我試圖獲得總和,最好使用Application.Evaluate(「SUM(Sheet1:Sheet3!A1)」)。 – OfficeAddinDev 2014-09-19 10:42:47

-2

未經檢驗的,但試試這個

Dim rng as string 
rng = "Sheet1:Sheet3!A1" 
worksheet("Sheet1").range("B1").formula = "=SUM(" & rng & ")" 
+0

這應該工作 - 或者至少它會評估 - 取決於OP的需求(實際上OP已經表明了這一點)。但正如Gary指出的那樣,你絕對*不能*定義一個跨越多張紙的「範圍」對象。 – 2014-09-19 01:21:36

+1

同意,這是在Excel級別使用3D引用,而不是VBA級別,並將所需的「範圍」存儲爲字符串。 (向合唱團傳道@DavidZemens,但是爲其他人可能會停止通過) – guitarthrower 2014-09-19 15:17:01

1

下面是一組基本完成同樣的事情UDF的功能。唯一要注意的是,參考3D範圍是一個字符串,即"Jan:Dec!A1",而不是垂直向上Jan:Dec!A1

'Adapted from https://web-beta.archive.org/web/20060313132405/http://www.j-walk.com/ss/excel/eee/eee003.txt by Andre Terra 
Function CountIf3D(Range3D As String, Criteria As String, _ 
    Optional Count_Range As Variant) As Variant 

    Dim sTestRange As String 
    Dim sCountRange As String 
    Dim Sheet1 As Integer 
    Dim Sheet2 As Integer 
    Dim n As Integer 
    Dim Count As Double 

    Application.Volatile 

    If Parse3DRange(Application.Caller.Parent.Parent.Name, _ 
     Range3D, Sheet1, Sheet2, sTestRange) = False Then 
     CountIf3D = CVErr(xlErrRef) 
    End If 

    If IsMissing(Count_Range) Then 
     sCountRange = sTestRange 
    Else 
     sCountRange = Count_Range.Address 
    End If 

    Count = 0 
    For n = Sheet1 To Sheet2 
     With Worksheets(n) 
     Count = Count + Application.WorksheetFunction.CountIf(.Range _ 
    (sTestRange), Criteria) 
     End With 
    Next n 
    CountIf3D = Count 
End Function 'CountIf3D 

Function SumIf3D(Range3D As String, Criteria As String, _ 
    Optional Sum_Range As Variant) As Variant 

    Dim sTestRange As String 
    Dim sSumRange As String 
    Dim Sheet1 As Integer 
    Dim Sheet2 As Integer 
    Dim n As Integer 
    Dim Sum As Double 

    Application.Volatile 

    If Parse3DRange(Application.Caller.Parent.Parent.Name, _ 
     Range3D, Sheet1, Sheet2, sTestRange) = False Then 
     SumIf3D = CVErr(xlErrRef) 
    End If 

    If IsMissing(Sum_Range) Then 
     sSumRange = sTestRange 
    Else 
     sSumRange = Sum_Range.Address 
    End If 

    Sum = 0 
    For n = Sheet1 To Sheet2 
     With Worksheets(n) 
     Sum = Sum + Application.WorksheetFunction.SumIf(.Range _ 
    (sTestRange), Criteria, .Range(sSumRange)) 
     End With 
    Next n 
    SumIf3D = Sum 
End Function 'SumIf3D 

Function AverageIf3D(Range3D As String, Criteria As String, _ 
    Optional Average_Range As Variant) As Variant 

    Dim sTestRange As String 
    Dim sSumRange As String 
    Dim Sheet1 As Integer 
    Dim Sheet2 As Integer 
    Dim n As Integer 
    Dim Sum As Double 
    Dim Count As Double 

    Application.Volatile 

    If Parse3DRange(Application.Caller.Parent.Parent.Name, _ 
     Range3D, Sheet1, Sheet2, sTestRange) = False Then 
     AverageIf3D = CVErr(xlErrRef) 
    End If 

    If IsMissing(Average_Range) Then 
     sSumRange = sTestRange 
    Else 
     sSumRange = Average_Range.Address 
    End If 

    Sum = 0 
    Count = 0 
    For n = Sheet1 To Sheet2 
     With Worksheets(n) 
     Sum = Sum + Application.WorksheetFunction.SumIf(.Range(sTestRange), Criteria, .Range(sSumRange)) 
     Count = Count + Application.WorksheetFunction.CountIf(.Range(sTestRange), Criteria) 
     End With 
    Next n 
    AverageIf3D = Sum/Count 
End Function 'SumIf3D 

Function Parse3DRange(sBook As String, SheetsAndRange _ 
    As String, FirstSheet As Integer, LastSheet As Integer, _ 
    sRange As String) As Boolean 

    Dim sTemp As String 
    Dim i As Integer 
    Dim Sheet1 As String 
    Dim Sheet2 As String 

    Parse3DRange = False 
    On Error GoTo Parse3DRangeError 

    sTemp = SheetsAndRange 
    i = InStr(sTemp, "!") 
    If i = 0 Then Exit Function 

    'next line will generate an error if range is invalid 
    'if it's OK, it will be converted to absolute form 
    sRange = Range(Mid$(sTemp, i + 1)).Address 

    sTemp = Left$(sTemp, i - 1) 
    i = InStr(sTemp, ":") 
    Sheet2 = Trim(Mid$(sTemp, i + 1)) 
    If i > 0 Then 
     Sheet1 = Trim(Left$(sTemp, i - 1)) 
    Else 
     Sheet1 = Sheet2 
    End If 

    'next lines will generate errors if sheet names are invalid 
    With Workbooks(sBook) 
    FirstSheet = .Worksheets(Sheet1).Index 
    LastSheet = .Worksheets(Sheet2).Index 

    'swap if out of order 
    If FirstSheet > LastSheet Then 
     i = FirstSheet 
     FirstSheet = LastSheet 
     LastSheet = i 
    End If 

    i = .Worksheets.Count 
    If FirstSheet >= 1 And LastSheet <= i Then 
     Parse3DRange = True 
    End If 
    End With 
Parse3DRangeError: 
    On Error GoTo 0 
    Exit Function 

End Function 'Parse3DRange 
+1

真的很酷!!! ............感謝您花時間回覆........如果我能不止一次地投票,我會的。 – 2016-12-16 00:11:07

+0

@加里的學生,很高興幫助!公平的代碼已經存在了。讓我知道你是否有任何進一步的問題 – 2016-12-16 06:20:52