メニュー

logo

カチシステムはお客様に寄り添った
システム開発と支援サービスを提供し
「やさしい最先端」を創造します。

【第59回】ロータス博士のWinActor塾~多重ループ 実践編Ⅱ

2022.02.17

さて今回は前の続きで多重ループのシナリオ作成じゃ。

皆さん、前回からシナリオを作成してみたりしたかのう?

難しくてわからなかったという方でも大丈夫。わしと一緒に残りを作っていこう。

前回の記事はこちら

なんかすぐ更新するって言ってませんでしたっけ。

もう僕内容忘れたんですけど・・・。

それは・・・ハカセの事情というものがあってな・・・。

わかりやすいようにと加筆修正を重ねていたらこんなことに。

すまんが忘れてしまったら前回の記事で復習してきて欲しい。

うーん、ハカセの事情かあ。

でも今回で完成するんですよね!?

もちろん!前回からの続きでループ内の処理を細かく説明するからついてくるのじゃ!

そして結構な長丁場になるぞ!

では早速いってみよう!

子ループ内の処理

ループ内ですべきこと

前回で多重ループの枠組みは完成しました。今回はループの中を作成します。

まずは九九の表の完成形をもう一度確認して、どのような処理が必要か考えてみましょう。

 

 

とにかく掛け算の結果が必要ですよね!

うむ、じゃが表を作るということは入力も必要じゃな。

ループ内で必要な処理をまとめると次の3つになる。

 

・セルの選択(移動)

・計算

・結果の入力 

 

この動きがループの中で繰り返されることになりますが、今回は2重ループのため

親ループで実行される処理と子ループで実行される処理を分けて考えていきます。 

まずは子ループの処理から考えましょう。

 

 

変数にするべきものを探す

前回決めた通り、子ループは表でいうと横向きの処理を担当しますので

掛け算の1の段だけの場合を考えてみます。 

 

 

それから単純に、どのような処理をするのかを文字に起こしてみます。

「1×1を計算してセルA1に結果の1を入れる」「1×2を計算してセルB2に結果の2を入れる」・・・

という風に1×9まで続きますね。

図にループの流れを入れると左から右へ、このように進みます。

 

 

ループ処理というのはその名の通り繰り返しですので、毎回同じ処理でなくてはいけません。

しかし先ほど文字に起こしたものを見てみるとどうでしょう。同じ文章ではありませんね。

 

異なる部分を探すと、計算部分の「1×1」、セルを選択する「A1」、結果の「1」が出てきます。

わかりやすいように1ループ目と2ループ目の文章を並べて比較すると・・・

 

1×1を計算してセルA1に結果の1を入れる

1×2を計算してセルB2に結果の2を入れる

 

こういった共通でない部分は変数にするべきものを示しています。

仮にそれぞれをX、Y、Zに置き換えてみると、先ほどの文章は「Xを計算してセルYに結果のZを入れる」となります。

このように表現すると、何度目のループでも使うことができますね。

 

なるほど、ループ中に変化するものは変数にするんですね。

となると必要なのは・・・「かける数」「かけられる数」

「入力セル位置」「計算結果」でしょうか。

的確すぎてびっくりするコメントじゃな。大正解じゃ!

ということで、次のように4つ変数を追加しよう。

前回エクセルに必要な変数を既に作っているから、計6つの変数が用意できたはずじゃ。

 

あれ?かける数、かけられる数は?

それにセル位置に初期値が入ってますね・・・。

うむ。これらについては順番に説明するから

とりあえず同じように変数を作成してほしい。

掛け算の考え方

なぜ博士は「かける数」「かけられる数」の変数を用意しなかったのでしょうか?

既に皆さんピンときているかと思いますが、この変数を用意してしまうと処理(ノード)が増えてしまうのです。

 

ロータス君は「かける数」と「かけられる数」を初期値1で準備して

子の1ループ毎に「かける数」を+1しようとしていました。そうすれば2ループ目には1×2となり計算が成立します。

