<HOME  <お願い事項  <Access2000 TOP   <Access97 TOP   <サイト内検索
  Ac2002--VBAの沼 > ループ処理
   1 2



ループ処理_2

さてでは、ちょっと遊んでみましょうか。え?ずっと遊んでるみたいだったって?うるさいわねー大きなお世話よっ。

わたしが小学生のころ、学習研究社の「科学と学習」という雑誌を購読してたんですが、その中に掲載されていた算数のマンガ(マンガかよ!)で、指数の計算を面白く扱っていたのを記憶してまして、それを以前「Access2000 VBAの小屋」でもちょっとネタにしたんです。それを読んだ方が、おそらく元ネタであろうと思われる落語の一節のことをお教えくださいました。
羽柴秀吉の知恵袋と言われた商人「曽呂利新左衛門」のお話です。
どうやらこの人の残した逸話等々が、落語の期限であるという説があるらしく、落語にくわしい人に聞いたら、

「知恵者の曽呂利新左衛門、太閤秀吉に気に入られるようなことを言って褒美をいただくこととなった。
太閤秀吉が『その方の望む所のものを褒美にとらせる』と言ったところ、新左衛門は、
『今日は米2粒、明日はその2倍の4粒、その次の日はその倍の8粒、倍々と増して、1ヶ月の間お米を賜りたい』
と答えた。秀吉は、その望みの小ささに二つ返事で快諾したが、その結果は…。」

というような筋書きらしいです。
(別の解釈に、「この広間の畳に、端の方から一畳目は米一粒、二畳目は二倍の二粒、三畳目はその倍の四粒、というように、二倍二倍と米を置き、広間の百畳分全部をいただきたい」と言ったらしい、というのもあるそうなんです。シチュエーションとしてはこっちの方が面白いかも・・・だって、台所方たちが、畳にひとつ、ふたつ・・・とお米粒を置いていく姿・・・なかなか面白いではありませんか)



これをね、プロシージャのネタにしてみようかな、と思うわけです。
とりあえず1ヶ月ってことで・・・30日間で計算をしてみましょう。30日後に、新左衛門は果たして何粒の米を手に入れることができるのか???
どんな感じの構文になるか、ちょっと考えてみてください。

考え方としては、

  米粒の数=最初は1粒
  繰り返しの回数 30回
  米粒の数 = 米粒の数 + 米粒の数  ←これが、今日もらう米粒の数
  今までの米粒の数 = 今までの米粒の数 + 米粒の数  ←今までもらった分に、今日もらう分を足す
  この処理を30回になるまで繰り返し

という感じですね。

そうすると、少なくとも米粒の数を数えるための変数が、2種類必要になりますかね。
それに、ループの回数をカウントする変数がひとつ。
変数は合計、3つあった方がよさそうです。

じゃあ、もうひとつプロシージャを作り足しましょう。
で、ループの処理だけ先に作っときましょうか。

で、そのほかの変数を宣言しておきます。

注意すべきは、変数のデータ型ですね。
これ、30回繰り返し計算した結果、だいたいどれくらいの米粒数になると思います?
実はコレ、相当な数になるんですよね。。。。
だから、Integerではエラーになってしまうんです。
Integerが扱えるのは、-32,768 〜 32,767 の範囲の値だけ・・・。
32,767を超えたところで、「オーバーフローしました」なんていうメッセージが出てしまいます。

ここは、Longというデータ型を使いましょう。
Long(長整数型)は、-2,147,483,648 〜 2,147,483,647までOKの数値型です。
Integerと同様、小数点以下の桁数は扱えないのですが、数を数えたりするために使用するデータ型なら十分でしょう。

繰り返しのカウンタ用の変数は、Integerでいいでしょう。
とりあえず、30日分ですから、この変数に30を超えた数が入ることはありませんしね。

こんな感じで、いいのかな・・・。
じゃあ、ループの外で、Debug.Printして、今日もらう分の米が何粒か、イミディエイトウィンドウで確認してみましょう。
と、こんな感じでしょうか。

出ます?なんか、出ますよね。

ここでひとつ、じっくりともう一度、ループの部分を眺めてみてください。
これ、おそらく、31日めにもらう米粒の数じゃないかと思うんですよね。

こういう↑感じになるはずなんです。
つまり、For Nextのループの中に入ったとき(i が1のときすでに)、2日目の計算をしていることになってるわけなんですね。

ためしに、Debug.Printをループの中に書いてみましょう。

わたしのはこんな感じに↓なりましたよ。

既に、2 から始まってますよね。



でも、デバッグの位置を変えると・・・。

1から数え始めます。

ループに入った瞬間は、まだ1日目の値が変数 t_kome に入ってるんですが、その後すぐに、「昨日の米粒の2倍」を計算してますからね・・・。

ループ処理って、こういう「ループの開始と終了のタイミング」を考えるのが、結構難しいんですよ。
もし、30日分の計算をしたいのなら、ループの回数を29にするのがいいかもしれないですね。
か、もう31日分計算しちゃうとか。。。

そしたら今回は、出力先をイミディエイトウィンドウにして、簡易リストを作っちゃいましょう。

こんな感じの↑コードを書いてみました。挑戦してみてください。
デバッグプリントをうまいこと使って、リストを作ろうというわけなんですが・・・。

決して見栄えのいいものじゃないですけれど、まあ、一覧表っぽい感じにはなりますよね。
ドラッグしてコピーして、メモ帳にでも貼り付けて印刷すれば、まあ、何日に何粒くらいもらってんのかくらいは、わかるようなリストができます。
これを、例えば「印刷したい」とか、テーブルにコピーしたいとか、それは・・・もうひとガンバリしないとならなそうです。
それはまた後日、お話しするといたしましょう。

「ループ」と「変数」についてと、デバッグプリントのやり方について、簡単にお話をいたしました。
このふたつは、主役にこそならないですが、要所要所で重要な役割を担いますので、じっくり理解を深めていきましょう。



さて、曽呂利新左衛門、米を手に入れることができたのかというと、実はそうではないらしい。
秀吉のけらいたちが日々の米の数を計算したところ、ものすごい数になることがわかり、米倉が危ういだけでなく、毎日コレだけの米粒を数えるなんてとても無理・・・・と泣きついたらしい。そこで秀吉が新左衛門に、褒美を別のものにさせてくれと申し出たとか。

ふふふ・・・。
「JA全農庄内米」という、お米についてのいろんな情報を発信しているサイトに、
http://www.shonaimai.or.jp/index.html
「お米は1粒何グラムですか?」という質問が載ってました(小学生からの質問らしいのですが)。
その回答を一部引用させていただきますと、
「お米はひと粒の重さが軽すぎるので、1000粒の重さでひかくします。この重さのことを「千粒重(せんりゅうじゅう)」と言います。千粒重は「玄米」の状態でだいたい22〜23グラムです。ですからひと粒は 0.022グラムくらいです」

ふむ。
すると、1,073,741,823 粒は23622320.106 グラムになります。
だいたい23,622キログラムということで、えーと、23トンですか???(爆笑)

だいたい毎年年間1000万トンのお米が取れるそうなんですが、安土桃山時代にどれほどの取れ高があったか、定かではありません・・・。
が、1俵というのは約60kgだそうなので、新左衛門はだいたい393俵ゲットできたことになるわけですね。
また、炊いたご飯茶碗一杯分で、だいたい2,300粒くらいあるらしいので(笑)新左衛門は466,844 杯分のゴハンをゲットできたはずだったのです。

どこまで本気だったのか、何か目的があったのか・・・その辺は、私にはわからないんですけどもね・・・。