2017-03-22 18 views
1

範囲オブジェクトの数式を再帰的に調べたいと思います。 私は前の文の文法上の正確さについてはあまり確信していません(いずれにしても、私は自分の英語を謝ります)。私は、これがもっとも簡単な例であると思う例を使って、 :VBAの式から値を再帰的に抽出します

mysheet = "Sheet1" 
    Sheets(mysheet).Range("A1").Formula = "=+B1" 
    Sheets(mysheet).Range("B1").Formula = "=+C1-C2" 
    Sheets(mysheet).Range("C1").Value = "value:val1" 
    Sheets(mysheet).Range("C2").Formula = "=+D1-D2" 
    Sheets(mysheet).Range("D1").Value = "value:val2" 
    Sheets(mysheet).Range("D2").Value = "value:val3" 

あなたは(?多分、再帰1)機能の種類について(コードのドラフトを以上)私にヒントを与えることができた文字列を返すことができ、そのような(のはそれを呼び出すmy_formulaましょう)、そのコマンド

MsgBox(my_formula) 

は以下を返します。

?あなたの答えのためのすべての多くのおかげで

がLESS THAN 1時間後にあなたに

UPDATEありがとう

こんにちは、私を助けてください。私は、セル内の値が効果的に文字列であること+単純な操作(+と - )+すべての依存関係が同じシートにあること+ $ X $ 1などの範囲がないことを指摘します。しかし、私はいくつかの方法(先例、NavigateArrow ...)によって投稿されたメソッド/プロパティを認識していますが、私が尋ねたのは、この種のメソッド/プロパティを頭痛のない最善の方法で使用する方法です。それは現実の生活の中で、より複雑な数式に拡張する方法のためではなく、メーリングリストへ -

は、このコードはあなたの例のために働くだろう再び

+0

これを行う範囲オブジェクトの組み込みプロパティがない限り、名前付き範囲、シート参照、ブック参照、接続などのために頭痛が起きることは想像できます。しかし、すべてのセル値がフォームA1または$ A $ 1? –

+0

https://msdn.microsoft.com/en-us/library/office/ff197707.aspxおそらく? –

+1

咳 - あなたはhttps://msdn.microsoft.com/en-us/library/office/ff196936.aspxを意味しませんか? –

答えて

2

、ありがとうございました。ただし、RangePrecedentsコレクションを再帰的に扱う方法については、開始してから、いくつかの方法で再開します。私はコードをコメントしましたが、それを理解する最も簡単な方法は、F8を使ってデバッグモードを実行することです。

Option Explicit 

Sub Test() 
    Dim ws As Worksheet 
    Dim rng As Range 
    Dim strOutput As String 

    'your test case from the original question  
    Set ws = ThisWorkbook.Sheets("Sheet1") 
    With ws 
     .Range("A1").Formula = "=+B1" 
     .Range("B1").Formula = "=+C1-C2" 
     .Range("C1").Value = "10" 
     .Range("C2").Formula = "=+D1-D2" 
     .Range("D1").Value = "20" 
     .Range("D2").Value = "30" 
    End With 

    'the cell you want to start from 
    Set rng = Sheet1.Range("A1") 

    'get the output from calling the recursive function 
    'note we pass the original formula in to kick off the function 
    strOutput = rng.Address(0, 0) & GetFullFormula(rng, rng.Formula) 

    'show user 
    MsgBox strOutput 

End Sub 

Function GetFullFormula(rng As Range, strFormula As String) As String 

    Dim rngPrecedents As Range 
    Dim rngPrecedent As Range 
    Dim strPrecedentAddress As String 
    Dim strPrecedentFormula As String 

    If rng.HasFormula Then 
     Set rngPrecedents = rng.Precedents 
     For Each rngPrecedent In rngPrecedents 
      'get the precedent cell address to check if in current formula (without $) 
      strPrecedentAddress = rngPrecedent.Address(0, 0) 
      'Debug.Print strFormula 
      'substiute into formula if matching a range address 
      If rngPrecedent.HasFormula Then 
       If InStr(1, strFormula, strPrecedentAddress, vbBinaryCompare) Then 
        'strip = from formula and put in brackets to preserve ordering 
        strPrecedentFormula = "(" & Mid(rngPrecedent.Formula, 2, Len(rngPrecedent.Formula) - 1) & ")" 
        'replace our formula with precedent formula 
        strFormula = Replace(strFormula, strPrecedentAddress, strPrecedentFormula) 
       End If 
       'carry on with recursion - passes formula back into function for expansion 
       GetFullFormula rngPrecedent, strFormula 
      Else 
       'just a value 
       If InStr(1, strFormula, strPrecedentAddress, vbBinaryCompare) Then 
        'replace the address with the value 
        strFormula = Replace(strFormula, strPrecedentAddress, rngPrecedent.Value) 
       End If 
      End If 
     Next rngPrecedent 
    End If 

    GetFullFormula = strFormula 

End Function 

出力:

=+(+10-(+20-30)) 

あなたは$A$1のようなセル参照を使用している場合、関数は、プレーンセル参照を想定しているため、このコードに問題があります。これらのケースや名前付きの範囲も処理できるようにコードを拡張することができますが、これは単なる基本的な例です。

関連する問題