<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>自作ゲーム - プログラミングで遊ブログ</title>
	<atom:link href="https://lemon818.com/category/it/%E8%87%AA%E4%BD%9C%E3%82%B2%E3%83%BC%E3%83%A0/feed/" rel="self" type="application/rss+xml" />
	<link>https://lemon818.com</link>
	<description>現役システムエンジニアが趣味でプログラミングする自由気ままなブログ</description>
	<lastBuildDate>Wed, 26 May 2021 16:59:09 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>	<item>
		<title>エクセルでできるデジタル時計の作り方（現在時刻を HH:MM:SS 表記！）</title>
		<link>https://lemon818.com/excel-degital-clock/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Wed, 26 May 2021 14:56:29 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[エクセル]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[作り方]]></category>
		<category><![CDATA[時計]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=5560</guid>

					<description><![CDATA[Excel で デジタル時計を作りました！！！ &#160; &#160; このデジタル時計は Excel Vba という Excel 上でプログラミングをして作成されています。 難しいそうに見えますが、二時間くらいで作…]]></description>
										<content:encoded><![CDATA[<div class="sc_frame_wrap solid yellow">
<div class="sc_frame "><strong><span style="color: #000000;">Excel で デジタル時計を作りました！！！</span></strong></div>
</div>
<p>&nbsp;</p>
<p><img fetchpriority="high" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/GIF-1.gif" alt="" width="880" height="399" class="aligncenter size-full wp-image-5565" /></p>
<p>&nbsp;</p>
<p>このデジタル時計は Excel Vba という Excel 上でプログラミングをして作成されています。</p>
<p>難しいそうに見えますが、二時間くらいで作れました！（デザインに時間がかかりましたが、こだわりさえしなければ30分で作り終えました）。</p>
<p>処理内容は<strong><span style="color: #3366ff;">Excelで現在時刻をデジタル数字フォントで永遠に表示</span></strong>してくれるプログラムです。</p>
<div>
<p>&nbsp;</p>
<p>この記事では、<strong>Excel で「デジタル時計を作る」方法について簡単に解説します。</strong></p>
<p>&nbsp;</p>
<div class="sc_frame_wrap block blue">
<div class="sc_frame_title">この記事でわかること！</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>ダウンロードできる「Excel デジタル時計」の機能について</li>
<li>「Excel デジタル時計」の作り方</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>もしよければ参考にしてみてください。</p>
<p>※ いつものようにつくったのも共有しときますので、よければどうぞ。</p>
<p>&nbsp;</p>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-analog-clock.xlsm">Excel  デジタル時計をダウンロード！</a></div>
</div>
<p>&nbsp;</p>
<div>
<div class="voice clearfix left n_bottom">
<div class="icon">
<p><img decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/07/hukurou.jpg" /></p>
<div class="name"></div>
</div>
<div class="text sc_balloon left white">作り方は簡単ですが、めんどくさいと思う方はぜひダウンロードしてみてください！</div>
</div>
</div>
<p>&nbsp;</p>
<div>
<h2>ダウンロードできる 「Excel デジタル時計」の機能について</h2>
</div>
<p>ダウンロードできる「Excel デジタル時計」の機能です。</p>
<p>機能といってもボタンが二つあるだけです。</p>
<p>&nbsp;</p>
<p><img decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock1.png" alt="" width="621" height="111" class="aligncenter wp-image-5572" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock1.png 515w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock1-300x54.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></p>
<p>&nbsp;</p>
<p>これらのボタンは下記のように動作します。</p>
<div class="sc_frame_wrap block orange">
<div class="sc_frame_title">機能！</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>START ボタン・・・時計スタート！（現在時刻を取得します！）</li>
<li>STOP ボタン・・・時計をストップ！（時刻の更新を停止します！）</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>時刻は一秒ごとに刻まれます。</p>
<p>初期値（はじめに表示されている時刻）は特に気にしなくてもOKです。</p>
<p>&nbsp;</p>
<h3>このシートには非表示行があります！</h3>
<p>このシートには非表示行があります。</p>
<p><span style="color: #ff0000;"><strong>この行（33行~43行）はこのデジタル時計を動かすのに重要な役割を担っているので絶対に消さないください！！</strong></span></p>
<p>&nbsp;</p>
<p><img decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock2.png" alt="" width="884" height="197" class="aligncenter wp-image-5574" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock2.png 1505w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock2-300x67.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock2-1024x228.png 1024w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock2-768x171.png 768w" sizes="(max-width: 884px) 100vw, 884px" /></p>
<p>&nbsp;</p>
<div>
<h2>「Excel デジタル時計」の作り方</h2>
</div>
<p>さてでは「Excel デジタル時計」の作り方について説明します。</p>
<p>この時計は Excel Vba というプログラミングで作成していきます。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap block blue">
<div class="sc_frame_title">作り方</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>現在時刻をカウントする Excel Vba プログラムを作成する</li>
<li>START、STOPボタン用の Excel Vba プログラムを作成する</li>
<li>数字をデジタル数字形式に表示させる（条件付き書式を設定する）</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>では順に説明します。</p>
<p>※ ここからはプログラミングの専門用語がでてきます！！</p>
<p>&nbsp;</p>
<h3>現在時刻をカウントする Excel Vba プログラムを作成する</h3>
<p>現在時刻をカウントする処理は下記の順に作成していきます。</p>
<p>&nbsp;</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>現在時刻を取得（hh:mm:ss形式）</li>
<li>取得した現在時刻（hh:mm:ss形式）を時間、分、秒で細かく分割</li>
<li>時間、分、秒をセルに書き込む</li>
<li>現在時刻を取得する処理（上記1~3）を1秒ごとに呼び出す</li>
</ol>
</div>
<p>&nbsp;</p>
<h4>現在時刻を取得（hh:mm:ss形式）</h4>
<p>まず 現在時刻を取得するのに「actWacth」プロシージャを定義します。</p>
<p>このプロシージャでは Format(Time, "hh:mm:ss") を変数 nowValue にセットする処理を実装しています。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">Public Sub actWatch()
  nowValue = Format(Time, "hh:mm:ss")
  hour1 = Mid(nowValue, 1, 1) 
  hour2 = Mid(nowValue, 2, 1) 
  minitue1 = Mid(nowValue, 4, 1) 
  minitue2 = Mid(nowValue, 5, 1) 
  second1 = Mid(nowValue, 7, 1) 
  second2 = Mid(nowValue, 8, 1)
End Sub</pre><p>
&nbsp;</p>
<h4>取得した現在時刻（hh:mm:ss形式）を時間、分、秒で細かく分割</h4>
<p>現在時刻が格納されている <span style="color: #3366ff;"><strong>nowValue（hh:mm:ss形式）を時間、分、秒で細かく分割</strong></span>します（デジタル数字形式にするため）。</p>
<p>この際 Mid 関数という指定した文字を分割する関数を使用します。</p>
<p>&nbsp;</p>
<p><strong>Mid関数は開始文字と終了文字を指定することで文字を分割することが可能</strong>です。</p>
<p>たとえば 10:51:47 という値の4文字目から5文字目を抽出しようとすると <strong>Mid("10:51:47",4,5)</strong>と記述します。</p>
<p>すると Mid("10:51:47",4,5) = 「5」となるわけです。</p>
<p>つまり今回の場合はこのようになります。</p>
<p>&nbsp;</p>
<p>（例）nowValue = "10:51:47"の場合</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>hour1 = Mid(nowValue, 1, 1)・・・1（2桁目の時間）</li>
<li>hour2 = Mid(nowValue, 2, 1)・・・0（1桁目の時間）</li>
<li>minitue1 = Mid(nowValue, 4, 1)・・・5（2桁目の分）</li>
<li>minitue2 = Mid(nowValue, 5, 1)・・・1（1桁目の分）</li>
<li>second1 = Mid(nowValue, 7, 1)・・・4（2桁目の秒）</li>
<li>second2 = Mid(nowValue, 8, 1)・・・7（1桁目の秒）</li>
</ol>
</div>
<p>&nbsp;</p>
<h4>時間、分、秒をセルに書き込む</h4>
<p>これは簡単です。</p>
<p>時間、分、秒の値を持つ変数（hour1,hour2,minitus1,minitu2,second1,second2）を Cells(行、列)に代入します。</p>
<p>※ PRINT_CELL_ROW、PRINT_CELL_COL は数字の定数です。好きな値にすれば好きなセルの位置に出力されます。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">' セルに時間、分、秒を表示させる 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL) = hour1 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 1) = hour2 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 2) = ":" 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 3) = minitue1 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 4) = minitue2 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 5) = ":" 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 6) = second1 
Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 7) = second2</pre><p>
&nbsp;</p>
<h4>現在時刻を取得する処理を1秒ごとに呼び出す</h4>
<p>つぎに現在時刻を取得する処理（「actWacth」プロシージャ）を一秒ごとに呼び出すようにします。</p>
<p>その際、Excel Vba の Application.OnTime という機能を用います。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">Application.OnTime Now + timeValue("00:00:01"), "actWacth"</pre><p>
&nbsp;</p>
<p>Application.OnTime は <span style="color: #3366ff;"><strong>指定した時刻に好きなプロシージャを呼び出すことができます</strong></span>。</p>
<p>つまり、Application.OnTime Now + timeValue("00:00:01"), "プロシージャ" とすることで</p>
<p>指定したプロシージャ（現在時刻を取得する「actWacth」）を1秒ごとに呼び出します。</p>
<p>&nbsp;</p>
<p>あとはこれをずっーと実行するだけ。。。それだけです。</p>
<p>今回はずーっと実行する処理として while 文、for 文のようなループ処理ではなく再帰処理にします。</p>
<p>つまり 「actWacth」プロシージャの中に Application.OnTime Now + timeValue("00:00:01"), "actWacth" と書くだけで</p>
<p>ずーっと「actWacth」プロシージャが実行されるというわけです。</p>
<p>&nbsp;</p>
<h5>Application.OnTime Now を停止させる方法について</h5>
<p>現在時刻を取得する「actWacth」を再帰処理で呼び出すと永遠に呼び出されてしまいます。</p>
<p>ですので、ここでは Excel シート上の特定のセルの値（Range(JUDGE_CELL)で指定する値）が TRUE の場合は動作し、FALSEの場合は停止させるよう条件式を追加します。</p>
<p>※ JUDGE_CELL は数字の定数です！値自体は何でもOKです！</p>
<p>&nbsp;</p><pre class="crayon-plain-tag"> ' 一秒ごとに現在時刻を取得 
If Range(JUDGE_CELL) = True Then 
　　Application.OnTime Now + timeValue("00:00:01"), "actWacth" 
End If</pre><p>
&nbsp;</p>
<h3>現在時刻をカウントする Excel Vba プログラム（全体）</h3>
<p>&nbsp;</p><pre class="crayon-plain-tag">Const PRINT_CELL_COL As Integer = 43
Const PRINT_CELL_ROW As Integer = 33
Const JUDGE_CELL As String = "AO33"

Public Sub actWacth()

    Dim nowValue As String
    Dim hour1, hour2, minitue1, minitue2, second1, second2
    
    ' 現在時刻を取得
    nowValue = Format(Time, "hh:mm:ss")
    
    ' hh:mm:ss 形式を時間、分、秒に細かく分ける
    hour1 = Mid(nowValue, 1, 1)
    hour2 = Mid(nowValue, 2, 1)
    minitue1 = Mid(nowValue, 4, 1)
    minitue2 = Mid(nowValue, 5, 1)
    second1 = Mid(nowValue, 7, 1)
    second2 = Mid(nowValue, 8, 1)
    
    ' セルに時間、分、秒を表示させる
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL) = hour1
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 1) = hour2
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 2) = ":"
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 3) = minitue1
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 4) = minitue2
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 5) = ":"
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 6) = second1
    Cells(PRINT_CELL_ROW, PRINT_CELL_COL + 7) = second2
    
    ' 一秒ごとに現在時刻を取得
    If Range(JUDGE_CELL) = True Then
    
        Application.OnTime Now + timeValue("00:00:01"), "actWacth"
    
    End If

End Sub</pre><p>
&nbsp;</p>
<h3>START、STOPボタン用の Excel Vba プログラムを作成する</h3>
<p>そして次に START、STOPボタンです。</p>
<p>&nbsp;</p>
<p>STARTは startWatch プロシージャで実装します。</p>
<p>Application.OnTime Now（指定したプロシージャを指定した時刻に呼び出す関数）を止めるように用意したセルの値（Range(JUDGE_CELL)で指定する値）を TRUE にし、</p>
<p>actWatch （現在時刻を取得する処理）を呼び出せばOKです。</p>
<p>&nbsp;</p>
<p>STOPは Range(JUDGE_CELL) に FALSE を代入するだけです。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">Const PRINT_CELL_COL As Integer = 43
Const PRINT_CELL_ROW As Integer = 33
Const JUDGE_CELL As String = "AO33"

Sub startWatch()

    Range(JUDGE_CELL) = True
    
    Call actWacth

End Sub

Sub stopWatch()

    Range(JUDGE_CELL) = False