親の1ループ毎に「かけられる数」を+1すれば2×1や3×1などにも対応できるでしょう。

このやり方は間違いではありません。しかし、WinActorのループを最大限に活かせばもっと楽に作ることができるのです。

ロータス君の方法では「カウントアップ」のノードが親と子のループにひとつずつ、

さらに子ループが終わるごとに「かける数」を1に戻すための処理が必要になります。

これらはWinActorの繰り返しノードにある「カウンタ」を利用することで一気に解決することができます。

 

九九の表をもう一度見てみましょう。

 

 

この中で適当に、親ループが4回目、子ループが5回目の結果を見てみます。

4×5=20ですね。

 

 

せっかくなので他の場所も見てみましょう。

今度は親の8ループ目と、子の2ループ目にしてみます。

 

 

 

8×2=16となりました。

このように、掛け算九九の表は「親のループ回数×子のループ回数」をすれば答えになるのです。

これは、2重ループにして親ループを縦、子ループを横の担当にしたためです。

えええ!こんなやり方が!?

僕をだましてたんですね博士!

いや・・・おそらくじゃが皆うすうす気付いておったぞ。

ロータス君のやり方でも全然OKじゃよ。

じゃがこの方法だともっと楽できるという感じじゃな。

繰り返しノードのカウンタには次のような特性がありました。

 

・カウンタに設定した変数は1ループ毎に自動で+1されていく

・ループ開始と同時に「1」で初期化される

 

この特性を利用すれば、親ループ終了後に「かける数」を1に戻さなくてもよくなります。

親が1ループして子ループに再突入すると、子ループのカウンタはまた「1」からスタートします。

 

てことはカウントアップのノードも、

1に戻すための処理も全部要らないってことに・・・。

これはマジシャンですね。

マジシャン・・・?

まあこのやり方のほうが圧倒的に楽で、フローもすっきりするじゃろう。

という訳で、前回用意した繰り返しノードにそれぞれカウンタを付けよう。

 

親ループ、子ループそれぞれのプロパティ「カウンタ」に、作成しておいた変数を割り当てます。

 

 

 

 

よし、ここまできたら「計算結果」変数に掛け算の結果を入れる処理も作ってしまおう。

掛け算をするという処理は毎ループ共通の処理じゃから

そのまま子ループに入れてしまってOKじゃな。

 

子ループの中に「四則演算」ノードを配置して次のように設定しましょう。

 

 

さらにさらに、入力も作ってしまおう!

計算→入力はワンセットじゃからな。

「セル位置」には初期値として「R1C1」が入っているから

そのままでも1回目の処理だけはうまくいくぞ。

 

1回目だけじゃダメなのでは・・・

それはそうじゃ。2回目以降をどうするか、これから考えるのじゃ。

ここまでで計算と入力はできておる。残るはセルの移動だけじゃ。

このR1C1をどうするか、じゃな!

では次のステップに進もう。

入力セル設定の考え方

ここまででA1のセルに計算結果を入力するという処理はできました。

問題は、この「A1」をどうやって「B1」にするかです。

確かに・・・A1に入力できたのは初期値にR1C1が入ってたからですよね。

そうすると、子の2ループ目は「セル位置」にR1C2を入れないと・・・。

そう、ここで躓く人のほとんどはセル位置を”設定”しようとしているのじゃ。

まさに今のロータス君じゃな。毎ループで共通の動きをさせたい場合は

”設定”ではなく”移動”という考え方をするのじゃ。

ここに気付いてしまえばあとは早いぞ!

 

1ループ目はR1C1、2ループ目はR1C2としていくと、ループ回数に応じて

「セル位置」の変数に入れる値を変えなければいけません。

これでは全ループで共通の処理とは言えませんね。

 

しかし、博士の言う”移動”という考えを用いれば解決します。

1の段の図で見てみましょう。

 

・セル位置を無理やり設定しようとすると・・・ 

 

 

・セルの移動を使うと・・・ 

 

 

移動のほうは全ての処理が共通になっていることがわかります。

