5

非常に大きな Excel ワークブック (数十のタブ、それぞれが 1 MB を超える、非常に複雑な計算) がいくつかあり、恐ろしい INDIRECT 関数を使用する数十、おそらく数百の数式が含まれています。これらの数式はワークブック全体に分散されており、いくつかのデータ テーブルをターゲットにして値を検索します。

次に、これらの数式の対象となるデータの範囲を、同じブック内の別の場所に移動する必要があります。

(理由は特に関係ありませんが、それ自体が興味深いものです。これらを Excel Calculation Services で実行する必要があり、かなり大きなテーブルを 1 つずつ読み込むための待ち時間が許容できないほど大きいことが判明しました。連続した範囲のテーブルであるため、それらすべてを 1 回のショットで読み込むことができます)。

移動するテーブルを現在参照しているすべての間接式を見つける方法はありますか?

これをオンラインで行う必要はありません。信頼できるものであれば、実行に 4 時間かかるものでも喜んで引き受けます。

.Precedent、.Dependent などのメソッドは直接式のみを追跡することに注意してください。

(また、スプレッドシートを書き直すことは私たちにとってオプションではありません)。

ありがとう!

4

5 に答える 5

5

vba を使用してワークブック全体を反復処理できます ( @PabloG および @euro-micelli のコードを含めました)。

Sub iterateOverWorkbook()
For Each i In ThisWorkbook.Worksheets
    Set rRng = i.UsedRange
    For Each j In rRng
        If (Not IsEmpty(j)) Then
            If (j.HasFormula) Then
                If InStr(oCell.Formula, "INDIRECT") Then
                    j.Value = Replace(j.Formula, "INDIRECT(D4)", "INDIRECT(C4)")
                End If
            End If
        End If
    Next j
Next i
End Sub

この例では、「indirect(D4)」をすべて「indirect(C4)」に置き換えます。より複雑な間接関数がある場合は、置換関数をより洗練されたものに簡単に交換できます。大きなワークブックであっても、パフォーマンスはそれほど悪くありません。

于 2008-08-29T16:53:09.723 に答える
1

Q: 「移動したいテーブルを現在参照しているすべての INDIRECT 式を見つける方法はありますか?」

私が読んだように、関心のある分野への参照については、INDIRECT の引数の内部を調べたいと考えています。OTTOMH 正規表現パーサーを使用するように VBA を作成するか、単純な INSTR を使用して INDIRECT を検索し (一致するものを前方に読み取る)、内部の文字列を EVALUATE() して実際のアドレスに変換し、複数の INDIRECT に対して必要に応じて繰り返します(...) を呼び出して、数式とその変換をシートの 2 つの列にダンプします。

于 2008-09-15T21:39:09.500 に答える
0

ライターが接続されている製品の言及に関するSOのエチケットが何であるかはわかりませんが、ExcelアドインであるOperis Analysis KitであるOAKは、INDIRECT関数を解決するセル参照に置き換えることができます。次に、Excelの監査ツールを使用して、各範囲の依存関係を判別できます。

もちろん、これはブックの一時的なコピーに対して行います。

詳細はこちら

  • http://www.operisanalysiskit.com/oakpruning.htm
  • http://www.operisanalysiskit.com/help/2007/index.html?oakconceptpruning.htm

この質問の時代を考えると、別の解決策または回避策を見つけたかもしれません。

于 2009-09-15T19:34:07.110 に答える
0

VBA では次のようなものを使用できます。

Sub ListIndirectRef()

Dim rRng As Range
Dim oSh As Worksheet
Dim oCell As Range

For Each oSh In ThisWorkbook.Worksheets
    Set rRng = oSh.UsedRange
    For Each oCell In rRng
        If InStr(oCell.Formula, "INDIRECT") Then
            Debug.Print oCell.Address, oCell.Formula
        End If
    Next
Next

End Sub

Debug.Print の代わりに、好みに合わせてコードを追加できます

于 2008-08-29T17:03:21.883 に答える
0

残念ながら、INDIRECT の引数は通常、それよりも複雑です。これは、シートの 1 つからの実際の数式であり、最も複雑な数式ではありません。

=IF(INDIRECT("'"&$B$5&"'!"&$O5&"1")="","",INDIRECT("'"&$B$5&"'!"&$O5&"1"))

うーん、ほとんどの文字を無視して関連する部分 (この例では "A..Z"、"0..9"、"!:" など) を探すだけの単純なパーサーを作成できますが、 「間接」の引数が関数の場合、問題が発生します。

おそらく、より安全なアプローチは、「間接的」のすべての出現を3枚目のシートに印刷することです。次に、目的の出力を追加し、小さな検索および置換プログラムを作成して、変更を書き戻すことができます。

巨大なスプレッドシートのすべてのセルを「取得」すると、膨大な量のメモリが必要になる可能性があります。私はまだそのリスクを冒そうとしています。

使用範囲を選択する PabloG の方法は、その方法です (元のコードに追加しました)。特に現在のセルに数式が含まれているかどうかを確認する場合、速度はかなり良好です。明らかに、これはすべてワークブックのサイズによって異なります。

于 2008-08-29T19:01:03.613 に答える