- PR -

Excel:自分で定義したFunctionを使用しているセルの自動再計算

投稿者投稿内容
Take-C
常連さん
会議室デビュー日: 2002/05/09
投稿数: 23
投稿日時: 2008-01-08 12:00
引用:

キナサイさんの書き込み (2008-01-07 17:27) より:
Volatile メソッドをユーザー定義関数内で使うのでは目的に合わないのですか?



以下のようにして試してみました。

コード:
Public Function MyTest(引数) As String

    Application.Volatile
    ・・・
    MyTest = ・・・ '計算

End Function



MyTestを使用しているセルが1つでも計算されたらMyTestを使用している他のセルもすべて再計算されますが、まったく関係ないセル(MyTestを使用していない数式が書かれているセル)が計算されてもこのロジックが走ってしまうようです。

ユーザがまったく関係のないセルを更新したときにはあまり再計算してほしくないのです。MyTestを使用している数式が書かれているセルを直接更新した場合はやむを得ませんが。

更新タイミングの点を除けば、最もシンプルにできそうですね。
Take-C
常連さん
会議室デビュー日: 2002/05/09
投稿数: 23
投稿日時: 2008-01-08 12:04
引用:

Error401さんの書き込み (2008-01-07 18:08) より:
よく読んでないんですが、MyTest()の中でActiveSheet.NameやActiveCell.Addressなどの情報をCollectionなどに登録し、更新するタイミングでそれらがまだセルに設定されているかどうかを確認しながら更新していくというのはどうでしょう?(セルに設定されていなかったらCollectionから除去する)



Error401さん、ありがとうございます。
こんなコードを書いてみました。
(使用機器の関係上、手でコピーしているため、間違いがあるかもしれません)

コード:
private MyCells As New Collection

Public Function MyTest(引数) As String

    Dim callerCell As Range
    Dim targetCell As Range
    Dim key As String

    Set callerCell = Application.Caller
    key = MyCellKey(callerCell)
    On Error Resume Next
    Set targetCell = MyCells.Item(key)
    On Error GoTo 0
    If targetCell Is Nothing Then
        Call MyCells.Add(callerCell, key)
    End If
    ・・・
    MyTest = ・・・ '計算

End Function

Public Sub Calc() '実際にはVC++による処理

    Dim myCell As Range
    Dim delCell As Range
    Dim deleteCells As New Collection

    For Each myCell in MyCells
        If InStr(1, myCell.Formula, "MyTest", vbTextCompare) >= 1 Then
            myCell.Formula = myCell.Formula '再計算させるため強引に上書き
        Else
            deleteCells.Add myCell
        End If
    Next

    For Each delCell in deleteCells
        MyCells.Remove MyCellKey(delCell)
    Next

End Sub

Private Function MyCellKey(tempCell As Range) As String

    MyCellKey = tempCell.Worksheet.Parent.Name & "," & _
                tempCell.Worksheet.Name & "," & _
                tempCell.Column & "," _
                tempCell.Row

End Function




これでCalcを動かせばMyTestを数式として含んでいるセルが自動的に更新されるようになりました。

なんか大掛かりになってきた感じですが、更新するタイミングは自分で完全に制御できそうです。
パフォーマンスが少し心配ですが。
Take-C
常連さん
会議室デビュー日: 2002/05/09
投稿数: 23
投稿日時: 2008-01-08 12:04
引用:

こあらさんの書き込み (2008-01-07 18:30) より:
Excel2000では Application.CalculateFull で誤魔化すしかないかもしれません。
シートの状態にもよりますが、個々セルごとに代入するよりは速そうです。



そうかもしれませんね。この辺はいろいろとパフォーマンスを検証する必要がありそうです。

スキルアップ/キャリアアップ(JOB@IT)