2012-12-12 8 views
5

Poniżej znajduje się przykład ustawić w programie Excel,Znajdź wszystkie użyte referencje we wzorze Excel

[column1] [column2] 

A1 =C3-C5 

A2 =((C4-C6)/C6) 

A3 =C4*C3 

A4 =C6/C7 

A5 =C6*C4*C3 

muszę wyodrębnić używane odwołań w formułach

Na przykład

for "A1", I simply need to get the C3 and C5. 
for A2, I need to get the C4 and C6. 

Odpowiedz

3

Ta funkcja zwraca oddzieloną przecinkami listę komórek źródłowych (precedensów):

 
Function References(rngSource As Range) As Variant 
    Dim rngRef As Range 
    Dim strTemp As String 
    On Error Resume Next 
    For Each rngRef In rngSource.Precedents.Cells 
     strTemp = strTemp & ", " & rngRef.Address(False, False) 
    Next 
    If Len(strTemp) 0 Then strTemp = Mid(strTemp, 3) 
    References = strTemp 
End Function 

Należy jednak pamiętać, że nie można tego użyć jako arkusza kalkulacyjnego UDF w arkuszu roboczym, ponieważ numer rngRef.Address powoduje niestety odwołanie cykliczne. Możesz jednak użyć go w małej procedurze, aby wypełnić inną kolumnę, np.

 
Sub ShowPrecedents() 
    Dim rng As Range 
    'Will paste precedents of A1:A6 into D1:D6 
    For Each rng In Range("D1:D6") 
     rng.Value = References(rng.Offset(, -3)) 
    Next 
End Sub 
+0

Będzie działać w przypadku lokalnych odniesień arkuszy, ale nie w przypadku odsyłaczy poza arkuszem. – brettdj

1

Wystarczy, aby zapewnić alternatywę ... Zauważ, że ten powróci duplikat wynik jeśli komórki nazywane są częściej niż raz

Sub testing() 
Dim result As Object 
Dim r As Range 
Dim testExpression As String 
Dim objRegEx As Object 

Set r = Cells(1, 2) ' INPUT THE CELL HERE , e.g. cells("A1") 
Set objRegEx = CreateObject("VBScript.RegExp") 
objRegEx.IgnoreCase = True 
objRegEx.Global = True 
objRegEx.Pattern = """.*""" ' remove expressions 
testExpression = CStr(r.Formula) 
testExpression = objRegEx.Replace(testExpression, "") 
objRegEx.Pattern = "(([A-Z])+(\d)+)" 'grab the address 

If objRegEx.test(testExpression) Then 
    Set result = objRegEx.Execute(testExpression) 
    If result.Count > 0 Then 
     For Each Match In result 
      Debug.Print Match.Value 
     Next Match 
    End If 
End If 
End Sub 

Wyniki są przechowywane w „Match.Value”

5

To jest aktualizacja:

Będzie działać dla lokalnych odniesień arkuszy, ale nie dla odniesień poza arkuszem. - brettdj 14 maja '14 godzinie 11:55

stosując metodę Larrys, wystarczy zmienić objRegEx.Pattern do:

(['].*?['!])?([[A-Z0-9_]+[!])?(\$?[A-Z]+\$?(\d)+(:\$?[A-Z]+\$?(\d)+)?|\$?[A-Z]+:\$?[A-Z]+|(\$?[A-Z]+\$?(\d)+)) 

To będzie:

  1. Szukaj dodatkowe linki zewnętrzne : (['].*?['!])?
  2. Wyszukaj opcjonalnie Arkusz odniesienia: ([[A-Z0-9_]+[!])?
  3. Wykonaj następujące czynności ps w priorytetowej kolejności:
  4. Szukaj przedziałów z numerami wierszy (oraz opcjonalnie $): \$?[A-Z]+\$?(\d)+(:\$?[A-Z]+\$?(\d)+)?
  5. Szukaj zakresach bez numerów wierszy (oraz opcjonalnie $): \$?[A-Z]+:\$?[A-Z]+
  6. szukać odniesień 1-komórkowe (oraz opcjonalnie $): (\$?[A-Z]+\$?(\d)+)

Powstałe w ten sposób:

Sub testing() 
Dim result As Object 
Dim r As Range 
Dim testExpression As String 
Dim objRegEx As Object 

Set r = Cells(1, 2) ' INPUT THE CELL HERE , e.g. RANGE("A1") 
Set objRegEx = CreateObject("VBScript.RegExp") 
objRegEx.IgnoreCase = True 
objRegEx.Global = True 
objRegEx.Pattern = """.*?""" ' remove expressions 
testExpression = CStr(r.Formula) 
testExpression = objRegEx.Replace(testExpression, "") 
objRegEx.Pattern = "(([A-Z])+(\d)+)" 'grab the address 

objRegEx.Pattern = "(['].*?['!])?([[A-Z0-9_]+[!])?(\$?[A-Z]+\$?(\d)+(:\$?[A-Z]+\$?(\d)+)?|\$?[A-Z]+:\$?[A-Z]+|(\$?[A-Z]+\$?(\d)+))" 
If objRegEx.test(testExpression) Then 
    Set result = objRegEx.Execute(testExpression) 
    If result.Count > 0 Then 
     For Each Match In result 
      Debug.Print Match.Value 
     Next Match 
    End If 
End If 
End Sub 

Spowoduje to, daje wartości wszystkich możliwych odniesień, co myślę z. (Zaktualizowano ten post, ponieważ potrzebowałem rozwiązania problemu).

+0

Nice. Alternatywnym podejściem, które może być prostsze, byłoby użycie właściwości 'FormulaR1C1', ponieważ byłoby to łatwiejsze do przeanalizowania niż domyślny styl adresowania" A1 ". Twoje podejście wydaje się być pod pewnym względem lepsze od podejścia w zaakceptowanej odpowiedzi, ponieważ jest w stanie rozróżnić odniesienia bezwzględne i względne.Z drugiej strony, bez większych modyfikacji twoje podejście nie byłoby w stanie zidentyfikować nazwanych zakresów (które akceptowana odpowiedź wciąż podnosi). Podejście hybrydowe może być optymalnym rozwiązaniem. –

+0

Próbowałem tego na komórce zawierającej następującą formułę: = IF (ISBLANK ("CU68X Data"! $ A9), "", IF ($ B45 & $ C45 & $ D45 & $ E45 = 'CU68X Data'! D9 & "CU68X Data" ! E9 i "CU68X Data"! F9 i "CU68X Data"! G9, "CU68X Data"! $ Y9, "Błąd warunku")). Zwrócił tylko pierwszą referencję ($ A9) ... jak to możliwe? – Dan

+0

Ta linia ma być zmieniony: '„objRegEx.Pattern = «» ««»*.?»”Usunąć expressions'
Również trzeba będzie zmienić wyrażenie do dołu, w celu uchwycenia Twoja poprawna formuła:
'objRegEx.Pattern =" ([']. *? ['!])? ([[A-Z0-9 _] + [!])? (\ $? [AZ] + \ $? (\ d) + (: \ $? [AZ] + \ $? (\ d) +)? | \ $? [AZ] +: \ $? [AZ] + | (\ $? [AZ] + \ $? (\ d) +)) "'
(Dodano tylko "?" w pierwszej grupie, aby ta grupa nie była zbyt zachłanna) –

Powiązane problemy