<HOME  <お願い事項  <Access2000 TOP   <Access97 TOP   <サイト内検索
  Ac2002--VBAの沼 > だるまさんがころんだ
  



今日は、「だるまさんがころんだ」をやります。
え?何それって?ご存じないですか?「だるまさんがころんだ」っていう遊び。

鬼がひとりいてですね。他の子はみんな鬼から離れたところにいるんです。
鬼は、みんなに背を向けて、「だるまさんがころんだ」と言い、言い終わったらみんなの方を振り返ります。
みんなは、鬼に「動いているところ」を見られてはいけません。鬼が「だるまさんがころんだ」と言いつつ後ろを向いている間だけ歩いたり、動いたり、走ったりできます。この間を利用して、少しずつ鬼に近づきます。
しかし、万が一、「だるまさんがころんだ」と言い終わって鬼が振り返ってから動いたり、止まれなくて一歩二歩歩いてしまったりしたら、鬼に捕まってしまいます。鬼に捕まったら、遊びからはずれ、鬼の所に行って捕虜になります。
こうして、脱落者がひとりふたりと増えていく可能性大なわけなんですが、うまいこと移動して、鬼に近づき、鬼に触れることができると、捕まっていた仲間を解放することができるわけです。鬼の負けです。
全員捕まえたら、鬼の勝ち。鬼交代です。

鬼は孤独です。

これをですね。フォーム内にいくつかプロシージャを作ることで、やってみようと思うわけです。
ええ。何の役にも立ちませんよ。ええ。そうですとも。



といっても、出来上がりは非常に粗末なもんで、こんな感じです。

「だるまさんがころんだっ」というボタンをクリックすると、距離が縮まり、動いちゃって鬼につかまっちゃった人が出て残りの人数が減ります。

で、何度も何度もボタンをクリックしているうちに、全員捕まってしまうこともあります。

誰かが鬼に近づくことができて、勝利した場合、生き残った人の人数が出るようにしています。

フォームは、こんなデザインにしています。テキストボックス4つと、コマンドボタン2つです。
テキストボックスは基本的には2つでいいんですが、距離が近づいたりした際、「がんばれ!」とか、ちょっとしたメッセージが赤字で出るようにしています。別に赤じゃなくてもいいんですけど、まあ、とりあえずわかりやすいように・・・。

このフォームの、各イベントで、ちょっとしたプロシージャを動かすことによって、「だるまさんがころんだ中継」みたいなゲーム(とはとても言えないような粗末なものですが)ができるわけです。

今回は、ちょっとしたコード例を示します。
一例ですので、いろいろと改良の余地がありますが・・。
でも、とりあえず・・・フォーム内の各コントロールと名前が一致していれば、動きます。

今までお話をさせていただいたことを踏まえれば、解読できる内容になってます。どういう処理をしていて、フォーム内のどのテキストボックスとどう結びついているか、処理の内容を読み取って「だるまさんがころんだ」を作ってみてください。
薄い文字になっているところはコメント文です。特別、新しいことはないですが、強いて言えば、赤字にしたところが、新しいといえば新しいかなぁというところ・・・これについては下のほうで補足をいたしますね。


Option Compare Database  '---各プロシージャで共通して使う変数を宣言
Dim Sanka As Long '-----参加人数
Dim Nokori As Long '-----今残ってる人の人数
Dim Datsuraku As Long '-----今回動いちゃった人
Dim Kyori As Integer '-----鬼との距離
Dim Idou As Integer '-----今回移動できた距離
Dim kyori2 As Variant '-----距離をメートル表示したいかも

Private Sub Form_Load()
Sanka = 100000000  '---今回参加する人数。1億人。
Nokori = Sanka  '---最初は、まだ誰も脱落してないので参加者全員が残っている。
Kyori = 2000  '---単位はcm。20メートルってところで。
'-----初期値をテキストボックスへ
Me!テキスト1 = Nokori & "人の人が参加します。"
Me!テキスト3 = "鬼までの距離" & Int(Kyori / 100) & "メートル"
Me!テキスト5 = ""
Me!テキスト6 = ""
'----コマンドボタンを使えるようにしたりしなかったり
Me!コマンド0.Enabled = True
Me!コマンド4.Enabled = False
End Sub