ループ回数によって処理の内容を変更する必要がなく、ループに適していると言えますね。 

実はセルの移動は、ライブラリで簡単に行うことができます。 

 

 

R1C1形式 次の列へ

 

ライブラリは以下の場所に格納されています。

 

NTTATライブラリ > 18_Excel関連 > 09_セル位置

 

 

プロパティは次のようになっています。 

 

 

 

「セル位置」にR1C1形式の番地が格納されている変数を指定すると

1列右のセル番地に書き換えてくれます。

 

例えば「R1C1」というデータが入っている変数をこのノードに指定すると

「R1C2」になって返ってくるという便利なものじゃ。

これでセル位置の問題は解決です。

このノードを子ループの中に配置して、変数「セル位置」を指定しましょう。

掛け算の計算→結果の入力→セル横移動という流れのループ処理ができあがります。

 

親ループの処理

続いて親ループに必要な処理を作っていこう。

親ループのほうも何かしないといけないんですか?

もう完成だと思ってたのに・・・。

それほど難しいことはしないから安心するのじゃ。

ここまで作った処理に足りない動きがあるじゃろう。

それがわかればもう完成したも同然じゃ!

あ、そういえばセルの移動が横にしか行ってないですね。

ちゃんと縦にも移動させないと。

そうじゃ!

ではセルを縦移動させることを考えてみよう。

 

セル移動のタイミング

ここまで作ってきた処理は、計算する段が1の段だけだった場合のものです。

2の段、3の段と計算していくためにはセルを一行ずつ下に動かしていかなければいけません。

そこで、まずセル位置を下に移動させるタイミングを考えてみましょう。

 

前回の図を見れば一目瞭然ですね。

 

1×9、2×9・・・の後に必ず次の段に移動しています。

つまりセル位置を下に移動させるタイミングは、子の9ループ目の処理が終わった後ということになります。

 

ちょっとまってください、博士。流れはこうなるってことですよね。

これまで「右に移動」でずっと回ってきたのに

最後だけ「下に移動」だと同じ処理にならないから変じゃないですか?

 

ふむ、ロータス君はどうやら多重ループの罠にはまっているようじゃな。

多重ループの罠!?

多重ループは処理が複雑になるにつれてややこしくなるからのう。

3重、4重ループなんかになるともう大変じゃ。

しっかりと流れを理解しないと、親の処理と子の処理を混同させてしまうミスも起きる。

ロータス君は「下に移動」を子の処理と勘違いしたんじゃろう。

その図を少しいじって・・・これを見て欲しい。

 

セルを下に移動させるのは親ループの役割なんじゃ。

確かに「子の9ループ目の後」と聞くと、子ループ内に処理を入れたくなるが

今回ループ回数が9じゃから、子ループが終了した後と同じなのじゃ。

なるほど・・・親ループとしては

「子ループの処理→セルを下に移動」の同じ処理で9回いけますね。

その通り!子ループに下移動を入れてしまうと「9ループ目限定の処理」として

作らなくてはならなくなるが、親ループにいれれば共通の処理となる。

もともと縦のループは親の担当じゃからな。子でやるのがそもそも間違いなのじゃ。

多重ループは奥が深いですね。

あとは1列目に戻す処理が足りてないですが、これは?

お、よく気付いたのう。感心じゃ。

セル位置を1列目に戻すのは、下移動と同じタイミングじゃな。

図に付け足そう。

 

よし、こんなもんじゃろう!

では「セルを下に移動」と「セルを1列目に移動」を作るぞ。

これも実はそれぞれノードひとつで済んでしまうのじゃ。

さすがWinActorじゃのう!

あ、自画自賛した。

セルを1行下に移動する

子ループでセル位置を1列右に進めたように、1行下に移動させるライブラリも用意されています。

 

 

R1C1形式 次の行へ

 

ライブラリは以下の場所に格納されています。

 

NTTATライブラリ > 18_Excel関連 > 09_セル位置 

 

 

 

プロパティは次のようになっています。 

 

 

 

使い方は「次の列へ」のライブラリと全く同じです。