End Sub</pre><p>
&nbsp;</p>
<p>これで現在時刻の表示は完了です！</p>
<p>あとはデジタル数字形式に変換する処理だけです！</p>
<p>&nbsp;</p>
<h3>数字をデジタル数字形式に表示させる（条件付き書式を設定する）</h3>
<p><strong>ここから結構難しい話です。</strong></p>
<p>&nbsp;</p>
<p>これはやり方はいろいろあると思いますが、今回は条件付き書式を利用します。</p>
<p>0 ~ 9 の10種類数字があり、そのデジタル数字を思い浮かべてみてください。</p>
<p>そうする<strong><span style="color: #ff0000;">とある規則があることに気づきませんか？</span></strong></p>
<p>&nbsp;</p>
<p>たとえばデジタル数字を「上、下、真ん中、左上、左下、右上、右下、」と７つのブロックに区切ります。</p>
<p>すると、<strong><span style="color: #3366ff;">ブロック単位で数字ごとにデジタル表記に必要な箇所が決まっている</span></strong>んです。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock6.png" alt="" width="618" height="339" class="aligncenter size-full wp-image-5579" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock6.png 618w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock6-300x165.png 300w" sizes="auto, (max-width: 618px) 100vw, 618px" /></p>
<p>&nbsp;</p>
<p>たとえば、0ならば真ん中以外の6つのブロック、1ならば右上と右下だけの2ブロック、....</p>
<p>こんな感じでブロック単位でみていると<span style="color: #3366ff;"><strong>数字毎に必要な箇所が固定化されています。</strong></span></p>
<p>これを表にまとめたのが、右上の表の画像です。</p>
<p>これさえ理解できればあとは<span style="color: #3366ff;"><strong>このルールを条件付き書式に反映させればいいだけ</strong></span>です。</p>
<p>つまり<strong>1の数字ならばセルの右上、右下の部分の色を変えればデジタル数字形式になります！</strong></p>
<p>&nbsp;</p>
<p>条件付き書式は設定箇所が多いため今回は設定のやりかただけを説明します。</p>
<p>※ 詳細な条件付き書式の設定はダウンロードした Excel デジタル時計ファイルをご確認ください！</p>
<p>&nbsp;</p>
<div>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-analog-clock.xlsm">Excel  デジタル時計をダウンロード！</a></div>
</div>
<p>&nbsp;</p>
<p>Excel の「ホーム」→「条件付き書式」→「ルールの管理」を押下します。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock3.png" alt="" width="845" height="298" class="aligncenter wp-image-5577" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock3.png 1165w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock3-300x106.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock3-1024x361.png 1024w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock3-768x271.png 768w" sizes="auto, (max-width: 845px) 100vw, 845px" /></p>
<p>&nbsp;</p>
<p>下記画面が表示されますので、新規ルールをクリックします。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock4.png" alt="" width="669" height="305" class="aligncenter size-full wp-image-5580" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock4.png 669w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock4-300x137.png 300w" sizes="auto, (max-width: 669px) 100vw, 669px" /></p>
<p>&nbsp;</p>
<p>書式ルールの編集画面がでてくるので、一番下の「数式を使用して書式設定するセルを決定」を選択し</p>
<p>「=COUNFIT($AR$37,"*"&amp;AT33&amp;"*")&gt;0」とします（これはあくまで一例です）。</p>
<p>&nbsp;</p>
<div>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock5.png" alt="" width="382" height="398" class="aligncenter size-full wp-image-5578" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock5.png 382w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock5-288x300.png 288w" sizes="auto, (max-width: 382px) 100vw, 382px" /></p>
<p>&nbsp;</p>
<p>条件付き書式は数式が真の場合にセルの色を変えたりすることができます。</p>
</div>
<p>たとえば「3」という数字をデジタル数字形式にする場合「右上、右下、上、下、真ん中」のセルの色を変えればOKということです。</p>
<p>&nbsp;</p>
<p>またCOUNTIFは特定の数字が含まれている数をカウントですが、画像右下の表で定義した「値」列に数字が含まれていれば</p>
<p>その「値」列に対応する「位置」列がわかります！あとはそこを条件付き書式で色を変えればOKです！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock7.png" alt="" width="512" height="391" class="aligncenter size-full wp-image-5581" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock7.png 512w, https://lemon818.com/wp/wp-content/uploads/2021/05/excel-degital-clock7-300x229.png 300w" sizes="auto, (max-width: 512px) 100vw, 512px" /></p>
<p>&nbsp;</p>
<p>※ COUNTIF 関数について詳しく知りたい方はこちらもどうぞ！</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/excel-countif/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/10/Excel_1540823069-150x150.png" width="150" height="150" alt="【Excel 関数】COUNTIF で特定の文字や数値をカウント！"></div><div class="title">【Excel 関数】COUNTIF で特定の文字や数値をカウント！</div><div class="date">2018.12.2</div><div class="substr">はじめに Excelで、特定の文字や数字がいくつあるか数えるとき、「COUNTIF」関数をよく使います。  この関数は、Excel 上で資料等まとめるときに大変便利な関数です。 この関数の使用方法について説明します。 COUNTIF 関数 COUNTIF 関数の基本的な使い方と、ちょっとしたテクニッ...</div></a></div>
<p>&nbsp;</p>
<div>
<h2>最後に</h2>
<p>いかがでしたでしょうか？</p>
<p>この記事では、<strong>Excel で「デジタル時計を作る」方法について簡単に解説しました。</strong></p>
</div>
<p>&nbsp;</p>
<p>なにもデジタル数字形式にしないならすごく簡単なので、よければぜひつくってみてください！</p>
<p>つくるのがめんどくさいならばぜひダウンロードしてみてください！</p>
<p>&nbsp;</p>
<div>
<p>この記事が読者の何かのお役に立てれば幸いです。</p>
<p>ではでは。</p>
<p>&nbsp;</p>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【Python】CentOS で画像から文字起こしをするサイトをつくったよ！</title>
		<link>https://lemon818.com/gazo-moziokoshi/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Tue, 18 May 2021 15:10:10 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[pytesseract]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tesseract-ocr]]></category>
		<category><![CDATA[文字起こし]]></category>
		<category><![CDATA[画像]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=5483</guid>

					<description><![CDATA[Pythonで画像から文字起こしをするサイトをつくりました！！！ &#160; &#160; どーもTakeです。 このたび兄弟ブログである「スーパー開発ブログ」で Pythonで画像から文字起こしをするサイトをつくりま…]]></description>
										<content:encoded><![CDATA[<div class="sc_frame_wrap solid yellow">
<div class="sc_frame "><strong><span style="color: #000000;">Pythonで画像から文字起こしをするサイトをつくりました！！！</span></strong></div>
</div>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/gazouai.gif" alt="" width="664" height="546" class="aligncenter size-full wp-image-5484" /></p>
<p>&nbsp;</p>
<p>どーもTakeです。</p>
<p>このたび兄弟ブログである「<a href="https://superaikun.com/">スーパー開発ブログ</a>」で <strong><span style="color: #000000;">Pythonで画像から文字起こしをするサイトをつくりました！！！</span></strong></p>
<p>記事は<a href="https://superaikun.com/gazoMoziokoshi">こちら</a>です。</p>
<p>&nbsp;</p>
<p>このページを作るのがかなり大変でした。。。。</p>
<p>CentOs7というサーバ上で「tesseract-ocr」と「pytesseract」というパッケージを使ってやったんですが、うまくいかないことばかり、、、</p>
<p>なので、構築手順を簡単にページにまとめました！</p>
<p>よければこのページを参考に作ってみてください！</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap block blue">
<div class="sc_frame_title">この記事でわかること！</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>画像から文字起こしするための環境構築する方法</li>
<li>実際にテスト用の Python スクリプトをつくって動作させるまで</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h2>画像から文字起こしするための環境構築</h2>
<p>&nbsp;</p>
<p>画像から文字起こしするための環境構築の方法について記述します。</p>
<p>この通りやればいけますが、下記を実行して<strong>エラーが出たら大抵うまくいきませんので、全部うまくいったことを確認してください。</strong></p>
<p>&nbsp;</p>
<h3>「tesseract-ocr」と「pytesseract」をインストールする</h3>
<p>&nbsp;</p>
<p>下記コマンドを実行してパッケージを入れます。</p><pre class="crayon-plain-tag"># yum install gcc gcc-c++ make
# yum install autoconf automake libtool
# yum install libjpeg-devel libpng-devel libtiff-devel zlib-devel</pre><p>
&nbsp;</p>
<p>つぎに「tesseract-ocr」を実行するために必要な「leptonica」を入れます。</p><pre class="crayon-plain-tag"># wget http://www.leptonica.org/source/leptonica-1.76.0.tar.gz
# tar -zxvf leptonica-1.76.0.tar.gz
# ./configure
# make
# make install</pre><p>
&nbsp;</p>
<p>つぎに vim コマンドで「/etc/profile」に下記内容を追記します。</p><pre class="crayon-plain-tag">export LD_LIBRARY_PATH=$LD_LIBRARY_PAYT:/usr/local/lib 
export LIBLEPT_HEADERSDIR=/usr/local/include 
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 
carried out source /etc/profileMake it effective</pre><p>
&nbsp;</p>
<p>そんで「tesseract-ocr」を入れます。</p>
<p>git コマンドが入っていない場合「yum install git」で入れます。</p><pre class="crayon-plain-tag"># git clone -b master https://github.com/tesseract-ocr/tesseract.git tesseract-ocr
# ./autogen.sh
# ./configure 
# make 
# make install
# ldconfig</pre><p>
&nbsp;</p>
<h3>「tessdata」で言語パッケージをとってくる</h3>
<p>&nbsp;</p>
<p>「tessdata」っていう言語パッケージを取ってきます。</p>
<p>下記コマンドを実行します。</p><pre class="crayon-plain-tag">git clone https://github.com/tesseract-ocr/tessdata.git
mv tessdata /usr/local/share/tessdata</pre><p>
&nbsp;</p>
<p>あとは実際に動くか試してみます。</p><pre class="crayon-plain-tag">$ tesseract ims.png out -| jen</pre><p>
&nbsp;</p>
<p>上記は「img.png」って画像を読み込ませて「out」（テキストとして出力）されます。</p>
<p>日本語を文字起こししたい場合は jpn で言語指定します。</p>
<p>実行後に「Error」となく実行できればOK、out.txtの中身を確認して正常に動いていれば問題なしです。</p>
<p>&nbsp;</p>
<h4>ポイント！</h4>
<p>&nbsp;</p>
<p>「mv tessdata /usr/local/share/tessdata」を<span style="color: #ff0000;"><strong>絶対に忘れないこと</strong></span>！！！</p>
<p>しかも「cp」コマンド（コピー）ではなく「mv」コマンド（移動）であること！です！</p>
<p>なんでかわからないですが、「cp」コマンドだと旨く読み込まれなかったです。</p>
<p>&nbsp;</p>
<p>わたしはそもそも「mv」コマンドを忘れて実行してしまい下のようなエラーがでて私は詰みました笑</p><pre class="crayon-plain-tag"># 実行しようとしたときの出来事
$ tesseract ims.png out -| jen
Error in pixReaddenTiff: function not present
Error in pixReadMem: tiff: no pix returned
Error in pixaGenerateFontFromStrina: pix not made
Error in bnfCreate: font pixa not made Tesseract Open Source OCR Engine v5.0.0-alpha-20210401-118-g1c77 with Leptonica
Error in pixReadStreamPng: function not present
Error in pixReadStrean: png: no pix returned
Error in pixRead: pix not read Error during processing</pre><p>
&nbsp;</p>
<h3>「pytesseract 」をインストールする</h3>
<p>&nbsp;</p>
<p>ここまでくればあとは「pip install pytesseract 」を実行します。</p>
<p>ここまでエラーなしでいけていればOKです。</p>
<p>&nbsp;</p>
<p>参考サイト：</p>
<ul>
<li><a href="https://www.programmersought.com/article/70164685281/">https://www.programmersought.com/article/70164685281/</a></li>
<li><a href="https://github.com/tex2e/ocr-jpn">https://github.com/tex2e/ocr-jpn</a></li>
</ul>
<p>&nbsp;</p>
<h2>実際にPythonコードを書いてみる</h2>
<p>&nbsp;</p>
<p>実際に「tesseract」を python上で動作させます。</p>
<p>下記内容を pythonファイルとして保存（今回は test.py）とします。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">from pytesseract import pytesseract
from PIL import Image

# 読み込み対象ファイルの指定
img = Image.open("./img.png", "r")

# tesseractコマンドのインストールパス
pytesseract.tesseract_cmd = "/usr/local/bin/tesseract"

# 文字列として出力できる。
result = pytesseract.image_to_string(img, lang="eng+jpn")

print(result)</pre><p>
&nbsp;</p>
<p>そして「python test.py 」と実行すればコマンドライン上に画像に含まれるメッセージが出力されます。</p>
<p>&nbsp;</p>
<p>処理の中身は超簡単です。</p>
<p>まず img.png っていう画像ファイルを読み込んで「/usr/local/tesseract」を呼び出して実行して変数に格納し、</p>
<p>その変数を出力するだけのスクリプトです。</p>
<p>&nbsp;</p>
<h2>最後に</h2>
<p>&nbsp;</p>
<p>いかがでしたでしょうか？</p>
<p><span style="color: #000000;">Pythonで画像から文字起こしをする方法を解説しました。</span></p>
<p>&nbsp;</p>
<p>わたしの兄弟ブログである「<a href="https://superaikun.com/">スーパー開発ブログ</a>」の<a href="https://superaikun.com/gazoMoziokoshi">こちら</a>の記事に実際に動作するものが乗っています。</p>
<p>ただ英語は精度がかなりいいんですが、日本語が精度が悪いです。。。</p>
<p>ですが、結構面白いサイトなのでぜひチェックして見てください！</p>
<p>ではでは。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【自作ブログ】WordPress 無し、PythonのDjangoでブログをつくりました！</title>
		<link>https://lemon818.com/superaikun/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Mon, 10 May 2021 15:00:15 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[業務で役立つExcelマクロ]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[スーパー開発ブログ]]></category>
		<category><![CDATA[自作ブログ]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=5401</guid>

					<description><![CDATA[&#160; どーも Takeです。久々の投稿です。 いつもたくさんのお問い合わせありがとうございます。そしてなかなか仕事が忙しくて返信できずすみません。。。 &#160; この度、新しいブログ「スーパー開発ブログ」を作…]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p>どーも Takeです。久々の投稿です。</p>
<p>いつもたくさんのお問い合わせありがとうございます。そしてなかなか仕事が忙しくて返信できずすみません。。。</p>
<p>&nbsp;</p>
<p>この度、新しいブログ「<a href="https://superaikun.com/">スーパー開発ブログ</a>」を作成しました！</p>
<p>このブログ、なんとWordpressなしでPython の Django というWebフレームワークのみで作成しました！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/superai1.png" alt="" width="1014" height="496" class="aligncenter wp-image-5402" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/superai1.png 1206w, https://lemon818.com/wp/wp-content/uploads/2021/05/superai1-300x147.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/05/superai1-1024x501.png 1024w, https://lemon818.com/wp/wp-content/uploads/2021/05/superai1-768x376.png 768w" sizes="auto, (max-width: 1014px) 100vw, 1014px" /></p>
<p>&nbsp;</p>
<h2>なぜWordpressなしでブログをつくったのか？</h2>
<p>&nbsp;</p>
<p>それは<span style="color: #ff0000;"><strong>「WordPress」だとどうしてもできないことが多かったから</strong></span>です。</p>
<p>&nbsp;</p>
<p>WordPressって本当に凄いソフトだと思います。</p>
<p>自動でマークアップもされプラグインもテーマも豊富で世界一のCMSだとも思っています。</p>
<p>&nbsp;</p>
<p>しかしIT系のブログを書いていると、文字だけではなく<span style="color: #0000ff;"><strong>実際にプログラミングが動く記事に乗せたいな</strong></span>と思っていました。</p>
<p>そう思って、目につけたのが私が一番好きな言語である Python であり、Python で一からつくってみよう！と思ったのがすべての始まりです。</p>
<p>&nbsp;</p>
<h2>Python の Django でブログ作ったら実際どんな感じなん？</h2>
<p>&nbsp;</p>
<p>苦労話とよかったところをいいます。</p>
<p>&nbsp;</p>
<h3>まず苦労話</h3>
<p>&nbsp;</p>
<p><strong><span style="font-size: 24px; color: #ff0000;">ブログを一からつくるのはめちゃくちゃ時間かかり、死ぬほど大変です。</span></strong></p>
<p>&nbsp;</p>
<p>なんやかんや仕事しながらやっていたら一か月くらいかかりました。</p>
<p>ともかく壁が多すぎる。。。。</p>
<p>&nbsp;</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>サーバの選定（さくらVPSを選択しました）</li>
<li>サーバの環境構築（ホスト名、FW設定、Apache設定、SSL設定（https化）、その他ssh接続等）</li>
<li>Python の Django フレームワークの開発（静的ページ、動的ページの設定、SNSタグ設定）</li>
<li>ページデザイン（これが死ぬほど大変、スマホでも崩れないように調整作業）</li>
</ol>
</div>
<p>&nbsp;</p>
<h4>サーバの選定</h4>
<p>&nbsp;</p>
<p>もともとブログ作成にはレンタルサーバーとして Xserver をつかっていたのですが、</p>
<p>今回は思い切って「さくらVPS」をつかってみました。</p>
<p>これは本当に使ってよかったと思いました。</p>
<p>しかし Linux サーバ系の知識がない人には結構ハードルが高いです。</p>
<p>さくらVPSのページがすごくわかりやすく書いていますが、それでもかなり苦労すると思います。</p>
<p>&nbsp;</p>
<h4>サーバの環境構築（ホスト名、FW設定、Apache設定、SSL設定（https化）、その他ssh接続等）</h4>
<p>&nbsp;</p>
<p><span style="font-size: 24px; color: #ff0000;">これが一番大変でした。</span></p>
<p>&nbsp;</p>
<p>ページがつながらない。。https化できない。。</p>
<p>Twtter でシェアできない。。とかとか</p>
<p>なんとか Google 先生の力を借りてやってようやく動くようになりましたが、、自力は無理です。</p>
<p>&nbsp;</p>
<h4>Python の Django フレームワークの開発（静的ページ、動的ページの設定、SNSタグ設定）</h4>
<p>&nbsp;</p>
<p>これは思いのほか簡単でした。</p>
<p>だいたいわからないことは調べたらでてきます、しかし量がおおい。。。。</p>
<p>Djangoの仕組みをしっかりと理解する必要があります。</p>
<p>&nbsp;</p>
<p>また静的ページ（htmlにべた書きするページ）だけなら正直1日で誰でもできます。</p>
<p>しかし動的ページ（データベースに記事を登録して運用するページ）を取り入れるとその分の設定が必要になり、結構大変でした。</p>
<p>しかも<strong><span style="color: #0000ff;">動的ページにPythonからの処理を受け取ってhtml画面に表示させるように実装もした</span></strong>ので、その設定をするのもめちゃくちゃ大変。。。。</p>
<p>&nbsp;</p>
<h4>ページデザイン（これが死ぬほど大変、スマホでも崩れないように調整作業）</h4>
<p>&nbsp;</p>
<p><span style="font-size: 20px; color: #ff0000;">これが二番目に大変でした。</span></p>
<p>&nbsp;</p>
<p>レスポンシブ対応（スマホ対応）の画面にするとどうしてもレイアウト崩れが発生しまくって修正に時間がかなりかかります。</p>
<p>ページデザインは Bootstrap でほぼカバーしましたが、</p>
<p>それでも実現できない箇所は CSS、JQuery でカバーしました。</p>
<p>&nbsp;</p>
<p>たぶんまだバグがありそう。。。見つけ次第直します。</p>
<p>&nbsp;</p>
<h3>つくってよかった点</h3>
<p>&nbsp;</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>プログラミング処理が画面表示できるようになった！</li>
<li>かなり実力がついた！！！</li>
</ol>
</div>
<p>&nbsp;</p>
<p><span style="color: #0000ff;">プログラミング処理が画面表示できるようになった点</span>が本当に嬉しいです。</p>
<p>クライアントサイドの言語（Javascript、JQuery等）ならば WordPressでも正直できますが、</p>
<p>Pythonの処理も画面で表示させれるようになりました！！！</p>
<p>具体的にはこの「<a href="https://superaikun.com/senga"><span>【無料・ダウンロードOK】写真から塗り絵（線画）をつくろう！</span></a>」です。</p>
<p>これはPythonで加工した画像を画面表示しています。本当に作ってよかった！</p>
<p>&nbsp;</p>
<p>あとめちゃくちゃ実力つきました！</p>
<p>Linuxの環境設定、Apache、証明書、ssl化、Python、html系フロントの知識。。。。</p>
<p>参考書なんか読むよりもはるかに実力がつきました！！！</p>
<p>出来た感想はやってよかった！！！！</p>
<p>&nbsp;</p>
<p>あとはコロナで外出もできなかったのでちょうど暇つぶしできてよかったと思います。</p>
<p>&nbsp;</p>
<h2>そこからようやくブログ完成！！！スタートライン！！</h2>
<p>&nbsp;</p>
<p>ようやく完成しました。</p>
<p>これからこのブログと新しいブログ「<a href="https://superaikun.com/">スーパー開発ブログ</a>」ふたつでいろいろと記事を作っていきたいと思います！！！</p>
<p>&nbsp;</p>
<p>つくっていて、「これパッケージにしたら絶対売れるだろうなあ」とか思いました。</p>
<p>本当に WordPress って便利。。。</p>
<p>ではでは。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【Excel VBA】マトリックス形式から表形式に変換するマクロの作成方法！</title>
		<link>https://lemon818.com/matrix_table/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Sat, 28 Nov 2020 07:30:10 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[Excel マクロ]]></category>
		<category><![CDATA[マトリクス]]></category>
		<category><![CDATA[マトリックス]]></category>
		<category><![CDATA[変換]]></category>
		<category><![CDATA[形式]]></category>
		<category><![CDATA[表]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=5338</guid>

					<description><![CDATA[どーも Takeです。 久々のブログ投稿です（さぼるにさぼってました笑）。 &#160; この記事ではマトリックス形式から表形式に変換するマクロの作成方法について簡単に解説します。 これはこのマクロが仕事で必要になったた…]]></description>
										<content:encoded><![CDATA[<p>どーも Takeです。</p>
<p>久々のブログ投稿です（さぼるにさぼってました笑）。</p>
<p>&nbsp;</p>
<p>この記事では<strong><span style="color: #3366ff;">マトリックス形式から表形式に変換するマクロ</span>の作成方法</strong>について簡単に解説します。</p>
<p>これはこのマクロが仕事で必要になったため、自分用に作りました。</p>
<p>&nbsp;</p>
<p>もしよければ参考にしてみてください。</p>
<p>※ いつものようにつくったのも共有しときますので、よければどうぞ（ブック保護、シート保護はかかってます）。</p>
<p>&nbsp;</p>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2020/11/convertMatricToTabularData.xlsm">マトリックス形式→表形式に変換するマクロ</a></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>マクロの作り方</h2>
<p>&nbsp;</p>
<p>マトリックス形式から表形式に変換するマクロの作り方を簡単にざっくり説明します。</p>
<p>正直超簡単なので、安心してください。</p>
<p>順にシート構成、VBAのソースコードと説明します。</p>
<p>&nbsp;</p>
<h3>シート構成</h3>
<p>&nbsp;</p>
<p>シートは下記４シートから構成されます。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap blue">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>main ・・・マクロのフロントシート。これは実行ボタンを置いて説明を書いただけのシートです。</li>
<li>setting(非表示シート) ・・・ 「matrix」シートの設定を記述するシートです（マクロ内で自動記載されます）。</li>
<li>matrix ・・・ 入力シート。マトリックス形式のデータを登録するシートです。</li>
<li>table ・・・ 出力シート。表形式のデータが出力されるシートです。</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>シートの内容について説明します。</p>
<p>※ mainシートは特に重要でないため省きます。</p>
<p>&nbsp;</p>
<h4>「setting」シート</h4>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2020/11/mt2.png" alt="" width="537" height="214" class="aligncenter size-full wp-image-5353" srcset="https://lemon818.com/wp/wp-content/uploads/2020/11/mt2.png 537w, https://lemon818.com/wp/wp-content/uploads/2020/11/mt2-300x120.png 300w" sizes="auto, (max-width: 537px) 100vw, 537px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;"><strong>「setting」シートは非表示シートのため中身が見れません。</strong></span></p>
<p>非表示にする理由として、値をいじられたくないからです。</p>
<p>このシートでは「matrix」シートの設定内容が Excel 関数で取得できるようになっています。</p>
<p>また Excel 関数が万が一消えたことを想定して Excel マクロ内で記述するように設定しています。</p>
<p>Excel 関数はこんな感じのことが書かれています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap blue">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>A5 セル ・・・=IFERROR(MATCH("*?",INDEX(matrix!A:A&amp;"",0),0),0)</li>
<li>B5 セル ・・・ =IFERROR(COUNTA(matrix!A:A)+1,0)</li>
<li>C5 セル ・・・ =IFERROR(MATCH("*?",INDEX(matrix!1:1&amp;"",0),0),0)</li>
<li>D5 セル ・・・ =IFERROR(COUNTA(matrix!1:1)+1,0)</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>要は<span style="color: #3366ff;"><strong>「matrix」シートの列と行のデータのはじまりと終わりの位置情報</strong></span>（セルの何行目何列目か）を取得しているだけです。</p>
<p>&nbsp;</p>
<h4>「matrix」シート</h4>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2020/11/mt3.png" alt="" width="528" height="335" class="aligncenter size-full wp-image-5354" srcset="https://lemon818.com/wp/wp-content/uploads/2020/11/mt3.png 528w, https://lemon818.com/wp/wp-content/uploads/2020/11/mt3-300x190.png 300w" sizes="auto, (max-width: 528px) 100vw, 528px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>「matrix」シートは<span style="color: #3366ff;"><strong>入力シート</strong></span>です。</p>
<p><span style="color: #ff0000;"><strong>注意点は列名、行名が入っている箇所のみデータが出力される点</strong></span>です。</p>
<p>上記の画面では、列名行名が入力されている赤枠しかデータ出力されないので注意が必要です。</p>
<p>&nbsp;</p>
<h4>「table」シート</h4>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2020/11/mt4.png" alt="" width="308" height="331" class="aligncenter size-full wp-image-5355" srcset="https://lemon818.com/wp/wp-content/uploads/2020/11/mt4.png 308w, https://lemon818.com/wp/wp-content/uploads/2020/11/mt4-279x300.png 279w" sizes="auto, (max-width: 308px) 100vw, 308px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>「table」シートは<span style="color: #3366ff;"><strong>出力</strong><strong>シート</strong></span>です。</p>
<p>「matrix」シートに登録されたデータが出力されます。</p>
<p>まあ、それだけです。</p>
<p>&nbsp;</p>
<h3>ソースコード</h3>
<p>&nbsp;</p>
<p>作成したマクロのVBA ソースコードは下記になります。</p>
<p>長そうに感じますが、そんな難しい処理はしていません。</p>
<p>コードの簡単な解説はソースコードの下にします。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">' ##############################################
' # マトリックス形式から表形式に変更するマクロ
' ##############################################

' シート一覧
Const SHEET_MAIN As String = "main"
Const SHEET_MATRIC As String = "matrix"
Const SHEET_TABLE As String = "table"
Const SHEET_SETTING As String = "setting"

' セル情報
Const CELL_M_C_S As String = "A5"
Const CELL_M_C_E As String = "B5"
Const CELL_M_R_S As String = "C5"
Const CELL_M_R_E As String = "D5"

'メッセージ
Const MSG_ERROR01 As String = "「" &amp; SHEET_MATRIC &amp; "」シートに値を正しく入力してください"
Const MSG_AFTER As String = "「" &amp; SHEET_TABLE &amp; "」シートに出力されました！"

' メイン
Sub main()

    Dim ms As Worksheet
    Dim ts As Worksheet
    Dim ss As Worksheet
    
    Dim mData, mCol, mRow
    
    Call setting(ms, ss, ts)

    Call getMatrixData(mData, mCol, mRow, ms, ss)

    Call setTableData(mData, mCol, mRow, ts)
    
    Call aterSetting

End Sub

' 初期設定
Private Sub setting(ByRef ms, ByRef ss, ByRef ts)
    
    Set ms = Worksheets(SHEET_MATRIC)
    Set ts = Worksheets(SHEET_TABLE)
    Set ss = Worksheets(SHEET_SETTING)
    
    ss.Range(CELL_M_C_S) = "=IFERROR(MATCH(" &amp; """" &amp; "*?" &amp; """" &amp; ",INDEX(matrix!A:A&amp;" &amp; """" &amp; """" &amp; ",0),0),0)"
    ss.Range(CELL_M_C_E).Value = "=IFERROR(COUNTA(matrix!A:A)+1,0)"
    ss.Range(CELL_M_R_S).Value = "=IFERROR(MATCH(" &amp; """" &amp; "*?" &amp; """" &amp; ",INDEX(matrix!1:1&amp;" &amp; """" &amp; """" &amp; ",0),0),0)"
    ss.Range(CELL_M_R_E).Value = "=IFERROR(COUNTA(matrix!1:1)+1,0)"
  
    ts.Cells.ClearContents
    
End Sub

' マトリックスデータ取得
Private Sub getMatrixData(ByRef mData, ByRef mCol, ByRef mRow, ByRef ms, ByRef ss)

    Dim dStartCol, dStartRow
    Dim dEndCol, dEndRow
    
    dStartCol = ss.Range(CELL_M_C_S)
    dStartRow = ss.Range(CELL_M_R_S)
    dEndCol = ss.Range(CELL_M_C_E)
    dEndRow = ss.Range(CELL_M_R_E)
    
    If dStartCol = 0 Or dStartRow = 0 Or dEndCol = 0 Or dEndRow = 0 Then
    
        MsgBox MSG_ERROR01
        End
    
    End If
    
    mRow = ms.Range(ms.Cells(1, dStartRow), ms.Cells(1, dEndRow))
    mCol = ms.Range(ms.Cells(dStartCol, 1), ms.Cells(dEndCol, 1))
    mData = ms.Range(ms.Cells(dStartCol, dStartRow), ms.Cells(dEndCol, dEndRow))

End Sub

' 表形式に書き込み
Private Sub setTableData(ByRef mData, ByRef mCol, ByRef mRow, ByRef ts)

    Application.ScreenUpdating = False

    Dim idx, x, y

    y = 1
    idx = 1
    
    For Each c In mCol
        x = 1
        For Each r In mRow
            ts.Cells(idx, 1) = c
            ts.Cells(idx, 2) = r
            ts.Cells(idx, 3) = mData(y, x)
            idx = idx + 1
            x = x + 1
        Next r
        y = y + 1
    Next c

    Application.ScreenUpdating = True

End Sub

' 後処理
Private Sub aterSetting()
    
    Application.ScreenUpdating = False
    
    MsgBox MSG_AFTER

    Sheets(SHEET_MAIN).Select
    Range("A1").Select
    Sheets(SHEET_MATRIC).Select
    Range("A1").Select
    Sheets(SHEET_TABLE).Select
    Range("A1").Select
    
    Application.ScreenUpdating = True
    
End Sub</pre><p>
&nbsp;</p>
<p>ソースコードでは下記のような処理を順にしています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap blue">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>メイン処理(main) ・・・ ただのメイン処理、ここに下記関数を順に実行しています。</li>
<li>初期設定（setting） ・・・ 「table」シートの初期化、シート名の設定、「setting」シートに関数を埋め込みます。</li>
<li>マトリックスデータ取得（getMatrixData） ・・・ 「matrix」シートの値を取得して配列に格納しています。</li>
<li>表形式に書き込み（setTableData） ・・・ 「matrix」シートの値（配列）をループ文（for Each文）で「table」シートに書き込みます。</li>
<li>後処理（aterSetting） ・・・ 完了メッセージ、全シートを「A1」セルに選択してます。</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>これがすべてです。めちゃくちゃシンプルなやり方だと思います。</p>
<p>「よくわからん」と思った人もソースコードをよく見ればたぶんなんとかわかると思います（ざっくりですみません。。）</p>
<p>&nbsp;</p>
<h2>最後に</h2>
<p>いかがでしょうか？</p>
<p>&nbsp;</p>
<p>今回は<strong>マトリックス形式から表形式に変換するマクロ</strong>の作成方法をご紹介しました。</p>
<p>ブログ書くの楽しいですね。またなんか作ったら投稿します。</p>
<p>&nbsp;</p>
<p>なんか作ってほしいマクロがあれば「お問い合わせ」から問い合わせてください。</p>
<p>簡単そうなものならつくります。</p>
<p>ではでは。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>エクセルで遊べる「神経衰弱」の作り方【Vba ゲーム】</title>
		<link>https://lemon818.com/concentration_game/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Tue, 08 Oct 2019 13:26:27 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[pickup]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[エクセル]]></category>
		<category><![CDATA[ゲーム]]></category>
		<category><![CDATA[神経衰弱]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=4469</guid>

					<description><![CDATA[はじめに &#160; どーも 暇人プログラマーTakeです。 今回も暇すぎて、Excel でトランプを使った「神経衰弱」を作ってみました！！ &#160; &#160; 作成時間はおよそ３時間くらいでした！ わたしは要…]]></description>
										<content:encoded><![CDATA[<h2>はじめに</h2>
<p>&nbsp;</p>
<p>どーも 暇人プログラマーTakeです。</p>
<p>今回も暇すぎて、Excel で<strong>トランプを使った</strong>「<span style="color: #ff0000;"><strong>神経衰弱</strong></span>」を作ってみました！！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei.gif" alt="" width="716" height="414" class="aligncenter wp-image-4530" /></p>
<p>&nbsp;</p>
<p>作成時間はおよそ３時間くらいでした！</p>
<p>わたしは要領が悪いので、作成に結構時間がかかってしまいました。。。</p>
<p>たぶんプログラミングが得意な人はもっと早くできると思います。</p>
<p>&nbsp;</p>
<p>この記事では、私が作成した「<span style="color: #ff0000;"><strong>神経衰弱</strong></span>」の<strong>操作方法</strong>と<strong>作成方法</strong>についてご紹介します～！</p>
<p>&nbsp;</p>
<h2>操作方法</h2>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_2.png" alt="" width="1433" height="219" class="aligncenter size-full wp-image-4539" srcset="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_2.png 1433w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_2-300x46.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_2-768x117.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_2-1024x156.png 1024w" sizes="auto, (max-width: 1433px) 100vw, 1433px" /></p>
<p>&nbsp;</p>
<p>操作方法は下記手順です。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">操作手順</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>数字の種類（２～１３）を設定します</li>
<li>マークの種類（<span style="color: #ff0000;">&#x2665;</span> &#x2660; <span style="color: #ff0000;">&#x2666;</span> &#x2663;）を設定します。</li>
<li>「START」押下します。すると、「ステータス」がゲーム中に変更されます。</li>
<li>セル上に赤いセルがでてきますので、どれかを二枚押します。</li>
<li>二枚同じ<span style="color: #ff0000;"><strong>数字</strong></span>ならカードの表示が消え、<strong><span style="color: #ff0000;">獲得枚数</span>が追加されます。</strong></li>
<li>全部カードの表示が消えれば、ゲーム終了です。</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>簡単に言うと、設定することして、ボタンを押下すれば、</p>
<p>あとは普通の「<span style="color: #ff0000;"><strong>神経衰弱</strong></span>」です。</p>
<p>&nbsp;</p>
<h3><strong>数字の種類（２～１３）</strong></h3>
<p>&nbsp;</p>
<p>ゲームに使う<strong>トランプの数字の種類</strong>のことを指します。</p>
<p>たとえば、数字の種類（２～１３）＝ 3 と設定すれば、</p>
<p>トランプの数字（2 ~10、J、Q、K）のうち3種類の数字（たとえば、２、４、Jの3種類）</p>
<p>を使うように設定するということです（この数値はランダムで決定します）。</p>
<p>&nbsp;</p>
<h3>マークの種類（<span style="color: #ff0000;">&#x2665;</span> &#x2660; <span style="color: #ff0000;">&#x2666;</span> &#x2663;）</h3>
<p>&nbsp;</p>
<p>ゲームに使うトランプの<strong>マークの種類</strong>のことです。</p>
<p>これは、「2」か「4」のみ設定できるのですが、</p>
<p>「2」と設定すると、<span style="color: #ff0000;">&#x2665;</span> &#x2660;の2種類、「4」と設定すると、<span style="color: #ff0000;">&#x2665;</span> &#x2660; <span style="color: #ff0000;">&#x2666;</span> &#x2663;の4種類が</p>
<p>神経衰弱のゲーム内で使用されるということです。</p>
<p>&nbsp;</p>
<h3>配置されるカードの枚数について</h3>
<p>&nbsp;</p>
<p>また配置されるカードの枚数ですが、</p>
<p>数字の種類（２～１３）×記号の種類（&#x2665; &#x2660; &#x2666; &#x2663;）の枚数になります。</p>
<p>つまり、最大が１3×4枚＝52 枚となります。</p>
<p>&nbsp;</p>
<h3>「START」と「FIN」ボタンについて</h3>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_3.png" alt="" width="883" height="249" class="aligncenter wp-image-4541" srcset="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_3.png 1375w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_3-300x84.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_3-768x216.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_3-1024x288.png 1024w" sizes="auto, (max-width: 883px) 100vw, 883px" /></p>
<p>&nbsp;</p>
<p>「START」ボタンを押下することで、ゲームが開始されます。</p>
<p>その際に「ステータス」という箇所が「ゲーム中」に変更されるのが確認できます。</p>
<p>また、トランプが表示されることが確認でき、押下も可能です（画面<strong><span style="color: #ff0000;">赤色</span></strong>のセルの箇所）。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_5-1.png" alt="" width="1370" height="400" class="aligncenter size-full wp-image-4551" srcset="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_5-1.png 1370w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_5-1-300x88.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_5-1-768x224.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_5-1-1024x299.png 1024w" sizes="auto, (max-width: 1370px) 100vw, 1370px" /></p>
<p>&nbsp;</p>
<p>「FIN」ボタンを押下することで、ゲームが終了します。</p>
<p>その際に「ステータス」という箇所が「ゲーム終了」に変更されるのが確認できます。</p>
<p>なお「ゲーム終了」状態では、カードを押下しても<span style="color: #ff0000;"><strong>反応しなくなります。</strong></span></p>
<p>&nbsp;</p>
<h2>作成方法</h2>
<p>&nbsp;</p>
<p>今回は、<span style="color: #0000ff;"><strong>Excel Vba</strong> </span>を用いて作成しました！</p>
<p>作成方法について、全部記述すると長くなるのですがご容赦ください。</p>
<p>&nbsp;</p>
<p>※ 専門的な用語もでてきますので、よくわかない方は、ページの一番下のダウンロードボタンから</p>
<p>Excel「神経衰弱」をダウンロードして遊んでみてください！</p>
<p>&nbsp;</p>
<h3>シート構成</h3>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">シート構成</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>神経衰弱</li>
<li>トランプマスタ（非表示シート）</li>
<li>作業用</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>「神経衰弱」はメインシートであるので、実施に<strong>神経衰弱を行う用のシート</strong>となります。</p>
<p>実装自体は Excel Vba で行っており、このシートはその実装結果を表示させているだけです。</p>
<p>&nbsp;</p>
<p>「トランプマスタ」は<strong>トランプに関する情報を登録するシート</strong>です。</p>
<p>具体的には、トランプで使用する数字とマークをどういうものを使用するかといったことを登録しています。</p>
<p>この値を参照してトランプとして扱う数字とマークを設定するように Excel Vba 上で動作させています。</p>
<p>&nbsp;</p>
<p>作業用シートは実際に<strong>神経衰弱のゲームを行っていく上で必要な情報を登録するシート</strong>です。</p>
<p>具体的には下記情報を登録しています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">必要な情報</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>マウスからクリックされたカードの情報（カードの値とカードのセルの位置）</li>
<li>クリックされた二枚のカードが同じ数字のカードであるか判定</li>
<li>全カード枚数、残り枚数、獲得枚数</li>
<li>ゲームステータス（ゲーム中か終了か）</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h3>ソースコード</h3>
<p>&nbsp;</p>
<p>Excel Vba のソースコードについては下記のような構成になっています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">ソースコード</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>Sheet1(神経衰弱)</li>
<li>STARTボタン押下処理</li>
<li>カード押下時の処理</li>
<li>ゲーム終了処理</li>
<li>定数定義</li>
<li>配置カードを設定</li>
<li>盤上へカードを配置</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h4>Sheet1(神経衰弱)</h4>
<p>&nbsp;</p>
<p>ここはシート上のクリックを検知し、その検知した結果、さまざまな処理を行う箇所です。</p>
<p>&nbsp;</p>
<p>具体的には、カードを配置する範囲のセルがクリックされている状態で</p>
<p>かつステータスが「ゲーム中」の場合にクリックが検知された場合に様々な処理を行うようにしています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">様々な処理</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>カード押下前の処理</li>
<li>カード押下時の処理</li>
<li>カード押下後の処理</li>
<li>カード終了時のフラグ</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">'シート操作の処理
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Dim NowCell
    Set NowCell = ActiveCell
    Dim GameStatus
    GameStatus = Worksheets(WORK_SHEET).Range(GAME_STATUS_PLACE).Value

    If GameStatus = MSG_GAME_START _
        And BOARD_Y &lt;= NowCell.Row And NowCell.Row &lt;= BOARD_Y + 8 _
        And BOARD_X &lt;= NowCell.Column And NowCell.Column &lt;= BOARD_X + 20 _
        And NowCell.Value &lt;&gt; "" _
    Then
        
        ' カード押下前の処理
        Call prepareCard(NowCell, NowCell.Address)
        
        ' カード押下時の処理
        Call openCard(NowCell)
        
        ' カード押下後の処理
        Call pushCard(NowCell.Value, NowCell.Address)
        
        'カード終了時のフラグ
        Call finGame
    
    End If
    
End Sub</pre>
&nbsp;</p>
<p>※ Excel シートのクリック検知について記事を以前記事を作成しましたの、よければ参考にご確認ください。</p>
<p>（わたしは以前これを知らなくてめちゃくちゃ悩んだ覚えがありますが、知っていれば超簡単です！）</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/excel-clickevent/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/10/5470d3ad4154f55e94757a88cf55ed08-150x150.png" width="150" height="150" alt="【Excel vba】マウスの左クリックのイベントを検知する簡単な方法"></div><div class="title">【Excel vba】マウスの左クリックのイベントを検知する簡単な方法</div><div class="date">2019.2.4</div><div class="substr">はじめに Excelで将棋のゲームをつくろうとしたときでした。 そういやどうやってマウスクリックを検知すればいいんやろう？ 私は仕事やブログでExcelを取り扱うことが多いですが、セルをクリックしたときにクリックしたことを検知しそこから処理を開始することがわかりませんでした。 いろいろ調べましたが、...</div></a></div>
<p>&nbsp;</p>
<h4>STARTボタン押下処理</h4>
<p>&nbsp;</p>
<p>ここでは、START ボタンが押下された場合の処理をまとめています。</p>
<p>私が作成したマクロは、STARTボタンを押下することでゲームが開始する仕様になっていますが、</p>
<p>ゲーム開始前の準備をここでは行うということです。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">ゲーム開始前の準備</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>メインシート 初期化</li>
<li>作業用シート 初期化</li>
<li>盤上にカードをセット</li>
<li>ゲームステータスの設定</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' START ボタン押下処理
Sub main()

    Application.ScreenUpdating = False
    
    Dim numArray
    
    ' メインシート 初期化
    Call setDefaultMainSheet

    ' メインシート 初期化
    Call setDefaultWorkSheet
    
    ' 配置するカードを設定
    numArray = setCard
   
    ' 盤上にカードをセット
    Call setBorad(numArray)

    ' ゲームステータス
    Worksheets(WORK_SHEET).Range(GAME_STATUS_PLACE).Value = MSG_GAME_START

    Application.ScreenUpdating = True

End Sub

' メインシート 初期化
Sub setDefaultMainSheet()

  With Worksheets(MAIN_SHEET)
    
    .Range(Cells(BOARD_Y, X + BOARD_X), Cells(BOARD_Y + 20, X + BOARD_X + 20)).Clear
  
  End With

End Sub


' 作業用シート 初期化
Sub setDefaultWorkSheet()

  With Worksheets(WORK_SHEET)
    
    .Range(FIRST_INFO_PLACE).ClearContents
    .Range(SECOND_INFO_PLACE).ClearContents
    .Range(FIRST_CELL_PLACE).ClearContents
    .Range(SECOND_CELL_PLACE).ClearContents
        
  End With

End Sub</pre>
&nbsp;</p>
<h4>カード押下時の処理</h4>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_0.png" alt="" width="759" height="389" class="aligncenter wp-image-4545" srcset="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_0.png 1001w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_0-300x154.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_0-768x394.png 768w" sizes="auto, (max-width: 759px) 100vw, 759px" /></p>
<p>&nbsp;</p>
<p>シート上の赤いセルをクリックした場合に実装される処理です。</p>
<p>Sheet1(神経衰弱)で動作を検知し、このソースコードに書かれたプロシージャが実行されるということです。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">ゲーム開始前の準備</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>カード押下前の処理</li>
<li>カード押下時の処理</li>
<li>カード押下後の処理</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h5>カード押下前の処理</h5>
<p>ここでは、まず一枚目と二枚目のカードが押下されたセルの情報（セルの値とセルの位置）を</p>
<p>「作業用シート」に記述します。</p>
<p>&nbsp;</p>
<h5>カード押下時の処理</h5>
<p>押下されたセルの配色を変更します。</p>
<p>赤色のカードとは、つまり赤色の背景色のセル（セル内の文字も赤色）ということですが、</p>
<p>カードが押下されたということが、カードを開く（表返す）ためにセルの背景色を<span style="color: #ff0000;"><strong>赤色</strong></span>から<strong>白色</strong>に変更しています。</p>
<p>また、この際に、<span style="color: #ff0000;">&#x2665;</span>と<span style="color: #ff0000;">&#x2666;</span>のマークを<strong><span style="color: #ff0000;">赤色</span></strong>、&#x2660;と&#x2663;を<strong>黒色</strong>にするように表示します。</p>
<p>&nbsp;</p>
<p>（<strong>下記はかなり悩んだところなんですが。。。</strong>）</p>
<p><span style="color: #ff0000;"><span style="color: #000000;">Excel Vbaでは、</span> &#x2665;<span style="color: #000000;">&#x2660;</span></span><span style="color: #ff0000;">&#x2666;</span>&#x2663;という文字が<span style="color: #ff0000;"><strong>読み取れません。</strong></span></p>
<p>読み取ろうとすると「?」となってしまいます（Excel 2016ではそうなりました。。）。</p>
<p>ですので、今回の対策として、</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">Vbaでマークが読み取れないときの対策</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li><span style="color: #ff0000;"><span style="color: #000000;">Excel Vbaで値としては、</span>&#x2665;<span style="color: #000000;">&#x2660;</span></span><span style="color: #ff0000;">&#x2666;</span>&#x2663;ではなく別の文字に置き換える（「H」「S」「D」「C」のように）</li>
<li>表示の前に「作業用」シートに置き換える前の値を記述しておく</li>
<li>表示させるときのみ<span style="color: #ff0000;">&#x2665;<span style="color: #000000;">&#x2660;</span></span><span style="color: #ff0000;">&#x2666;</span>&#x2663;に置き換える（VLookup関数をつかって「トランプマスタ」シートから参照）</li>
<li>カードを裏返すときに、置き換える前の文字を入力するようにする</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h5>カード押下後の処理</h5>
<p>ここでは、カードが二枚クリックされたかを判定し、</p>
<p>判定した結果、同じ数字であるかそうでないかを比較し、同じならカードを削除します。</p>
<p>&nbsp;</p>
<p>判定方法は、「作業用シート」のB2、C2の値が両方空白かどうかで判定します。</p>
<p>両方とも値が含まれていれば、二枚クリックされたということです。</p>
<p>&nbsp;</p>
<p>数字の比較については、「作業用シート」のB2、C2の値を比較しますが、</p>
<p>このときカードのマーク無視するようにします（つまり一番最後の文字を無視して数字部分のみ判定します）。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)

' カード押下前の処理
Sub prepareCard(ByVal CardInfo, ByVal CardAddress)

    Dim firstCard
    Dim secondCard
    Dim firstPlace
    Dim secondPlace
        
    firstCard = Worksheets(WORK_SHEET).Range(FIRST_INFO_PLACE).Value
    secondCard = Worksheets(WORK_SHEET).Range(SECOND_INFO_PLACE).Value


    ' 1枚目が押下されたとき
    If firstCard = "" Then
        
        Worksheets(WORK_SHEET).Range(FIRST_INFO_PLACE).Value = CardInfo
        Worksheets(WORK_SHEET).Range(FIRST_CELL_PLACE).Value = CardAddress
        
    ' 2枚目が押下されたとき
    ElseIf secondCard = "" Then
    
        Worksheets(WORK_SHEET).Range(SECOND_INFO_PLACE).Value = CardInfo
        Worksheets(WORK_SHEET).Range(SECOND_CELL_PLACE).Value = CardAddress

    End If

End Sub

' カード押下時の処理
Sub openCard(ByRef CellValue)

    Dim inputValue
    Dim cardValueLast
    
    inputValue = ouputVlookup(CellValue)
    cardValueLast = Right(CellValue, 1)
    
    With CellValue
        .Value = inputValue
        .Borders.LineStyle = xlContinuous
        .Borders.Color = RGB(255, 0, 0)
        .Interior.ColorIndex = CARD_COLOR_WHITE
        
        If cardValueLast = "H" Or cardValueLast = "D" Then
            .Font.ColorIndex = CARD_COLOR_RED
        Else
            .Font.ColorIndex = CARD_COLOR_BLACK
        End If

    End With
              
End Sub

' カード押下後の処理
Sub pushCard(ByVal CardInfo, ByVal CardAddress)

    Dim firstCard
    Dim secondCard
    Dim firstPlace
    Dim secondPlace
        
    firstCard = Worksheets(WORK_SHEET).Range(FIRST_INFO_PLACE).Value
    secondCard = Worksheets(WORK_SHEET).Range(SECOND_INFO_PLACE).Value

    firstPlace = Worksheets(WORK_SHEET).Range(FIRST_CELL_PLACE).Value
    secondPlace = Worksheets(WORK_SHEET).Range(SECOND_CELL_PLACE).Value

    ' 1枚目が押下されたとき
    If secondCard &lt;&gt; "" Then
            
        Sleep WAIT_TIME
        
        ' カードが同じとき
        If Worksheets(WORK_SHEET).Range(JUDGE_PLACE).Value = 1 _
        And firstPlace &lt;&gt; secondPlace _
        Then
            
            Call deleteCard(firstPlace)
            Call deleteCard(secondPlace)

        ' カードが違うとき
        Else

            Call backCard(firstPlace, firstCard)
            Call backCard(secondPlace, secondCard)
                    
        End If
        
        ' 作業用シート 初期化
        Call setDefaultWorkSheet
        
    End If
   
End Sub


' 違うカードをもとに戻す（ひっくり返す）
Private Sub backCard(ByVal CardPlace, ByVal CardValue)

    Application.ScreenUpdating = False
    
    With Worksheets(MAIN_SHEET).Range(CardPlace)
        
        .Value = CardValue
        .ColumnWidth = CARD_HEIGHT
        .RowHeight = CARD_WIDTH
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Font.ColorIndex = CARD_COLOR_RED
        .Interior.ColorIndex = CARD_COLOR_RED
    
    End With
    
    Application.ScreenUpdating = True

End Sub

' 同じカードの場合削除する
Private Sub deleteCard(ByVal CardPlace)

    With Worksheets(MAIN_SHEET).Range(CardPlace)
        
        .ClearContents
        .ColumnWidth = CARD_HEIGHT
        .RowHeight = CARD_WIDTH
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Font.ColorIndex = CARD_COLOR_WHITE
        .Interior.ColorIndex = CARD_COLOR_WHITE
    
    End With

End Sub</pre>
&nbsp;</p>
<h4>ゲーム終了処理</h4>
<p>&nbsp;</p>
<p>ここでは、ゲーム終了処理に関する処理が含まれます。</p>
<p>ゲームが終了するパターンは主に2通りです。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">マーク読み取れない対策</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>神経衰弱のカードがすべてめくられて終わるパターン</li>
<li>「FIN」ボタンが押下されて終了するパターン</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>①のすべてカードがめくられたときの検知方法ですが、</p>
<p>二枚目のカードがクリックされた後に</p>
<p>作業用シートの「残り枚数」と記載のある個所（F2）が０になったときに終了するように処理します。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_6.png" alt="" width="1361" height="197" class="aligncenter size-full wp-image-4563" srcset="https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_6.png 1361w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_6-300x43.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_6-768x111.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/10/shikei_6-1024x148.png 1024w" sizes="auto, (max-width: 1361px) 100vw, 1361px" /></p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">'ゲーム終了処理
Sub finGame()
    
    Dim finFlag
    
    finFlag = Worksheets(WORK_SHEET).Range(REMAIN_CARD_NUM).Value
    
    If finFlag = 0 Then
    
        MsgBox MSG_FIN_GAME
        
        Worksheets(WORK_SHEET).Range(GAME_STATUS_PLACE).Value = MSG_GAME_END

    End If
    
End Sub

'ゲーム終了押下
Sub pushFinGame()
            
    Worksheets(WORK_SHEET).Range(GAME_STATUS_PLACE).Value = MSG_GAME_END
    
End Sub</pre>
&nbsp;</p>
<h4>定数定義</h4>
<p>&nbsp;</p>
<p>ここでは、Excel Vba で扱う定数についてまとめて定義しています。</p>
<p>シート名、カードを配置する箇所（盤上という表現で記載）などなどです。</p>
<p>（たぶん、ソースコード見たほうがはやいとおもいます。）</p>
<h5></h5>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' --- シート情報 ---

Public Const MAIN_SHEET As String = "神経衰弱"
Public Const MASTER_SHEET As String = "トランプマスタ"
Public Const WORK_SHEET As String = "作業用"


' --- 「神経衰弱」シート ---

' データの範囲 盤上の設定
Public Const BOARD_X As Integer = 3
Public Const BOARD_Y As Integer = 6

Public Const SET_NUM_MAIN_RANGE As String = "F3"
Public Const SET_KIGO_MAIN_RANGE As String = "L3"

' カード情報
Public Const CARD_HEIGHT As Integer = 5
Public Const CARD_WIDTH As Integer = 50
Public Const CARD_COLOR_RED As Integer = 3
Public Const CARD_COLOR_WHITE As Integer = 2
Public Const CARD_COLOR_BLACK As Integer = 1

' --- 「トランプマスタ」シート ---

Public Const MASTER_RANGE As String = "A2:B5"


' --- 「作業用」シート ---

' 残りカード枚数
Public Const REMAIN_CARD_NUM As String = "F2"

' 押下カードの情報
Public Const FIRST_INFO_PLACE As String = "B2"
Public Const SECOND_INFO_PLACE As String = "C2"

Public Const FIRST_CELL_PLACE As String = "B3"
Public Const SECOND_CELL_PLACE As String = "C3"

' カードが一致するか
Public Const JUDGE_PLACE As String = "D2"

' カードをもとに戻す時間
Public Const WAIT_TIME As Integer = 1000

' ゲームステータス確認
Public Const GAME_STATUS_PLACE As String = "H2"

' --- その他 ---

' 判定フラグ
Public Const PUSH_FIRST_CARD As Integer = 0
Public Const PUSH_SECOND_CARD_SAME As Integer = 1
Public Const PUSH_SECOND_CARD_DIFF As Integer = 2


' --- メッセージ ----

' ゲームステータス
Public Const MSG_GAME_START As String = "ゲーム中"
Public Const MSG_GAME_END As String = "ゲーム終了"

' ゲーム終了時
Public Const MSG_FIN_GAME As String = "お疲れ様でした！！ゲームを終了します！！"

' VLOOKUPの出力
Function ouputVlookup(ByVal Str)

    ouputVlookup = "=VLOOKUP(""" &amp; Str &amp; """,トランプマスタ!I:K,3,FALSE)"

End Function</pre>
&nbsp;</p>
<h4>配置カードを設定</h4>
<p>&nbsp;</p>
<p>ここでは「START」ボタン押下時にはじめにカードを配置する処理を記述しています。</p>
<p>大きくは setCard() プロシージャで処理を実装しています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">実装内容</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>何種類の数字をゲームをするか、「神経衰弱」シートの数字とマークの種類から決定</li>
<li>上記の情報から、使用する数字を決定</li>
<li>最終的に使うカードの種類を決定し、配列に格納</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>ちょっとわかりにくかったかもなので、補足します。</p>
<p>はじめに「神経衰弱」シートで「３種類」の数字と「４種類」のマークを使用するとします。</p>
<p>つぎに「３種類」の数字の中からどの数字にするか（1 ~ 10の中で）ランダムに選択します。</p>
<p>たとえば、1、４、９と使うとすると</p>
<p>１、４、９ ×　「４種類」のマーク<span style="color: #ff0000;">&#x2665;<span style="color: #000000;">&#x2660;</span></span><span style="color: #ff0000;">&#x2666;</span>&#x2663; = 12種類の文字列を作成し、配列に格納します。</p>
<p>そして最終的に配列をランダムにシャッフルし、その配列をシートに出力するということです。</p>
<p>※ ここでは、配列の生成のみで、シートへの出力は別の「盤上へカードを配置」で行います。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' ゲームで使うカードの設定
' 数字 + 記号を文字列を含む配列で返す

Function setCard() As String()

    Dim numArray
    Dim allCardArray
    Dim setCardNumber As Integer
    
    ' 何種類の数字をゲームをするか
    setCardNumber = Worksheets(MAIN_SHEET).Range(SET_NUM_MAIN_RANGE)
    
    ' 上記の種類のランダム数字で決定
    numArray = getCardArray(setCardNumber)
    
    ' 最終的に使うカードの種類を決定
    setCard = decideCardArray(numArray)
    
End Function

' 上記の種類のランダム数字で決定
Private Function getCardArray(ByRef Num As Integer) As String()

    Dim i As Long
    Dim myNum As Long
    Dim numArray() As String
    Dim myFlag(1 To 13) As Boolean

    '乱数系列を初期化
    Randomize
    
    For i = 1 To Num
        Do
            myNum = Int((13 - 1 + 1) * Rnd + 1)
        Loop Until myFlag(myNum) = False
        
        ReDim Preserve numArray(i - 1)
        numArray(i - 1) = myNum
        myFlag(myNum) = True
    Next i

    getCardArray = numArray

End Function


' 最終的に使うカードの種類を決定
Private Function decideCardArray(ByRef numArray) As String()
    
    Dim i As Integer: i = 0
    Dim sumArray() As String
    Dim kigoMaster: kigoMaster = Worksheets(MASTER_SHEET).Range(MASTER_RANGE)
    Dim kigoNum: kigoNum = Worksheets(MAIN_SHEET).Range(SET_KIGO_MAIN_RANGE)

    For Each Var In numArray
        
        ReDim Preserve sumArray(i)
        sumArray(i) = Var &amp; kigoMaster(1, 1)
        i = i + 1
        ReDim Preserve sumArray(i)
        sumArray(i) = Var &amp; kigoMaster(2, 1)
        i = i + 1
        
        If kigoNum = 4 Then
            ReDim Preserve sumArray(i)
            sumArray(i) = Var &amp; kigoMaster(3, 1)
            i = i + 1
            ReDim Preserve sumArray(i)
            sumArray(i) = Var &amp; kigoMaster(4, 1)
            i = i + 1
        End If
    
    Next Var

    decideCardArray = cardShuffle(sumArray)

End Function

' カードをシャッフル
Private Function cardShuffle(ByRef cardArray) As String()

    For i = 0 To UBound(cardArray)
        Randomize
        rn = Int(UBound(cardArray) * Rnd)
        tmp = cardArray(i)
        cardArray(i) = cardArray(rn)
        cardArray(rn) = tmp
    Next
    
    cardShuffle = cardArray

End Function</pre>
&nbsp;</p>
<h4>盤上へカードを配置</h4>
<p>&nbsp;</p>
<p>「配置カードを設定」で生成した配列をシートに表示させます。</p>
<p>&nbsp;</p>
<p>その表示の際に、カードの装飾も行っています。</p>
<p>カードの装飾とはつまりセルの配色を指します（たとえば、セルの値、罫線、背景色など）。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' 盤上へカードを配置
Sub setBorad(ByRef numArray)

    Dim X: X = 0
    Dim Y: Y = 0
    Dim j: j = 0
    
    Dim arraylength: arraylength = UBound(numArray) + 1
    
    Do
        ' カードの装飾
        Call paintCard(numArray(j), X + BOARD_X, Y + BOARD_Y)
        
        If X &gt;= 20 Then
            X = 0
            Y = Y + 2
        Else
            X = X + 2
        End If
        
        arraylength = arraylength - 1
        j = j + 1
    
    Loop Until arraylength = 0

End Sub

' カードの装飾
Private Sub paintCard(ByVal CardValue, ByVal X, ByVal Y)
 
    With Worksheets(MAIN_SHEET).Cells(Y, X)
        
        .Value = CardValue
        .ColumnWidth = CARD_HEIGHT
        .RowHeight = CARD_WIDTH
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Orientation = xlVertical
        .Font.Bold = True
        .Font.ColorIndex = CARD_COLOR_RED
        .Interior.ColorIndex = CARD_COLOR_RED

    End With

End Sub</pre>
&nbsp;</p>
<h2>まとめ</h2>
<p>&nbsp;</p>
<p>いかがでしょうか？</p>
<p>&nbsp;</p>
<p>Excel Vba があれば簡単に作れますでのよければぜひ作ってみてください！</p>
<p>※ 作成した Excel 「神経衰弱」は下記からダウンロードできます。よければぜひ遊んでみてください！</p>
<p>&nbsp;</p>
<div class="button frame block green">
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2019/10/shinkeisuijyaku.xlsm">Excel 「神経衰弱」をダウンロードする！！</a></div>
</div>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>エクセルで遊べる「まるばつゲーム」の作り方【Vba ゲーム】</title>
		<link>https://lemon818.com/marubatu_game/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Mon, 30 Sep 2019 14:16:46 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[pickup]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[まるばつゲーム]]></category>
		<category><![CDATA[エクセル]]></category>
		<category><![CDATA[ゲーム]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=4435</guid>

					<description><![CDATA[&#160; スーパー暇人プログラマー の Take です。 半年ぶり？ぐらいに Excel でゲームをつくりました。 それは、、、 小学校とかで友人とよくやった「あの〇と×を書くだけの究極の頭脳戦」である「まるばつゲー…]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p>スーパー暇人プログラマー の Take です。</p>
<p>半年ぶり？ぐらいに Excel でゲームをつくりました。</p>
<p>それは、、、</p>
<p>小学校とかで友人とよくやった「<strong>あの〇と×を書くだけの究極の頭脳戦</strong>」である「<span style="color: #ff0000;"><strong>まるばつゲーム</strong></span>」です！！！！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu_GIF.gif" alt="" width="509" height="437" class="aligncenter wp-image-4449" /></p>
<p>&nbsp;</p>
<p><span style="color: #0000ff;"><span style="color: #000000;">この記事をご覧の方の中には、</span><strong>懐かしすぎて涙が止まらない人</strong></span>もたくさんいるのではないでしょうか？</p>
<p>この記事では、「<strong>あの〇と×を書くだけの究極の頭脳戦</strong>」である「<span style="color: #ff0000;"><strong>まるばつゲーム</strong></span>」の遊び方と作成方法をご紹介します！！</p>
<p>※ もし「まるばつゲーム」が好きすぎて仕方ない人は、ぜひ下記ボタンからダウンロードしてやってみてください！</p>
<p>&nbsp;</p>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2019/10/marubatsu.xlsm">無料で「まるばつゲーム」をダウンロードする！！</a></div>
<p>&nbsp;</p>
<h2>遊び方</h2>
<p>まず「ゲーム開始」ボタンを押下します。</p>
<p>その後、下記画面の赤枠にクリックすると、自動で「〇」か「×」が入力されます。</p>
<p>※ 先行は「〇」後攻は「×」が入力されます。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu2.png" alt="" width="491" height="318" class="aligncenter wp-image-4448" srcset="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu2.png 540w, https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu2-300x194.png 300w" sizes="auto, (max-width: 491px) 100vw, 491px" /></p>
<p>&nbsp;</p>
<p>あとは、同じ記号（「〇」か「×」）が三つそろえば勝ちという</p>
<p><span style="color: #0000ff;"><strong>シンプル中のシンプルなまるばつゲーム</strong></span>するだけです。</p>
<p>勝敗が付いた時点でゲームが終了し、メッセージが表示されます。</p>
<p>※ 中断したい場合は「ゲーム終了」を押下してください。</p>
<h2>「まるばつゲーム」の作り方</h2>
<p>ここからプログラムの専門用語がでてきますので、よくわからない人も適当に眺めてください。</p>
<p>まず、Excel Vba という、Excel のプログラミング言語で作成します。</p>
<h3>定数定義</h3>
<p>シート情報、まるばつゲームのボード情報、その他メッセージ等をここで一括に登録しちゃいます。</p>
<h4>ソースコード</h4>
<pre class="crayon-plain-tag">' 定数定義

' シート名
Public Const MARUBATSU_SHEET As String = "marubatsu"

'メッセージの表示位置
Public Const X_MESSAGE As Integer = 14
Public Const Y_MESSAGE As Integer = 3


' ボードのセル番号
Public Const BOARD_X As Integer = 8
Public Const BOARD_Y As Integer = 4
Public Const BOARD_MAX As Integer = 2

' その他定数
Public Const MARU As String = "〇"
Public Const BATSU As String = "×"
Public Const START_MESSAGE As String = "ゲーム開始"
Public Const END_MESSAGE As String = "ゲーム終了"
Public Const WIN_MESSAGE As String = "の勝ち！！！"
Public Const DRAWN_MESSAGE As String = "引き分け！！！"</pre>
&nbsp;</p>
<h3>ボタンが押されたときに処理するマクロ</h3>
<p>Excel 上のシートにある「ゲーム開始」「ゲーム終了」ボタンが押されたときに処理するマクロの定義です。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu3.png" alt="" width="501" height="86" class="aligncenter wp-image-4451" srcset="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu3.png 541w, https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu3-300x52.png 300w" sizes="auto, (max-width: 501px) 100vw, 501px" /></p>
<p>ボタンごとにそれぞれ下記のように動作します。</p>
<div class="sc_frame_wrap block orange">
<div class="sc_frame_title">ボタンと処理が起動するマクロ</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>「ゲーム開始」 : startGame プロシージャ<br />
→ シートの初期化 + N列目に「ゲーム開始」メッセージ追加</li>
<li>「ゲーム終了」 : endGame プロシージャ<br />
→ N列目に「ゲーム終了」メッセージ追加</li>
</ol>
</div>
</div>
</div>
</div>
<div></div>
<div>実はこのマクロ、こっそり「<strong>非表示</strong>」セルがあります（N列目）。</div>
<div></div>
<div>ここで、ゲームが開始しているか、終了しているかを判断しています。</div>
<div></div>
<div>つまり「ゲーム開始」というメッセージがあればゲーム中、「ゲーム終了」とあれば、ゲーム終了となります。</div>
<div></div>
<div></div>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu4.png" alt="" width="616" height="379" class="aligncenter wp-image-4452" srcset="https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu4.png 799w, https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu4-300x184.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/09/marubatsu4-768x472.png 768w" sizes="auto, (max-width: 616px) 100vw, 616px" /></p>
<p>また、上記画面の「ゲーム開始」というメッセージの下に「0」という文字がありますが、</p>
<p>これは盤上の「〇と×」の数を示します。</p>
<p>※ 上記画面では、「〇と×」が「０」個のため、「０」と表示されています。</p>
<h4>ソースコード</h4>
<pre class="crayon-plain-tag">'まるばつゲーム 開始
Sub startGame()
    
    Call defaultSet

    setMsg (START_MESSAGE)

End Sub

'まるばつゲーム 終了
Sub endGame()
    
    setMsg (END_MESSAGE)

End Sub


' 初期設定
Private Sub defaultSet()
    
    Range(Cells(BOARD_Y, BOARD_X), Cells(BOARD_Y + 2, BOARD_X + 2)).ClearContents
    
End Sub


' メッセージの設定
Private Sub setMsg(Msg As String)

    Worksheets(MARUBATSU_SHEET).Cells(Y_MESSAGE, X_MESSAGE).Value = Msg
    Worksheets(MARUBATSU_SHEET).Cells(Y_MESSAGE + 1, X_MESSAGE).Value = 0
    
End Sub</pre>
&nbsp;</p>
<h3>マウスクリック等のシートの操作</h3>
<p>下記ソースコードで、ごちゃごちゃ書いていますが、処理はシンプルです。</p>
<div class="sc_frame_wrap block orange">
<div class="sc_frame_title">処理内容</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>選択したセルに「〇」か「×」を置く。<br />
→ クリック数が偶数なら「〇」、奇数なら「×」とする</li>
<li>勝敗が付いたかを確認<br />
→ 同じ記号（つまり「〇」か「×」）が縦、横、斜めに並んでいるか<br />
→ 3つ並んでいるか、勝敗が付かない（盤上すべてに記号が配置された）なら処理終了</li>
</ol>
</div>
</div>
</div>
</div>
<p>※ もしシート上のクリックをどうやって検知しているかわからない人は下記リンクをどうぞ！</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/excel-clickevent/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/10/5470d3ad4154f55e94757a88cf55ed08-150x150.png" width="150" height="150" alt="【Excel vba】マウスの左クリックのイベントを検知する簡単な方法"></div><div class="title">【Excel vba】マウスの左クリックのイベントを検知する簡単な方法</div><div class="date">2019.2.4</div><div class="substr">はじめに Excelで将棋のゲームをつくろうとしたときでした。 そういやどうやってマウスクリックを検知すればいいんやろう？ 私は仕事やブログでExcelを取り扱うことが多いですが、セルをクリックしたときにクリックしたことを検知しそこから処理を開始することがわかりませんでした。 いろいろ調べましたが、...</div></a></div>
<h4>ソースコード</h4>
<pre class="crayon-plain-tag">' シートの操作部分
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
 
    Dim NowCell
    Set NowCell = ActiveCell
    
    Dim Msg As String: Msg = Worksheets(MARUBATSU_SHEET).Cells(Y_MESSAGE, X_MESSAGE).Value
    
    If Msg = START_MESSAGE _
    And BOARD_Y &lt;= NowCell.Row _
    And NowCell.Row &lt;= BOARD_Y + BOARD_MAX _
    And BOARD_X &lt;= NowCell.Column _
    And NowCell.Column &lt;= BOARD_X + BOARD_MAX _
    Then
    
        With Worksheets(MARUBATSU_SHEET).Cells(NowCell.Row, NowCell.Column)
            If getCount Mod 2 = 0 Then
              .Value = MARU
            Else
              .Value = BATSU
            End If
        End With
        
        ' 〇×の数をカウント
        Call plusCount
        
        ' 勝敗チェック
        If checkGame(getCount) = True Then
        
            Dim Winner
            
            If getCount Mod 2 = 1 Then
              Winner = MARU
            Else
              Winner = BATSU
            End If
            
            MsgBox Winner &amp; WIN_MESSAGE
            Call endGame
        End If
        
        If getCount = 9 And checkGame(getCount) = False Then
            
            MsgBox DRAWN_MESSAGE
        
        End If
    
    End If
    
End Sub

' カウント設定
Private Sub plusCount()

    Worksheets(MARUBATSU_SHEET).Cells(Y_MESSAGE + 1, X_MESSAGE).Value _
        = Worksheets(MARUBATSU_SHEET).Cells(Y_MESSAGE + 1, X_MESSAGE).Value + 1
    
End Sub

' カウントを取得
Function getCount() As String

    getCount = Worksheets(MARUBATSU_SHEET).Cells(Y_MESSAGE + 1, X_MESSAGE).Value

End Function

' 値を取得
Function getValue(ByRef X, ByRef Y) As String

    getValue = Worksheets(MARUBATSU_SHEET).Cells(Y, X).Value

End Function

' 勝敗チェック
Function checkGame(num As String) As Boolean

    checkGame = False
    
    For Y = BOARD_Y To BOARD_Y + BOARD_MAX

        For X = BOARD_X To BOARD_X + BOARD_MAX
            
            If getValue(X, Y) = MARU _
            Or getValue(X, Y) = BATSU _
            Then
            
                Dim firstValue: firstValue = getValue(X, Y)
                
                If isSameValue(firstValue, X, X, Y + 1, Y + BOARD_MAX) = True _
                Or isSameValue(firstValue, X + 1, X + BOARD_MAX, Y, Y) = True _
                Or isSameValue(firstValue, X + 1, X + BOARD_MAX, Y + 1, Y + BOARD_MAX) = True _
                Or isSameValue(firstValue, X - 1, X - BOARD_MAX, Y + 1, Y + BOARD_MAX) = True _
                Then
                
                    checkGame = True
                    Exit For
                End If

            End If
                                     
            Next X
            
        If checkGame = True Then
            
            Exit For
        
        End If
    
    Next Y


End Function

' 指定の座標が同じ値か確認
Function isSameValue(ByRef Value, ByRef X1, _
                    ByRef X2, ByRef Y1, ByRef Y2) As Boolean

    If getValue(X1, Y1) = Value And getValue(X2, Y2) = Value _
    Then
    
        isSameValue = True
    End If

End Function</pre>
&nbsp;</p>
<h2>最後に</h2>
<p>いかがでしょうか？</p>
<p>私はこの「まるばつゲーム」をつくるのに一時間くらいかかりました。</p>
<p>たぶん、できる人はもっと早くできると思います。</p>
<p>&nbsp;</p>
<p>もし「〇と×の究極の頭脳戦」である「まるばつゲーム」を Excel でやりたくて仕方ない方がいましたら、</p>
<p>ぜひ下記ボタンからダウンロードしてやってみてください！</p>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2019/10/marubatsu.xlsm">無料で「まるばつゲーム」をダウンロードする！！</a></div>
<div></div>
<div>ではでは。</div>
<div></div>
<div><span></span></div>
<div></div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>エクセルで遊べるテトリスの作り方【Vba ゲーム】</title>
		<link>https://lemon818.com/excel-tetoris/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Wed, 20 Feb 2019 12:12:17 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[pickup]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[ゲーム]]></category>
		<category><![CDATA[テトリス]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=3830</guid>

					<description><![CDATA[エクセルでテトリスを作りました！！ &#160; 前からつくってみたいなあと思っていたゲームの一つで、これもなかなか時間がかかりました。 仕事終わってからだらだら作っていたら一週間くらいかかりました（工数はだいたい１人日…]]></description>
										<content:encoded><![CDATA[<p><span style="color: #ff6600;"><strong>エクセルでテトリスを作りました！！</strong></span></p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/tetoriasu.gif" alt="" width="474" height="470" class="aligncenter wp-image-4465" /></p>
<p>&nbsp;</p>
<p>前からつくってみたいなあと思っていたゲームの一つで、これもなかなか時間がかかりました。</p>
<p>仕事終わってからだらだら作っていたら一週間くらいかかりました（工数はだいたい１人日～２人日くらい）。</p>
<p>&nbsp;</p>
<p>ですが、思ったより簡単に作れました。エクセルで過去にオセロや将棋などつくりましたが、</p>
<p>毎回思うことがゲーム作りに必要なものは<span style="color: #ff6600;"><strong>根気</strong></span>と<span style="color: #ff6600;"><strong>気合</strong></span>です。</p>
<p>&nbsp;</p>
<p>この記事では、作成したテトリスについて、その操作方法と作成方法についてご紹介します。</p>
<p>※ 作成方法したエクセルのテトリスについては下記からダウンロード可能ですので、ぜひ遊んでみてください。</p>
<p>&nbsp;</p>
<div class="button frame block blue"><a href="https://lemon818.com/wp/wp-content/uploads/2019/02/tetoris.xlsm" class="midium">エクセルのテトリスをダウンロードする</a></div>
<h2>操作方法</h2>
<p>作成したテトリスの操作方法について説明します。</p>
<p>&nbsp;</p>
<h3>ゲームの開始と終了</h3>
<p>&nbsp;</p>
<p>テトリスを開始するときは「START」ボタンをクリックしますが、ゲームを終了する場合はキーボードの「Home」キーを押下します。</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">ゲームの開始と終了</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>「Start」ボタン : テトリスの開始</li>
<li>キーボードの「Home」 : テトリスの終了</li>
</ol>
</div>
</div>
</div>
</div>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-2.png" alt="" width="627" height="549" class="aligncenter wp-image-3846" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-2.png 801w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-2-300x263.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-2-768x672.png 768w" sizes="auto, (max-width: 627px) 100vw, 627px" /></p>
<h3>キーボード操作</h3>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">操作方法</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>「←」「↑」「↓」「→」キー : ブロックの移動</li>
<li>「Ctrl」キー : ブロックの回転</li>
<li>「Home」キー : テトリスの終了</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>後は、いつものテトリスです。ブロックを一行そろえて消すだけです。</p>
<p>またテトリスには、一行ずつ消すよりもまとめて消したほうがお得というルールがありますね。今回それを下記式で表しています。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame ">
<div class="sc_frame_text">Score = Score + 100 + [消した行の数] * 300</div>
</div>
</div>
<p>&nbsp;</p>
<p>テトリスを作った割にテトリスのポイントのつけ方がよくわからなかったので、こんな感じで付けました。</p>
<p>Score とは点数のことで、「Score = Score + ~ 」とは、もともとの Score の値にどんどん足していきますよということです。</p>
<p>例えば削除した行が１行なら Score = 400点、2行なら700点つきます（答えを知っている人は教えてほしいです）。</p>
<p>&nbsp;</p>
<h3>終了条件</h3>
<p>&nbsp;</p>
<p>前述しましたがゲームを終了する場合はキーボードの「Home」キーを押下しますが、それ以外にもテトリスが続行できない場合も終了するようにしています。</p>
<p>要はブロックが天井を突き抜けた状態です。このときは強制的にテトリスが終了します。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3.png" alt="" width="664" height="513" class="aligncenter wp-image-3847" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3.png 806w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3-300x232.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3-768x594.png 768w" sizes="auto, (max-width: 664px) 100vw, 664px" /></p>
<h2>作成方法</h2>
<p>&nbsp;</p>
<p>Excel vba で作成しています。要はプログラミングして作成しました。</p>
<p>実際のテトリスの作成手順は下記の５つになります。<span style="color: #ff6600;"><strong>この５つができればテトリスは作れます。</strong></span></p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">作成手順</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>下準備（定数と変数の定義 &amp; レイアウトの作成）</li>
<li>ブロックを描く</li>
<li>ブロックの移動、回転</li>
<li>ブロックが一行並べば消す</li>
<li>テトリスの終了条件をつける</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>これだけみれば、「案外簡単そうだなあ」と思われる人もいるかもしれませんが、案外めんどくさいです。</p>
<p>特にめんどくさいのが、ブロックの移動、回転の処理です。では順をおって説明します。</p>
<p>&nbsp;</p>
<h3>メイン関数</h3>
<p>&nbsp;</p>
<p>作成したテトリスのメイン関数です。</p>
<p>処理概要を説明しますと、まず定数、変数の定義とレイアウト作成などの下準備を行います。</p>
<p>その後 Do While True ~ をつかって無限ループさせ、ブロックを落とすようにします。</p>
<p>その無限ループの処理の中で下記の処理を行います。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame_title">無限ループ内処理</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>0.3 秒ごとに一行したにブロックが移動</li>
<li>その0.3秒のうちの0.1秒ごとにキーボードのイベントを取得</li>
<li>ブロックが一番下までいけば、一行そろっているブロックがあるか確認し、あれば消してスコアをつける</li>
<li>その後、ブロックが天井より上かどうか確認（ゲームオーバーであるか）</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>これだけです。天井という言い方が正しいかはわかりませんが、</p>
<p>ブロックが指定したセルの行よりあれば終了するようにしています（先ほど貼ったやつです）。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3.png" alt="" width="591" height="457" class="aligncenter wp-image-3847" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3.png 806w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3-300x232.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-3-768x594.png 768w" sizes="auto, (max-width: 591px) 100vw, 591px" /></p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">'メイン
Sub Tetris()
    
    Dim x As Integer
    Dim y As Integer
    Dim n As Integer
    Dim i As Integer
    Dim Block As Integer: Block = 0
    Dim Next_Block As Integer: Next_Block = 0
    
    ' 初期化
    Call setting(x, y)
    
    Do While True
        x = START_X
        y = START_Y
        ROTATE_NUM = 0
        
        Call setBlock(Block, Next_Block)
    
        For y = START_Y To BOTTOM_Y
            For n = 1 To 3
                Call setEvent(x, y, Block)
                Application.Wait [Now() +  "00:00:00.10"]
            Next n
            
            ' ブロックを移動できない状態ならブロックを削除
            If DropBlock(x, y, Block) = False Then
                Call checkRowBlock
                Exit For
            End If
        Next y
        Call checkgame
    Loop
    
End Sub</pre>
&nbsp;</p>
<p>次にメイン関数の処理をプロシージャにわけて説明します。</p>
<p>&nbsp;</p>
<h3>下準備（定数と変数の定義 &amp; レイアウトの作成）</h3>
<p>&nbsp;</p>
<h4>定数と変数の定義</h4>
<p>&nbsp;</p>
<p>まず初めに定数と変数の定義します。</p>
<p>記事作成での都合上、最初に定数と変数の定義を最初にきていますが、プログラミングをしている段階では、必要なたびにどんどん定義しています（当たり前ですが、）。</p>
<p>&nbsp;</p>
<p>定数については、レイアウトの位置情報（何行何列目のセルに描くか）とブロックの色について定義づけしています（固定なので）。</p>
<p>また、変数については、ブロックの先頭セルと、テトリスのスコア、ブロックの回転数について定義しています。これらは後で説明しますのでいまは適当に流していただいて問題ありません。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">'シート名
Public Const TETRIS_SHEET As String = "Tetris"

'テトリス位置
Public Const BOTTOM_Y As Integer = 27
Public Const BOTTOM_X_LEFT As Integer = 3
Public Const BOTTOM_X_RIGHT As Integer = 15
Public Const START_X As Integer = 8
Public Const START_Y As Integer = 4

'ブロックの先頭位置
Public TOP_X_L As Integer
Public TOP_X_R As Integer
Public TOP_Y As Integer

'ブロックの先頭位置
Public Const NEXT_START_X As Integer = 23
Public Const NEXT_START_Y As Integer = 7

' スコア
Public Const SCORE_POSITION_X As Integer = 24
Public Const SCORE_POSITION_Y As Integer = 12
Public Score As Integer

' 回転数
Public ROTATE_NUM As Integer

'色の定義 0 → 白 | 1 → 黒
Public Const NO_COLOR As Integer = 0
Public Const BLOCK1_COLOR As Integer = 3
Public Const BLOCK2_COLOR As Integer = 8
Public Const BLOCK3_COLOR As Integer = 5
Public Const BLOCK4_COLOR As Integer = 50
Public Const BLOCK5_COLOR As Integer = 46
Public Const BLOCK6_COLOR As Integer = 29
Public Const BLOCK7_COLOR As Integer = 27</pre>
&nbsp;</p>
<h4>テトリスのレイアウト</h4>
<p>テトリスの枠のレイアウトを vba で書くようにします。</p>
<p>これはもし間違えてシート上のセルを消してしまった場合も問題ないようにするためです。</p>
<p>作成するレイアウトは、下記画像の<span style="color: #3366ff;"><strong>青矢印</strong></span>の箇所（テトリスの周りのブロックと、次のテトリスを表示させる黒枠の箇所）です。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-4.png" alt="" width="456" height="370" class="aligncenter wp-image-3852" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-4.png 687w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-4-300x244.png 300w" sizes="auto, (max-width: 456px) 100vw, 456px" /></p>
<p>&nbsp;</p>
<p>また、もともとブロックが描いてある場合もいったん消してきれいにするようにしています。</p>
<p>下記はソースコードですが、setting プロシージャがメイン関数で、その中に ①テトリスの周りのブロックと、②次のテトリスを表示させる黒枠の箇所のレイアウトの設定を行っています。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Option Explicit

' 初期化
Sub setting(ByRef x As Integer, ByRef y As Integer)

    x = START_X
    y = START_Y
    Score = 0
    ROTATE_NUM = 0
    
    Application.ScreenUpdating = False
    
    Call settingTetris

    Call settingNextBlock
    
    Worksheets(TETRIS_SHEET).Cells(SCORE_POSITION_Y, SCORE_POSITION_X).Value = Score

End Sub

Private Sub settingTetris()

    Application.ScreenUpdating = False
    
    With Worksheets(TETRIS_SHEET).Range(Cells(START_Y, BOTTOM_X_LEFT), Cells(BOTTOM_Y, BOTTOM_X_LEFT))
        .Interior.color = RGB(192, 192, 192)
        .Borders.LineStyle = xlContinuous
    End With
    
    With Worksheets(TETRIS_SHEET).Range(Cells(START_Y, BOTTOM_X_RIGHT), Cells(BOTTOM_Y, BOTTOM_X_RIGHT))
        .Interior.color = RGB(192, 192, 192)
        .Borders.LineStyle = xlContinuous
    End With

    With Worksheets(TETRIS_SHEET).Range(Cells(BOTTOM_Y, BOTTOM_X_LEFT), Cells(BOTTOM_Y, BOTTOM_X_RIGHT))
        .Interior.color = RGB(192, 192, 192)
        .Borders.LineStyle = xlContinuous
    End With

    Worksheets(TETRIS_SHEET).Range(Cells(1, BOTTOM_X_LEFT + 1), Cells(BOTTOM_Y - 1, BOTTOM_X_RIGHT - 1)).ClearFormats
    
    Application.ScreenUpdating = True

End Sub

Sub settingNextBlock()

    Application.ScreenUpdating = False
    
    Worksheets(TETRIS_SHEET).Range(Cells(START_Y + 1, NEXT_START_X - 1), Cells(START_Y + 4, NEXT_START_X + 3)).ClearFormats
    
    Application.ScreenUpdating = True
    
End Sub</pre>
&nbsp;</p>
<h3>ブロックを描く</h3>
<p>&nbsp;</p>
<p>テトリスのブロックは下記の７種類あるそうです。なので、これを描くようにします。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-5.png" alt="" width="522" height="116" class="aligncenter wp-image-3861" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-5.png 624w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-5-300x67.png 300w" sizes="auto, (max-width: 522px) 100vw, 522px" /></p>
<p>&nbsp;</p>
<p>今回これらのブロックに名前をつけています。左から１、２ .... ７という数値をつけそれを Block という変数にもたせるようにしています。</p>
<p>ブロックの描き方についてはただセルに色と枠線をつけるだけです。</p>
<p>また、セルに入れる処理を毎回書くのが面倒だったので、paintColor プロシージャにまとめ、座標情報（何行何列目に入力するか）のみで描けるようにしてあります。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Option Explicit

' ランダムにブロックを取得
Sub getRandBlock(ByVal x As Integer, ByVal y As Integer, ByRef Block As Integer)
    
    Select Case Block
        Case 1
            Call makeBlock1(x, y)
        Case 2
            Call makeBlock2(x, y)
        Case 3
            Call makeBlock3(x, y)
        Case 4
            Call makeBlock4(x, y)
        Case 5
            Call makeBlock5(x, y)
        Case 6
            Call makeBlock6(x, y)
        Case 7
            Call makeBlock7(x, y)
    End Select

    Call setTopPlace(x, y, Block)

End Sub

' 正方形　ブロック作成
Private Sub makeBlock1(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK1_COLOR
    
    Call paintColor(color, x + 1, y)
    Call paintColor(color, x + 2, y)
    Call paintColor(color, x + 1, y - 1)
    Call paintColor(color, x + 2, y - 1)
    
End Sub

' 長方形　ブロック作成
Private Sub makeBlock2(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK2_COLOR
    
    If ROTATE_NUM = 0 Then
        Call paintColor(color, x + 2, y)
        Call paintColor(color, x + 2, y - 1)
        Call paintColor(color, x + 2, y - 2)
        Call paintColor(color, x + 2, y - 3)
    Else
        Call paintColor(color, x, y - 2)
        Call paintColor(color, x + 1, y - 2)
        Call paintColor(color, x + 2, y - 2)
        Call paintColor(color, x + 3, y - 2)
    End If
    
End Sub

' L字　ブロック作成
Private Sub makeBlock3(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK3_COLOR
    
    If ROTATE_NUM = 1 Then
        Call paintColor(color, x, y)
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x, y - 2)
        Call paintColor(color, x + 1, y - 2)
    ElseIf ROTATE_NUM = 2 Then
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 2, y - 1)
        Call paintColor(color, x + 2, y)
    ElseIf ROTATE_NUM = 3 Then
        Call paintColor(color, x, y)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 1, y - 2)
    Else
        Call paintColor(color, x, y)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 2, y)
        Call paintColor(color, x, y - 1)
    End If
    
End Sub

' 逆L字　ブロック作成
Private Sub makeBlock4(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK4_COLOR
    
    If ROTATE_NUM = 1 Then
        Call paintColor(color, x, y)
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x, y - 2)
        Call paintColor(color, x + 1, y)
    ElseIf ROTATE_NUM = 2 Then
        Call paintColor(color, x, y)
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 2, y - 1)
    ElseIf ROTATE_NUM = 3 Then
        Call paintColor(color, x, y - 2)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 1, y - 2)
    Else
        Call paintColor(color, x, y)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 2, y)
        Call paintColor(color, x + 2, y - 1)
    End If
    
End Sub

' 山　ブロック作成
Private Sub makeBlock5(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK5_COLOR
    
    If ROTATE_NUM = 1 Then
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 1, y - 2)
        Call paintColor(color, x + 2, y - 1)
    ElseIf ROTATE_NUM = 2 Then
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 2, y - 1)
        Call paintColor(color, x + 1, y)
    ElseIf ROTATE_NUM = 3 Then
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 1, y - 2)
    Else
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 1, y - 2)
        Call paintColor(color, x + 2, y - 1)
    End If
    
End Sub

' Z字　ブロック作成
Private Sub makeBlock6(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK6_COLOR
    
    If ROTATE_NUM = 1 Then
        Call paintColor(color, x, y)
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 1, y - 2)
    Else
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 2, y)
    End If
    
End Sub

' 逆Z字　ブロック作成
Private Sub makeBlock7(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = BLOCK7_COLOR
    
    If ROTATE_NUM = 1 Then
        Call paintColor(color, x, y - 1)
        Call paintColor(color, x, y - 2)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
    Else
        Call paintColor(color, x, y)
        Call paintColor(color, x + 1, y)
        Call paintColor(color, x + 1, y - 1)
        Call paintColor(color, x + 2, y - 1)
    End If
    
End Sub

' セルの色つける
Private Sub paintColor(ByVal color As Integer, ByVal x As Integer, ByVal y As Integer)

    Application.ScreenUpdating = False
    
    With Worksheets(TETRIS_SHEET).Cells(y, x)
        .Borders.LineStyle = xlContinuous
        .Interior.ColorIndex = color
    End With
    Application.ScreenUpdating = True
    
End Sub</pre>
そしてブロックを描く機能をつくれば、今度はそのブロックをランダムに取得するようにします。</p>
<p>具体的には 1 ~ 7 のうちのランダムな数値を取得し、取得した値からブロックを生成するようにします。</p>
<p>例えば 3 という数値が取得したらブロック３を出力するようにします。</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' 落とすブロックのセット
Private Sub setBlock(ByRef Block As Integer, ByRef Next_Block As Integer)
        
    Randomize
    
    Call settingNextBlock

    If Block = 0 Then
        Block = Int(7 * Rnd + 1)
    Else
        Block = Next_Block
    End If

    Next_Block = Int(7 * Rnd + 1)
    
    Select Case Next_Block
        Case 1
            Call getRandBlock(NEXT_START_X - 1, NEXT_START_Y, Next_Block)
        Case 2
            Call getRandBlock(NEXT_START_X - 1, NEXT_START_Y + 1, Next_Block)
        Case 5
            Call getRandBlock(NEXT_START_X, NEXT_START_Y + 1, Next_Block)
        Case Else
            Call getRandBlock(NEXT_START_X, NEXT_START_Y, Next_Block)
    End Select
    
    Call getRandBlock(START_X, START_Y, Block)
    
End Sub</pre>
&nbsp;</p>
<p>またブロックの削除処理もつくっています。</p>
<p>これはブロックを移動させるときに必要な処理です（後で説明します）。</p>
<p>ブロックの削除の仕方ですが、簡単に指定した行と列の書式を削除しているだけです。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Option Explicit

' ランダムにブロックを取得
Sub deleteRandBlock(ByVal x As Integer, ByVal y As Integer, ByRef Block As Integer)
    
    Select Case Block
        Case 1
            Call deleteBlock1(x, y)
        Case 2
            Call deleteBlock2(x, y)
        Case 3
            Call deleteBlock3(x, y)
        Case 4
            Call deleteBlock4(x, y)
        Case 5
            Call deleteBlock5(x, y)
        Case 6
            Call deleteBlock6(x, y)
        Case 7
            Call deleteBlock7(x, y)
    End Select

End Sub

' 正方形　ブロック削除
Private Sub deleteBlock1(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 3
    
    Call deleteFormat(x + 1, y)
    Call deleteFormat(x + 2, y)
    Call deleteFormat(x + 1, y - 1)
    Call deleteFormat(x + 2, y - 1)
    
End Sub

' 長方形　ブロック削除
Private Sub deleteBlock2(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 8
    
    If ROTATE_NUM = 0 Then
        Call deleteFormat(x + 2, y)
        Call deleteFormat(x + 2, y - 1)
        Call deleteFormat(x + 2, y - 2)
        Call deleteFormat(x + 2, y - 3)
    Else
        Call deleteFormat(x, y - 2)
        Call deleteFormat(x + 1, y - 2)
        Call deleteFormat(x + 2, y - 2)
        Call deleteFormat(x + 3, y - 2)
    End If
    
End Sub

' L字　ブロック削除
Private Sub deleteBlock3(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 5
    
    If ROTATE_NUM = 1 Then
        Call deleteFormat(x, y)
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x, y - 2)
        Call deleteFormat(x + 1, y - 2)
    ElseIf ROTATE_NUM = 2 Then
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 2, y - 1)
        Call deleteFormat(x + 2, y)
    ElseIf ROTATE_NUM = 3 Then
        Call deleteFormat(x, y)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 1, y - 2)
    Else
        Call deleteFormat(x, y)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 2, y)
        Call deleteFormat(x, y - 1)
    End If
    
End Sub

' 逆L字　ブロック削除
Private Sub deleteBlock4(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 50
    
    If ROTATE_NUM = 1 Then
        Call deleteFormat(x, y)
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x, y - 2)
        Call deleteFormat(x + 1, y)
    ElseIf ROTATE_NUM = 2 Then
        Call deleteFormat(x, y)
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 2, y - 1)
    ElseIf ROTATE_NUM = 3 Then
        Call deleteFormat(x, y - 2)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 1, y - 2)
    Else
        Call deleteFormat(x, y)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 2, y)
        Call deleteFormat(x + 2, y - 1)
    End If
    
End Sub

' 山　ブロック削除
Private Sub deleteBlock5(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 46
    
    If ROTATE_NUM = 1 Then
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 1, y - 2)
        Call deleteFormat(x + 2, y - 1)
    ElseIf ROTATE_NUM = 2 Then
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 2, y - 1)
        Call deleteFormat(x + 1, y)
    ElseIf ROTATE_NUM = 3 Then
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 1, y - 2)
    Else
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 1, y - 2)
        Call deleteFormat(x + 2, y - 1)
    End If
    
End Sub

' Z字　ブロック削除
Private Sub deleteBlock6(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 29
    
    If ROTATE_NUM = 1 Then
        Call deleteFormat(x, y)
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 1, y - 2)
    Else
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 2, y)
    End If
    
End Sub

' 逆Z字　ブロック削除
Private Sub deleteBlock7(ByVal x As Integer, ByVal y As Integer)
    
    Const color As Integer = 27
    
    If ROTATE_NUM = 1 Then
        Call deleteFormat(x, y - 1)
        Call deleteFormat(x, y - 2)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
    Else
        Call deleteFormat(x, y)
        Call deleteFormat(x + 1, y)
        Call deleteFormat(x + 1, y - 1)
        Call deleteFormat(x + 2, y - 1)
    End If
    
End Sub

' セルの書式の削除
Private Sub deleteFormat(ByVal x As Integer, ByVal y As Integer)
    
    Application.ScreenUpdating = False
    With Worksheets(TETRIS_SHEET).Cells(y, x)
        .ClearFormats
    End With
    Application.ScreenUpdating = True
End Sub</pre>
&nbsp;</p>
<h3>ブロックの移動、回転</h3>
<p>&nbsp;</p>
<p>ブロックの移動は「←」「↑」「↓」「→」のキーボード入力で行っています。</p>
<p>「←」「↑」「↓」「→」のキーボード入力のイベントを検知したときに、下記プロシージャが呼び出されるようにしてあります。</p>
<p>ブロックの移動についてですが、移動前のブロックの書式を削除→次のブロックに色をつけるというふたつの処理を行っています。</p>
<p>前章「ブロックを描く」で説明しました、「ブロックを描く」処理と「ブロックを削除」処理の二つを呼び出して処理させています。</p>
<p>またブロックを移動させるときの注意点は<span style="color: #ff6600;"><strong>移動範囲</strong></span>です。</p>
<p>当然ですがブロックが壁を貫いたり、底を突き抜けて動いていたら<strong>テトリスになりません。</strong></p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-6.png" alt="" width="259" height="449" class="aligncenter wp-image-3862" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-6.png 425w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-6-173x300.png 173w" sizes="auto, (max-width: 259px) 100vw, 259px" /></p>
<p>&nbsp;</p>
<p>ですので今回はブロックごとに<strong>先頭セル</strong>をもたせてあり、<strong>先頭セル</strong>の次の行ももしくは列のセルの色が白色（背景色）でならブロックが移動できるようにしています。</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Option Explicit

#If VBA7 Then
'32bit PC
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal ms As Long)
Private Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Long
#Else
'64bit PC
Private Declare PtrSafe Sub Sleep Lib "kernel32.dll" (ByVal ms As LongPtr)
Private Declare PtrSafe Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As LongPtr) As Long
#End If

' キーボードイベント検知
Sub setEvent(ByRef x As Integer, ByRef y As Integer, ByRef Block As Integer)
    ' 左矢印
    If GetAsyncKeyState(vbKeyLeft) &lt;&gt; 0 Then
        Call moveLeft(x, y, Block)
    End If
    ' 右矢印
    If GetAsyncKeyState(vbKeyRight) &lt;&gt; 0 Then
        Call moveRight(x, y, Block)
    End If
    ' 下矢印
    If GetAsyncKeyState(vbKeyDown) &lt;&gt; 0 Then
        Call moveDown(x, y, Block)
    End If
    ' Ctrl 回転
    If GetAsyncKeyState(vbKeyControl) &lt;&gt; 0 Then
        Call rotateBlock(x, y, Block)
    End If
    ' Homeボタン 終了
    If GetAsyncKeyState(vbKeyHome) &lt;&gt; 0 Then
        MsgBox "Game Fin!" &amp; Chr(13) &amp; "Score : " &amp; Score
        End
    End If
End Sub

' 右に移動
Private Sub moveRight(ByRef x As Integer, ByRef y As Integer, ByRef Block As Integer)
    
    If TOP_X_R &lt;= BOTTOM_X_RIGHT And checkColor_Right(TOP_X_R, y, Block) = True Then
        Call deleteRandBlock(x, y, Block)
        x = x + 1
        Call getRandBlock(x, y, Block)
    End If
End Sub

' 左に移動
Private Sub moveLeft(ByRef x As Integer, ByRef y As Integer, ByRef Block As Integer)
    
    If TOP_X_L &gt; BOTTOM_X_LEFT And checkColor_Left(TOP_X_L, y, Block) = True Then
        Call deleteRandBlock(x, y, Block)
        x = x - 1
        Call getRandBlock(x, y, Block)
    End If
End Sub

' 下に移動
Private Sub moveDown(ByRef x As Integer, ByRef y As Integer, ByRef Block As Integer)
    
    If TOP_Y &lt; BOTTOM_Y And checkColor_Down(x, TOP_Y, Block) = True Then
        Call deleteRandBlock(x, y, Block)
        y = y + 1
        Call getRandBlock(x, y, Block)
    End If
End Sub

' 自然にブロックが落ちる動き
Function DropBlock(ByRef x As Integer, ByRef y As Integer, ByRef Block As Integer) As Boolean

    If TOP_Y &lt; BOTTOM_Y And checkColor_Down(TOP_X_R, TOP_Y, Block) = True Then
        Call deleteRandBlock(x, y, Block)
        Call getRandBlock(x, y + 1, Block)
        DropBlock = True
    Else
        DropBlock = False
    End If

    
End Function

' 隣の色の確認 置ける箇所ならTrue 左方向
Function checkColor_Left(ByVal x As Integer, ByVal y As Integer, ByRef Block As Integer) As Boolean

    checkColor_Left = False
    
    Select Case Block
        Case 1
            If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
            And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
            Then
                checkColor_Left = True
            End If
        Case 2
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 2) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 3) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    Then
                        checkColor_Left = True
                    End If
            End Select
        Case 3
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_L + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
            End Select
        Case 4
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
            End Select
        Case 5
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
            End Select
        Case 6
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
            End Select
        Case 7
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_L, TOP_Y - 1) = True _
                    Then
                        checkColor_Left = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Left = True
                    End If
            End Select
    End Select

End Function

' 隣の色の確認 置ける箇所ならTrue 右方向
Function checkColor_Right(ByVal x As Integer, ByVal y As Integer, ByRef Block As Integer) As Boolean

    checkColor_Right = False
    
    Select Case Block
        Case 1
            If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
            And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
            Then
                checkColor_Right = True
            End If
        Case 2
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 2) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 3) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    Then
                        checkColor_Right = True
                    End If
            End Select
        Case 3
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R - 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_R, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
            End Select
        Case 4
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_R - 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
            End Select
        Case 5
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_R, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_R, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
            End Select
        Case 6
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_R, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_R, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
            End Select
        Case 7
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_R, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    Then
                        checkColor_Right = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_R + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R + 1, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 2) = True _
                    Then
                        checkColor_Right = True
                    End If
            End Select
    End Select

End Function


' 隣の色の確認 置ける箇所ならTrue 下方向
Function checkColor_Down(ByVal x As Integer, ByVal y As Integer, ByRef Block As Integer) As Boolean

    checkColor_Down = False
    
    Select Case Block
        Case 1
            If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
            And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
            Then
                checkColor_Down = True
            End If
        Case 2
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 2, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
            End Select
        Case 3
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y - 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
            End Select
        Case 4
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_L, TOP_Y - 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
            End Select
        Case 5
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 2
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 3
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
            End Select
        Case 6
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y) = True _
                    Then
                        checkColor_Down = True
                    End If
            End Select
        Case 7
            Select Case ROTATE_NUM
                Case 0
                    If checkNoColor(TOP_X_L, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_L + 1, TOP_Y + 1) = True _
                    And checkNoColor(TOP_X_R, TOP_Y) = True _
                    Then
                        checkColor_Down = True
                    End If
                Case 1
                    If checkNoColor(TOP_X_L, TOP_Y) = True _
                    And checkNoColor(TOP_X_R, TOP_Y + 1) = True _
                    Then
                        checkColor_Down = True
                    End If
            End Select
    End Select

End Function

' 指定セルの色がデフォルトの色か デフォルトの色ならTrue
Public Function checkNoColor(ByVal x As Integer, ByVal y As Integer) As Boolean
    
    Dim color
    
    color = Worksheets(TETRIS_SHEET).Cells(y, x).Interior.color
    
    If color = RGB(255, 255, 255) Then
        checkNoColor = True
    Else
        checkNoColor = False
    End If

End Function</pre>
&nbsp;</p>
<p>つぎにブロックの回転ですが（これ結構悩んだんですが）一番早いのがブロックごとにパターンをつくってセルに描くことです。</p>
<p>順に説明しますと、ブロックの回転は「Ctrl」キーで回転するようにしていますが、</p>
<p>その「Ctrl」キーの入力イベントを検知した後、「Ctrl」キーが押された回数を変数 ROTATE_NUM にもたせます。</p>
<p>&nbsp;</p>
<p>例えば「Ctrl」キーが２回入力されれば ROTATE_NUM = 2となります。そして、ブロック名が「2」で ROTATE_NUM = 2 なら「こう描く！」と決めておきます。</p>
<p>※具体的には下記表のようにパターン化します。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-8.png" alt="" width="321" height="486" class="aligncenter wp-image-3865" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-8.png 419w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-8-198x300.png 198w" sizes="auto, (max-width: 321px) 100vw, 321px" /></p>
<p>&nbsp;</p>
<p>あとは上記表の組み合わせをガリガリ書くだけです（これが書き間違えなどあって大変でしたね、、、）。</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Option Explicit

' ブロック 回転
Sub rotateBlock(ByRef x As Integer, ByRef y As Integer, ByRef Block As Integer)
    
    Dim tmp_ROTATE_NUM
    
    Call deleteRandBlock(x, y, Block)
    
    Select Case Block
        Case 2, 6, 7
            If ROTATE_NUM = 0 Then
                tmp_ROTATE_NUM = ROTATE_NUM + 1
            Else
                tmp_ROTATE_NUM = 0
            End If
        Case 3, 4, 5
            If ROTATE_NUM &lt;&gt; 3 Then
                tmp_ROTATE_NUM = ROTATE_NUM + 1
            Else
                tmp_ROTATE_NUM = 0
            End If
    End Select
    
    ' 回転できるか確認
    If checkRotateBlock(x, y, Block) = True Then
        
        ' 端っこで回転させる場合、ブロックをずらす
        If Block = 2 And TOP_X_R = BOTTOM_X_RIGHT - 1 And ROTATE_NUM = 0 Then x = BOTTOM_X_RIGHT - 4
        If Block = 2 And TOP_X_R &lt;= BOTTOM_X_LEFT + 2 And ROTATE_NUM = 0 Then x = BOTTOM_X_LEFT + 1
        If Block = 3 And TOP_X_R = BOTTOM_X_RIGHT - 1 And ROTATE_NUM = 1 Then x = BOTTOM_X_RIGHT - 3
        If Block = 4 And TOP_X_R = BOTTOM_X_RIGHT - 1 And ROTATE_NUM = 1 Then x = BOTTOM_X_RIGHT - 3
        If Block = 6 And TOP_X_R = BOTTOM_X_RIGHT - 1 And ROTATE_NUM = 1 Then x = BOTTOM_X_RIGHT - 3
        If Block = 7 And TOP_X_R = BOTTOM_X_RIGHT - 1 And ROTATE_NUM = 1 Then x = BOTTOM_X_RIGHT - 3
        
        ROTATE_NUM = tmp_ROTATE_NUM
        Call getRandBlock(x, y, Block)
        Call setTopPlace(x, y, Block)
    Else
        Call getRandBlock(x, y, Block)
    End If
    
End Sub

' ブロックが回転できるか できるなら True
Function checkRotateBlock(ByVal x As Integer, ByVal y As Integer, ByRef Block As Integer)
    
    checkRotateBlock = False
    
    Select Case Block
        Case 1
            checkRotateBlock = checkRotateBlock1(x, y)
        Case 2
            checkRotateBlock = checkRotateBlock2(x, y)
        Case 3
            checkRotateBlock = checkRotateBlock3(x, y)
        Case 4
            checkRotateBlock = checkRotateBlock4(x, y)
        Case 5
            checkRotateBlock = checkRotateBlock5(x, y)
        Case 6
            checkRotateBlock = checkRotateBlock6(x, y)
        Case 7
            checkRotateBlock = checkRotateBlock7(x, y)
    End Select

End Function

' 正方形　ブロックが回転できるか できるなら True
Function checkRotateBlock1(ByVal x As Integer, ByVal y As Integer) As Boolean
    
    checkRotateBlock1 = True
    
    Const color As Integer = BLOCK1_COLOR
    
    If checkNoColor(color, x + 1, y) = False _
    Or checkNoColor(x + 2, y) = False _
    Or checkNoColor(x + 1, y - 1) = False _
    Or checkNoColor(x + 2, y - 1) = False _
    Then
        checkRotateBlock1 = False
    End If

End Function

' 長方形　ブロックが回転できるか できるなら True
Function checkRotateBlock2(ByVal x As Integer, ByVal y As Integer)

    checkRotateBlock2 = True
    
    Const color As Integer = BLOCK2_COLOR
    
    If ROTATE_NUM = 1 Then
        If checkNoColor(x + 2, y) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Or checkNoColor(x + 2, y - 2) = False _
        Or checkNoColor(x + 2, y - 3) = False _
        Then
            checkRotateBlock2 = False
        End If

    Else
        If checkNoColor(x, y - 2) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Or checkNoColor(x + 2, y - 2) = False _
        Or checkNoColor(x + 3, y - 2) = False _
        Then
            checkRotateBlock2 = False
        End If

    End If
    
End Function

' L字　ブロックが回転できるか できるなら True
Function checkRotateBlock3(ByVal x As Integer, ByVal y As Integer)
    
    checkRotateBlock3 = True
    
    Const color As Integer = BLOCK3_COLOR
    
    If ROTATE_NUM = 0 Then
        If checkNoColor(x, y) = False _
        Or checkNoColor(x, y - 1) = False _
        Or checkNoColor(x, y - 2) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Then
            checkRotateBlock3 = False
        End If

    ElseIf ROTATE_NUM = 1 Then
        If checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Or checkNoColor(x + 2, y) = False _
        Then
            checkRotateBlock3 = False
        End If

    ElseIf ROTATE_NUM = 2 Then
        If checkNoColor(x, y) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Then
            checkRotateBlock3 = False
        End If

    Else
        If checkNoColor(x, y) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 2, y) = False _
        Or checkNoColor(x, y - 1) = False _
        Then
            checkRotateBlock3 = False
        End If

    End If
    
End Function

' 逆L字　ブロックが回転できるか できるなら True
Function checkRotateBlock4(ByVal x As Integer, ByVal y As Integer)
    
    checkRotateBlock4 = True
    
    Const color As Integer = BLOCK4_COLOR
    
    If ROTATE_NUM = 0 Then
        If checkNoColor(x, y) = False _
        Or checkNoColor(x, y - 1) = False _
        Or checkNoColor(x, y - 2) = False _
        Or checkNoColor(x + 1, y) = False _
        Then
            checkRotateBlock4 = False
        End If

    ElseIf ROTATE_NUM = 1 Then
        If checkNoColor(x, y) = False _
        Or checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Then
            checkRotateBlock4 = False
        End If
    ElseIf ROTATE_NUM = 2 Then
        If checkNoColor(x, y - 2) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Then
            checkRotateBlock4 = False
        End If
    Else
        If checkNoColor(x, y) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 2, y) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Then
            checkRotateBlock4 = False
        End If
    End If
    
End Function

' 山　ブロックが回転できるか できるなら True
Function checkRotateBlock5(ByVal x As Integer, ByVal y As Integer)
    
    checkRotateBlock5 = True
    
    Const color As Integer = BLOCK5_COLOR
    
    If ROTATE_NUM = 0 Then
        If checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Then
            checkRotateBlock5 = False
        End If
    ElseIf ROTATE_NUM = 1 Then
        If checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Or checkNoColor(x + 1, y) = False _
        Then
            checkRotateBlock5 = False
        End If
    ElseIf ROTATE_NUM = 2 Then
        If checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Then
            checkRotateBlock5 = False
        End If
    Else
        If checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Then
            checkRotateBlock5 = False
        End If
    End If
    
End Function

' Z字　ブロックが回転できるか できるなら True
Function checkRotateBlock6(ByVal x As Integer, ByVal y As Integer)
    
    checkRotateBlock6 = True
    
    Const color As Integer = BLOCK6_COLOR
    
    If ROTATE_NUM = 0 Then
        If checkNoColor(x, y) = False _
        Or checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 1, y - 2) = False _
        Then
            checkRotateBlock6 = False
        End If
    Else
        If checkNoColor(x, y - 1) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 2, y) = False _
        Then
            checkRotateBlock6 = False
        End If
    End If
    
End Function

' 逆Z字　ブロックが回転できるか できるなら True
Function checkRotateBlock7(ByVal x As Integer, ByVal y As Integer)
    
    checkRotateBlock7 = True
    
    Const color As Integer = BLOCK7_COLOR
    
    If ROTATE_NUM = 0 Then
        If checkNoColor(x, y - 1) = False _
        Or checkNoColor(x, y - 2) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Then
            checkRotateBlock7 = False
        End If
    Else
        If checkNoColor(x, y) = False _
        Or checkNoColor(x + 1, y) = False _
        Or checkNoColor(x + 1, y - 1) = False _
        Or checkNoColor(x + 2, y - 1) = False _
        Then
            checkRotateBlock7 = False
        End If
        
    End If
    
End Function</pre>
&nbsp;</p>
<h3>ブロックが一行並べば消す</h3>
<p>&nbsp;</p>
<p>ブロックの移動が完了すれば次は、ブロックが一行そろっているか確認し、そろっている場合はその行を削除してスコアに加算します。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-7.png" alt="" width="589" height="202" class="aligncenter wp-image-3863" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-7.png 669w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-tetoris-7-300x103.png 300w" sizes="auto, (max-width: 589px) 100vw, 589px" /></p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' ブロックの1列ブロックが削除できるところか
Sub checkRowBlock()
    
    Dim x, y, n: n = BOTTOM_Y
    Dim nocolor As Integer
    Dim flag
    Dim Score_num: Score_num = 0
    Dim cellcolor1, cellcolor2
    
    ' そろっている行をグレーにする
    For y = BOTTOM_Y - 1 To START_Y Step -1
        nocolor = 0
        For x = BOTTOM_X_LEFT + 1 To BOTTOM_X_RIGHT - 1 Step 1
            If checkNoColor(x, y) = True Then
              nocolor = nocolor + 1
            End If
        Next x
        If nocolor = BOTTOM_X_RIGHT - BOTTOM_X_LEFT - 1 Then
            Exit For
        ElseIf nocolor = 0 Then
            flag = 1
            For x = BOTTOM_X_LEFT + 1 To BOTTOM_X_RIGHT - 1 Step 1
                With Worksheets(TETRIS_SHEET).Cells(y, x)
                    .Interior.color = RGB(192, 192, 192)
                    .Borders.LineStyle = xlContinuous
                End With
            Next x
        End If
    Next y
    
    ' グレーの行を削除
    If flag = 1 Then
        Application.ScreenUpdating = False
        For y = BOTTOM_Y - 1 To START_Y Step -1
            cellcolor1 = Worksheets(TETRIS_SHEET).Cells(y, BOTTOM_X_LEFT + 1).Interior.color
            If cellcolor1 = RGB(192, 192, 192) Then
                Score_num = Score_num + 1
                For n = y To START_Y Step -1
                    For x = BOTTOM_X_LEFT + 1 To BOTTOM_X_RIGHT - 1
                        With Worksheets(TETRIS_SHEET).Cells(n, x)
                            .ClearFormats
                            .Interior.color = Worksheets(TETRIS_SHEET).Cells(n - 1, x).Interior.color
                        End With
                        If checkNoColor(x, n - 1) = False Then
                            With Worksheets(TETRIS_SHEET).Cells(n, x)
                                .Borders.LineStyle = xlContinuous
                            End With
                        End If
                    Next x
                Next n
            End If
            cellcolor1 = Worksheets(TETRIS_SHEET).Cells(y, BOTTOM_X_LEFT + 1).Interior.color
            If cellcolor1 = RGB(192, 192, 192) Then
                y = y + 1
            End If
        Next y
        Application.ScreenUpdating = False
     End If
     
     If Score_num &gt; 0 Then
         Score = Score + 100 + Score_num * 300
     End If
     
     Worksheets(TETRIS_SHEET).Cells(SCORE_POSITION_Y, SCORE_POSITION_X).Value = Score
      
End Sub</pre>
&nbsp;</p>
<h3>テトリスの終了条件をつける</h3>
<p>&nbsp;</p>
<p>あとは終了条件だけですね。ある行を天井と決め、その行よりも一つ上の行を端から端までセルの書式を確認し、ブロックがあれば（セルに色がついてあれば）メッセージを表示させ終了させます。</p>
<p>&nbsp;</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">' ゲーム終了
Private Sub checkgame()
    
    Dim x

    For x = BOTTOM_X_LEFT + 1 To BOTTOM_X_RIGHT - 1
        If checkNoColor(x, START_Y - 1) = False Then
          MsgBox "Game Over!" &amp; Chr(13) &amp; "Score : " &amp; Score
          End
        End If
    Next x

End Sub</pre>
&nbsp;</p>
<h2>最後に</h2>
<p>いかがでしょうか？</p>
<p>長々と失礼しました。この記事49000文字近くまでいってました、、、まあ大半がソースコードですが。</p>
<p>これ思ったより作るのめんどくさかったですね。。けれどゲームをつくるのってやっぱり楽しいです。</p>
<p>&nbsp;</p>
<p>皆様もよければぜひ参考に作ってみてください！</p>
<p>最後にこのテトリスが気になる人もしくは作成したテトリスを参考にしたい人がいれば、ぜひダウンロードしてみてください！</p>
<p>&nbsp;</p>
<div class="button frame block blue"><a href="https://lemon818.com/wp/wp-content/uploads/2019/02/tetoris.xlsm" class="midium">エクセルのテトリスをダウンロードする</a></div>
<div></div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【Excel vba】マウスの左クリックのイベントを検知する簡単な方法</title>
		<link>https://lemon818.com/excel-clickevent/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Mon, 04 Feb 2019 12:44:49 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[Worksheet_SelectChange]]></category>
		<category><![CDATA[イベント検知]]></category>
		<category><![CDATA[右クリック]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=3741</guid>

					<description><![CDATA[はじめに Excelで将棋のゲームをつくろうとしたときでした。 そういやどうやってマウスクリックを検知すればいいんやろう？ 私は仕事やブログでExcelを取り扱うことが多いですが、セルをクリックしたときにクリックしたこと…]]></description>
										<content:encoded><![CDATA[<h2>はじめに</h2>
<p>Excelで将棋のゲームをつくろうとしたときでした。</p>
<div class="voice clearfix left n_bottom">
<div class="icon">
<p><img decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/07/hukurou.jpg" /></p>
<div class="name"></div>
</div>
<div class="text think_balloon left white">そういやどうやってマウスクリックを検知すればいいんやろう？</div>
</div>
<p>私は仕事やブログでExcelを取り扱うことが多いですが、セルをクリックしたときにクリックしたことを検知しそこから処理を開始することがわかりませんでした。</p>
<p>いろいろ調べましたが、まあ最初はうまくいかなかった、、です。</p>
<p>そんな中私が見つけた一番簡単なクリック検知する方法についてご紹介します。</p>
<p>※話が全く変わりますが、Excel でクリック検知を用いて作成した将棋のゲームは下記リンクです。</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/excel-syogi/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-1-150x150.png" width="150" height="150" alt="Excelでゲームをつくろう！ ～将棋～（操作編）【Excel vba】"></div><div class="title">Excelでゲームをつくろう！ ～将棋～（操作編）【Excel vba】</div><div class="date">2019.2.1</div><div class="substr">エクセルで「2人用将棋」作っちゃいました！！   前回は Excel vba でオセロを作成しましたがそのときは１日でサクサク作れたため、調子にのって将棋をつくろうとしたら一週間もかかってしまいました...  苦労した点 仕事で疲れすぎて、開発する気力と体力が持たない... マウスクリックのイベント...</div></a></div>
<h2>クリック検知をする方法</h2>
<p>Excel の vba 画面を開き、赤枠のプルダウンメニューを開きます。このとき、VBAProject に<span style="color: #ff6600;"><strong>「標準モジュール」を選択しないようにしてください。</strong></span></p>
<p>そしてプルダウンメニューから「Worksheet」を選択します。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-1.png" alt="" width="873" height="274" class="aligncenter wp-image-3745" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-1.png 1070w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-1-300x94.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-1-768x241.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-1-1024x322.png 1024w" sizes="auto, (max-width: 873px) 100vw, 873px" /></p>
<p>するとvba の編集画面に「Worksheet_SelectChange」 というプロシージャがでてきます。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-2.png" alt="" width="955" height="205" class="aligncenter wp-image-3746" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-2.png 1161w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-2-300x64.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-2-768x165.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-2-1024x220.png 1024w" sizes="auto, (max-width: 955px) 100vw, 955px" /></p>
<p>これはクリックを検知するためのプロシージャで、右クリックを検知するためには「Worksheet_SelectChange」プロシージャとなっている必要があります。</p>
<p>また<span style="color: #ff6600;"><strong>「Worksheet_SelectChange」プロシージャの名前は変更できない</strong></span>のでご注意ください。</p>
<p>もしこのプロシージャが表示されない場合は、右のプルダウンメニューから「SelectionChange」を選択してください。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-3.png" alt="" width="753" height="247" class="aligncenter size-full wp-image-3748" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-3.png 753w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-3-300x98.png 300w" sizes="auto, (max-width: 753px) 100vw, 753px" /></p>
<p>では実際にクリック検知を行ったvba 処理の例をご紹介します。</p>
<p>例えばシートのあるセルをクリックするとメッセージが表示されるプログラムを作成します。</p><pre class="crayon-plain-tag">Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Dim NowCell
    Set NowCell = ActiveCell
    
    MsgBox NowCell.Column
    
End Sub</pre><p>
これは<strong>クリックしたセルの列番号をメッセージで表示させるプログラム</strong>です。</p>
<p>これをクリック処理をしたいシートを選択して vba 編集画面 に貼り付けます。画面では「Sheet1」を選択しています。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-5.png" alt="" width="716" height="212" class="aligncenter wp-image-3751" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-5.png 787w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-5-300x89.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-5-768x227.png 768w" sizes="auto, (max-width: 716px) 100vw, 716px" /></p>
<p>そしてシート画面に戻り「Sheet1」の好きなセルを選択してください。</p>
<p>下記画面のようにクリックしたセルの列番号が表示されていることが確認できます。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-6.png" alt="" width="576" height="284" class="aligncenter wp-image-3752" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-6.png 618w, https://lemon818.com/wp/wp-content/uploads/2019/02/excel-click-6-300x148.png 300w" sizes="auto, (max-width: 576px) 100vw, 576px" /></p>
<h2>最後に</h2>
<p>いかがでしょうか。</p>
<p>今回はただシートのクリックを検知しそのセルの列番号を表示させるプログラムをご紹介しましたが、「Worksheet_SelectChange」プロシージャの中身を好きなように編集することで、さまざまなプログラムを作成することができます。</p>
<p>ぜひこの技を応用させていろいろなものを作成してみてください。ではでは。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Excelでゲームをつくろう！ ～将棋～（操作編）【Excel vba】</title>
		<link>https://lemon818.com/excel-syogi/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Thu, 31 Jan 2019 15:42:19 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[pickup]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[ゲーム]]></category>
		<category><![CDATA[ダウンロード]]></category>
		<category><![CDATA[将棋]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=3723</guid>

					<description><![CDATA[エクセルで「2人用将棋」作っちゃいました！！ &#160; &#160; 前回は Excel vba でオセロを作成しましたがそのときは１日でサクサク作れたため、調子にのって将棋をつくろうとしたら一週間もかかってしまいま…]]></description>
										<content:encoded><![CDATA[<p><strong><span style="color: #ff6600;">エクセルで「2人用将棋」作っちゃいました！！</span></strong></p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/syogi.gif" alt="" width="643" height="482" class="aligncenter wp-image-4480" /></p>
<p>&nbsp;</p>
<p>前回は <span>Excel vba で</span>オセロを作成しましたがそのときは１日でサクサク作れたため、調子にのって将棋をつくろうとしたら<span style="color: #ff0000;"><strong>一週間もかかってしまいました...</strong></span></p>
<p>&nbsp;</p>
<div class="sc_frame_wrap block blue">
<div class="sc_frame_title">苦労した点</div>
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>仕事で疲れすぎて、開発する気力と体力が持たない...</li>
<li>マウスクリックのイベント検知する方法がよくわからない...</li>
<li>駒の動きをすべて実装させるがものすごく大変...</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>苦労した点はものすごくありますが、<strong>とにかく働きながらつくるのが大変でしたね</strong>。</p>
<p>帰るのが 9時、10時でそっから作るってこと本当に大変....</p>
<p>&nbsp;</p>
<p>まあそんな話どうでもいいので、「マウスクリックのイベント検知する方法」については<strong>知らないとどうしようもない</strong>ので、やり方について別記事にまとめようと思います。</p>
<p>※ クリック検知を行う方法については下記になります。ぜひ参考にしてください。</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/excel-clickevent/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/10/5470d3ad4154f55e94757a88cf55ed08-150x150.png" width="150" height="150" alt="【Excel vba】マウスの左クリックのイベントを検知する簡単な方法"></div><div class="title">【Excel vba】マウスの左クリックのイベントを検知する簡単な方法</div><div class="date">2019.2.4</div><div class="substr">はじめに Excelで将棋のゲームをつくろうとしたときでした。 そういやどうやってマウスクリックを検知すればいいんやろう？ 私は仕事やブログでExcelを取り扱うことが多いですが、セルをクリックしたときにクリックしたことを検知しそこから処理を開始することがわかりませんでした。 いろいろ調べましたが、...</div></a></div>
<p>&nbsp;</p>
<p>今回はこのページでは作成した Excel 将棋ファイルについて、その操作方法についてご紹介します。</p>
<p>将棋の作成方法については、別記事でご紹介します（作成中といいつつあまり進んでないのでがんばります。。）</p>
<p>※ Excel 将棋ファイルについて下記からダウンロード可能です。</p>
<p>&nbsp;</p>
<div class="button frame block orange"><a href="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-syogi_ver1.0.xlsm" class="midium">Excel 将棋ファイルをダウンロードする</a></div>
<p>&nbsp;</p>
<h2>操作方法</h2>
<p>ここでは、ダウンロードしたエクセルについて説明します。</p>
<div class="sc_frame_wrap blue">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<div class="sc_designlist ol square solid blue">
<ol>
<li>ゲーム開始と終了</li>
<li>駒の操作方法</li>
<li>勝敗について</li>
<li>先手後手について</li>
<li>王手について</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h3>ゲームの開始と終了</h3>
<p>将棋を始める際は「ゲーム開始」ボタンを押下し、ゲームを終了する場合は「ゲーム終了」を押下します。</p>
<p>&nbsp;</p>
<p>また、「ゲーム開始」ボタンを押下するとセル番号 Q2の位置の表示が「ゲーム中」、「ゲーム開始」ボタンを押下すると「開始待ち」となります。</p>
<p>&nbsp;</p>
<p>つまり、この表示が「ゲーム中」の場合はゲームがプレイでき、「開始待ち」の場合はゲームがプレイできません。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-2.png" alt="" width="507" height="291" class="aligncenter wp-image-3735" srcset="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-2.png 665w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-2-300x172.png 300w" sizes="auto, (max-width: 507px) 100vw, 507px" /></p>
<p>&nbsp;</p>
<h3>駒の操作方法</h3>
<p>基本は<strong>マウス操作</strong>になります。</p>
<p>動かしたい駒をクリックすると選択セルが黄色に変化なり、移動できる駒の箇所が薄い黄色になります。</p>
<p>&nbsp;</p>
<p>そして移動できる駒の箇所にクリックすることで駒が移動できます。</p>
<p>また持ち駒の処理についても同様に持ち駒から置きたい駒が黄色になり、置ける箇所が薄い黄色になります。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-4.png" alt="" width="986" height="365" class="aligncenter wp-image-3736" srcset="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-4.png 1241w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-4-300x111.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-4-768x284.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-4-1024x379.png 1024w" sizes="auto, (max-width: 986px) 100vw, 986px" /></p>
<p>&nbsp;</p>
<p>また今回「二歩」の処理を行っております。「二歩」とは同じ列も自分の「歩」の駒を２つ以上は置けないという将棋のルールですが、</p>
<p>元々自分の「歩」の駒がある列に持ち駒から「歩」を置こうとしても置けないようにしています。</p>
<p>具体的には、作成した Excel ファイルでは駒を置ける箇所が薄い黄色をしていますが、そこで「二歩」になるセルに色をつけないように設定しています。</p>
<p>&nbsp;</p>
<h3>勝敗について</h3>
<p>将棋の勝敗はルール上は「王」がとられた時点で終了ですが、</p>
<p>実際に将棋での勝敗が付くケースは、</p>
<p>相手が投了するか「王」が詰む（「王」がどこに動いても次に相手の駒にとられてしまう）状態で</p>
<p>勝敗が付く場合しかないです。</p>
<p>&nbsp;</p>
<p>私もかなり昔に将棋をやっていてアマチュア初段をとったことがありますが、「王」がとられて「負けました～」って言っている人は見たことがありません。</p>
<p>なので、本当は「王」が詰む状態で勝敗をつけたいところですが、今回は<strong>「王」をとった場合に勝敗が決まる</strong>ようにしています。</p>
<p>&nbsp;</p>
<h3>先手後手について</h3>
<p>先手後手についてですが、文字が反転していないほうが先手で反転しているほうが後手です。</p>
<p>後手から始めたいということは、このExcel ファイルでは今のところできません（機能追加予定。。）</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-3.png" alt="" width="666" height="517" class="aligncenter wp-image-3733" srcset="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-3.png 811w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-3-300x233.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-3-768x597.png 768w" sizes="auto, (max-width: 666px) 100vw, 666px" /></p>
<h3>王手について</h3>
<p>自分もしくは相手の「王」の駒が次で相手にとれますよ～という状態が王手ですが、</p>
<p>もし王手の状態になるとメッセージが表示されるようになっています。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-5.png" alt="" width="815" height="473" class="aligncenter wp-image-3737" srcset="https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-5.png 1097w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-5-300x174.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-5-768x446.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/01/excel-syogi-5-1024x595.png 1024w" sizes="auto, (max-width: 815px) 100vw, 815px" /></p>
<p>本来は王手なら「王」を動かさないといけないのですが、</p>
<p>今回の Excel ファイルでは<span style="color: #ff0000;"><strong>「王手」の状態でも「王」以外の駒も動けます。</strong></span></p>
<p>&nbsp;</p>
<p>なので、、まあメッセージだけなんですが、「王手」のときは「王」を動かすようにしてください。。</p>
<p>あと、「打ち歩詰め」という「王」が詰む（つまり「王」が動かない、どうやっても次に相手の駒にとられてしまう）場合に「歩」を打って詰ませると反則になるというルールがありますが、</p>
<p>それができていません（将棋の経験があるにもかかわらず完全に忘れていました。）ので</p>
<p>これについては、機能追加する予定です。</p>
<p>&nbsp;</p>
<h2>最後に</h2>
<p>いかがでしたでしょうか？</p>
<p>&nbsp;</p>
<p>ぜひ、Excel で将棋をやってみて将棋のおもしろさというか Excel ってなんでもできるなあと実感していただければと思います。</p>
<p>また似たようなやつで 「Excel でオセロをつくってみた」もありますので、そちらも<span style="color: #ff0000;"><strong>暇なら</strong></span>ぜひご参照ください。</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/vba_osero/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/11/osero-150x150.png" width="150" height="150" alt="Excelでゲームをつくろう！ ～オセロ～（操作編）【Excel vba】"></div><div class="title">Excelでゲームをつくろう！ ～オセロ～（操作編）【Excel vba】</div><div class="date">2018.11.21</div><div class="substr">「Excel vba をつかってゲームを作ってみよう！」の第一弾「2人用オセロ」です。 「Excel でいろいろなゲームをつくってみたい」という思いで、仕事終わりにがんばって作成しました。 みなさまに...</div></a></div>
<p><span></span></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>エクセルでおみくじをしよう！【Excel Vba】</title>
		<link>https://lemon818.com/excel-omikuzi/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Fri, 28 Dec 2018 13:01:35 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[自作ゲーム]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[おみくじ]]></category>
		<category><![CDATA[ダウンロード]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=3356</guid>

					<description><![CDATA[はじめに さてもうそろそろ新年を迎えますが、「正月に家を出たくない」「くじだけは引きたい」という悩みはありませんか？（おそらくないかもしれませんが。。） 今回はExcel Vba をつかって Excel さえあれば簡単に…]]></description>
										<content:encoded><![CDATA[<h2>はじめに</h2>
<p>さてもうそろそろ新年を迎えますが、「正月に家を出たくない」「くじだけは引きたい」という悩みはありませんか？（おそらくないかもしれませんが。。）</p>
<p>今回はExcel Vba をつかって Excel さえあれば簡単につくれるおみくじについて紹介します！</p>
<p>実際に作ってみた Excel マクロファイルは下記になります。</p>
<div class="voice clearfix left n_bottom">
<div class="button frame block green"><a href="https://lemon818.com/wp/wp-content/uploads/2019/01/omikuzi.xlsm" class="midium">Excel おみくじをダウンロードする！</a></div>
</div>
<h2>Excel おみくじの使い方</h2>
<p>ダウンロードするとわかると思いますが、「くじを引く」ボタンをクリックすると下の黒枠（B12:B18）に結果が表示されます。</p>
<p>注意点ですが<strong>シート名（おみくじ）を変更しないでください。</strong>変更すると正常に動作しなくなります。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/12/0c685b5d2a0e4878a2725f8da76b3efc.png" alt="" width="846" height="400" class="aligncenter wp-image-3364" srcset="https://lemon818.com/wp/wp-content/uploads/2018/12/0c685b5d2a0e4878a2725f8da76b3efc.png 937w, https://lemon818.com/wp/wp-content/uploads/2018/12/0c685b5d2a0e4878a2725f8da76b3efc-300x142.png 300w, https://lemon818.com/wp/wp-content/uploads/2018/12/0c685b5d2a0e4878a2725f8da76b3efc-768x363.png 768w" sizes="auto, (max-width: 846px) 100vw, 846px" /></p>
<h2>Excel おみくじの作り方</h2>
<p>シート構成と VBA のソースコード（プログラミングの中身）について順にご紹介します。</p>
<h3>シート構成</h3>
<p>実はこのExcelファイルは２つのシートから構成されています。</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>「おみくじ」シート</li>
<li>「くじマスタ」シート（非表示）</li>
</ol>
</div>
<p>「くじマスタ」シートは非表示にしてありますので、確認したい場合はシート名のところを「右クリック」→「再表示」→ 「くじマスタ」を選択し「OK」を押してください。</p>
<h5>「おみくじ」シート</h5>
<p>おみくじを引くメインのシートです。注意点は結果が表示される<strong>セルの位置（B13:B18）は動かさないようにしてください</strong>（タイトルは別に変更してもOKです）。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/12/f992e3bc9b69a27d16e37030650ff532.png" alt="" width="780" height="480" class="aligncenter wp-image-3363" srcset="https://lemon818.com/wp/wp-content/uploads/2018/12/f992e3bc9b69a27d16e37030650ff532.png 926w, https://lemon818.com/wp/wp-content/uploads/2018/12/f992e3bc9b69a27d16e37030650ff532-300x185.png 300w, https://lemon818.com/wp/wp-content/uploads/2018/12/f992e3bc9b69a27d16e37030650ff532-768x473.png 768w" sizes="auto, (max-width: 780px) 100vw, 780px" /></p>
<h5>「くじマスタ」シート</h5>
<p>くじの結果を登録しているシートです。</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>A列 : 番号 ← おみくじの番号です。わかりやすくつけているだけで動作上は不要ですが<strong>消さないようにしてください。</strong></li>
<li>B列 : おみくじ ← おみくじの結果です。下に新しく値を付け足しても問題なく動きますが、<strong>こちらも消さないでください。</strong></li>
</ol>
</div>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/12/862deca05cc936ed6377f2a68f5d3706.png" alt="" width="348" height="351" class="aligncenter size-full wp-image-3368" srcset="https://lemon818.com/wp/wp-content/uploads/2018/12/862deca05cc936ed6377f2a68f5d3706.png 348w, https://lemon818.com/wp/wp-content/uploads/2018/12/862deca05cc936ed6377f2a68f5d3706-150x150.png 150w, https://lemon818.com/wp/wp-content/uploads/2018/12/862deca05cc936ed6377f2a68f5d3706-297x300.png 297w" sizes="auto, (max-width: 348px) 100vw, 348px" /></p>
<h3>動作概要</h3>
<p>動作概要ですが、下記のようになります。</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li> 0 ~ 5 のランダム値 result を取得する</li>
<li>「くじマスタ」シートのB列2行目以降の値を動的配列 omikuzi に格納する</li>
<li>配列 omikuzi(result)の値を取得し、「おみくじ」シートに値を出力する</li>
</ol>
<p>順に説明します。</p>
<p>（１） 0 ~ 5 のランダム値として「3」を取得した場合、 変数 result に 「3」 を代入します。</p>
<p>（２）「くじマスタ」シートのB列2行目以降の値（大吉、吉、中吉、小吉、凶、大凶）を配列 omikuzi に格納します。つまり、配列 omikuzi の中身は以下のようになっています。</p>
<div class="sc_designlist li fa_angle_o blue">
<ul>
<li>omikuzi(0) = 大吉</li>
<li>omikuzi(1) = 吉</li>
<li>omikuzi(2) = 中吉</li>
<li>omikuzi(3) = 小吉</li>
<li>omikuzi(4) = 凶</li>
<li>omikuzi(5) = 大凶</li>
</ul>
</div>
<p>（３）result を 配列 omikuzi のインデックスにし、その値を「おみくじ」シートに値を出力します。たとえば result = 3 の場合、result をインデックスとするため omikuzi(3) = 小吉となります。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/12/bb56c1c2af122824c2bcfa63be0eed4d.png" alt="" width="613" height="300" class="aligncenter wp-image-3373" srcset="https://lemon818.com/wp/wp-content/uploads/2018/12/bb56c1c2af122824c2bcfa63be0eed4d.png 662w, https://lemon818.com/wp/wp-content/uploads/2018/12/bb56c1c2af122824c2bcfa63be0eed4d-300x147.png 300w" sizes="auto, (max-width: 613px) 100vw, 613px" /></p>
</div>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Const MASTERSHEET As String = "くじマスタ"
Const OUTPUTSHEET As String = "おみくじ"
Const OUTPUTCELL As String = "B12"

Sub おみくじ()
 
    Dim result As Integer: result = Int(Rnd * 6)
    Dim omikuzi() As String: ReDim omikuzi(0)
     
    For i = 2 To getMaxRow(MASTERSHEET, "A")
        omikuzi(UBound(omikuzi)) = Worksheets(MASTERSHEET).Cells(i, 2).Value
        ReDim Preserve omikuzi(UBound(omikuzi) + 1)
    Next i
    ReDim Preserve omikuzi(UBound(omikuzi) - 1)
    
    
    Worksheets(OUTPUTSHEET).Range(OUTPUTCELL).Value = omikuzi(result)
    
End Sub

Function getMaxRow(sheetName As String, row As String)

    getMaxRow = Worksheets(sheetName).Range(row &amp; "65536").End(xlUp).row

End Function</pre>
<div class="voice clearfix left n_bottom">
<h2>最後に</h2>
<p>いかがでしょうか？</p>
<p>&nbsp;</p>
<p>これで<span class="sc_marker" style="background: linear-gradient(transparent 50%, #ffff66 50%);">いつでもどこでも年中くじが無料で引き放題</span>ですね！！ぜひ新年の変わり目にいっぱつ運試しに引いてみてはいかがでしょうか？</p>
<p>&nbsp;</p>
<div class="voice clearfix left n_bottom">
<div class="button frame block green"><a href="https://lemon818.com/wp/wp-content/uploads/2019/01/omikuzi.xlsm" class="midium">Excel おみくじをダウンロードする！</a></div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