Private Sub コマンド0_Click()
'-----動いちゃったりして鬼に見つかっちゃった人の数を毎回はじき出す
Datsuraku = Int((Nokori * Rnd) + 1)
'-----「だるまさんがころんだ」の間に走れる距離といったらだいたい2メートルちょっとが限界かな
Idou = Int((210 * Rnd) + 1)
'-----残りの人数と、残りの距離を計算
Nokori = Nokori - Datsuraku
Kyori = Kyori - Idou
kyori2 = Kyori / 100
If Nokori <= 0 And Kyori > 0 Then '----残り人数が0人になった場合で、まだ距離がある場合
  Me!テキスト1 = "残念!全員捕まってしまいました。"
  Me!テキスト3 = "惜しい!あと" & kyori2 & "メートルだったのに!"
  Me!テキスト5 = ""
  Me!テキスト6 = ""
  Me!コマンド4.Enabled = True
  DoCmd.GoToControl "コマンド4"
  Me!コマンド0.Enabled = False
ElseIf Nokori > 0 And Kyori > 0 Then '----まだ残ってる人がいて、距離もある場合
  Me!テキスト1 = "残りあと " & Nokori & "人"
  Me!テキスト3 = "鬼までの距離 あと" & kyori2 & "メートル!"
   Select Case Kyori
     Case 50 To 100
       Me!テキスト6 = "残り1メートルをきった!落ち着いて!"
     Case 1 To 49
       Me!テキスト6 = "あともうちょっと!がんばれ!"
   End Select
   Select Case Nokori
     Case 20 To 50
       Me!テキスト5 = "残り人数少なくなってきたぞ!がんばれ!"
     Case 5 To 19
       Me!テキスト5 = "慎重に!落ち着いて!"
     End Select
ElseIf Nokori > 0 And Kyori <= 0 Then '----まだ残っている人がいて、距離が0になった場合
  Me!テキスト3 = "勝利!!全員解放!!!"
  Me!テキスト1 = "生き残った人 " & Nokori & "人"
  Me!テキスト5 = ""
  Me!テキスト6 = ""
  Me!コマンド4.Enabled = True
  DoCmd.GoToControl "コマンド4"
  Me!コマンド0.Enabled = False

Else '------それ以外・・・タイミング悪く、残りの人数も距離も同時に0になってしまった場合など
  Me!テキスト1 = "残念!全員捕まってしまいました。"
  Me!テキスト3 = "惜しい!もうちょっとだったのに!"
  Me!テキスト5 = ""
  Me!テキスト6 = ""
  Me!コマンド4.Enabled = True
  DoCmd.GoToControl "コマンド4"
  Me!コマンド0.Enabled = False
End If
End Sub

Private Sub コマンド4_Click() '----もう一回最初からやるときのボタン
Nokori = Sanka '---最初は、まだ誰も脱落してないので参加者全員が残っている。
Kyori = 2000 '---単位はcm
'-----初期値をテキストボックスへ
Me!テキスト1 = Nokori & "人の人が参加します。"
Me!テキスト3 = "鬼までの距離" & Int(Kyori / 100) & "メートル"
Me!テキスト5 = ""
Me!テキスト6 = ""
'----コマンドボタンを使えるようにしたりしなかったり
Me!コマンド0.Enabled = True
DoCmd.GoToControl "コマンド0"
Me!コマンド4.Enabled = False
End Sub



どうでしょう。だいたい、どんなことをやっているか読み取れますですか?
そんな変わったことはやってないので、

  ・どんなイベントで動くようになっているのか
  ・どんな名前の変数が宣言されているのか
  ・それぞれの変数にはいつどんな値が代入されているのか
  ・If や Select Case ではどんな処理をやってるのか

といったところを中心に見ていけば、対して難しくもないと思いますよ。

え?1億人も参加するなんて多すぎるって?
鬼との間20メートルの間にどうやって1億人もの人がいられるのかって?
んもーそんな細かいことは言いっこなしですよ。

いろいろ試してみたんですけどね。この、
  参加人数1億人
  距離20メートル(フォーム上では10cm)
っていうのが、一番勝敗のバランスがよさそうな気がするんですよ。

まあ、いいではありませんか。1億人の人がいっせいにだるまさんがころんだをする光景、思い浮かべてみてください。
けっこう面白いと思うんですけども・・・。

【赤字の部分の補足】

■ElseIf
  If ... Elseによる条件式を、もう少し複雑にするために使う構文です。読み方は「えるすいふ」でいいと思います。
  ふつうは、If  Else で、2択(AAAか、それ以外か)になるわけです。
  これをやや3択っぽくしたい場合(AAAか、BBBか、それ以外か)に使います。
  ちょっと難しいので・・・。ほんとはうまいこと条件を考えて、Select Case で3択にした方が応用しやすいかもしれませんけど・・・。