「セル位置(R1C1形式)」にセル番地の格納された変数を指定することで

変数の中身が1行下に移動したもので上書きされます。

 

それでは、変数「セル位置」を指定してシナリオ内に配置しましょう。

配置する場所は親ループ内で子ループが終了した直後です。

 

 

 

セルを1列目に移動する

ここも”移動”の考え方を使うのじゃ。

1列目に”設定”しようとすると、ループ内で共通の処理にできないからのう。

これにも便利なライブラリがあるからそれを使っていこう。

 

 

R1C1形式 列移動(上書き)

 

ライブラリは以下の場所に格納されています。

 

NTTATライブラリ > 18_Excel関連 > 09_セル位置 

 

 

プロパティは次のようになっています。 

 

 

 

これまでのセル移動ノードと同じく「セル位置(R1C1形式)」にセル番地の入った変数を指定することで

移動後のセル位置が格納されます。

異なるのは「列移動数」という項目で、ここには移動量を数字で入力します。

例えば「R1C1」の入った変数を「セル位置(R1C1形式)」に指定して「列移動数」に「5」を入れた場合、

「R1C6」が指定した変数に格納されます。

 

このノードの良いところは、マイナスの値も入れられるという点じゃ。

列移動数に「5」を入れれば、列は+5ということで右に5列移動される。

これを「-5」とすると左に5列移動させることができるのじゃ。

え!そんな使い方があるなんて!

注釈にも書いてないのに・・・こういうのもあるんですね。

うむ。これは自分で色々試したりしないとなかなか気づかないかも知れんのう。

さて、問題は何列マイナスさせるかじゃが・・・次の図を見て欲しい。

博士は、セル位置をマイナスさせることで1列目に移動させようとしています。

では何列移動させれば1列目になるでしょうか。この図の赤い部分に注目してください。

 

 

子ループの処理は「計算→入力→移動」がワンセットです。

これは子ループ最後の9列目の処理でも変わらず、R1C9に入力が行われた後、

10列目が必要かどうかにかかわらず移動処理が行われます。 

 

つまり、子ループ終了直後の「セル位置」の変数内は「R1C10」が格納されていることになります。

10から1にするにはいくつマイナスすれば良いか、わかりますね。

 

ハイ!ハイ!わかります!-9です!!

そこを自信満々に言われても・・・

では「-9」を設定して、セルの下移動と同じ場所にノードを配置しましょう。 

 

 

見易いようにグループ化しておるが、そこはお好みで。

これで必要なパーツは全て揃ったのう。完成じゃ!

おお・・・ついに完成したんですね。

なんだか長い道のりに感じました。

実際、長々と説明してしまったが・・・。

多重ループはしっかり理解して欲しい内容ではあったからのう。

では最後に実行結果を見て終わりとしよう!

シナリオ全体像と実行結果

シナリオ全体像

今回のシナリオは次のようなフローとなっています。

 

クリックで拡大表示されます。

  • 全体像

 

作成した変数と初期値は次の通りです。

 

 

 

実行結果

 

 

 

シナリオダウンロード

今回作成したシナリオはこちらからDL可能です。

 

第59回WinActor塾_完成後シナリオ.zip (11KB)

 

※ファイルの解凍には会員用パスワードが必要となります。会員登録はこちらから。

 

 

 

どうじゃったかな?これで多重ループが多少使えるようになったかと思う。

九九だけでなく、実務で表を扱う際や繰り返し行う作業に広く応用できるぞ。

これを機にループへの興味を持ってもらえたら嬉しいのう。

難しい内容でしたけど、ノード数削減にもなってフローがきれいになるし

難易度に見合った便利さがありますね!ループってすごいんですね!

うむ、ループはすごいんじゃよ。語り始めるとキリがないが・・・。

これ以上長くなるとアレじゃから、これでおしまいとするぞ。

ではお疲れさまじゃ!また次回!


 

関連記事こちらの記事も合わせてどうぞ。

最近の記事

カテゴリ

PAGETOP