2017-04-05 213 views
0

Excel 2010.我需要找出FormulaArrays在工作表中的位置。特別是我需要得到他們的地址。如何通過Excel工作表中的FormulaArrays進行循環

我不知道給定(1x1)單元格是否是「ArrayArray」的一部分,而是知道FormulaArray「blocks」所在的位置。例如,如果在A1:B2中輸入了一個公式數組,我希望得到FormulaArray區域超出範圍A1:B2的信息,而不是知道單個單元格A1,A2,B1,B2是「一個「公式陣列。

這可能嗎?

回答

1

這並不像我希望的那麼容易。 Excel似乎沒有公開您的數組公式的集合來循環。這意味着你必須檢查每個單元格。在高級別代碼:

  1. 掃描每個單元格。
  2. 如果單元格包含數組公式,它會提取地址。
  3. 如果地址是新的,則將其添加到地址變量中。
  4. 將所有地址輸出到屏幕。

    ' Returns the address of array formula in the current worksheet. 
    Sub GetArrayFormulaRangeAddresses() 
        Dim r As Range    ' Used to loop over active cells. 
        Dim addresses() As String ' Holds each found address. 
        Dim address As String  ' Used to avoid duplicate entries. 
        Dim foundCount As Integer ' Count of found array formulas. 
    
        ' Initialise vars. 
        foundCount = -1 
    
        ' Check every active cell, in currently selected tab. 
        ' Ideally you would loop over a formula collection but 
        ' the Excel object model does not appear to expose this. 
        For Each r In ActiveSheet.UsedRange.Cells 
    
         ' Found one. 
         ' WARNING: Array formula contains values, 
         ' even when cell is not part of an array formula. 
         If r.FormulaArray Like "={*}" Then 
    
          ' WARNING: Cannot pass array until after firt redim statement. 
          ' To avoid check found count, then addresses array. 
          If foundCount = -1 Then 
    
           ' Not found, add to list. 
           foundCount = foundCount + 1 
           ReDim Preserve addresses(foundCount) 
           addresses(foundCount) = r.CurrentArray.address 
    
          Else 
           ' Check if address already found. 
           If Not CheckArrayContains(addresses, r.CurrentArray.address) Then 
    
            ' Not found, add to list. 
            foundCount = foundCount + 1 
            ReDim Preserve addresses(foundCount) 
            addresses(foundCount) = r.CurrentArray.address 
           End If 
          End If 
         End If 
        Next 
    
    
        ' TODO: Action you output as necessary! 
        For foundCount = LBound(addresses) To UBound(addresses) 
         MsgBox addresses(foundCount) 
        Next 
    End Sub 
    
    ' Returns true if the passed array contains a value. 
    ' Otherwise returns false. 
    Public Function CheckArrayContains(ByRef CheckArray() As String, ByVal CheckValue As String) As Boolean 
        Dim i As Integer  ' Counter, used to check each element of the array. 
    
        ' Check existing members. 
        For i = LBound(CheckArray) To UBound(CheckArray) 
         If CheckArray(i) = CheckValue Then 
    
          ' Match found. 
          CheckArrayContains = True 
          Exit Function 
         End If 
        Next 
    
        ' No match found. 
        CheckArrayContains = False 
    End Function 
    

我覺得這個代碼可以改進:

  1. REDIM是昂貴的。這可能會更好地調整批量1000的陣列。
  2. Excel Object Model可能暴露您可以循環的集合。
  3. 對於較大的工作簿,提取所有地址並重復刪除結果會更快。
+0

由於某些原因'如果r.FormulaArray Like「= {*}」Then'對我來說不起作用(Excel 2010),我必須用'If r.HasArray Then'替換這行。 – Janthelme

相關問題