■Me!コマンド4.Enabled = True →  DoCmd.GoToControl "コマンド4" →   Me!コマンド0.Enabled = False
  一行ずつバラバラに見れば、どれも一度はお話をしていることだと思います。あるいは、ヘルプで探せますですよね。
  問題は、なぜ、GoToControlを間に挟んでるか、ということですね。これがなぜか・・・。
  Enabled をFalseにするということは、つまり、このコマンドボタンを使用不可にする、って動作なわけです。
  具体的には、ボタンの標題が白くなって、いかにも「クリックできなさそう」なボタンにします。
  ここでは、コマンド0っていうボタンをクリックしたときのイベントで、コマンド0を使用不可にしたいわけなんです。
  でも、クリックしたときって、そのボタンが「使われている状態(フォーカスが当たってる)」なわけで・・・。
  そういうときって、「使用可能」とかいうプロパティは、いじれないんですよ。自分が座ってるゴザをたたもうとしてるようなもんです。
  そこで、いったん他のコントロールに移動をして(どこでもいいんですが、今回はコマンド4というボタンに移動)から、Falseにします。
  これ、けっこう盲点だったりするんで、抑えておかれるといいかもしれませんですね。

こうやってつらつら書いてあるソースを見ても、どうも今ひとつ頭に入ってこないな・・・見る気がしない・・・とお感じになられた方も多いんじゃないかと思います。このページからコピー&ペーストしても、VBEにはうまく貼り付かないかもしれないですが、解読していくのが面倒でしたら、貼り付けて使ってみてください。
ただし、そのまま貼り付けても、動かない可能性があることは・・・わかってらっしゃいますよね。
テキストボックスやボタンの名前と合わせないといけないです。
また、どの位置に置いたテキストボックスが、どの処理に絡むのか・・・・は、解読してってみてください。



ときどき・・・。
ソース丸ごとメールしてよこして「これ、どこが悪いか見てください!!!」なんて言う人がいるんですけどね・・・。
コードを書くことに慣れてる慣れてない別にして、人が書いたコードって、なかなか解読しにくいもんなんですよ。
それは、皆さんもお感じになったことと思います。
誰だってそうですよ。人が書いたコードを理解するのには時間がかかりますし、そもそもあまり気持ちが乗らないもんです。

なぜ気が乗らないもんかって言うとですね・・・。これには理由があります。皆さんがVBAにあまりお詳しくないからとか、そういうことじゃないですよ。多分、かなりキャリアのある人だって(キャリアのある人こそ)人のコードを解析するのは辛いと思うと思います。
今までご覧いただいて、お分かりいただけてると思いますが・・・ひとつの処理を作るまでに、そういうコードを書くに至ったまでに、いろんな「行ったり来たり試行錯誤」があるわけじゃないですか。その「試行錯誤」があってこそ、こういう結果に至ってるわけで、そこんとこ知らずして、何も語れないはずなんです。VBAに限ったことではありませんけれどね。
そこを読み取るのは、至難の業です。それを、他人に強要する人の心理は、どうも理解しがたいものがあります。
人が作ったコードを読み取るのがすごくおっくうに感じるのは、そこなんです。表面だけ見ても伝わらないものがあるんですよ。

人それぞれですから・・・わたしがどうこう言うべきことではありませんけれども・・・。
自分で書くより、人が作ったコードを見るほうが得意、という人もたくさんいるかもしれません。わかんないけど。
VBAでプロシージャを作る作業は「作文」に似てます。単語ひとつひとつの意味と、1文の意味と、そして、どういう順番でそれらを語るか・・・によって、相手(つまりMS-Access)にどのように伝わるか、が、変わってくるのです。
単語の意味と、1文の意味は、ある程度暗記したり人の書いたソースのマネをすることでモノにすることができます。でも、「語る順番」は・・・語ったことのない人には、多分習得は難しい。経験がモノを言います。何通りもやり方が考えられるし、誤った順番で語るととんでもないことになりかねない。。。。

わたしは、そんなふうに考えてます。



お話がちょっとそれちゃいましたですが・・・動きましたですか?
これでもけっこう楽しいと思うんですけどね。え?楽しくない?うーむ、そうですか・・・。
楽しくないついでに、今日は、もうちょっといじってみようかな・・・と思います。では、次のページに・・・。