<?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>vba - プログラミングで遊ブログ</title>
	<atom:link href="https://lemon818.com/tag/vba/feed/" rel="self" type="application/rss+xml" />
	<link>https://lemon818.com</link>
	<description>現役システムエンジニアが趣味でプログラミングする自由気ままなブログ</description>
	<lastBuildDate>Tue, 28 Jun 2022 23:43:49 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>	<item>
		<title>【Vba】エクセルでピアノつくってみた！（猫ふんじゃったが演奏できます！）</title>
		<link>https://lemon818.com/excel-piano/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Wed, 09 Jun 2021 15:07:58 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[BeepAPI]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[ドレミファソラシド]]></category>
		<category><![CDATA[ピアノ]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=5792</guid>

					<description><![CDATA[Excel でピアノをつくってみました！！ &#160; &#160; &#160; これはこのブログが100記事記念ということですごいものを作ってみたい！と思って作っていました。 （ 作り終わった後にいろいろと調べてみ…]]></description>
										<content:encoded><![CDATA[<div class="sc_frame_wrap solid yellow">
<div></div>
<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/06/piano.gif" alt="" width="1201" height="376" class="aligncenter wp-image-5793" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>これはこのブログが100記事記念ということで<span style="color: #000000;"><strong>すごいものを作ってみたい！</strong></span>と思って作っていました。</p>
<p>（ 作り終わった後にいろいろと調べてみると、Excel ピアノって世の中に出回ってるとしてすこしがっかりしましたが、、、）</p>
<p>&nbsp;</p>
<div>
<p>この記事では、<span style="color: #3366ff;"><strong>Excel のピアノの作り方について簡単に解説します。</strong></span></p>
<p>今回は Excel Vba というプログラミング言語で作成しました。</p>
<p>&nbsp;</p>
<p>注意書きですが<span style="color: #ff0000;"><strong>私はピアノがまったくわかっていない</strong></span>ので、Excel ピアノは作れるようになりますが、</p>
<p>もっと音楽が詳しい方はさらにいいものが作れると思います。</p>
<p>&nbsp;</p>
<p>もしよければ参考にしてみてください。</p>
<p>&nbsp;</p>
<p>また下記ボタンから「<strong>猫ふんじゃった</strong>」<strong>が演奏される Excel ファイルがダウンロードできます。</strong></p>
</div>
<p>興味があればぜひどうぞ！</p>
<p>&nbsp;</p>
<div>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2021/06/excelPiano_ver1.0.xlsm">Excel でピアノを演奏してみる！</a></div>
<p>&nbsp;</p>
<h2>Excel ピアノの作り方！</h2>
</div>
<p>Excel ピアノの作り方は下記二つです。</p>
<div class="sc_frame_wrap orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>ピアノ用のExcelシートを準備</li>
<li>Excel Vba で ピアノを実装する</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>これらを順に説明します。</p>
<p>&nbsp;</p>
<h3>ピアノ用のExcelシートを準備</h3>
<p>まずExcel シートを下記の画像のように準備します。</p>
<p><img decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano3png.png" alt="" width="1185" height="603" class="aligncenter  wp-image-5798" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano3png.png 1363w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano3png-300x153.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano3png-1024x521.png 1024w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano3png-768x391.png 768w" sizes="(max-width: 1185px) 100vw, 1185px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>これは実際にこのページからダウンロードできる Excel を見たほうが速いと思うので、説明は簡略化します。</p>
<p>しかし注意点は<span style="color: #ff0000;"><span style="color: #000000;">このシートには</span><strong>非表示列<span style="color: #000000;">（上記画像の</span>赤枠<span style="color: #000000;">の箇所</span></strong><span style="color: #000000;"><strong>）</strong></span></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>左（A列）の<span style="color: #ff0000;"><strong>赤枠</strong></span>・・・「ドレミ」を出すために必要な周波数</li>
<li>上部（3行目）の<span style="color: #ff0000;"><strong>赤枠</strong></span>・・・今のセルの位置から0の数をカウントしている（０が10回連続したら終了する処理を実装しているため）</li>
<li>上部（4行目）の<span style="color: #ff0000;"><strong>赤枠</strong></span>・・・水色の表に値が入っているセルの行位置を取得</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h3>Excel Vba で ピアノを実装する</h3>
<p>今回 Excel ピアノを実装する上で下記のような3つのプロシージャ（関数）を用意しました。</p>
<div class="sc_frame_wrap orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>selectCol プロシージャ・・・いま読み込んでいる列を表示させる処理</li>
<li>myBeepプロシージャ・・・ BeepAPI で音を出す（引数 vioce が周波数の値となる）</li>
<li>pianoプロシージャ・・・Excel ピアノのメインの処理、シートの楽譜情報から音を出す処理までをまとめています</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>これはいまは意味がわからなくても大丈夫です。</p>
<p>(　´_ゝ｀)ﾌｰﾝって感じでさらーっと流してもらえればと思います。</p>
<p>&nbsp;</p>
<h4>selectCol プロシージャ・・・いま読み込んでいる列を表示させる処理</h4>
<p>いま読み込んでいる列を表示させる処理というのは</p>
<p>下記のように列が順番に選択されてくる処理を意味します。</p>
<p>&nbsp;</p>
<p><img decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/piano.gif" alt="" width="1025" height="321" class="aligncenter wp-image-5793" /></p>
<p>&nbsp;</p>
<p>これは3列から順に列を選択していくだけのすごく簡単な処理です。</p>
<p>たとえば Columns("C:C").Select とすると C列が選択されます。</p>
<p>それをC,D,E .... と順にずらしていくということです。</p>
<p>&nbsp;</p>
<h4>myBeepプロシージャ・・・ BeepAPI で音を出す</h4>
<p>今回ピアノの「ドレミファソラシド」を鳴らすために <strong>BeepAPI</strong> というAPI を用いりました。</p>
<p>このAPIではパソコンのBeep音（パソコンのピーとかブーってなる音）を鳴らすことができます。</p>
<p>&nbsp;</p>
<p>BeepAPIを用いるには、はじめに下記のような<strong>おまじない</strong>を書く必要があります（意味はわからなくても動きます）。</p>
<div>
<pre class="crayon-plain-tag">Declare Function BeepAPI Lib "kernel32.dll" Alias "Beep" _
(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)</pre>
</div>
<p>&nbsp;</p>
<p>注意点ですが、これをつかうときは<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/2021/06/excel-piano2.png" alt="" width="339" height="119" class="aligncenter size-full wp-image-5797" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano2.png 339w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-piano2-300x105.png 300w" sizes="auto, (max-width: 339px) 100vw, 339px" /></p>
<p>&nbsp;</p>
<p>そして実際にBeepAPI から「ドレミファソラシド」を出すには周波数と鳴らす時間間隔（今回は<strong>200</strong>と設定）の設定が必要です。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap block orange">
<div class="sc_frame_title">ポイント！</div>
<div class="sc_frame ">
<div class="sc_frame_text"><strong>BeepAPI（周波数、時間）</strong>と指定することで ビープ音を鳴らすことができます！</div>
</div>
</div>
<p>&nbsp;</p>
<p>なおBeepAPI で「ドレミ」を使う上で下記の周波数表を使いました。</p>
<p>&nbsp;</p>
<table style="border-collapse: collapse; width: 26.0601%;">
<tbody>
<tr>
<td style="width: 12.2205%; text-align: center; background-color: #66c9fa;"><strong>周波数</strong></td>
<td style="width: 13.8396%; text-align: center; background-color: #66c9fa;"><strong>音</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>262</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>ド</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>264</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>レ</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>330</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>ミ</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>392</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>ファ</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>440</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>ラ</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>493</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>シ</strong></td>
</tr>
<tr>
<td style="width: 12.2205%; text-align: center;"><strong>523</strong></td>
<td style="width: 13.8396%; text-align: center;"><strong>ド</strong></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>※ 周波数については<a href="http://palm.org/f_pal/f_pal_special/sp011_pyrol_scale.html"><span>ドレミファ音階のHz対応表</span></a>を参考にしました。</p>
<p>&nbsp;</p>
<p>たとえば「ド」を鳴らそうとします。</p>
<p>その場合は BeepAPI(262, 200)のように呼び出してやればOKってことです！</p>
<p>&nbsp;</p>
<h4>pianoプロシージャ・・・Excel ピアノのメインの処理</h4>
<p>piano プロシージャとは前章で説明しました、下記処理をまとめて実行する処理（いわばメイン処理）です。</p>
<div class="sc_designlist ol square solid  blue">
<ol>
<li>selectCol プロシージャ・・・ いま読み込んでいる列を表示させる処理</li>
<li>myBeepプロシージャ・・・ BeepAPI で音を出す（引数 vioce が周波数の値となる）</li>
</ol>
</div>
<p>&nbsp;</p>
<p>まとめただけなので、特に説明することもないので割愛します。。</p>
<p>&nbsp;</p>
<h4>Excel ピアノのソースコード</h4>
<p>&nbsp;</p>
<p>プログラミングのソースコードは下記になります。</p>
<div>
<pre class="crayon-plain-tag">Declare Function BeepAPI Lib "kernel32.dll" Alias "Beep" _
(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Const TIME_INTERVAL = 200
Const CELL_START_COL = 4

Const CELL_CHECK_ROW = 3
Const CELL_VOICE_ROW = 4
Const CELL_START_ROW = 5

Sub piano()
    
    Dim i
    Dim voice, voiceRow
    
    i = CELL_START_COL
    
    While Cells(CELL_CHECK_ROW, i) &lt; 10 And Cells(CELL_CHECK_ROW, i) &lt;&gt; ""
        
        Call selectCol(i)

        voiceRow = Cells(CELL_VOICE_ROW, i).Value + CELL_VOICE_ROW
        
        If voiceRow &lt;&gt; 0 And voiceRow &lt;&gt; "" Then
            voice = Cells(voiceRow, 1).Value
            Call myBeep(voice)
        Else
            Sleep TIME_INTERVAL
        End If
        i = i + 1
        
    Wend
    
End Sub

Private Sub selectCol(i)


    buf = Cells(1, i).Address(True, False)
    buf = Left(buf, InStr(buf, "$") - 1)
    Columns(buf &amp; ":" &amp; buf).Select
    
End Sub

Private Sub myBeep(voice)

    Call BeepAPI(voice, TIME_INTERVAL)

End Sub</pre>
</div>
<p>&nbsp;</p>
<div>
<div>
<h2>最後に</h2>
<p>&nbsp;</p>
<p>いかがでしたでしょうか？</p>
<p>この記事では、<span style="color: #3366ff;"><strong>Excel のピアノの作り方について簡単に解説しました。</strong></span></p>
</div>
<p>&nbsp;</p>
<p>この Excel でぜひいろんな曲を作って遊んでいただければと思います。</p>
<div>
<p>この記事がいいなと思った方は SNS で共有いただければ嬉しいです。</p>
</div>
<p>&nbsp;</p>
<p>また100記事いけたのは読者の皆様からおかげです。</p>
<p>これからは Excel の情報以外にもさまざまな役に立つ情報を発信していきたいと思います。</p>
<div>
<p>ではでは。</p>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Excelでできる！複数のファイル名を一括置換するツール！</title>
		<link>https://lemon818.com/filename_bulk_replace/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Sat, 05 Jun 2021 01:52:34 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[業務で役立つExcelマクロ]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[エクセル]]></category>
		<category><![CDATA[ファイル名]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[一括置換]]></category>
		<category><![CDATA[複数]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=4644</guid>

					<description><![CDATA[&#160; 「手作業でファイル名をちまちま変更するの超めんどくさくないですか？」 &#160; 私はある日、お客さんから「100ファイル近くのExcelファイルのファイル名を手作業で変更してくれ～」っていう依頼がありま…]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<div class="sc_frame_wrap solid yellow">
<div class="sc_frame ">
<div class="sc_frame_text"><span style="color: #000000;">「<strong>手作業でファイル名をちまちま変更するの</strong><span style="color: #ff0000;"><strong>超めんどくさくない</strong></span><strong>ですか？</strong>」</span></div>
</div>
</div>
<p>&nbsp;</p>
<p>私はある日、お客さんから「100ファイル近くのExcelファイルのファイル名を手作業で変更してくれ～」っていう依頼がありました。</p>
<p>具体的には「ファイル名_v1.2.xlsx」→「ファイル名_v1.3.xlsx」にしてくれ～～っていう内容です。</p>
<p>&nbsp;</p>
<p>もちろん、ファイル数が少ないなら手でやったほうが速いと思いますが、</p>
<p>毎回、100ファイル近くを手作業でやるのにどれだけ時間がかかるか・・</p>
<p>しかし仕事をしていれば、<strong><span style="color: #ff0000;">少なからずそんなめんどくさい作業をすることがある</span></strong>と思います。</p>
<p>&nbsp;</p>
<p>そこでこの度はExcel をつかって<span style="color: #0000ff;"><strong>ボタン一つ</strong></span><strong><span style="color: #0000ff;">でファイル名を一括置換するツール</span>を作りました！</strong></p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/replaceFile.gif" alt="" width="1106" height="452" class="aligncenter wp-image-5753" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>このツールは Excel Vba というプログラミングで作成されています。</p>
<p>この記事では「<strong>Excelでできる複数のファイル名を一括置換するツール</strong>」の使い方と作り方をご紹介します！</p>
<p>&nbsp;</p>
<div>
<p>※ いつものようにつくったのも共有しときますので、よければどうぞ（ブック保護、シート保護はかかってます）。</p>
<p>※ 2022/06 機能追加しました！！50000ファイルまで置換可能！実行中画面の追加実装など！よければインストールどうぞ！</p>
<p>&nbsp;</p>
<div class="button frame block green"><a class="midium" href="https://lemon818.com/wp/wp-content/uploads/2022/06/replaceFileName_ver1.1.xlsm">Excelでできる複数のファイル名を一括置換するツール</a></div>
<p>&nbsp;</p>
<h2>ファイル名を一括置換するツールの使い方</h2>
</div>
<p>この「Excelでできる複数のファイル名を一括置換するツール」では以下の用に使います。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>「検索ボタン」を押下しリネームしたいファイル一覧を取得します。</li>
<li>ファイル名（置換後）列にファイル名を入力します。</li>
<li>「一括置換」ボタンでファイル名が変更できます。</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<h3>「検索ボタン」を押下してリネームしたいファイル一覧を取得</h3>
<p>まず「検索ボタン」を押下します。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename1.png" alt="" width="664" height="242" class="aligncenter size-full wp-image-5758" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename1.png 664w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename1-300x109.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></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/2021/06/excel-rename2.png" alt="" width="941" height="530" class="aligncenter size-full wp-image-5759" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename2.png 941w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename2-300x169.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename2-768x433.png 768w" sizes="auto, (max-width: 941px) 100vw, 941px" /></p>
<p>&nbsp;</p>
<p>これにてB列とＣ列にファイル名とフォルダ名がそれぞれ出力されます。</p>
<p>ファイル名、フォルダ名を手入力しても問題ないですが、<span style="color: #ff0000;"><strong>入力し間違えないようにする必要があります。</strong></span></p>
<p>&nbsp;</p>
<h3>ファイル名（置換後）列にファイル名を入力</h3>
<p>ファイル名（置換後）列にファイル名を入力します。</p>
<p>このツールではファイル名（置換前）→ファイル名（置換後）のようにファイルがリネーム（名前が変更）されます。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename3.png" alt="" width="1031" height="441" class="aligncenter wp-image-5760" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename3.png 1204w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename3-300x128.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename3-1024x438.png 1024w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename3-768x329.png 768w" sizes="auto, (max-width: 1031px) 100vw, 1031px" /></p>
<p>&nbsp;</p>
<p>ファイル名（置換後）列に入力後、チェック列（E列）の値がOKになっていれば問題なしです。</p>
<p>なおチェック列がOK以外の値の場合は<span style="color: #ff0000;"><strong>ファイル名置換処理が実行されません。</strong></span></p>
<p>&nbsp;</p>
<h4>チェック列がＯK以外のケース</h4>
<p>チェック列では入力した値に誤りがあるかどうかをチェックします。</p>
<div class="sc_frame_wrap orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li><span style="color: #ff0000;">ファイル名（置換後）列に重複している項目がないか</span></li>
<li><span style="color: #3366ff;">ファイル名（置換前）列とファイル名（置換後）列で同じ値がないか</span></li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>もし上記項目を満たした場合、下記画面のようにエラーメッセージが表示されるようになっています。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename6.png" alt="" width="785" height="200" class="aligncenter size-full wp-image-5765" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename6.png 785w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename6-300x76.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename6-768x196.png 768w" sizes="auto, (max-width: 785px) 100vw, 785px" /></p>
<p>&nbsp;</p>
<p>※ なおこのエラーメッセージはH列（非表示列）に入力していますので、H列は消さないようにお願いします！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename7.png" alt="" width="461" height="278" class="aligncenter size-full wp-image-5767" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename7.png 461w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename7-300x181.png 300w" sizes="auto, (max-width: 461px) 100vw, 461px" /></p>
<p>&nbsp;</p>
<h3>「一括置換」ボタンでファイル名が変更</h3>
<p>最後に「一括置換」ボタンを押下します。</p>
<p>すると下記のような処理完了メッセージが表示されます。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename4.png" alt="" width="883" height="492" class="aligncenter size-full wp-image-5761" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename4.png 883w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename4-300x167.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename4-768x428.png 768w" sizes="auto, (max-width: 883px) 100vw, 883px" /></p>
<p>&nbsp;</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/06/excel-rename5.png" alt="" width="813" height="408" class="aligncenter size-full wp-image-5762" srcset="https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename5.png 813w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename5-300x151.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/06/excel-rename5-768x385.png 768w" sizes="auto, (max-width: 813px) 100vw, 813px" /></p>
<p>&nbsp;</p>
<p>以上がこのツールの使い方です。</p>
<p>続いてはこのツールの使い方を説明します。</p>
<p>&nbsp;</p>
<div>
<h2>ファイル名を一括置換するツールの作り方（Excel Vba）</h2>
<p><strong><span style="color: #ff0000;">ここからプログラミングの少し難しい話になります！</span></strong></p>
<p>&nbsp;</p>
<p>今回は「<strong>Excelでできる複数のファイル名を一括置換するツール</strong>」を作るうえで下記のような Excel VBA コードを作成しました。</p>
</div>
<p>このコードを Excel の開発タブ→ Visual Basic で表示されるエディタに貼り付ければOKです。</p>
<p>※ 開発タブがない場合は下記ページを参考にしてください。</p>
<div class="sc_getpost"><a class="clearfix" href="https://lemon818.com/vba_start/" ><div class="sc_getpost_thumb post-box-thumbnail__wrap"><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/10/8e3b6f7cb40cde9b9f4399d6869f96f9-1.png" width="702" height="356"></div><div class="title">３分でできる！Excel VBA の開発を行うために必要な事前準備</div><div class="date">2018.11.14</div><div class="substr">いまから 「vba を始めたいけれど、Excel で何をどうやってすればいいかわからない」という悩みはありませんか？ 本ページでは vba をどうやってはじめるか３分以内に終わる方法を解説します。 v...</div></a></div>
<p>&nbsp;</p>
<div>
<pre class="crayon-plain-tag">'=================================================================================
' 複数ファイル名を一括置換マクロ
'=================================================================================

Const SEARCH_WORD = "\*.*"

Const CELL_PRINT_COL = 2
Const CELL_PRINT_ROW = 2
Const CELL_SEARCH_WORD = "B3"


' ファイル一覧取得
Sub getFileList()

    Application.ScreenUpdating = False

    Dim folderName
    Dim lastRow
    
    folderName = getFolderName()
    fileList = Dir(folderName &amp; SEARCH_WORD)
    
    ' 最終行取得
    If Cells(CELL_PRINT_ROW + 1, CELL_PRINT_COL) = "" Then
        lastRow = CELL_PRINT_ROW + 1
    Else
        lastRow = Cells(CELL_PRINT_ROW, CELL_PRINT_COL).End(xlDown).Row
    End If
    
    Do While fileList &lt;&gt; ""
                
        Cells(lastRow, CELL_PRINT_COL) = folderName
        Cells(lastRow, CELL_PRINT_COL + 1) = fileList
        lastRow = lastRow + 1
        fileList = Dir()
        
    Loop
    
    Application.ScreenUpdating = True
    
End Sub


' ファイル名を一括置換
Sub replaceFile()

    Application.ScreenUpdating = False

    Dim folderName
    Dim beforeFile
    Dim afterFile
    Dim i
    
    On Error Resume Next
    i = CELL_PRINT_ROW + 1
    
    While Cells(i, CELL_PRINT_COL) &lt;&gt; ""
    
        folderName = Cells(i, CELL_PRINT_COL)
        beforeFile = folderName &amp; "\" &amp; Cells(i, CELL_PRINT_COL + 1)
        afterFile = folderName &amp; "\" &amp; Cells(i, CELL_PRINT_COL + 2)
        
        If check(beforeFile, afterFile) And Cells(i, CELL_PRINT_COL + 3) = "OK" Then
            Name beforeFile As afterFile
            Cells(i, CELL_PRINT_COL + 4) = "OK"
        Else
            Cells(i, CELL_PRINT_COL + 4) = "NG"
        End If
    
        i = i + 1
    
    Wend
    
    Application.ScreenUpdating = True
    
    MsgBox "ファイル名を一括置換しました！"
    
End Sub

' 初期化
Sub reset()

    Application.ScreenUpdating = False
    
    Range(Cells(CELL_PRINT_ROW + 1, CELL_PRINT_COL), Cells(Rows.Count, CELL_PRINT_COL + 2)).ClearContents
    Range(Cells(CELL_PRINT_ROW + 1, CELL_PRINT_COL + 4), Cells(Rows.Count, CELL_PRINT_COL + 4)).ClearContents
     
    Application.ScreenUpdating = True

End Sub


' 入力精査
Private Function check(ByVal beforeFile, ByVal afterFile) As Boolean

    If Dir(beforeFile) &lt;&gt; "" And Dir(afterFile) = "" Then
        check = True
    Else
        check = False
    End If
    
End Function


' ダイアログでフォルダ名取得
Private Function getFolderName()

    Dim folderPath As Variant
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = 0 Then
            End
        End If
        folderPath = .SelectedItems(1)
    End With
    
    getFolderName = folderPath
  
End Function</pre>
&nbsp;</p>
<p>とりあえず上をコピーすればOKですが、それだとあまりに味気ないので説明します。</p>
<p>まずこのプログラムは以下のような機能があります。</p>
</div>
<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>getFileList() ・・・ （リネームする）ファイル一覧を取得</li>
<li>replaceFile() ・・・ ファイル名を一括置換</li>
<li>reset() ・・・  出力シートを初期化</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>今回のツールでの「（リネームする）ファイル一覧を取得」と「ファイル名を一括置換」する方法について説明します。</p>
<p>※ reset（）については割愛します。</p>
<p>&nbsp;</p>
<h3>Excel で（リネームする）ファイル一覧を取得・・・getFileList()</h3>
<p>ファイル一覧を取得する方法は下記になります。</p>
<div class="sc_frame_wrap orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>ダイアログでフォルダ名取得</li>
<li>取得したフォルダ名をもとにフォルダ下のファイル一覧を取得</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>フォルダ名取得用のダイアログ画面は Application.FileDialog(msoFileDialogFolderPicker)で取得します。</p>
<p>戻り値として選択したフォルダ名（フルパス）で取得できます。</p>
<p>&nbsp;</p>
<p>その取得したフォルダ名から Dir 関数でファイル一覧を取得し、シートに出力するだけです。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">' ファイル一覧取得
Sub getFileList()

    Application.ScreenUpdating = False

    Dim folderName
    Dim lastRow
    
    folderName = getFolderName()
    fileList = Dir(folderName &amp; SEARCH_WORD)
    
    ' 最終行取得
    If Cells(CELL_PRINT_ROW + 1, CELL_PRINT_COL) = "" Then
        lastRow = CELL_PRINT_ROW + 1
    Else
        lastRow = Cells(CELL_PRINT_ROW, CELL_PRINT_COL).End(xlDown).Row
    End If
    
    Do While fileList &lt;&gt; ""
                
        Cells(lastRow, CELL_PRINT_COL) = folderName
        Cells(lastRow, CELL_PRINT_COL + 1) = fileList
        lastRow = lastRow + 1
        fileList = Dir()
        
    Loop
    
    Application.ScreenUpdating = True
    
End Sub

' ダイアログでフォルダ名取得
Private Function getFolderName()

    Dim folderPath As Variant
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = 0 Then
            End
        End If
        folderPath = .SelectedItems(1)
    End With
    
    getFolderName = folderPath
  
End Function</pre><p>
&nbsp;</p>
<p>&nbsp;</p>
<h3>Excel でファイル名を一括置換・・・replaceFile()</h3>
<p>シートに記述されている置換前後のファイル名を取得し、それらを Name 関数で取得します。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap block orange">
<div class="sc_frame_title">ポイント！</div>
<div class="sc_frame ">
<div class="sc_frame_text">ファイル名の変更 ・・・ Name 置換前のファイル名 As 置換後のファイル名</div>
</div>
</div>
<p>&nbsp;</p>
<p>このリネーム（ファイル名を変更する）処理は<span style="color: #3366ff;"><strong>一行ずつ</strong></span>実行されます。</p>
<p>このファイル名変更処理をシートの表の（B列）に値が実行されるまで実行します。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">' ファイル名を一括置換
Sub replaceFile()

    Application.ScreenUpdating = False

    Dim folderName
    Dim beforeFile
    Dim afterFile
    Dim i
    
    On Error Resume Next
    i = CELL_PRINT_ROW + 1
    
    While Cells(i, CELL_PRINT_COL) &lt;&gt; ""
    
        folderName = Cells(i, CELL_PRINT_COL)
        beforeFile = folderName &amp; "\" &amp; Cells(i, CELL_PRINT_COL + 1)
        afterFile = folderName &amp; "\" &amp; Cells(i, CELL_PRINT_COL + 2)
        
        If check(beforeFile, afterFile) And Cells(i, CELL_PRINT_COL + 3) = "OK" Then
            Name beforeFile As afterFile
            Cells(i, CELL_PRINT_COL + 4) = "OK"
        Else
            Cells(i, CELL_PRINT_COL + 4) = "NG"
        End If
    
        i = i + 1
    
    Wend
    
    Application.ScreenUpdating = True
    
    MsgBox "ファイル名を一括置換しました！"
    
End Sub

' 入力精査
Private Function check(ByVal beforeFile, ByVal afterFile) As Boolean

    If Dir(beforeFile) &lt;&gt; "" And Dir(afterFile) = "" Then
        check = True
    Else
        check = False
    End If
    
End Function</pre><p>
&nbsp;</p>
<p>また上記処理では入力したファイル名が正しいかどうかを精査する check 関数も実行しております。</p>
<p>この check関数は下記条件すべてを満たす場合に True、それ以外は False を返します。</p>
<p>&nbsp;</p>
<div class="sc_frame_wrap orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>置換前のファイル（B列）が存在するか</li>
<li>置換後のファイル（C列）が存在しないか</li>
<li>チェック列（E列）がOKであるか</li>
</ol>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<div>
<h2>最後に</h2>
<p>&nbsp;</p>
<p>いかがでしたでしょうか？</p>
<p>この記事では「<strong>Excelでできる複数のファイル名を一括置換するツール</strong>」の使い方と作り方について解説しました。</p>
</div>
<p>&nbsp;</p>
<p>このツールさえあれば<span style="color: #3366ff;"><strong>どれだけファイル数が多くてもファイル名の一括置換がラクラクできます！</strong></span></p>
<div>
<p>この記事が読者の何かのお役に立てれば幸いです。</p>
<p>ではでは。</p>
</div>
]]></content:encoded>
					
		
		
			</item>
		<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 loading="lazy" 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 loading="lazy" 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="auto, (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 loading="lazy" 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="auto, (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>Excel 全シートをA1セル選択、拡大率100%、スクロールを一番左上にするマクロ！</title>
		<link>https://lemon818.com/excel-default-setting/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Tue, 11 May 2021 15:22:13 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[A1セル]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[スクロール]]></category>
		<category><![CDATA[一番左上]]></category>
		<category><![CDATA[拡大率100%]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=5407</guid>

					<description><![CDATA[「Excelファイルを提出するときは全シートをA1選択、拡大率100%、スクロール位置を一番左上にしろ！！」 &#160; 社会人として働いていて、一度はこんなこと言われたことないでか？ &#160; どーも Takeで…]]></description>
										<content:encoded><![CDATA[<div class="sc_frame_wrap solid yellow">
<div class="sc_frame "><span style="color: #000000;">「<strong>Excelファイルを提出するときは全シートをA1選択、拡大率100%、スクロール位置を一番左上にしろ！！</strong>」</span></div>
</div>
<p>&nbsp;</p>
<p>社会人として働いていて、一度はこんなこと言われたことないでか？</p>
<p>&nbsp;</p>
<p>どーも Takeです。</p>
<p>わたしはすごい適当な性格なので、このへんよく忘れてしまいます。新人のときは良く怒られました。。。</p>
<p>最初は手で直していたんですが、そのうちめんどくさくなって<strong>マクロ化</strong>しました！！！</p>
<p>&nbsp;</p>
<p>今回はそのマクロを作る方法について超簡単にご紹介します！！</p>
<p>&nbsp;</p>
<h2>マクロの作り方</h2>
<p>&nbsp;</p>
<p>マクロの作り方は<strong>超簡単</strong>です。</p>
<p>「開発タブ」→ 「Visual Studio」からエディタを開きます。</p>
<p>※ 開発タブが表示されていない場合は「ファイル」→「オプション」→「リボンのユーザ設定」で開発をチェックいれればOKです！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2018/11/vbe.png" alt="" width="1082" height="609" class="aligncenter wp-image-1269" srcset="https://lemon818.com/wp/wp-content/uploads/2018/11/vbe.png 1311w, https://lemon818.com/wp/wp-content/uploads/2018/11/vbe-300x169.png 300w, https://lemon818.com/wp/wp-content/uploads/2018/11/vbe-768x432.png 768w, https://lemon818.com/wp/wp-content/uploads/2018/11/vbe-1024x576.png 1024w, https://lemon818.com/wp/wp-content/uploads/2018/11/vbe-660x371.png 660w" sizes="auto, (max-width: 1082px) 100vw, 1082px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>それで下記を貼り付けます。</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">Sub シートを整える()

    Dim ws As Worksheet
    Dim firstWs As Worksheet
    Dim firstFlag
    On Error Resume Next
    
　　Application.ScreenUpdating = False

    firstFlag = False
    
    For Each s In Worksheets
        
        Dim nowSheet As Worksheet
        Set nowSheet = Worksheets(s.Name)
        
        ' 最初のシート情報を控えておく
        If firstFlag = False Then
            
            Set firstWs = nowSheet
            firstFlag = True
            
        End If
        
        nowSheet.Activate
        
        ' 横スクロールを一番左
        ActiveWindow.ScrollColumn = 1
        
        ' 縦スクロールを一番上
        ActiveWindow.ScrollRow = 1
        
        ' 拡大率100%
        ActiveWindow.Zoom = 100
        
        ' A1セルを選択
        nowSheet.Range("A1").Select
        
    Next
    
    ' 最初のシートを選択
    firstWs.Select

　　Application.ScreenUpdating = True
    
End Sub</pre><p>
&nbsp;</p>
<p>貼ったら Excel を保存します。</p>
<p>注意点ですが、ファイル拡張子を「<strong>xlam</strong>」にします（これがのちのち役立ってきます！！）。</p>
<p>ファイル名はなんでもOKです。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet2.png" alt="" width="932" height="529" class="aligncenter size-full wp-image-5413" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet2.png 932w, https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet2-300x170.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet2-768x436.png 768w" sizes="auto, (max-width: 932px) 100vw, 932px" /></p>
<p>&nbsp;</p>
<p>これでOKです。</p>
<p>すると<span style="color: #ff0000;"><strong>保存したのに「.xlam」ファイルが表示されねえーーー</strong></span>ってなりませんか？</p>
<p>「.xlam」ファイルはExcelの仕様で表示されません（なんでかは知りません。。）。</p>
<p>ですが、裏では開かれていることになっています。</p>
<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/defaultSet3.png" alt="" width="431" height="444" class="aligncenter wp-image-5414" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet3.png 398w, https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet3-291x300.png 291w" sizes="auto, (max-width: 431px) 100vw, 431px" /></p>
<p>&nbsp;</p>
<p>それで下記のような画面が出るので、</p>
<p>コマンドの選択欄を「マクロ」にして→ さっき作ったマクロ「シートを整える」を追加→OKボタンを押下します。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet4.png" alt="" width="930" height="673" class="aligncenter size-full wp-image-5415" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet4.png 930w, https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet4-300x217.png 300w, https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet4-768x556.png 768w" sizes="auto, (max-width: 930px) 100vw, 930px" /></p>
<p>&nbsp;</p>
<p>あとは以下のようにボタンが表示されればOKです。</p>
<p>これでどんなExcelブックを開いてもいつでも「A1セル選択、拡大率100%、スクロールを一番左上」ができます！！</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet5.png" alt="" width="447" height="237" class="aligncenter size-full wp-image-5416" srcset="https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet5.png 447w, https://lemon818.com/wp/wp-content/uploads/2021/05/defaultSet5-300x159.png 300w" sizes="auto, (max-width: 447px) 100vw, 447px" /></p>
<p>&nbsp;</p>
<h2>このマクロについて</h2>
<p>&nbsp;</p>
<p>このマクロがどういう風に動いているかザックリ説明します。</p>
<p>&nbsp;</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>まずExcel ブックにある全シート情報を取得しそれでループ処理をします。</li>
<li>その際に一番最初のシート情報を控えておきます。</li>
<li>シートに対して下記を実行します。</li>
</ol>
</div>
<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>ActiveWindow.ScrollColumn = 1　・・・横（列）の位置を左</li>
<li>ActiveWindow.ScrollRow = 1　・・・縦（行）の位置を先頭</li>
<li>ActiveWindow.Zoom = 100　・・・拡大率100%</li>
<li>nowSheet.Range("A1").Select　・・・　A1セル選択</li>
</ol>
</div>
</div>
</div>
</div>
<div class="sc_designlist ol square solid blue">
<ol></ol>
</div>
<p>&nbsp;</p>
<p>最後に一番前のシートにもどりますが、<strong><span style="color: #ff0000;">一番前のシートが非表示の場合は戻らない</span></strong>のでご注意ください。</p>
<p>&nbsp;</p>
<h2>最後に</h2>
<p>&nbsp;</p>
<p>いかがでしたでしょうか？</p>
<p>これのマクロさえあれば、Excelファイルの提出前のめんどくさい作業もなくなると思います。</p>
<p>&nbsp;</p>
<p>ではでは。</p>
<p>&nbsp;</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>【Excel Vba】サブディレクトリを含むファイル一覧を取得するマクロ</title>
		<link>https://lemon818.com/excel-filelist/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Tue, 12 Mar 2019 11:33:00 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[業務で役立つExcelマクロ]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[サブディレクトリ]]></category>
		<category><![CDATA[サブフォルダ]]></category>
		<category><![CDATA[ファイル一覧]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=4097</guid>

					<description><![CDATA[はじめに Excel でカウントディレクトリのファイルに加えてサブディレクトリに含まれるファイルの一覧を出力するマクロの作成方法についてご紹介します。 ちょっと専門用語が多かったような気もするので、 要するにあるフォルダ…]]></description>
										<content:encoded><![CDATA[<h2>はじめに</h2>
<p>Excel でカウントディレクトリのファイルに加えて<strong>サブディレクトリに含まれるファイルの一覧を出力するマクロ</strong>の作成方法についてご紹介します。</p>
<p>ちょっと専門用語が多かったような気もするので、</p>
<p>要するに<span style="color: #ff6600;"><strong>あるフォルダ内にフォルダの中のファイルも全部含めてファイル一覧させる</strong></span>方法についてご紹介します。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-00.png" alt="" width="732" height="383" class="aligncenter wp-image-4131" srcset="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-00.png 774w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-00-300x157.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-00-768x402.png 768w" sizes="auto, (max-width: 732px) 100vw, 732px" /></p>
<p>&nbsp;</p>
<p>今回は <strong>Excel Vba</strong> を使います。</p>
<p>自分でつくってみてだいたい１～２時間くらいでできましたが、結構簡単なのでぜひ興味のある方は参考にしてみてください。</p>
<p>※実際に作成したマクロは下記からダウンロードできますので、興味のある方はぜひダウンロードしてみてください。</p>
<div class="button frame block green"><a href="https://lemon818.com/wp/wp-content/uploads/2020/06/filelist.xlsm" class="midium">サブディレクトリを含むファイル一覧マクロをダウンロード</a></div>
<p>&nbsp;</p>
<h2>作成方法</h2>
<p>ご紹介します Excel マクロは大きく二つの機能から構成されています。</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 reg blue">
<ol>
<li>ファイル一覧を出力するパスを取得</li>
<li>取得したパスからファイル一覧を出力</li>
</ol>
</div>
</div>
</div>
</div>
<h3>ファイル一覧を出力するパスを取得</h3>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-3.png" alt="" width="694" height="197" class="aligncenter wp-image-4111" srcset="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-3.png 726w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-3-300x85.png 300w" sizes="auto, (max-width: 694px) 100vw, 694px" /></p>
<p>ファイル一覧を表示させるためのファイルパスを取得するための機能をご紹介します。</p>
<p>下記画面のように「フォルダパス取得」ボタンを押下することで、ファイル一覧を表示させるためのファイルパス（下画面なら「C:\test」)を表示させます。</p>
<p>下記にソースコードを記載します。</p>
<pre class="crayon-plain-tag">Option Explicit

Const X As Integer = 1
Const Y As Integer = 8
Const CELL_FILE_PATH As String = "B3"

Const ERRORMESSAGE As String = "フォルダ一覧を出力するための正しいパスを入力ください。"
Const COMPLETEMSG As String = "処理が完了しました。"

' ファイルパス取得
Sub getFilePath()

     With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            Range(CELL_FILE_PATH).Value = .SelectedItems(1)
        End If
    End With
    
End Sub

' メイン
Sub getFileList()

    Dim start_x As Long: start_x = X
    Dim start_y As Long: start_y = Y
    Dim searchFolderPath As String
    Dim checkFolderPath
    
    Application.ScreenUpdating = False
    On Error Resume Next
    
    searchFolderPath = Range(CELL_FILE_PATH).Value
    
    ' ファイルの存在チェック
    checkFolderPath = Dir(searchFolderPath, vbDirectory)
    
    If searchFolderPath = "" Or checkFolderPath = "" Then
        MsgBox ERRORMESSAGE, vbCritical
        End
    End If

    ' シートの初期化
    Call settingSheet
    
    '　ファイル一覧作成
    Call printFileList(searchFolderPath, start_x, start_y)

    ' フォーマット整形
    Call formattingSheet

    MsgBox COMPLETEMSG, vbInformation

    Application.ScreenUpdating = True

End Sub

' ファイル一覧作成
Private Sub printFileList(searchFolderPath As String, ByRef start_x, ByRef start_y)
    
    Dim fso As New FileSystemObject
    Dim folderList As Folders
    Dim folderName As folder
    Dim fileName As File
    
    Dim str As String
    Dim slashNum As Long
    
    Set folderList = fso.GetFolder(searchFolderPath).SubFolders
    
    'フォルダ内のファイル名の取得し、セルにパスとファイル名を書き込む
    For Each fileName In fso.GetFolder(searchFolderPath).Files
        
        slashNum = InStrRev(fileName.Path, "\")
        Cells(start_y, start_x).Value = Mid(fileName.Path, slashNum + 1)
        Cells(start_y, start_x + 1).Value = Left(fileName.Path, slashNum - 1)
        Cells(start_y, start_x + 2).Value = Format(fileName.Size / 1024, "0.#0000") &amp; " バイト"
        Cells(start_y, start_x + 3).Value = fileName.DateCreated
        Cells(start_y, start_x + 4).Value = fileName.DateLastModified
        start_y = start_y + 1
    
    Next
    
    ' サブフォルダ一覧取得　再帰処理
    For Each folderName In folderList
        Call printFileList(folderName.Path, start_x, start_y)
    Next
    
End Sub

' シートの初期化
Private Sub settingSheet()

    Dim maxCol
    Dim maxRow

    maxRow = Cells(Rows.Count, X).End(xlUp).Row
    maxCol = Cells(Y, Columns.Count).End(xlToLeft).Column
    Range(Cells(Y, X), Cells(maxRow + Y, maxCol + X)).ClearContents

End Sub

' フォーマット整形
Private Sub formattingSheet()

    Columns("A:E").Select
    Columns("A:E").EntireColumn.AutoFit
    Range("A1").Select

End Sub</pre> </p>
<p>&nbsp;</p>
<p>要はダイアログ画面からファイルをファイルパスを選択して、選択した値をB3セルに書き込むというそれだけの処理です。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-4.png" alt="" width="676" height="523" class="aligncenter wp-image-4116" srcset="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-4.png 793w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-4-300x232.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-4-768x595.png 768w" sizes="auto, (max-width: 676px) 100vw, 676px" /></p>
<p>&nbsp;</p>
<h3>取得したパスからファイル一覧を出力</h3>
<p>これは「ファイル一覧出力」ボタンを押下することで、<strong>取得したパスのファイル一覧出力を出力させる処理</strong>です。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-7.png" alt="" width="970" height="297" class="aligncenter wp-image-4125" srcset="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-7.png 1049w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-7-300x92.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-7-768x235.png 768w, https://lemon818.com/wp/wp-content/uploads/2019/03/filelist-7-1024x313.png 1024w" sizes="auto, (max-width: 970px) 100vw, 970px" /></p>
<p>&nbsp;</p>
<p>処理は下記の順番になります。順を追って説明していきます。</p>
<div class="sc_designlist ol square solid blue">
<ol>
<li>取得したパスが正しい値であるかを確認</li>
<li>シートの初期化</li>
<li><span>ファイル一覧作成</span></li>
<li><span>シートのフォーマット整形</span></li>
</ol>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>取得したパスが正しい値であるかを確認</h4>
<div class="sc_designlist ol square solid blue">
<p>ここでは<strong>取得したパスが正しいパスか</strong>どうかを確認します。</p>
<p>前述しました「ファイルパス取得」ボタンを押していれば間違いなく正しいパスが取得できますが、</p>
<p>ボタンを押し忘れたり誤って値を入力することで<strong>わけわからんパスを参照することを防ぎます。</strong></p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Const ERRORMESSAGE As String = "フォルダ一覧を出力するための正しいパスを入力ください。"
    Dim searchFolderPath As String
    Dim checkFolderPath

    searchFolderPath = Worksheets(FOLDERPATH).Range("B3").Value
    
    ' ファイルの存在チェック
    checkFolderPath = Dir(searchFolderPath, vbDirectory)
    
    If searchFolderPath = "" Or checkFolderPath = "" Then
        MsgBox ERRORMESSAGE, vbCritical
        End
    End If</pre>
取得したパスを変数 searchFolderPath に格納し、Dir 関数を用いてファイルの存在チェックを行います。</p>
<p>その結果を<span>checkFolderPathに格納し、もし searchFolderPath か checkFolderPath の値が空の場合はエラーメッセージを表示させ処理を終了します。</span></p>
<p>&nbsp;</p>
</div>
<h4>シートの初期化</h4>
<p>これは処理を行う前にシートをきれいにする処理のことです。</p>
<p>具体的には、ファイル一覧を出力しているセル範囲（B6以降のセル）の値のみを削除しています（書式は削除していません）。</p>
<h5>ソースコード</h5>
<pre class="crayon-plain-tag">Const X As Integer = 2
    Const Y As Integer = 6

    Dim start_x As Long: start_x = X
    Dim start_y As Long: start_y = Y    

    ' シートの初期化
    maxRow = Worksheets(FOLDERPATH).Cells(Rows.Count, X).End(xlUp).Row
    maxCol = Worksheets(FOLDERPATH).Cells(Y, Columns.Count).End(xlToLeft).Column
    Worksheets(FOLDERPATH).Range(Cells(Y, X), Cells(maxRow + Y, maxCol + X)).ClearContents</pre>
&nbsp;</p>
<h4>ファイル一覧作成</h4>
<p>ここではファイル一覧を取得し、それをシートに出力する処理です。</p>
<p>引数は、取得したパス searchFolderPath、書き込むセルの位置 start_x、 start_y の３つです。</p>
<p>まずはフォルダ以外のファイル名を取得し、そのファイルの情報（下記に記載します）を取得します。</p>
<p>下記の 変数 fileNameは<strong>フォルダ内にあるファイルを変数に格納させた値</strong>と思ってください。</p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid blue">
<ol>
<li>ファイル名  ※下記に記載</li>
<li>ファイルのパス（ファイル名を除く） → <span>Left(fileName.Path, slashNum - 1)</span></li>
<li>ファイルサイズ（バイト）→ <span class="crayon-s">Format(fileName.Size / 1024, "</span><span class="crayon-cn">0.</span><span class="crayon-o">#</span><span class="crayon-cn">0</span><span class="crayon-s">") &amp; "</span><span class="crayon-h"> </span><span>バイト"</span></li>
<li>作成日時  → <span class="crayon-v">fileName</span><span class="crayon-sy">.</span><span class="crayon-e">DateCreated</span></li>
<li>更新日時 → <span class="crayon-v">fileName</span><span class="crayon-sy">.</span><span class="crayon-e">DateLastModified</span></li>
</ol>
</div>
</div>
</div>
</div>
<h5>※ ファイル名の処理</h5>
<p><span class="crayon-v">まず、フォルダ内のファイルのフルパス </span><span class="crayon-v">fileName</span><span class="crayon-sy">.</span><span class="crayon-v">Path とし、その fileName<span class="crayon-sy">.</span>Pathの後方から最初に来る「\」よりも後ろの値を取得します。</span></p>
<p>何言っているかよくわからない方もいると思いますので、もう少し具体的に説明しますと</p>
<p>例えば<span class="crayon-v">フォルダ内のファイルのフルパス </span><span class="crayon-v">fileName</span><span class="crayon-sy">.</span><span class="crayon-v">Pathが以下のような値としますと、</span></p>
<div class="sc_frame_wrap inline blue">
<div class="sc_frame ">
<div class="sc_frame_text">C:\test\test1\aaa.txt</div>
</div>
</div>
<div>このうちファイル名は「<strong>aaa.txt</strong>」であるため、まずこの文字列を<strong>前から数えて「\」がある箇所が何番目にあるか</strong>を確認し、</div>
<div>その値を <span>slashNumとします。</span></div>
<div></div>
<div>そして <span class="crayon-v"> </span><span class="crayon-v">fileName</span><span class="crayon-sy">.</span><span class="crayon-v">Path から 「</span><span>slashNum - 1」番目以降（- 1は「\」を除くため）にある文字を抽出することでファイル名が取得できます。 </span></div>
<div></div>
<div>下記にソースコードを記載します。</div>
<pre class="crayon-plain-tag">slashNum = InStrRev(fileName.Path, "\")
        'セルにパスとファイル名を書き込む
        Worksheets(FOLDERPATH).Cells(start_y, start_x).Value = Mid(fileName.Path, slashNum + 1)</pre>
&nbsp;</p>
<p>次にフォルダ内にあるサブフォルダ（サブディレクトリ）については、GetFolder関数を用いて取得します。</p>
<p>そして再帰処理（つまり処理を繰り返す）を行い、<strong>サブフォルダが見つからなくなくなる</strong>まで処理をくり返します。</p>
<p>その処理を繰り返している間も、<span style="color: #ff6600;"><strong>そのフォルダに含まれるファイル名はすべて出力する</strong></span>ようにします。</p>
<p>下記にソースコードを記載します。</p><pre class="crayon-plain-tag">' ファイル一覧作成
Private Sub printFileList(searchFolderPath As String, ByRef start_x, ByRef start_y)
    
    Dim fso As New FileSystemObject
    Dim folderList As Folders
    Dim folderName As folder
    Dim fileName As File
    
    Dim str As String
    Dim slashNum As Long
    
    Set folderList = fso.GetFolder(searchFolderPath).SubFolders
    
    'フォルダ内のファイル名の取得
    For Each fileName In fso.GetFolder(searchFolderPath).Files
        slashNum = InStrRev(fileName.Path, "\")
        'セルにパスとファイル名を書き込む
        Worksheets(FOLDERPATH).Cells(start_y, start_x).Value = Mid(fileName.Path, slashNum + 1)
        Worksheets(FOLDERPATH).Cells(start_y, start_x + 1).Value = Left(fileName.Path, slashNum - 1)
        Worksheets(FOLDERPATH).Cells(start_y, start_x + 2).Value = Format(fileName.Size / 1024, "0.#0") &amp; " バイト"
        Worksheets(FOLDERPATH).Cells(start_y, start_x + 3).Value = fileName.DateCreated
        Worksheets(FOLDERPATH).Cells(start_y, start_x + 4).Value = fileName.DateLastModified
        start_y = start_y + 1
    Next
    
    ' サブフォルダ一覧取得　再帰処理
    For Each folderName In folderList
        Call printFileList(folderName.Path, start_x, start_y)
    Next
    
End Sub</pre><p>
&nbsp;</p>
<h2>最後に</h2>
<p>いかがでしょうか？</p>
<p>もしつくるのめんどくせえとか実際に作ったのがそんなのか見てみたい！という人がいましたら下記ボタンからダウンロードできますので、ぜひ試してみてください。</p>
<div class="button frame block green"><a href="https://lemon818.com/wp/wp-content/uploads/2019/03/filelist.xlsm" class="midium">サブディレクトリを含むファイル一覧マクロをダウンロード</a></div>
<div></div>
<div></div>
<div><span></span></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-sekigae/</link>
		
		<dc:creator><![CDATA[Take]]></dc:creator>
		<pubDate>Wed, 06 Feb 2019 13:28:02 +0000</pubDate>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[名簿]]></category>
		<category><![CDATA[席替え]]></category>
		<guid isPermaLink="false">https://lemon818.com/?p=3767</guid>

					<description><![CDATA[はじめに 名簿リストから席を自動で決定してくれる Excel マクロの作り方についてご紹介します。 このマクロは席数を自分で指定できるようにしてあるので、例えば 4 × 4 や ５× 6 の席でも自由に変えて席替えできる…]]></description>
										<content:encoded><![CDATA[<h2>はじめに</h2>
<p><strong>名簿リストから席を自動で決定してくれる Excel マクロの作り方</strong>についてご紹介します。</p>
<p>このマクロは<strong></strong><span style="color: #ff6600;"><strong>席数を自分で指定できるようにしてある</strong></span>ので、例えば 4 × 4 や ５× 6 の席でも自由に変えて席替えできることができます。</p>
<p>小学校や中学、高校では、気分転換のためかなんとなくか目的はさまざまですが、とにかく定期的に席替えが行われると思います。</p>
<p>そんなとき毎回くじ作ってそのくじを引いてみんなでギャーギャー騒いで...って楽しいんですが、<strong>教員の方は早く帰りたいのかもしれません。</strong></p>
<p>そんな教師はあんまり見たことがないんですが、少なからず席替えに時間を割くことがほとんどなくなりますので「いいな」と思われた人はぜひ使ってみてください。</p>
<p>※実際に作成した Excel マクロは下記のボタンからダウンロードできます。</p>
<div class="button frame block green"><a href="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-zasekihyo.xlsm" class="midium">Excel 座席表自動作成マクロをダウンロードする</a></div>
<p>&nbsp;</p>
<h2>操作方法</h2>
<p>（１）<strong>名前を入力します。</strong>名前の左に番号が付いていますが、番号はなんでもいいです。</p>
<p>ダウンロードしたマクロには番号を自動で入力する関数を埋め込んでいますが、消して出席番号とかにしていただいても問題ありません。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-3.png" alt="" width="224" height="232" class="aligncenter wp-image-3784" /></p>
<p>（２）<strong>席の行数と列数</strong>を入力します。値は整数を入力してください。また「チェック」というセルで入力チェックを行ってます。</p>
<p>例えば、名簿シートに１０人で座席数が６（行数 : 2  列数 : 3）の場合は、４人分席が不足していますね。こういうときは「チェック」欄に座席数が不足しています。というメッセージが表示されます。</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-4.png" alt="" width="585" height="466" class="aligncenter wp-image-3785" /></p>
<p>（３）「座席表を作成」ボタンを押下します。すると別シート「座席表」に結果が表示されます。</p>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-5.png" alt="" width="243" height="68" class="aligncenter size-full wp-image-3786" /></p>
<h2>座席表自動作成マクロの作り方</h2>
<p>座席表自動生成マクロの作成方法についてご紹介します。今回は Excel vba をつかって作成しています。</p>
<div class="sc_frame_wrap block green">
<div class="sc_frame_title">シート構成</div>
<div class="sc_frame ">
<div class="sc_designlist li fa_angle_o green">
<ul>
<li>「名簿」シート : 名簿を入力するシート</li>
<li>「座席表」シート : 座席表が出力されるシート</li>
</ul>
</div>
</div>
</div>
<p>シートは上記２種類から構成されます。要は入力用シートとして「名簿」、出力用シートとして「座席表」の２種類です。</p>
<h5>「名簿」シート</h5>
<p><img loading="lazy" decoding="async" src="https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-2.png" alt="" width="675" height="477" class="aligncenter wp-image-3773" srcset="https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-2.png 825w, https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-2-300x212.png 300w, https://lemon818.com/wp/wp-content/uploads/2019/02/zasekihyo-2-768x543.png 768w" sizes="auto, (max-width: 675px) 100vw, 675px" /></p>
<p>入力欄は「名前」「行数」「列数」の三つです。</p>
<p>「番号」はいちおうつけていますが、<strong>処理上は何の関係もありません。</strong>つまりどんな番号が入力されても問題なく動作できます。</p>
<p>ダウンロード用の Excel マクロは自動で入力できるようにしていますが、上書きして出席番号にしていただいても何の問題ありません。</p>
<h5>「座席表」シート</h5>
<p>初期はまっさらなシートです。処理が完了した後に座席表が書き出されます。</p>
<p>&nbsp;</p>
<h3>処理内容（Excel vba）</h3>
<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>
<h4>名簿シートの読み込み</h4>
<p>これはシンプルな処理で、「名簿」シートのB列２行目からセルの値が空白になるまで読み込んで配列に入力しているだけです。</p><pre class="crayon-plain-tag">'名簿シートの読み込み
Private Sub readNameList(ByRef NameList() As String)
    
    Const x As Integer = 2
    Const y As Integer = 3
    
    Dim Name As String
    Dim index As Integer: index = 0

    Do
        ReDim Preserve NameList(index)
        Name = Worksheets(NAMELISTSHEET).Cells(y + index, x).Value
        NameList(index) = Name
        index = index + 1
    Loop Until Name = ""
    
    If UBound(NameList) = 0 Then
        MsgBox "名前を入力してください"
        End
    End If
    
    ReDim Preserve NameList(UBound(NameList) - 1)

End Sub</pre><p>
<h4>座席表シートへの書き込み</h4>
<p>「名簿」シートから取得した名前のデータを含む配列をランダムに取り出して、取り出した値を「座席表」シートに書き込むだけの処理です。</p>
<p>ソースコードを見ると複雑そうに見えますがやっていることはシンプルです。</p>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame ">
<div class="sc_frame_text">
<div class="sc_designlist ol square solid orange">
<ol>
<li>「名簿」シートのエラー処理（座数の行数と列数  :　数値以外 or 0のとき or 空白ならエラー)</li>
<li>  エラー処理が終わったら「座席表」シートをいったん初期化</li>
<li>「名簿」シートから取得した名前を「座席表」シートに書き込む</li>
</ol>
</div>
</div>
</div>
</div>
<pre class="crayon-plain-tag">' 座席シート表への書き込み
Private Sub writeZasekihyo(ByRef NameList() As String)

    Const x As Integer = 2
    Const y As Integer = 4
    Dim RandList() As Integer
    Dim Name As String
    Dim i, j, k
    j = 0
    k = 0
    
    Dim Max_Row
    Dim Max_Column
    
    Max_Row = Worksheets(NAMELISTSHEET).Cells(2, 4).Value
    Max_Column = Worksheets(NAMELISTSHEET).Cells(2, 5).Value
 
    If Max_Row = "" Or Max_Column = "" Then
        MsgBox "行と列を入力してください"
        End
    End If
    
    If Max_Row &lt; 1 Or Max_Column &lt; 1 _
        Or IsNumeric(Max_Row) = False Or IsNumeric(Max_Column) = False Then
        MsgBox "行と列には 1 以上の数値を入力してください"
        End
    End If
    
    
    ' 乱数作成
    Call calRandomArray(RandList, UBound(NameList) + 1)
    
    ' 初期化
    Application.ScreenUpdating = False
    
    Call defaultSetting(x, y - 2, Max_Row)
    
    ' 座席表へ書き込み
    For i = 0 To Max_Row * Max_Column - 1
        If i &lt;= UBound(RandList) Then
            Name = NameList(RandList(i))
        Else
            Name = ""
        End If
        Call writeZasekihyo_oneChair(k + x, j + y, Name)
        If k = Max_Column - 1 Then
            k = 0
            j = j + 1
            If j = Max_Row Then
                Exit For
            End If
        Else
            k = k + 1
        End If
    Next i

    Application.ScreenUpdating = True
    
End Sub

' 乱数生成
Sub calRandomArray(ByRef arr() As Integer, ByVal MAX_NUM As Integer)

    Dim i, rand As Integer
    Dim num() As Boolean
    ReDim num(MAX_NUM)
    ReDim arr(MAX_NUM)
    
    Randomize
    For i = 0 To MAX_NUM - 1
        Do
        rand = Int(Rnd() * MAX_NUM)
        Loop Until num(rand) = False
        arr(i) = rand
        num(rand) = True
    Next i

    ReDim Preserve arr(UBound(arr) - 1)
    
End Sub

' 初期化
Private Sub defaultSetting(ByVal x As Integer, ByVal y As Integer, ByVal Max_Row As Integer)

    Worksheets(ZASEKISHEET).Select
    
    With Worksheets(ZASEKISHEET).Range(Cells(y, x), Cells(y + 100, x + Max_Row + 100))
        .ClearContents
        .Borders.LineStyle = xlLineStyleNone
    End With
    
    Worksheets(ZASEKISHEET).Rows("2:2").Select
    Selection.Delete Shift:=xlUp

    Worksheets(ZASEKISHEET).Range("A1").Select

End Sub

' 座席のセルの書式
Private Sub writeZasekihyo_oneChair(ByVal x As Integer, ByVal y As Integer, ByVal Name As String)
    
    With Worksheets(ZASEKISHEET).Cells(y, x)
        .Value = Name
        .Borders.LineStyle = xlContinuous
        .RowHeight = 50
        .ColumnWidth = 20
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Font.Size = 20
    End With
        
End Sub</pre>
<h4>教卓の書き込み</h4>
<p>最後に教卓を書き込む処理です。２行目に固定で、列は座席表の列数の値に応じて書き込まれます。</p>
<p>席の列数を2で割ったときの剰余計算（余りを算出）をして、その値が1の場合（つまり奇数のとき）は、席の列数を２で割った値を整数に変換し、得られた値 + 2を書き込み先の列番号とします。</p>
<p>席の列数を剰余計算をした値が0の場合（つまり偶数のとき）、席の列数を２で割った値を整数に変換し、得られた値 + 1 と得られた値 + 2 を書き込み先の列番号（事前に二つのセルを結合させるように処理）とします。</p>
<p>例えば席の列数が７（奇数）の場合、7 ÷ 2 = 3.5 を整数にして 3にします。そして 3 + 2 = 5 列目のセルに書き込むようにします。</p>
<p>また席の列数が８（偶数）の場合、8 ÷ 2 = 4とし、4 + 1 = 5 列目と 4 + 2 = 6 列目を書き込み先の列番号とします。</p>
<p>最後の + 2 ですが、これは<strong>B列（つまりセルの２列目）から座席表を書き込むように処理するため</strong>につけています。</p><pre class="crayon-plain-tag">' 教卓を描く
Private Sub writeKyotaku()

    Const x As Integer = 2
    Const y As Integer = 4
    Dim kyotaku As Integer
    Dim Max_Column As Integer
    
    Max_Column = Worksheets(NAMELISTSHEET).Cells(2, 5).Value
    kyotaku = Int(Max_Column / 2)
        
    If Int(Max_Column / 2) = 0 Then
        kyotaku = 0
        With Worksheets(ZASEKISHEET).Cells(2, kyotaku + x)
            .Value = "教卓"
            .Borders.LineStyle = xlContinuous
            .RowHeight = 50
            .ColumnWidth = 20
            .HorizontalAlignment = xlCenter
            .VerticalAlignment = xlCenter
            .Font.Size = 20
        End With
    Else
        If Max_Column Mod 2 = 1 Then
            kyotaku = Int(Max_Column / 2)
            With Worksheets(ZASEKISHEET).Cells(2, kyotaku + x)
                .Value = "教卓"
                .Borders.LineStyle = xlContinuous
                .RowHeight = 50
                .ColumnWidth = 20
                .HorizontalAlignment = xlCenter
                .VerticalAlignment = xlCenter
                .Font.Size = 20
            End With
        Else
            kyotaku = Int(Max_Column / 2) - 1
            With Worksheets(ZASEKISHEET).Range(Cells(2, kyotaku + x), Cells(2, kyotaku + x + 1))
                .Merge
                .Value = "教卓"
                .Borders.LineStyle = xlContinuous
                .RowHeight = 50
                .ColumnWidth = 20
                .HorizontalAlignment = xlCenter
                .VerticalAlignment = xlCenter
                .Font.Size = 20
            End With
        End If
    End If

    
End Sub</pre><p>
&nbsp;</p>
<h2>まとめ</h2>
<p>いかがでしょうか？</p>
<p>かなりざっくりした説明だったかもしれませんので、もし作るのがめんどくさいと感じた方は下記ボタンからダウンロードしてみてください。</p>
<div class="button frame block green"><a href="https://lemon818.com/wp/wp-content/uploads/2019/02/excel-zasekihyo.xlsm" class="midium">Excel 座席表自動作成マクロをダウンロードする</a></div>
<p>&nbsp;</p>
<p><span></span></p>
]]></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>
	</channel>
</rss>
