事例:
以前こんなことを聞かれた事がある。「このセルに毎日の実績を入力すれば累計値がどんどん増えていくようにできませんかね~?」
”このセル”というのは一箇所。すなわち同じセルに入力するたびに累計値に加算されていくようにしたいらしかった。イメージ的にはこんな感じか。
当時の私の答えは、
「無理です。」
上のような数式を入力すると、こんなメッセージが現れて警告される。
循環参照、すなわち再帰的な計算はエクセルではできないということだ。
しかし今更ながら、エクセルのオプションにこんな項目があったのを思い出した。
最初に見た時に、すぐに循環参照のことを言っているんだろうなと思いながらも、なぜか今まで試さず、このこと自体を思考の隅っこに放置していた。
というわけで、やっと重い腰を上げて実験してみた。
実験:
まずこのオプション設定をこんな感じに変更。
「反復計算を行う」にチェックを入れて、「最大反復回数」を”1”に設定してみた。この「最大反復回数」というのはいわゆる無限ループを回避するための設定だろう。
変化の最大値についても同様に無限ループ回避のための設定だろうが、動作が想像できないので今はそのまま。
そして再び、この数式を。
こんどは警告メッセージは現れない。
そして、これが初期状態。
本日実績としてB3に最初から"100"が入力されていたのでC3の累計は"100"となっている。
そして、この状態からB3に数値を入力してみる。
例えば、"50"。
と、ここまで予想通りの動きだ。
問題点:
これで、最初の事例の件は解決だな。とりあえず保存しておこう。とセーブボタンをポチっとしたとたん・・・
ん?今なにか変わったような?
じつは、セーブしただけで、こんな風に。
見てのとおり、もう"50"増えて累計値が"200"になってしまった。
最初は意味がわからなかったが、これはエクセルが保存時に”再計算”されるために起こる現象だ。
数式が実行されるタイミングは、多くの人が通常”自動”に設定していると思う。この”自動”の中に”保存時”というのが入っているのだ。
これは問題だ。
このままでは、使えない。
なにか、策を考えねば。
解決策:
というわけで、ロック機能とリセット機能を付けてみた。
C3の数式:
=IF($D$2="計算実行",C3+B3,IF($D$2="リセット",0,C3))
使い方は、
最初にD2を”リセット”にして、C3を0クリア。
次に、”計算実行”にして、B3に数値入力。
入力終了後にD2を”ロック”にする。
あとはお好きな操作を。
これで、今回は終了・・・
でもない。
再び問題発生:
実は再計算処理が悪さをするシチュエーションがまだあったのだ。
それは、本日実績の数値をそのままの状態で、”ロック”から”計算実行”や”リセット”から”計算実行”に切り替えた場合だ。
このとき発生するのは、「本日実績が累計値に2回足されてしまう」という現象。
これは調査の結果、理由は不明だが、
ドロップダウンリストから選択した場合、なぜか再計算が2回発生してしまう。
ということが原因になっていた。
これからも分かるように、(考えてみれば当たり前だが)要は何らかの原因で再計算が発生するたびに累計値も再計算されるということ。
例えば、他の無関係のセルへの入力とか。
つまりほとんど何もできないっていうこと。
(もちろん再計算のタイミングを熟知していて、そのときに累計値に足されるセルの内容を0や空白にしておけばある程度は回避できると思うが・・・)
結論:
結局、結論は、
循環参照(反復計算)を使った、累計値の計算は、やはり、
「無理です。」(現実的には)
ということだ。
結論を覆して解決:
と、一旦は結論を出したが、もうちょっと粘ってみた。
その結果、循環参照(反復計算)を使った、累計値の計算を実装できた。
ある程度シチュエーションは限定されるが、今回の「本日実績」のように、累積をとる回数が数えられる場合には適用可能なやり方だ。
なお、このやり方でも、今回実装したロック機能はやはり必要。
そして、本日実績の項目が複数あったりして途中に再計算が入っても累計値には影響しない。
そのやり方は、今はまだ非公開。興味がある人は考えてみよう。
ヒントは、
”反復計算はやはり必要”
”操作者には見せないが、こっそり毎日の数値を保持している”
”累計値はそっちの累計をとる”
”もちろん数式だけで実現”
サンプルは作ったのでこちらのサンプルページの
「日々の実績値入力&累計計算」
というところにあります。
これで本当におしまい。