<?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>マクロ &#8211; まったりエンジニア</title>
	<atom:link href="https://javeo.jp/tag/%E3%83%9E%E3%82%AF%E3%83%AD/feed/" rel="self" type="application/rss+xml" />
	<link>https://javeo.jp</link>
	<description>ほどほどレベルのプログラミング</description>
	<lastBuildDate>Sun, 31 May 2026 12:06:21 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://javeo.jp/wp-content/uploads/2026/05/cropped-サイトアイコン2-32x32.png</url>
	<title>マクロ &#8211; まったりエンジニア</title>
	<link>https://javeo.jp</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>VBAでJSONを扱う方法 VBA-JSONの使い方</title>
		<link>https://javeo.jp/vba-json/</link>
					<comments>https://javeo.jp/vba-json/#comments</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Fri, 22 May 2026 23:00:00 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=111</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2026/05/vba-json-1024x538.jpg" class="webfeedsFeaturedVisual" /></p>ExcelVBAでJSONを扱うなら定番ライブラリ「VBA-JSON」がおすすめです、JsonConverter.basの導入から参照設定、ParseJsonでのパース、ConvertToJsonでの生成、配列やネストへのアクセスまで初心者向けにまとめました]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2026/05/vba-json-1024x538.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<p class="wp-block-paragraph">「VBAでJSONを読み込みたいんだけど、標準機能だとどうにもならない…」と手が止まっていませんか？</p>



<p class="wp-block-paragraph">結論から言うと、<strong><span class="swl-marker mark_yellow">ExcelVBAでJSONを扱うなら「VBA-JSON」という定番ライブラリを入れるのが一番ラク</span></strong>です</p>



<p class="wp-block-paragraph">やることはシンプルで、<code>JsonConverter.bas</code> というファイルを1つ取り込んで、参照設定を1つ入れるだけ、あとは <code>ParseJson</code> でJSONを読み込んで、<code>ConvertToJson</code> でJSONを書き出せます</p>



<p class="wp-block-paragraph">この記事では、VBA-JSONの導入から実際の使い方(パース・生成・配列やネストへのアクセス・ループ処理)まで、初心者の方にも分かるように順を追って解説していきます、つまずきポイントとFAQ、AIにコードを書いてもらうコツもまとめているので、必要なところだけ拾い読みでも大丈夫です</p>



<h2 class="wp-block-heading">VBAでJSONを扱うなら VBA-JSON が定番</h2>



<p class="wp-block-paragraph">まず大前提として、<strong>VBAには標準でJSONを扱う機能がありません</strong></p>



<p class="wp-block-paragraph">Excelには CSV を読む機能はあっても、JSONをそのまま「項目ごとに取り出す」みたいなことは素のVBAだとできないんですよね</p>



<p class="wp-block-paragraph">そこで使うのが、オープンソースのライブラリ「<strong>VBA-JSON</strong>」です</p>



<p class="wp-block-paragraph">GitHubの <a href="https://github.com/VBA-tools/VBA-JSON" target="_blank" rel="noopener noreferrer">VBA-tools/VBA-JSON</a> で公開されていて、JSON界隈ではかなり知られた定番です、最新は <code>v2.3.1</code> で、WindowsのExcelでもMacのExcelでも動きます</p>



<p class="wp-block-paragraph">使う関数は基本的にこの2つだけ覚えればOKです</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li><strong>ParseJson</strong> … JSON文字列を、VBAで扱えるデータ(Dictionary / Collection)に変換する(=読み込む)</li>



<li><strong>ConvertToJson</strong> … VBAのデータを、JSON文字列に変換する(=書き出す)</li>
</ul>



<p class="wp-block-paragraph">「読み込む」と「書き出す」の往復、これだけです、難しそうに見えて中身はシンプルなので安心してください</p>



<h2 class="wp-block-heading">VBAでJSONを扱う場面はどんなとき？</h2>



<p class="wp-block-paragraph">そもそも「ExcelでJSONなんて使うの？」と思うかもしれませんが、最近のWeb APIはJSONで返ってくるのがほぼ標準なので、意外と日常業務の中で出番があります</p>



<p class="wp-block-paragraph">たとえばこんなケースです</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li>為替レートや天気予報のWeb APIを叩いてExcelに取り込む</li>



<li>WebサービスからダウンロードしたデータをVBAで集計する</li>



<li>取引先のシステムとJSON形式でデータをやり取りする</li>



<li>WordPressや社内システムのREST APIを操作する</li>
</ul>



<p class="wp-block-paragraph">VBA-JSONを使えるようになると、<strong>Excel完結の作業に外部データを取り込める幅</strong>が一気に広がります、普段の集計シートに「最新のデータを自動で引っ張ってくる」ような仕組みを足せるイメージですね</p>



<p class="wp-block-paragraph">実際にWeb APIへリクエストを送ってJSONを受け取る流れは、<a href="https://javeo.jp/ebay-api-request/" target="_blank" rel="noopener noreferrer">eBay APIにVBAでリクエストを送る方法を解説した記事</a>でも具体例を扱っているので、API連携をやってみたい方はあわせてどうぞ</p>



<h2 class="wp-block-heading">そもそもJSONって何？という人向けの基礎</h2>



<p class="wp-block-paragraph">「JSONって言葉は聞くけど、よく分かってない」という方のために、ここで一度ざっくり整理しておきます、もう分かってる方は読み飛ばしてOKです</p>



<p class="wp-block-paragraph">JSON(<strong>J</strong>ava<strong>S</strong>cript <strong>O</strong>bject <strong>N</strong>otation)は、テキストベースのデータ交換フォーマットです</p>



<p class="wp-block-paragraph">Web APIからデータを取得するとき、他システムとのデータやり取りなど、いろんな場面で使われています、軽量で人間にも機械にも読みやすいのが特徴ですね</p>



<h3 class="wp-block-heading">JSONの基本構造と記述ルール</h3>



<p class="wp-block-paragraph">細かいルールはいくつかありますが、まず押さえておきたいのはこのあたりです</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li>項目名は「&#8221;」(ダブルクォーテーション)で囲む</li>



<li>文字列も「&#8221;」(ダブルクォーテーション)で囲む</li>



<li>数値は小数点を含めてそのまま表記(クォーテーション不要)</li>



<li>真偽値(Boolean)は「true」「false」のどちらか ※小文字、「&#8221;」は付けない</li>



<li>Null値は「null」 ※小文字、「&#8221;」は付けない</li>



<li>「[ ]」で囲んだ配列の中も、上記と同じルール</li>
</ul>



<p class="wp-block-paragraph">形としては「<code>"キー": 値</code>」のセットが基本で、複数のデータを <code>{ }</code> で囲んだものを「オブジェクト」、順序のあるデータの並びを <code>[ ]</code> で囲んだものを「配列」と呼びます</p>



<p class="wp-block-paragraph">このあたりの言葉は、VBA-JSONを使うときに何度も出てくるので、なんとなく頭に入れておくと後がスムーズです</p>



<h3 class="wp-block-heading">JSONのサンプルをExcelの表で考えてみる</h3>



<p class="wp-block-paragraph">JSONはCSVほど一目で分かる形式じゃないので、サンプルと一緒に見方を説明します、この記事ではずっとこのデータを例に進めていきます</p>



<p class="wp-block-paragraph">たとえばこんなJSON形式のデータがあるとして</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-json" data-lang="JSON"><code>[{&quot;name&quot;:&quot;Javeo&quot;,&quot;birthdate&quot;:{&quot;year&quot;:2000,&quot;month&quot;:1,&quot;day&quot;:1},&quot;height&quot;:180,&quot;weight&quot;:70,&quot;favorite_foods&quot;:[&quot;Meat&quot;,&quot;Vegetables&quot;],&quot;glasses&quot;:true},{&quot;name&quot;:&quot;Javelin&quot;,&quot;birthdate&quot;:{&quot;year&quot;:2002,&quot;month&quot;:2,&quot;day&quot;:2},&quot;height&quot;:150,&quot;weight&quot;:null,&quot;favorite_foods&quot;:[&quot;Sweets&quot;],&quot;glasses&quot;:false}]</code></pre></div>



<p class="wp-block-paragraph">一行だと分かりづらいので、整形するとこうなります(VSCodeなどのエディタで簡単に整形できます)</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-json" data-lang="JSON"><code>[
  {
    &quot;name&quot;: &quot;Javeo&quot;,
    &quot;birthdate&quot;: {
      &quot;year&quot;: 2000,
      &quot;month&quot;: 1,
      &quot;day&quot;: 1
    },
    &quot;height&quot;: 180,
    &quot;weight&quot;: 70,
    &quot;favorite_foods&quot;: [
      &quot;Meat&quot;,
      &quot;Vegetables&quot;
    ],
    &quot;glasses&quot;: true
  },
  {
    &quot;name&quot;: &quot;Javelin&quot;,
    &quot;birthdate&quot;: {
      &quot;year&quot;: 2002,
      &quot;month&quot;: 2,
      &quot;day&quot;: 2
    },
    &quot;height&quot;: 150,
    &quot;weight&quot;: null,
    &quot;favorite_foods&quot;: [
      &quot;Sweets&quot;
    ],
    &quot;glasses&quot;: false
  }
]</code></pre></div>



<p class="wp-block-paragraph">これをExcel的に表にすると、こんなイメージになります</p>



<figure class="wp-block-table is-all-centered"><table><tbody><tr><th rowspan="2">name</th><th colspan="3">birthdate</th><th rowspan="2">height</th><th rowspan="2">witght</th><th colspan="2" rowspan="2">favorite_foods</th><th rowspan="2">glasses</th></tr><tr><th>year</th><th>month</th><th>day</th></tr><tr><td>javeo</td><td>2000</td><td>1</td><td>1</td><td>180</td><td>70</td><td>Meat</td><td>Vegetables</td><td>true</td></tr><tr><td>Javelin</td><td>2002</td><td>2</td><td>2</td><td>150</td><td></td><td>Sweets</td><td></td><td>false</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">つまりJSONをざっくり言うと、<strong>項目と値が対になっていて、「{ }」が階層を、「[ ]」が配列のデータ群を表している</strong>と思えばOKです</p>



<p class="wp-block-paragraph">この「JaveoとJavelinの2人分のデータ」を、これからVBA-JSONで取り出していきます</p>



<h2 class="wp-block-heading">VBA-JSONの導入手順(2026年版)</h2>



<p class="wp-block-paragraph">ここが一番大事なパートです、導入でつまずく人が多いので、順番にやっていきましょう</p>



<p class="wp-block-paragraph">やることは大きく分けて2つ、<strong><span class="swl-marker mark_yellow">「JsonConverter.basのインポート」と「参照設定」</span></strong>だけです</p>



<div class="swell-block-step" data-num-style="circle">
<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l"><strong>ライブラリのダウンロード</strong></div><div class="swell-block-step__body">
<p class="wp-block-paragraph">GitHubの<a href="https://github.com/VBA-tools/VBA-JSON" target="_blank" rel="noreferrer noopener">VBA-tools/VBA-JSON</a>リポジトリにアクセス</p>
</div></div>



<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l"><strong>ファイルを探す</strong></div><div class="swell-block-step__body">
<p class="wp-block-paragraph">ページ内にある「<code>JsonConverter.bas</code>」をダウンロード</p>



<p class="wp-block-paragraph">※何年も更新されていませんが、文字列を分解するだけのプログラムで特に改良点がないってだけなので気にせずどうぞ</p>
</div></div>



<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l"><strong>VBAへのインポート</strong></div><div class="swell-block-step__body">
<p class="wp-block-paragraph">VBAで使えるようにするにはVBEの画面でインポートするだけ</p>



<div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"><a href="https://javeo.jp/wp-content/uploads/2022/02/image-6.png"><img decoding="async" width="298" height="398" src="https://javeo.jp/wp-content/uploads/2022/02/image-6.png" alt="" class="wp-image-159 size-full" srcset="https://javeo.jp/wp-content/uploads/2022/02/image-6.png 298w, https://javeo.jp/wp-content/uploads/2022/02/image-6-225x300.png 225w" sizes="(max-width: 298px) 100vw, 298px" /></a></figure><div class="wp-block-media-text__content">
<p class="wp-block-paragraph">プロジェクトエクスプローラー<br>右クリック→「ファイルのインポート」</p>
</div></div>



<p class="wp-block-paragraph">もしくは「JsonConverter.bas」をプロジェクトエクスプローラーへドラッグ&amp;ドロップでもOK</p>



<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2022/02/VBA-JSONをインポート.gif"><img decoding="async" width="868" height="474" src="https://javeo.jp/wp-content/uploads/2022/02/VBA-JSONをインポート.gif" alt="" class="wp-image-167"/></a></figure>
</div></div>



<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l">Microsoft Scripting Runtime に参照設定する</div><div class="swell-block-step__body">
<p class="wp-block-paragraph">VBA-JSONを動かすには参照設定が要ります</p>



<p class="wp-block-paragraph">VBA-JSONは内部で「Dictionary」という、キーと値をセットで扱うデータの入れ物を使っています、このDictionaryをそのまま書くスタイル(早期バインディングと言います)で動かすために、<strong><span class="swl-marker mark_yellow">Microsoft Scripting Runtime への参照設定が必要</span></strong>になります</p>



<p class="wp-block-paragraph">設定はVBEのメニューからで、手順はこうです</p>



<ol style="background-color:#f8fbfd" class="wp-block-list -list-under-dashed has-background">
<li>VBEのメニューで「ツール → 参照設定」を開く</li>



<li>一覧から「<code>Microsoft Scripting Runtime</code>」を探す</li>



<li>チェックボックスにチェックを入れて「OK」を押す</li>
</ol>



<p class="wp-block-paragraph">これを忘れると、コードを実行したときに「ユーザー定義型は定義されていません」というエラーが出ます、後ろのFAQでも触れますが、この参照設定はかなりの確率でハマるので先に済ませておくのがおすすめです</p>
</div></div>
</div>



<h3 class="wp-block-heading">Mac の Excel で使う場合</h3>



<p class="wp-block-paragraph">MacのExcelには Microsoft Scripting Runtime が無いので、参照設定の代わりに同じ作者の「<strong>VBA-Dictionary</strong>」というライブラリを一緒に入れます</p>



<p class="wp-block-paragraph"><a href="https://github.com/VBA-tools/VBA-Dictionary" target="_blank" rel="noopener noreferrer">VBA-tools/VBA-Dictionary</a> から <code>Dictionary.cls</code> をダウンロードして、JsonConverter.bas と同じようにインポートすればOKです、WindowsとMacの両方で動かしたいときも、参照設定ではなくこのVBA-Dictionaryを使う形にしておくと安心ですね</p>



<p class="wp-block-paragraph">ここまでできたら準備は完了です、いよいよ実際にJSONを扱っていきます</p>



<h2 class="wp-block-heading">ParseJson でJSONを解析(パース)してみる</h2>



<p class="wp-block-paragraph">JSON形式のテキストを、VBAで扱えるデータ構造(DictionaryやCollection)に変換することを「<strong>解析(パース)</strong>」と言います</p>



<p class="wp-block-paragraph">このパースが、<code>ParseJson</code> 関数を使えば<strong>たった一行で完了</strong>します</p>



<p class="wp-block-paragraph">まずはWeb APIからJSONを取ってきてパースする、いちばんよくある形のサンプルです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>&#39; /// 事前準備 ///
&#39; VBEの [ツール] &gt; [参照設定] から下記にチェックを入れる
&#39; ・Microsoft Scripting Runtime   (Dictionary用、VBA-JSONに必須)
&#39; ・Microsoft XML, v6.0           (APIを叩く場合)
Sub GetJsonData()
    Dim http As Object
    Dim jsonText As String
    Dim parsedData As Object &#39; 解析後のデータ格納用

    &#39; Web APIからJSONデータを取得(例)
    Set http = CreateObject(&quot;MSXML2.XMLHTTP&quot;)
    http.Open &quot;GET&quot;, &quot;https://javeo.jp/wp-json/test/v1/data&quot;, False
    http.send
    jsonText = http.responseText

    &#39; ここがVBA-JSONの本体、JSONを解析
    Set parsedData = ParseJson(jsonText)

    &#39; 解析したデータをデバッグ出力
    Debug.Print &quot;名前: &quot; & parsedData(1)(&quot;name&quot;)
    Debug.Print &quot;身長: &quot; & parsedData(1)(&quot;height&quot;)

    Set http = Nothing
    Set parsedData = Nothing
End Sub</code></pre></div>



<p class="wp-block-paragraph">長く見えるかもしれませんが、VBA-JSONを使っている箇所は、結局このたった一行だけです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Set parsedData = ParseJson(jsonText)</code></pre></div>



<p class="wp-block-paragraph">この一行を通すことで、最初のサンプルにあった「長いただの文字列」が、<code>parsedData(1)("name")</code> といった具合に<strong>要素を指定してデータを取り出せる構造</strong>に変わります</p>



<p class="wp-block-paragraph">APIを使わず、手元の文字列をそのままパースして試すこともできます、まずは動きを確かめたいときはこちらが手っ取り早いです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Sub ParseSample()
    Dim jsonText As String
    Dim parsedData As Object

    &#39; 動作確認用に文字列を直接用意
    jsonText = &quot;[{&quot;&quot;name&quot;&quot;:&quot;&quot;Javeo&quot;&quot;,&quot;&quot;height&quot;&quot;:180}]&quot;

    Set parsedData = ParseJson(jsonText)

    Debug.Print parsedData(1)(&quot;name&quot;) &#39; → Javeo
    Debug.Print parsedData(1)(&quot;height&quot;) &#39; → 180
End Sub</code></pre></div>



<p class="wp-block-paragraph">VBAの中で「&#8221;」を書くときは「&#8221;&#8221;」と2つ重ねる必要があるので、そこだけ少し読みづらいですが、やっていることは「文字列をパースして取り出す」だけです</p>



<h2 class="wp-block-heading">パースしたJSONから値を取り出す(配列・オブジェクト・ネスト)</h2>



<p class="wp-block-paragraph">ここがVBA-JSONを使ううえで一番つまずきやすく、そして一番大事なところです</p>



<p class="wp-block-paragraph">ポイントは、<strong>パース後のデータが「Dictionary」と「Collection」の2種類に化けている</strong>という点です</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li>JSONの「{ }」(オブジェクト)→ <strong>Dictionary</strong> になる(キー名で取り出す)</li>



<li>JSONの「[ ]」(配列)→ <strong>Collection</strong> になる(番号で取り出す)</li>
</ul>



<p class="wp-block-paragraph">この区別さえ分かれば、あとは指定の仕方が決まります、サンプルの「JaveoとJavelinのデータ」を例に、ひとつずつ見ていきましょう</p>



<h3 class="wp-block-heading">配列(Collection)は番号で取り出す</h3>



<p class="wp-block-paragraph">サンプルのJSONは全体が「[ ]」で囲まれた配列なので、パース直後の <code>parsedData</code> はCollectionになっています</p>



<p class="wp-block-paragraph">Collectionは「何番目」という番号(インデックス)で要素を取り出します、<strong>VBAのCollectionは1番から始まる</strong>のがポイントで、0番からじゃないので注意です</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>&#39; 1人目(Javeo)のデータを取り出す
Set firstPerson = parsedData(1)

&#39; 2人目(Javelin)のデータを取り出す
Set secondPerson = parsedData(2)</code></pre></div>



<h3 class="wp-block-heading">オブジェクト(Dictionary)はキー名で取り出す</h3>



<p class="wp-block-paragraph">取り出した1人分のデータ(<code>parsedData(1)</code>)は「{ }」のオブジェクトなので、こちらはDictionaryです</p>



<p class="wp-block-paragraph">Dictionaryは番号ではなく、<strong>キー名(項目名)を指定して</strong>値を取り出します</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>&#39; 1人目の名前と身長
Debug.Print parsedData(1)(&quot;name&quot;)   &#39; → Javeo
Debug.Print parsedData(1)(&quot;height&quot;) &#39; → 180

&#39; 真偽値もそのまま取れる
Debug.Print parsedData(1)(&quot;glasses&quot;) &#39; → True</code></pre></div>



<p class="wp-block-paragraph"><code>parsedData(1)("name")</code> は「配列の1番目(Collection)→ その中のnameキー(Dictionary)」という読み方になります、カッコが連続するのは、この2段階を一気に書いているからなんですね</p>



<h3 class="wp-block-heading">ネスト(入れ子)は同じ要領でつなげる</h3>



<p class="wp-block-paragraph">サンプルの <code>birthdate</code> は、中にさらに <code>year / month / day</code> を持つ「入れ子のオブジェクト」です、こういうネストも、考え方は同じでカッコをつなげるだけです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>&#39; 1人目の生年月日(birthdateの中のyear)
Debug.Print parsedData(1)(&quot;birthdate&quot;)(&quot;year&quot;)  &#39; → 2000
Debug.Print parsedData(1)(&quot;birthdate&quot;)(&quot;month&quot;) &#39; → 1

&#39; 配列の中の値(favorite_foodsの1個目)
Debug.Print parsedData(1)(&quot;favorite_foods&quot;)(1) &#39; → Meat</code></pre></div>



<p class="wp-block-paragraph">コツは、<strong><span class="swl-marker mark_yellow">「{ }が来たらキー名」「[ ]が来たら番号」をJSONの形に合わせて交互に書いていく</span></strong>だけ、整形したJSONを見ながら指でたどると間違えにくいです</p>



<h3 class="wp-block-heading">ループでまとめて処理する</h3>



<p class="wp-block-paragraph">実際の業務では「全員分をシートに書き出す」みたいに、繰り返し処理(ループ)で回すことがほとんどです</p>



<p class="wp-block-paragraph">配列(Collection)は <code>For Each</code> でぐるっと回せます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Sub WriteToSheet()
    Dim parsedData As Object
    Dim person As Object
    Dim i As Long

    Set parsedData = ParseJson(jsonText) &#39; jsonTextは取得済みとする

    i = 1
    &#39; 配列の要素(1人分のデータ)を1件ずつ取り出す
    For Each person In parsedData
        Cells(i, 1).Value = person(&quot;name&quot;)
        Cells(i, 2).Value = person(&quot;height&quot;)
        Cells(i, 3).Value = person(&quot;birthdate&quot;)(&quot;year&quot;)
        i = i + 1
    Next person
End Sub</code></pre></div>



<p class="wp-block-paragraph">キー名が分からないオブジェクトを総当たりで見たいときは、<code>.Keys</code> でキー一覧を回す手もあります</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Dim key As Variant
&#39; 1人目のオブジェクトのキーと値を全部出す
For Each key In parsedData(1).Keys
    Debug.Print key & &quot; = &quot; & parsedData(1)(key)
Next key</code></pre></div>



<p class="wp-block-paragraph">ここまでで「読み込む(パース)」側はバッチリです、配列は番号・オブジェクトはキー名、これさえ押さえれば、たいていのJSONは取り出せます</p>



<h2 class="wp-block-heading">ConvertToJson でVBAのデータをJSONに変換(生成)</h2>



<p class="wp-block-paragraph">今度は逆方向、つまりVBAのDictionaryやCollectionから<strong>JSON文字列を作る(生成する)</strong>パターンです、こちらは <code>ConvertToJson</code> 関数を使います</p>



<p class="wp-block-paragraph">「VBAで作ったデータをAPIに送りたい」「JSON形式でファイルに保存したい」みたいなときに出番があります</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Sub CreateJsonString()
    Dim postData As Object
    Dim skillsCollection As Collection
    Dim jsonString As String

    &#39; データを格納する親オブジェクトを準備
    Set postData = CreateObject(&quot;Scripting.Dictionary&quot;)

    &#39; 基本的なキーと値を追加
    postData(&quot;name&quot;) = &quot;鈴木 一郎&quot;
    postData(&quot;age&quot;) = 25

    &#39; 配列用のオブジェクトを「Collection」で準備
    Set skillsCollection = New Collection

    &#39; Collectionにデータを追加
    skillsCollection.Add &quot;Word&quot;
    skillsCollection.Add &quot;PowerPoint&quot;

    &#39; 親オブジェクトにCollectionを追加
    postData.Add &quot;skills&quot;, skillsCollection

    &#39; DictionaryをJSON文字列に変換
    jsonString = ConvertToJson(postData)

    &#39; 結果をイミディエイトウィンドウに出力
    Debug.Print jsonString
    &#39; 想定される出力: {&quot;name&quot;:&quot;鈴木 一郎&quot;,&quot;age&quot;:25,&quot;skills&quot;:[&quot;Word&quot;,&quot;PowerPoint&quot;]}

    &#39; オブジェクトの解放
    Set postData = Nothing
    Set skillsCollection = Nothing
End Sub</code></pre></div>



<p class="wp-block-paragraph">ポイントは、<strong><span class="swl-marker mark_yellow">JSONの「{ }」はDictionary、「[ ]」はCollectionで組み立てる</span></strong>という点です、パースのときと逆の対応関係になっているだけなので、慣れると自然に書けるようになります</p>



<p class="wp-block-paragraph">この <code>jsonString</code> をWeb APIに送信(POSTなど)すれば、VBAで作ったデータをサーバーに送れます</p>



<h3 class="wp-block-heading">改行付きで見やすく出力したいとき</h3>



<p class="wp-block-paragraph">デフォルトのままだと、生成されるJSONは改行なしの一行になります、人が読む用にきれいに整形したいときは、<code>Whitespace</code> オプションを付けます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>&#39; インデント2つ分で改行を入れて整形
jsonString = ConvertToJson(postData, Whitespace:=2)</code></pre></div>



<p class="wp-block-paragraph">ファイルに保存して中身を確認したいときなんかは、こちらのほうが見やすくておすすめです</p>



<h2 class="wp-block-heading">VBA-JSONを使わずにJSONを扱う方法(JScript)</h2>



<p class="wp-block-paragraph">ここまでVBA-JSONをおすすめしてきましたが、「ライブラリを追加したくない」「配布先でインポートさせるのが面倒」というケースもありますよね</p>



<p class="wp-block-paragraph">そういうときの代替案として、<strong>Windows標準のJScriptエンジンを使ってJSONをパースする方法</strong>もあるので紹介しておきます</p>



<p class="wp-block-paragraph">JScriptはWindowsに最初から入っているスクリプト実行の仕組みで、これを <code>ScriptControl</code> という部品から呼び出すと、JavaScriptの <code>JSON.parse</code> をVBAから間接的に使えます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Sub ParseByJScript()
    Dim sc As Object
    Dim jsonText As String
    Dim parsed As Object

    jsonText = &quot;{&quot;&quot;name&quot;&quot;:&quot;&quot;Javeo&quot;&quot;,&quot;&quot;height&quot;&quot;:180}&quot;

    &#39; JScriptエンジンを用意
    Set sc = CreateObject(&quot;ScriptControl&quot;)
    sc.Language = &quot;JScript&quot;

    &#39; JavaScriptのJSON.parseで解析
    Set parsed = sc.Eval(&quot;(&quot; & jsonText & &quot;)&quot;)

    &#39; プロパティ名で値を取り出す
    Debug.Print parsed.name   &#39; → Javeo
    Debug.Print parsed.height &#39; → 180
End Sub</code></pre></div>



<p class="wp-block-paragraph">この方法のメリットは、外部ライブラリのインポートが要らないことです</p>



<p class="wp-block-paragraph">ただ、いくつか弱点もあって、正直なところ常用にはVBA-JSONのほうが向いています</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li><code>ScriptControl</code> は32bit版のOfficeでしか動かない(64bit版では別の書き方が必要)</li>



<li>取り出した値の扱い(配列やネスト)がVBA-JSONより少しクセがある</li>



<li>Macでは使えない</li>
</ul>



<p class="wp-block-paragraph">なので個人的には、<strong><span class="swl-marker mark_yellow">基本はVBA-JSON、どうしてもライブラリを足せない事情があるときだけJScript</span></strong>という使い分けがおすすめです</p>



<h2 class="wp-block-heading">VBA-JSONのよくあるつまずき・FAQ</h2>



<p class="wp-block-paragraph">VBA-JSONでハマりやすいポイントを、質問形式でまとめておきます、エラーが出たらまずここを確認してみてください</p>



<h3 class="wp-block-heading">「ユーザー定義型は定義されていません」と出る</h3>



<p class="wp-block-paragraph">これは <strong><span class="swl-marker mark_yellow">参照設定の漏れ</span></strong>がほぼ原因です</p>



<p class="wp-block-paragraph">VBA-JSONはDictionaryを使うので、WindowsのExcelなら「ツール → 参照設定」で <code>Microsoft Scripting Runtime</code> にチェックが入っているか確認してください、入っていなければチェックを入れて保存し、もう一度実行すれば直ります</p>



<p class="wp-block-paragraph">MacのExcelの場合は、前述のVBA-Dictionary(<code>Dictionary.cls</code>)を取り込んでいるかを確認しましょう</p>



<h3 class="wp-block-heading">「KeyNotFoundError」のようなエラーが出る</h3>



<p class="wp-block-paragraph">これは、<strong>JSONに存在しないキー名を指定して取り出そうとした</strong>ときに出るエラーです</p>



<p class="wp-block-paragraph">キー名のタイプミス、大文字小文字の違い、そもそもそのキーが無いJSONだった、あたりが定番の原因ですね</p>



<p class="wp-block-paragraph">このエラーはハマりやすいので、原因の切り分けと対処法を <a href="https://javeo.jp/vba-json-error/" target="_blank" rel="noopener noreferrer">VBA-JSONでKeyNotFoundErrorが発生するときの対処をまとめた記事</a> で別途くわしく解説しています、同じエラーで止まっている方はそちらをどうぞ</p>



<h3 class="wp-block-heading">日本語が文字化けする</h3>



<p class="wp-block-paragraph">Web APIから取得したJSONの日本語が文字化けする場合は、<strong>文字コードの取り違え</strong>が原因のことが多いです</p>



<p class="wp-block-paragraph">多くのAPIはUTF-8で返してくるので、<code>responseText</code> をそのまま使うとShift_JIS環境で化けることがあります、その場合は <code>responseBody</code>(バイト列)を取得して、UTF-8として読み直すと直ります</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>Dim stream As Object
Set stream = CreateObject(&quot;ADODB.Stream&quot;)
stream.Open
stream.Type = 1               &#39; バイナリ
stream.Write http.responseBody
stream.Position = 0
stream.Type = 2               &#39; テキスト
stream.Charset = &quot;UTF-8&quot;       &#39; UTF-8として読み直す
jsonText = stream.ReadText
stream.Close</code></pre></div>



<h3 class="wp-block-heading">キーがあるか分からないとき、どう書けばいい？</h3>



<p class="wp-block-paragraph">キーが存在するか不安なときは、取り出す前に <code>.Exists</code> でチェックすると安全です(Dictionaryの機能です)</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="VBA"><code>If parsedData(1).Exists(&quot;weight&quot;) Then
    Debug.Print parsedData(1)(&quot;weight&quot;)
Else
    Debug.Print &quot;weightキーはありません&quot;
End If</code></pre></div>



<p class="wp-block-paragraph">これを挟んでおくと、キーが無いJSONが来てもエラーで止まらずに処理を続けられます</p>



<h2 class="wp-block-heading">VBA-JSONの活用例</h2>



<p class="wp-block-paragraph">導入と使い方が分かったところで、「で、実際どんなことに使えるの？」というイメージを少し具体的にしておきます</p>



<p class="wp-block-paragraph">いちばん多いのは、やはり <strong><span class="swl-marker mark_yellow">Web APIのレスポンス(JSON)をパースしてシートに展開する</span></strong>パターンです、為替レート・天気・在庫情報みたいな「外部の最新データ」をExcelに自動で取り込めると、手作業のコピペがまるごと無くなります</p>



<p class="wp-block-paragraph">たとえばフリマやECのAPIを叩いて、出品データや売上をExcelに集計する、みたいな使い方ですね、APIへリクエストを送る具体的な書き方は <a href="https://javeo.jp/ebay-api-request/" target="_blank" rel="noopener noreferrer">eBay APIにVBAでリクエストを送る方法の記事</a> にまとめているので、JSONパースと組み合わせると一通りの流れがつかめます</p>



<p class="wp-block-paragraph">逆に <code>ConvertToJson</code> 側だと、VBAで組み立てたデータをJSONにして、メール本文やAPIのリクエストボディに載せる、といった使い方ができます、VBAから自動でメールを送る仕組みは <a href="https://javeo.jp/vba-gmail-send/" target="_blank" rel="noopener noreferrer">VBAでGmailを送信する方法の記事</a> で扱っているので、データ生成と通知を組み合わせたい方はあわせてどうぞ</p>



<p class="wp-block-paragraph">そもそもVBA自体がはじめてで「Dim とか For Each の書き方からあやしい…」という方は、先に <a href="https://javeo.jp/vba-beginner-001/" target="_blank" rel="noopener noreferrer">VBA入門の記事</a> で基礎をさらっておくと、この記事のコードもぐっと読みやすくなると思います</p>



<h2 class="wp-block-heading">AIにVBA-JSONのコードを書いてもらうコツ</h2>



<p class="wp-block-paragraph">最近はClaudeやChatGPTにVBAコードを書いてもらう人も増えてきました、もちろんVBA-JSONを使ったコードも、頼めば書いてくれます</p>



<p class="wp-block-paragraph">ただ、AIにそのまま「VBAでJSONをパースして」と頼むと、<strong>意図しない実装を返してくる</strong>ことがあるんですよね</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li>VBA-JSONを使わず、自前のJSON解析関数をゼロから書こうとする</li>



<li>参照設定の前提がズレていて、そのままだと動かないコードを返す</li>



<li>標準機能だけで無理やり読もうとして、やたら長いコードになる</li>
</ul>



<p class="wp-block-paragraph">こうしたズレを避けるには、依頼するときに次のような前提を明示するのがおすすめです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain" data-lang="AIへの依頼例"><code>VBAで○○のJSONデータをパースするコードを書いてほしい
前提:
- VBA-JSON(JsonConverter.bas)を導入済み
- ParseJson の戻り値を Dictionary / Collection として直接扱う
- 参照設定は Microsoft Scripting Runtime を入れている前提
- 配列は番号、オブジェクトはキー名でアクセスする形で</code></pre></div>



<p class="wp-block-paragraph">エラーが出たときも、コードとエラーメッセージをまとめて貼り付ければ、AIが原因と対処をだいたい提示してくれます、自分でハマる時間がかなり減らせるので、これは活用しない手はないです</p>



<p class="wp-block-paragraph">ClaudeでVBAコードを書いてもらう基本的な流れは <a href="https://javeo.jp/claude-howto-beginner/" target="_blank" rel="noopener noreferrer">Claudeの使い方を初心者向けに解説した記事</a> にまとめているので、AIにコードを頼むのが初めての方は、そちらから読むとスムーズだと思います</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">VBA-JSONを使えば、これまでVBAでは扱いにくかったJSONが、ぐっと身近になります</p>



<p class="wp-block-paragraph">導入のポイントはこの2つだけです</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li><code>JsonConverter.bas</code> をVBEにインポートする</li>



<li><code>Microsoft Scripting Runtime</code> に参照設定する(Macは VBA-Dictionary)</li>
</ul>



<p class="wp-block-paragraph">使い方も、覚える関数は2つだけです</p>



<ul style="background-color:#FFFFDC80" class="wp-block-list -list-under-dashed has-background">
<li><strong>JSONを読み込むなら <code>ParseJson</code></strong>(配列は番号、オブジェクトはキー名で取り出す)</li>



<li><strong>JSONを書き出すなら <code>ConvertToJson</code></strong>(「{ }」はDictionary、「[ ]」はCollectionで組む)</li>
</ul>



<p class="wp-block-paragraph">この導入2ステップと関数2つさえ押さえれば、Web APIとの連携をはじめ、VBAでできることの幅がかなり広がります</p>



<p class="wp-block-paragraph">まずは手元の短いJSONを <code>ParseJson</code> に通して、<code>Debug.Print</code> で1個取り出してみるところから始めると、感覚がつかみやすいと思います</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-json/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA】VBAでもWebDriverWaitを使いたい</title>
		<link>https://javeo.jp/vba-webdriverwait/</link>
					<comments>https://javeo.jp/vba-webdriverwait/#respond</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Sun, 07 Sep 2025 14:44:23 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[SeleniumBasic]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[スクレイピング]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=3569</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p>待機処理が必要な理由 SeleniumでWebサイトを操作するときにありがちな内容がこちら これらを解決するには「要素が存在する・表示される・有効になる」まで待機処理が必要です WebDriverWaitクラスでできるこ [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p class="wp-block-paragraph">PythonでSeleniumを利用するときに利用必須ともいえるWebDriverWaitとexpected_conditionsですが、残念ながらVBAにはありません</p>



<p class="wp-block-paragraph">この記事では、<strong>VBAでWebDriverWait</strong>+expected_conditions<strong>を再現するクラス</strong>を作り、有用な待機処理を実現します</p>



<p class="wp-block-paragraph">※Pythonの場合はこちらをどうぞ</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-excel-python wp-block-embed-excel-python"><div class="wp-block-embed__wrapper">
https://javeo.jp/python_wait/
</div></figure>
</div>



<h2 class="wp-block-heading">待機処理が必要な理由</h2>



<p class="wp-block-paragraph">SeleniumでWebサイトを操作するときにありがちな内容がこちら</p>



<ul class="wp-block-list">
<li>ページロードが完了していないうちに要素を取得してエラー</li>



<li>JavaScriptで動的に生成されるボタンや入力欄がまだ非表示</li>



<li>ボタンが表示されてもクリック可能になる前に操作しようとしてエラー</li>
</ul>



<p class="wp-block-paragraph">これらを解決するには「要素が存在する・表示される・有効になる」まで待機処理が必要です</p>



<h2 class="wp-block-heading">WebDriverWaitクラスでできること</h2>



<p class="wp-block-paragraph">今回作ったVBAクラス <code>WebDriverWait</code> は、PythonのWebDriverWaitに近い操作性で以下の条件を待機できます</p>



<figure class="wp-block-table"><table><thead><tr><th>メソッド</th><th>説明</th></tr></thead><tbody><tr><td><code>UntilPresence(By)</code></td><td>DOM上に指定した <code>By</code> が存在するまで待機</td></tr><tr><td><code>UntilVisibleLocated(By)</code></td><td>画面上に <code>By</code> で指定した要素が表示されるまで待機 (<code>IsDisplayed</code>)</td></tr><tr><td><code>UntilVisible(element)</code></td><td>指定した <code>WebElement</code> が表示されるまで待機</td></tr><tr><td><code>UntilEnableLocated(By)</code></td><td>画面上に <code>By</code> で指定した要素が利用可能になるまで待機 (<code>IsDisplayed &amp; IsEnabled</code>)</td></tr><tr><td><code>UntilEnable(element)</code></td><td>指定した <code>WebElement</code> が利用可能になるまで待機</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">ポイント：</p>



<ul class="wp-block-list">
<li>成功時は <code>WebElement</code> を返す</li>



<li>タイムアウト時は <code>Nothing</code> を返す</li>



<li>Pythonのように例外処理に頼らずVBAらしい安全な設計</li>
</ul>



<h2 class="wp-block-heading">VBA版WebDriverWaitの実装例</h2>



<p class="wp-block-paragraph">以下のクラスモジュールをVBAに追加してください※クラス名は <strong><code>WebDriverWait</code></strong> にしています</p>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2025/09/image.jpg"><img decoding="async" width="1024" height="538" src="https://javeo.jp/wp-content/uploads/2025/09/image-1024x538.jpg" alt="" class="wp-image-3570" srcset="https://javeo.jp/wp-content/uploads/2025/09/image-1024x538.jpg 1024w, https://javeo.jp/wp-content/uploads/2025/09/image-300x158.jpg 300w, https://javeo.jp/wp-content/uploads/2025/09/image-150x79.jpg 150w, https://javeo.jp/wp-content/uploads/2025/09/image-768x403.jpg 768w, https://javeo.jp/wp-content/uploads/2025/09/image.jpg 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box not-nested-style cocoon-block-toggle"><input id="toggle-checkbox-202509242213270" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-202509242213270">プログラムを見る</label><div class="toggle-content">
<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-file="WebDriverWait " data-lang="Visual Basic + VBA"><code>&#39;--- クラス名: WebDriverWait ---
Option Explicit
&#39;====================================================================================================
&#39; PythonのWebDriverWaitの一部を再現したクラス
&#39; ※条件に合致した場合はWebElementを返して一致しなかった場合はNothingを返す
&#39;   - UntilPresenceeLocated・DOM上に指定したelementが表示されるまで待機は発生し得ないから準備していない
&#39;   - UntilPresence・・・・・DOM上に指定したByが表示されるまで待機
&#39;   - UntilVisibleLocated・・画面上に指定したelementが表示されるまで待機（IsDisplayed）
&#39;   - UntilVisible ・・・・・画面上に指定したByが表示されるまで待機（IsDisplayed）
&#39;   - UntilEnableLocated・・画面上に指定したelementが利用できるまで待機（IsDisplayed & IsEnabled）
&#39;   - UntilEnable ・・・・・画面上に指定したByが利用できるまで待機（IsDisplayed & IsEnabled）
&#39;====================================================================================================
Private pDriver As Selenium.WebDriver
Private pTimeout As Double
Private pInterval As Double

Public Sub Init(driver As Selenium.WebDriver, Optional timeoutSeconds As Double = 10, Optional intervalSeconds As Double = 0.5)
    Set pDriver = driver
    pTimeout = timeoutSeconds
    pInterval = intervalSeconds
End Sub

&#39; Presence
Public Function UntilPresence(By As Selenium.By) As Selenium.WebElement
    Dim start As Double: start = Timer
    Dim elem As Selenium.WebElement
    
    Do
        On Error Resume Next
        Set elem = pDriver.FindElement(By)
        On Error GoTo 0
        
        If Not elem Is Nothing Then
            Set UntilPresence = elem
            Exit Function
        End If
        
        DoEvents
        Application.wait Now + TimeSerial(0, 0, pInterval)
    Loop While Timer - start &lt; pTimeout
    
    Set UntilPresence = Nothing
End Function

&#39; Visibility (By指定)
Public Function UntilVisibleLocated(By As Selenium.By) As Selenium.WebElement
    Dim start As Double: start = Timer
    Dim elem As Selenium.WebElement
    
    Do
        On Error Resume Next
        Set elem = pDriver.FindElement(By)
        On Error GoTo 0
        
        If Not elem Is Nothing Then
            If elem.IsDisplayed Then
                Set UntilVisibleLocated = elem
                Exit Function
            End If
        End If
        
        DoEvents
        Application.wait Now + TimeSerial(0, 0, pInterval)
    Loop While Timer - start &lt; pTimeout
    
    Set UntilVisibleLocated = Nothing
End Function

&#39; Visibility (element指定)
Public Function UntilVisible(elem As Selenium.WebElement) As Selenium.WebElement
    Dim start As Double: start = Timer
    
    Do
        If Not elem Is Nothing Then
            If elem.IsDisplayed Then
                Set UntilVisible = elem
                Exit Function
            End If
        End If
        
        DoEvents
        Application.wait Now + TimeSerial(0, 0, pInterval)
    Loop While Timer - start &lt; pTimeout
    
    Set UntilVisible = Nothing
End Function

&#39; Enable (By指定)
Public Function UntilEnableLocated(By As Selenium.By) As Selenium.WebElement
    Dim start As Double: start = Timer
    Dim elem As Selenium.WebElement
    
    Do
        On Error Resume Next
        Set elem = pDriver.FindElement(By)
        On Error GoTo 0
        
        If Not elem Is Nothing Then
            If elem.IsDisplayed And elem.IsEnabled Then
                Set UntilEnableLocated = elem
                Exit Function
            End If
        End If
        
        DoEvents
        Application.wait Now + TimeSerial(0, 0, pInterval)
    Loop While Timer - start &lt; pTimeout
    
    Set UntilEnableLocated = Nothing
End Function

&#39; Enable (element指定)
Public Function UntilEnable(elem As Selenium.WebElement) As Selenium.WebElement
    Dim start As Double: start = Timer
    
    Do
        If Not elem Is Nothing Then
            If elem.IsDisplayed And elem.IsEnabled Then
                Set UntilEnable = elem
                Exit Function
            End If
        End If
        
        DoEvents
        Application.wait Now + TimeSerial(0, 0, pInterval)
    Loop While Timer - start &lt; pTimeout
    
    Set UntilEnable = Nothing
End Function
</code></pre></div>
</div></div>



<h2 class="wp-block-heading">使い方サンプル</h2>



<p class="wp-block-paragraph">このブログの練習用ページでテストできるようにしていますので自由にテストしてください</p>



<p class="wp-block-paragraph">ポイントはInit部分で引数は下記の通りです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>wait.Init driver, {最大待機秒数}, {判定間隔}</code></pre></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box not-nested-style cocoon-block-toggle"><input id="toggle-checkbox-202509242213271" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-202509242213271">プログラムを見る</label><div class="toggle-content">
<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Sub test()
    Dim driver As New Selenium.ChromeDriver
    Dim By As New Selenium.By
    
    driver.Get &quot;https://javeo.jp/practice_scraping/&quot;

    Dim wait As New WebDriverWait
    wait.Init driver, 10, 0.5

    &#39; presence_of_element_located(By)
    Dim elemUser As Selenium.WebElement
    Set elemUser = wait.UntilPresence(By.Css(&quot;#input_test&quot;))
    

    &#39; visibility_of_element_located(By)
    Dim elemPass As Selenium.WebElement
    Set elemPass = wait.UntilVisibleLocated(By.Css(&quot;#textarea_test&quot;))

    &#39; element_to_be_clickable(By)
    Dim elemBtn As Selenium.WebElement
    Set elemBtn = wait.UntilClickableLocated(By.Css(&quot;[name=&quot;&quot;checkbox_test&quot;&quot;]&quot;))

    
    elemUser.SendKeys &quot;testuser&quot;
    elemPass.SendKeys &quot;secret&quot;
    elemBtn.Click
End Sub
</code></pre></div>
</div></div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">個人的にPythonでもSeleniumを使うのでWebDriverWaitが使えない不便さを感じていました</p>



<p class="wp-block-paragraph">PythonとVBAでは思想も違うので適当にいじってますが、ほぼ同じように使えてスッキリです！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-webdriverwait/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA】VBA-JSON不要！VBAでChromedriverを自動更新</title>
		<link>https://javeo.jp/vba-chromedriver-auto-update-lite/</link>
					<comments>https://javeo.jp/vba-chromedriver-auto-update-lite/#respond</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Sun, 07 Sep 2025 13:09:12 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[SeleniumBasic]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[スクレイピング]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=3564</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p>やっていること 以前作成したVBAはJSON API endpointsを総当たりで取得していたのでJSONをパースする必要がありましたが、APIでドライバのバージョンを直接取得できることに気づいて少し手順を簡略化できま [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p class="wp-block-paragraph">以前に別で作成したVBAのChromedriver自動更新プログラムですが色々見直すと実はVBA-JSONなしでも十分ってことに気づいて別途作成しました</p>



<p class="wp-block-paragraph">条件付きの簡略版ではありますのでご自身の環境に合わせて使い分けてください</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-excel-python wp-block-embed-excel-python"><div class="wp-block-embed__wrapper">
https://javeo.jp/vba-chromedriver-auto-update/
</div></figure>
</div>



<h2 class="wp-block-heading">やっていること</h2>



<ol class="wp-block-list has-watery-yellow-background-color has-background">
<li>chromedriverの保存先は端末環境によって違うので候補となる3箇所のフォルダ有無を確認</li>



<li>chromeの保存先も端末環境によって違うので候補となる3箇所のフォルダ有無を確認</li>



<li>PowerShellでchromeのバージョンを取得する<br>※なので一瞬PowerShellの画面がチラつきます</li>



<li>APIでChrome.exeのビルドまで一致している最新chromedriverのダウンロードパスを取得</li>



<li>ダウンロードしたzipファイルを解凍してをseleniumbasic用のフォルダへコピーする</li>
</ol>



<p class="wp-block-paragraph">以前作成したVBAはJSON API endpointsを総当たりで取得していたのでJSONをパースする必要がありましたが、APIでドライバのバージョンを直接取得できることに気づいて少し手順を簡略化できました</p>



<p class="wp-block-paragraph">処理としては数秒しか変わりませんがVBA-JSOＮ不要になったのは個人的にGoodポイント</p>



<p class="is-style-information-box has-box-style wp-block-paragraph">ここからは以前と同じことを書いてますが単独でこのページを見ていただいた方向けです</p>



<h2 class="wp-block-heading">必要な参照設定</h2>



<p class="wp-block-paragraph">このプログラムを実行するために設定した参照設定</p>



<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2023/07/image-4.png"><img decoding="async" width="455" height="317" src="https://javeo.jp/wp-content/uploads/2023/07/image-4.png" alt="" class="wp-image-3282" srcset="https://javeo.jp/wp-content/uploads/2023/07/image-4.png 455w, https://javeo.jp/wp-content/uploads/2023/07/image-4-300x209.png 300w, https://javeo.jp/wp-content/uploads/2023/07/image-4-150x105.png 150w" sizes="(max-width: 455px) 100vw, 455px" /></a></figure>



<p class="wp-block-paragraph">追加したのは下記3つ</p>



<ul class="wp-block-list has-watery-yellow-background-color has-background">
<li>Microsoft Scripting Runtime</li>



<li>Microsoft XML, v6.0</li>



<li>Selenium Type Library</li>
</ul>



<p class="wp-block-paragraph">ここは旧バージョンと変わりありません</p>



<h2 class="wp-block-heading">ファイルへの反映手順</h2>



<p class="wp-block-paragraph">サンプルファイルとソースは下部に準備していますがファイルへの反映方法がわからない方向けに反映と使い方です</p>



<p class="wp-block-paragraph">そんなことわかってるからはよソースを！って方は<a href="#program-source" data-type="internal" data-id="#program-source">下部のソース</a>まで飛んじゃってください</p>



<h3 class="wp-block-heading">プロパティウィンドウを表示しておく</h3>



<p class="wp-block-paragraph">あとからモジュール名を変更したいので、もし表示されていない時は表示しておく</p>



<div class="wp-block-cocoon-blocks-blank-box-1 blank-box block-box">
<p class="wp-block-paragraph">ヘッダーメニュー：表示　→　プロパティウィンドウ　※F4がショートカットキー</p>
</div>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44.png"><img decoding="async" width="1024" height="555" src="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44-1024x555.png" alt="" class="wp-image-1298" srcset="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44-1024x555.png 1024w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44-300x163.png 300w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44-150x81.png 150w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44-768x416.png 768w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44-1536x832.png 1536w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_44.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h3 class="wp-block-heading">標準モジュールを追加</h3>



<p class="wp-block-paragraph">自動更新プログラム用にモジュールを追加する</p>



<div class="wp-block-cocoon-blocks-blank-box-1 blank-box block-box">
<p class="wp-block-paragraph">ヘッダーメニュー：挿入　→　標準モジュール</p>
</div>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54.png"><img decoding="async" width="1024" height="555" src="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54-1024x555.png" alt="" class="wp-image-1299" srcset="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54-1024x555.png 1024w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54-300x163.png 300w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54-150x81.png 150w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54-768x416.png 768w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54-1536x832.png 1536w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h03_54.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h3 class="wp-block-heading">モジュール名を変更する</h3>



<p class="wp-block-paragraph">必須ではないんですが、わかりやすい運用のためにはモジュール名変更推奨です</p>



<p class="wp-block-paragraph">今回は&#8221;<span class="marker-under">ChromeDriverAutoUpdateModule</span>&#8220;にします</p>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04.png"><img decoding="async" width="1024" height="555" src="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04-1024x555.png" alt="" class="wp-image-1300" srcset="https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04-1024x555.png 1024w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04-300x163.png 300w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04-150x81.png 150w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04-768x416.png 768w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04-1536x832.png 1536w, https://javeo.jp/wp-content/uploads/2023/08/2023-08-01_09h05_04.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h3 class="wp-block-heading">プログラムの使い方</h3>



<p class="wp-block-paragraph">「<span class="marker-under">&lt;モジュール名&gt;.&lt;プロシージャ名&gt;()</span>  ※&#8221;&lt;モジュール名&gt;.&#8221;は省略可」でプログラムを呼び出せるので、本体プログラムの最初に「<span class="marker-under">ChromeDriverAutoUpdateModule.ChromeDriverAutoUpdate()</span>」を追加すれば必要なときにchromedriverが自動更新されます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-file="sample" data-lang="Visual Basic + VBA"><code>Sub main()
&#39;---Chromedriverの自動更新 ※別モジュールを参照
If ChromeDriverAutoUpdateModule.ChromeDriverAutoUpdate Then
    Exit Sub
End If

&#39;－－・－－・－－以下にプログラムを－－・－－・－－
End Sub</code></pre></div>



<h2 class="wp-block-heading">Chromedriverの書き込み権限がない時</h2>



<p class="wp-block-paragraph">Winsows11からセキュリティ周りが厳しくなったのか管理者権限でSeleniumBasicをインストールした場合、Chromedriverを更新しようとすると書き込み権限なしエラーが発生するので対応まとめました</p>



<p class="wp-block-paragraph">画像の通りですが下記手順で権限設定ができます</p>



<ol class="wp-block-list has-watery-blue-background-color has-background">
<li>&#8220;C:\Program Files&#8221;にある&#8221;SeleniumBasic&#8221;フォルダを右クリック</li>



<li>右クリックメニューで&#8221;プロパティ&#8221;をクリック</li>



<li>セキュリティタブに移って&#8221;編集&#8221;ボタンをクリック</li>



<li>&#8220;Users（{コンピュータ名}\Users）&#8221;をクリック</li>



<li>&#8220;フルコントロール&#8221;にチェックがついていないはずなのでクリックしてチェックを付ける</li>



<li>&#8220;適用&#8221;ボタンをクリック</li>
</ol>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25.png"><img decoding="async" width="1024" height="538" src="https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25-1024x538.png" alt="" class="wp-image-3175" srcset="https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25-1024x538.png 1024w, https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25-300x158.png 300w, https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25-150x79.png 150w, https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25-768x403.png 768w, https://javeo.jp/wp-content/uploads/2023/07/2025-08-01_08h03_25.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">サンプルファイル</h2>



<p class="wp-block-paragraph">JSON-VBA含めて最低限のモジュールをセットしたファイル準備したので一から作る時のベースにしていただければ</p>





<h2 class="wp-block-heading" id="program-source">最後に実際のソース</h2>



<p class="wp-block-paragraph">まずはGithubをご利用の方向けはこちら</p>



<p class="wp-block-paragraph"><a href="https://github.com/javeo2022/webdriver_manager_VBA_Lite" target="_blank" rel="noreferrer noopener">https://github.com/javeo2022/webdriver_manager_VBA_Lite</a></p>



<p class="wp-block-paragraph">例によってコピペ用はこちらです</p>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box not-nested-style cocoon-block-toggle"><input id="toggle-checkbox-202510131456140" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-202510131456140">ソースを見る</label><div class="toggle-content">
<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function URLDownloadToFile Lib &quot;urlmon&quot; Alias &quot;URLDownloadToFileA&quot; _
                        (ByVal pCaller As Long, _
                         ByVal szURL As String, _
                         ByVal szFileName As String, _
                         ByVal dwReserved As Long, _
                         ByVal lpfnCB As Long) As Long
Private Declare PtrSafe Function SHCreateDirectoryEx Lib &quot;shell32.dll&quot; Alias &quot;SHCreateDirectoryExA&quot; _
                        (ByVal hwnd As LongPtr, ByVal pszPath As String, ByVal psa As LongPtr) As Long
#Else
Private Declare Function URLDownloadToFile Lib &quot;urlmon&quot; Alias &quot;URLDownloadToFileA&quot; _
                        (ByVal pCaller As Long, _
                         ByVal szURL As String, _
                         ByVal szFileName As String, _
                         ByVal dwReserved As Long, _
                         ByVal lpfnCB As Long) As Long
Private Declare Function SHCreateDirectoryEx Lib &quot;shell32.dll&quot; Alias &quot;SHCreateDirectoryExA&quot; _
                        (ByVal hwnd As LongPtr, ByVal pszPath As String, ByVal psa As LongPtr) As Long
#End If

Private Type VersionType &#39;---本当はクラスオブジェクトにしたいけどこれだけのためにモジュール作りたくない
    Major As Long
    Minor As Long
    Build As Long
    Revision As Long
    BuildVersion As String
    RevisionVersion As String
End Type
Const ZIP_FILE As String = &quot;chromedriver.zip&quot;
Const DRIVER_EXE As String = &quot;chromedriver.exe&quot;
Dim workPath As String
Sub test()
Call ChromeDriverAutoUpdate
End Sub
Public Function ChromeDriverAutoUpdate(Optional ByVal ForcedExecution As Boolean = False) As Boolean
&#39;====================================================================================================
&#39;chrome.exeとchromedriver.exeのバージョンを比較してchromedriverを自動更新する
&#39;もしくは強制実行フラグ（ForcedExecution）がTrueでも実行する
&#39;====================================================================================================
    Dim chromePath As String &#39;---chrome.exeが保存されているパス
    Dim chromeFullpath As String &#39;---chrome.exeまで含めたフルパス
    Dim chromeVersion As VersionType
    Dim chromedriverPath As String
    Dim chromedriverFullPath As String
    Dim objFso As New Scripting.FileSystemObject
    &#39; ---chromedriverをダウンロード用のフォルダを作成する　※Seleniumのキャッシュ構造に合わせている
    workPath = Environ(&quot;USERPROFILE&quot;) & &quot;\.cache\selenium\seleniumbasic&quot;
    Select Case SHCreateDirectoryEx(0&, workPath, 0&)
        Case 0:
            &#39; ---作成成功
        Case 183
            &#39; ---作成済み
        Case Else:
            &#39; ---作成できなかった時
            MsgBox &quot;ダウンロード用フォルダを作成できませんでした&quot; & vbCrLf & Error(Err), vbCritical
            ChromeDriverAutoUpdate = False
            Exit Function
    End Select
    
    &#39;---chrome本体のフォルダを探す
    Select Case True
        Case objFso.FolderExists(Environ(&quot;LOCALAPPDATA&quot;) & &quot;\Google\Chrome\Application&quot;)
            chromePath = Environ(&quot;LOCALAPPDATA&quot;) & &quot;\Google\Chrome\Application&quot;
        Case objFso.FolderExists(Environ(&quot;ProgramW6432&quot;) & &quot;\Google\Chrome\Application&quot;)
            chromePath = Environ(&quot;ProgramW6432&quot;) & &quot;\Google\Chrome\Application&quot;
        Case objFso.FolderExists(Environ(&quot;ProgramFiles&quot;) & &quot;\Google\Chrome\Application&quot;)
            chromePath = Environ(&quot;ProgramFiles&quot;) & &quot;\Google\Chrome\Application&quot;
        Case Else
            MsgBox &quot;&#39;chrome&#39;フォルダが見つかりません&quot;, vbCritical
            ChromeDriverAutoUpdate = False
            Exit Function
    End Select
    
    &#39;---念のためchrome.exeを確認する
    If objFso.FileExists(chromePath & &quot;\chrome.exe&quot;) = True Then
        chromeFullpath = chromePath & &quot;\chrome.exe&quot;
    Else
        MsgBox &quot;&#39;chrome.exe&#39;が見つかりません&quot;, vbCritical
        Exit Function
    End If
    
    &#39;---SeleniumBasicのフォルダを探す
    Select Case True
        Case objFso.FolderExists(Environ(&quot;LOCALAPPDATA&quot;) & &quot;\SeleniumBasic&quot;)
            chromedriverPath = Environ(&quot;LOCALAPPDATA&quot;) & &quot;\SeleniumBasic&quot;
        Case objFso.FolderExists(Environ(&quot;ProgramW6432&quot;) & &quot;\SeleniumBasic&quot;)
            chromedriverPath = Environ(&quot;ProgramW6432&quot;) & &quot;\SeleniumBasic&quot;
        Case objFso.FolderExists(Environ(&quot;ProgramFiles&quot;) & &quot;\SeleniumBasic&quot;)
            chromedriverPath = Environ(&quot;ProgramFiles&quot;) & &quot;\SeleniumBasic&quot;
        Case Else
            MsgBox &quot;&#39;SeleniumBasic&#39;のフォルダが見つかりません&quot;, vbCritical
            ChromeDriverAutoUpdate = False
            Exit Function
    End Select
    
    &#39;---念のためchromedriver.exeを確認する
    If objFso.FileExists(chromedriverPath & &quot;\&quot; & DRIVER_EXE) = False Then
        Debug.Print &quot;&#39;chromedriver.exe&#39;が見つかりませんでした&quot;
    End If
    chromedriverFullPath = chromedriverPath & &quot;\&quot; & DRIVER_EXE
        
    &#39;---chrome.exeのバージョンを取得する
    If GetChromeVersion(chromeFullpath, chromeVersion) = False Then &#39;---chrome.exeのバージョンを取得する
        MsgBox &quot;&#39;chrome.exe&#39;のバージョンが取得できませんでした&quot;, vbCritical
        ChromeDriverAutoUpdate = False
        Exit Function
    End If
    
    &#39;---chrome.exeのバージョンに合わせたchromedriver.exeをダウンロードする
    If ChromedriverQuickCheck(chromedriverPath, chromeVersion) = False Then &#39;---chromedriverのバージョンを取得する
        MsgBox &quot;&#39;chromedriver.exe&#39;のバージョンが取得できませんでした&quot;, vbCritical
        ChromeDriverAutoUpdate = False
        Exit Function
    End If
    
    &#39;---結果として更新していない場合もあるが、更新失敗じゃなくて更新不要な判定だからTrueを返す
    ChromeDriverAutoUpdate = True
Exit Function
ErrLabel:     &#39;---予期せぬエラーの分岐
    MsgBox &quot;chromedriver の入替に失敗しました&quot; & vbCrLf & Error(Err) & vbCrLf & &quot;※この画面のキャプチャを作成者へ送ってください&quot;
    ChromeDriverAutoUpdate = False
End Function
Private Function GetChromeVersion(ByVal chromeFullpath As String, ByRef chromeVersion As VersionType) As Boolean
&#39;====================================================================================================
&#39;PowerShellでchrome.exeのバージョン情報を取得する　※一瞬PowerShellが立ち上がる
&#39;====================================================================================================
    Dim command As String
    Dim objRet As Object
    
    On Error GoTo ErrLabel
        &#39;---chromeバージョン情報の初期値
        chromeVersion.Major = 1
        chromeVersion.Minor = 0
        chromeVersion.Build = 0
        chromeVersion.Revision = 0
        &#39;---chrome.exeのバージョンを取得するPowerShellコマンド
        command = &quot;powershell.exe -NoProfile -ExecutionPolicy Bypass (Get-Item -Path &#39;&quot; & chromeFullpath & &quot;&#39;).VersionInfo.FileVersion&quot;
        &#39;---PowerShellの実行結果をセット
        Set objRet = CreateObject(&quot;WScript.Shell&quot;).Exec(command)
        &#39;---PowerShellのコマンドレットの実行結果を取得
        chromeVersion.RevisionVersion = Trim(objRet.StdOut.ReadAll)
        &#39;---情報の取得が終わったらオブジェクトをクリアする
        Set objRet = Nothing
        &#39;---改行コードが含まれているから削除する
        chromeVersion.RevisionVersion = Trim(Replace(Replace(Replace(chromeVersion.RevisionVersion, vbCrLf, vbNullString), vbCr, vbNullString), vbLf, vbNullString))
        &#39;---バージョン情報を分けて返す
        With CreateObject(&quot;VBScript.RegExp&quot;) &#39;---正規表現の準備
            .Pattern = &quot;\d+\.\d+\.\d+(\.\d+)?&quot;
            .Global = True
            If .test(chromeVersion.RevisionVersion) Then &#39;---念のため正規表現でバージョン情報をチェックする
                chromeVersion.Major = CLng(Split(chromeVersion.RevisionVersion, &quot;.&quot;)(0))
                chromeVersion.Minor = CLng(Split(chromeVersion.RevisionVersion, &quot;.&quot;)(1))
                chromeVersion.Build = CLng(Split(chromeVersion.RevisionVersion, &quot;.&quot;)(2))
                If UBound(Split(chromeVersion.RevisionVersion, &quot;.&quot;)) &gt;= 3 Then &#39;---リビジョン番号がなければ9999を仮でセット※基本あるはず
                    chromeVersion.Revision = CLng(Split(chromeVersion.RevisionVersion, &quot;.&quot;)(3))
                Else
                    chromeVersion.Revision = 9999
                End If
                chromeVersion.BuildVersion = Join(Array(chromeVersion.Major, chromeVersion.Minor, chromeVersion.Build), &quot;.&quot;) &#39;---リビジョンを覗いたショートバージョン情報をセットする
                Debug.Print &quot;Chromeのバージョン：&quot; & chromeVersion.RevisionVersion
            Else &#39;---正規表現不一致なら失敗で返す
                MsgBox &quot;chrome.exe のバージョン情報取得に失敗しました&quot; & vbCrLf & &quot;[取得バージョン情報：&quot; & chromeVersion.RevisionVersion & &quot;]&quot; & vbCrLf & &quot;※この画面のキャプチャを作成者へ送ってください&quot;
                GetChromeVersion = False
                Exit Function
            End If
        End With
        GetChromeVersion = True
    On Error GoTo 0
    Exit Function
ErrLabel:     &#39;---予期せぬエラーの分岐
    MsgBox &quot;chrome.exe のバージョン情報取得に失敗しました&quot; & vbCrLf & &quot;[&quot; & Error(Err) & &quot;]&quot; & vbCrLf & &quot;※この画面のキャプチャを作成者へ送ってください&quot;
    GetChromeVersion = False
End Function
Private Function ChromedriverQuickCheck(chromedriverPath, chromeVersion As VersionType) As Boolean
    Dim objHttp As New MSXML2.XMLHTTP60
    Dim targetVarsion As String
    Dim uri As String
    Dim api_endpoints As String
    Dim downloadPath As String
    Dim objFso As New Scripting.FileSystemObject
    Const TARGET_PLATFORM As String = &quot;win64&quot;

    api_endpoints = &quot;https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_&quot; & chromeVersion.BuildVersion
    On Error GoTo ErrLabel
        With objHttp
            .Open &quot;GET&quot;, api_endpoints, False
            .Send
            targetVarsion = .responseText &#39;---JSON endpoints から情報を収集する
            downloadPath = workPath & &quot;\&quot; & targetVarsion
            &#39;--- 念のためリビジョンバージョンを比較する
            If chromeVersion.Major &gt;= CLng(Split(targetVarsion, &quot;.&quot;)(0)) Then
                &#39;--- まだダウンロードしていなかったらダウンロードする
                If objFso.FileExists(downloadPath & &quot;\&quot; & DRIVER_EXE) = False Then
                    uri = &quot;https://storage.googleapis.com/chrome-for-testing-public/&quot; & targetVarsion & &quot;/&quot; & TARGET_PLATFORM & &quot;/chromedriver-&quot; & TARGET_PLATFORM & &quot;.zip&quot;
                    Call DownloadChromedriver(uri, targetVarsion)
                    Call objFso.DeleteFile(chromedriverPath & &quot;\&quot; & DRIVER_EXE, True)
                    Debug.Print &quot;インストールしたChromedriverのバージョン：&quot; & targetVarsion
                End If
                &#39;--- chromedriverはいつでも上書きする
                Call objFso.GetFile(downloadPath & &quot;\&quot; & DRIVER_EXE).Copy(chromedriverPath & &quot;\&quot; & DRIVER_EXE, True)
            Else
                Debug.Print &quot;Chromeのバージョンが古いためChromedriverは更新しません&quot;
            End If
        End With
    On Error GoTo 0
    ChromedriverQuickCheck = True
    Exit Function
ErrLabel:     &#39;---予期せぬエラーの分岐
    MsgBox &quot;chromedriver.exe の更新に失敗しました&quot; & vbCrLf & &quot;[&quot; & Error(Err) & &quot;]&quot; & vbCrLf & &quot;※この画面のキャプチャを作成者へ送ってください&quot;
    ChromedriverQuickCheck = False
End Function
Private Function DownloadChromedriver(ByVal url As String, targetVersion As String) As Boolean
    Dim rc As Long
    Dim downloadPath As String
    Dim newDriverPath As String
    Dim objFso As New Scripting.FileSystemObject
    Dim objFolder As Scripting.Folder
    downloadPath = workPath & &quot;\&quot; & targetVersion
    &#39; ---chromedriverのフォルダを作成する
    Select Case SHCreateDirectoryEx(0&, downloadPath, 0&)
        Case 0:
            &#39; ---作成成功
        Case 183
            &#39; ---作成済み
        Case Else:
            &#39; ---作成できなかった時
            MsgBox &quot;ChromeDriver用フォルダを作成できませんでした&quot; & vbCrLf & Error(Err), vbCritical
            DownloadChromedriver = False
            Exit Function
    End Select
    
    &#39;---ファイルをダウンロードする
    If URLDownloadToFile(0, url, workPath & &quot;\&quot; & ZIP_FILE, 0, 0) &lt;&gt; 0 Then
        MsgBox &quot;ChromeDriverをダウンロードできませんでした&quot; & vbCrLf & Error(Err), vbCritical
        DownloadChromedriver = False
        Exit Function
    End If
    Application.DisplayAlerts = False
    &#39;---zipを既定のフォルダに向けて解凍する
    With CreateObject(&quot;Shell.Application&quot;) &#39;---zipを既定のフォルダに向けて解凍する
        .Namespace((downloadPath)).CopyHere .Namespace((workPath & &quot;\&quot; & ZIP_FILE)).Items
    End With
    &#39;--- 解凍したフォルダから再起処理してchromedriver.exeのフルパスを取得する
    newDriverPath = SearchFilesRecursively(downloadPath & &quot;\&quot;, &quot;chromedriver.exe&quot;)
    If newDriverPath = &quot;&quot; Then
        MsgBox &quot;chromedriver.exe の更新に失敗しました&quot;
        DownloadChromedriver = False
    End If
    &#39;---chromedriverをバージョンフォルダ直下に移動する
    Call objFso.MoveFile(newDriverPath, downloadPath & &quot;\&quot;)
    &#39;---chromedriverがなくなった不要フォルダを削除する
    For Each objFolder In objFso.GetFolder(downloadPath).SubFolders
        objFolder.Delete True
    Next
    &#39;---zipファイルを削除する
    Call objFso.DeleteFile(workPath & &quot;\&quot; & ZIP_FILE, True)
    Application.DisplayAlerts = True
    DownloadChromedriver = True
End Function
Function SearchFilesRecursively(ByVal folderPath As String, fileName As String) As String
    &#39;====================================================================================================
    &#39; folderPathを起点に再帰処理でサブフォルダまで対象にしてfileNameを探してフルパスを返す
    &#39;====================================================================================================
    Dim objFso As New Scripting.FileSystemObject
    Dim objFolder As Scripting.Folder
    Dim subFolder As Scripting.Folder
    Dim objFile As Scripting.File
    Dim result As String

    &#39; ファイル一覧をチェック
    For Each objFile In objFso.GetFolder(folderPath).Files
        If objFile.Name = fileName Then
            SearchFilesRecursively = objFile.Path
            Exit Function
        End If
    Next objFile

    &#39; サブフォルダを再帰的に探索
    For Each subFolder In objFso.GetFolder(folderPath).SubFolders
        result = SearchFilesRecursively(subFolder.Path, fileName)
        If result &lt;&gt; &quot;&quot; Then
            SearchFilesRecursively = result
            Exit Function
        End If
    Next subFolder

    &#39; 見つからなかった場合
    SearchFilesRecursively = &quot;&quot;
End Function
</code></pre></div>
</div></div>



<h2 class="wp-block-heading">あとがき</h2>



<p class="wp-block-paragraph">こちらが後出しなので簡易版としましたがむしろこちらを正規版で過去作成した方を特殊版にした方がいいかなと思っているレベル</p>



<p class="wp-block-paragraph">今後改修するとしたらこちらになる予定です</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-chromedriver-auto-update-lite/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA入門】変数と定数を徹底解説</title>
		<link>https://javeo.jp/variables-constants/</link>
					<comments>https://javeo.jp/variables-constants/#respond</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Sun, 31 Aug 2025 07:48:53 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=3520</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2025/08/VBA入門-1-1024x538.jpg" class="webfeedsFeaturedVisual" /></p>変数 変数とは 変数が何かというとその名の通り&#8221;中身が変わる数（値）&#8221;のことを指します 計算結果や文字列、オブジェクトなどを一時的に格納して利用しますがExcel作業に例えると、セルに値を入力して [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2025/08/VBA入門-1-1024x538.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box info-box">
<p class="wp-block-paragraph">VBAに限らずプログラミングにおいて変数と定数は基礎中の基礎</p>



<p class="wp-block-paragraph">言語によって細々ルールがありますがVBAでのルールや注意点をまとめていきます</p>
</div>



<h2 class="wp-block-heading">変数</h2>



<h3 class="wp-block-heading">変数とは</h3>



<p class="wp-block-paragraph">変数が何かというとその名の通り&#8221;中身が<strong><span class="marker-under">変</span></strong>わる<strong><span class="marker-under">数</span></strong>（値）&#8221;のことを指します</p>



<p class="wp-block-paragraph">計算結果や文字列、オブジェクトなどを一時的に格納して利用しますがExcel作業に例えると、セルに値を入力して必要なときに参照するイメージに近いです</p>



<h3 class="wp-block-heading">変数を使う目的</h3>



<p class="wp-block-paragraph">変数を使う一番の目的は、&#8221;<strong><span class="marker-under">プログラムの中で扱う値を一時的に記憶し、再利用できるようにすること</span></strong>&#8220;です</p>



<p class="wp-block-paragraph">もし変数を使わずに直接セルや数値を書き込むだけだと、同じ処理を繰り返すときに毎回手直しが必要になり、コードの柔軟性が失われます</p>



<p class="wp-block-paragraph">変数を使うことで以下のメリットがあります</p>



<ul class="wp-block-list has-watery-green-background-color has-background">
<li><strong>処理の効率化</strong>：一度計算した値を保存し、繰り返し利用できる</li>



<li><strong>保守性の向上</strong>：変更が必要な場合、変数の値を変えるだけで済む</li>



<li><strong>可読性の向上</strong>：意味のある名前をつけることで、コードを読んだ人が目的を理解しやすい</li>



<li><strong>一時的なデータ保持</strong>：途中計算の結果やフラグ（条件判定用のTrue/Falseなど）を保持する</li>
</ul>



<h3 class="wp-block-heading">変数の書き方</h3>



<p class="wp-block-paragraph">VBAで変数を宣言する場合の基本形は&#8221;<span class="marker-under">Dim 変数名 As データ型</span>&#8220;です</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Dim score As Integer
Dim name As String</code></pre></div>



<ul class="wp-block-list has-watery-green-background-color has-background">
<li>Dim … 変数を宣言するためのキーワード</li>



<li>変数名 … 値を格納する箱の名前　※後述の命名規則を要確認</li>



<li>データ型 … その変数にどの種類のデータを入れるか指定</li>
</ul>



<h3 class="wp-block-heading">変数の命名規則</h3>



<p class="wp-block-paragraph">VBAは柔軟なプログラムなので実は日本語を変数名にすることもできます・・・が、一般的には英語で書きますし他の言語では受け入れられないのがほぼなのでまずは英語で書きましょう</p>



<p class="wp-block-paragraph">そしてVBAで多く使われるのは<strong><span class="marker-under">キャメルケース</span></strong>でハンガリアン記法の利用もボチボチ</p>



<p class="wp-block-paragraph">他がNGってわけでもないですが一般的な記述にすることで可読性と保守性が上がるのでなるべく合わせましょう</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Dim targetRow As Long   &#39; ---キャメルケース
Dim lngRow As Long      &#39; ---ハンガリアン記法
Dim target_row As Long  &#39; ---スネークケース 
Dim TargetRow As Long   &#39; ---パスカルケース
Dim 対象行 As Long       &#39; ---日本語は非推奨</code></pre></div>



<h3 class="wp-block-heading">変数のスコープ</h3>



<p class="wp-block-paragraph">変数にはスコープと言われる考え方がありまして、Dimの代わりに&#8221;<span class="marker-under"><strong>Private/Public</strong></span>&#8220;で宣言することで使える範囲が変わります</p>



<p class="wp-block-paragraph">範囲の考え方はおおきくわけて2つ</p>



<ul class="wp-block-list has-watery-green-background-color has-background">
<li>同一プロジェクト内（≒Excelファイル）でモジュールを跨いで利用することができるか・・・①②</li>



<li>同一モジュール内でプロシージャを跨いで利用できるか・・・③④</li>
</ul>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2025/08/image-24.png"><img decoding="async" width="1024" height="538" src="https://javeo.jp/wp-content/uploads/2025/08/image-24-1024x538.png" alt="" class="wp-image-3522" srcset="https://javeo.jp/wp-content/uploads/2025/08/image-24-1024x538.png 1024w, https://javeo.jp/wp-content/uploads/2025/08/image-24-300x158.png 300w, https://javeo.jp/wp-content/uploads/2025/08/image-24-150x79.png 150w, https://javeo.jp/wp-content/uploads/2025/08/image-24-768x403.png 768w, https://javeo.jp/wp-content/uploads/2025/08/image-24.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h4 class="wp-block-heading">宣言する場所による違い（プロシージャ内外）</h4>



<p class="wp-block-paragraph">プロシージャ外で宣言すると同一モジュール内の全プロシージャで変数が利用できるようになり、変数の値はプロシージャを跨いでも保持されます</p>



<p class="wp-block-paragraph">プロシージャ内で宣言すると同一プロシージャの中だけで利用できるようになります</p>



<figure class="wp-block-table"><table><thead><tr><th>修飾子</th><th>スコープ</th></tr></thead><tbody><tr><td><code>プロシージャ内</code></td><td>そのプロシージャだけ</td></tr><tr><td><code>プロシージャ外</code></td><td>そのモジュールの全プロシージャ</td></tr></tbody></table></figure>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">メモ</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">変数は同一範囲内で重複して宣言することはできません</p>



<p class="wp-block-paragraph">なのでプロシージャ外で宣言した変数名はプロシージャ内でもう一度宣言することはできませんが、プロシージャ内で宣言するのであれば適用範囲で重複しないのでプロシージャを跨げば同一名の変数を利用できます（紛らわしいので推奨はしませんが）</p>
</div></div>



<h4 class="wp-block-heading">プロシージャ外で宣言する場合のPrivete/Publicステートメント</h4>



<p class="wp-block-paragraph">プロシージャ外で宣言する場合はDimの代わりにPrivateとPublicも利用できます</p>



<figure class="wp-block-table"><table><thead><tr><th>修飾子</th><th>スコープ</th><th>他モジュールからアクセス</th></tr></thead><tbody><tr><td><code>Private</code></td><td>モジュール内限定</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 不可</td></tr><tr><td><code>Public</code></td><td>プロジェクト全体</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 可能</td></tr></tbody></table></figure>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">メモ</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">※Privete/Publicの宣言をしていない場合はPrivateが適用されます</p>
</div></div>



<h3 class="wp-block-heading">データ型について</h3>



<p class="wp-block-paragraph">変数は&#8221;文字&#8221;や&#8221;数字&#8221;などデータの型を指定することができます</p>



<p class="wp-block-paragraph">指定しないことも可能ですが、プログラムでは数字の100（ひゃく）と文字の100（いちぜろぜろ）は違うのでエラー・バグの温床になってしまうため原則指定します</p>



<h4 class="wp-block-heading">基本的なデータ型</h4>



<p class="wp-block-paragraph">まずは基本になる様々な&#8221;<span class="marker-under"><strong>値</strong></span>&#8220;を取り扱う時に指定するデータ型から</p>



<figure class="wp-block-table"><table><thead><tr><th>データ型</th><th>説明</th><th class="has-text-align-right" data-align="right">初期値</th><th>例</th><th class="has-text-align-center" data-align="center">使用頻度</th></tr></thead><tbody><tr><td>String</td><td>文字列</td><td class="has-text-align-right" data-align="right">&#8220;&#8221;</td><td><code>Dim name As String</code></td><td class="has-text-align-center" data-align="center">高</td></tr><tr><td>Long</td><td>大きな整数（約±20億）</td><td class="has-text-align-right" data-align="right">0</td><td><code>Dim population As Long</code></td><td class="has-text-align-center" data-align="center">高</td></tr><tr><td>Date</td><td>日付・時刻</td><td class="has-text-align-right" data-align="right">0:00:00</td><td><code>Dim today As Date</code></td><td class="has-text-align-center" data-align="center">高</td></tr><tr><td>Boolean</td><td>True/False</td><td class="has-text-align-right" data-align="right">False</td><td><code>Dim isActive As Boolean</code></td><td class="has-text-align-center" data-align="center">中</td></tr><tr><td>Double</td><td>小数を含む実数</td><td class="has-text-align-right" data-align="right">0</td><td><code>Dim price As Double</code></td><td class="has-text-align-center" data-align="center">低</td></tr><tr><td>Integer</td><td>整数（-32,768～32,767）</td><td class="has-text-align-right" data-align="right">0</td><td><code>Dim age As Integer</code></td><td class="has-text-align-center" data-align="center">低</td></tr><tr><td>Byte</td><td>0～255の整数</td><td class="has-text-align-right" data-align="right">0</td><td><code>Dim flag As Byte</code></td><td class="has-text-align-center" data-align="center">低</td></tr><tr><td>Currency</td><td>金額（小数点4桁まで）</td><td class="has-text-align-right" data-align="right">0</td><td><code>Dim salary As Currency</code></td><td class="has-text-align-center" data-align="center">激低</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Integerは使われるところをよく見かけますが、Longが上位互換みたいなものなので使う必要が無いって意味で使用頻度は&#8221;低&#8221;にしています</p>



<h4 class="wp-block-heading">オブジェクト型について</h4>



<p class="wp-block-paragraph">基本形と違って&#8221;値&#8221;ではなくデータの箱のようなものを格納するオブジェクト型がありまして、このオブジェクト型は何か一つのことを指すわけではなく&#8221;<strong>Workbook（ブック）</strong>&#8220;、&#8221;<strong>Worksheet（シート）</strong>&#8220;、&#8221;<strong>Range（セル）</strong>&#8220;などをまとめてオブジェクト型と呼びます</p>



<p class="wp-block-paragraph">種類は無数にあるのでここでは触れませんが、VBAを利用していれば嫌でも出会うので細かい話はサンプルプログラムの説明などで</p>



<p class="wp-block-paragraph">ちなみにオブジェクト型に代入するときはSetステートメントが必要なので利用時にはご注意を</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Dim name As String
Dim wb As Workbook

name = &#39;ジャベ雄&#39;
Set wb = Thisworkbook &#39; ---オブジェクトへの代入はSetから始める</code></pre></div>



<h4 class="wp-block-heading">なるべく使用を控えたいけど便利な万能データ型</h4>



<p class="wp-block-paragraph">データ型の冒頭で触れたデータ型を&#8221;指定しない&#8221;時に関連しますが、データ型の一つに万能型の&#8221;<strong><span class="marker-under">Variant</span></strong>&#8220;がありまして、指定しない場合はこの万能型が適用されます</p>



<p class="wp-block-paragraph">もう一つオブジェクト型なら何でも入る&#8221;<strong><span class="marker-under">Object</span></strong>&#8220;があります</p>



<p class="wp-block-paragraph">ObjectはVariantでも代用できないわけではないですが、なるべくデータ型は指定する思想があるので最低限使い分けはしたいところ</p>



<figure class="wp-block-table"><table><thead><tr><th>データ型</th><th>説明</th></tr></thead><tbody><tr><td>Variant</td><td>オブジェクト型も含め全てのデータ型になれる</td></tr><tr><td>Object</td><td>オブジェクト型なら何にでもなれる</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Variant型（データ型を指定しない）はなるべく避けたいとことですが、Arrayなど一部Variantでしか取り扱えない場合や、プログラムの中でどのデータ型になるかわからない場合があるので状況に応じて利用しましょう</p>



<h4 class="wp-block-heading">列挙型（Enum）とユーザー定義データ型（Type）</h4>



<p class="wp-block-paragraph">イレギュラー枠でEnumとTypeがありまして、EnumはLongの集合体、Typeは変数を束ねると考えるとしっくりきます</p>



<p class="wp-block-paragraph">これも奥が深いのでここでは紹介だけまでにして、サンプルソース置くのでこんなのもあるんだーぐらいでどうぞ</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Enum WeekDay
    Sunday      &#39; 0
    Monday      &#39; 1
    Tuesday     &#39; 2
    Wednesday   &#39; 3
    Thursday    &#39; 4
    Friday      &#39; 5
    Saturday    &#39; 6
End Enum

Sub ShowDay()
    MsgBox &quot;今日の曜日は: &quot; & WeekDay.Monday  &#39; 結果は「1」
End Sub</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Type Employee
    Name As String
    Age As Integer
    Salary As Double
End Type

Sub ShowEmployee()
    Dim emp As Employee
    emp.Name = &quot;田中 太郎&quot;
    emp.Age = 30
    emp.Salary = 5000000

    MsgBox &quot;氏名: &quot; & emp.Name & vbCrLf & _
           &quot;年齢: &quot; & emp.Age & vbCrLf & _
           &quot;給与: &quot; & emp.Salary & &quot;円&quot;
End Sub
</code></pre></div>



<h2 class="wp-block-heading">定数</h2>



<h3 class="wp-block-heading">定数とは</h3>



<p class="wp-block-paragraph">定数は&#8221;中身を<strong><span class="marker-under">定</span></strong>めたわる<strong><span class="marker-under">数</span></strong>（値）&#8221;のことを指します</p>



<p class="wp-block-paragraph">基本的な使い方は変数と同じですが違いがあるところだけピックアップします</p>



<h3 class="wp-block-heading">定数を使う目的</h3>



<p class="wp-block-paragraph">定数の目的は、<strong>決して変わらない値をプログラム中で安全に使うこと</strong>です</p>



<p class="wp-block-paragraph">例えば消費税率や基準日などをいつか一括で修正する可能性がある値は、後から修正するときに見落としやすく、バグの原因になります</p>



<p class="wp-block-paragraph">その他にも定数を使うことで以下のメリットがあります</p>



<ul class="wp-block-list has-watery-green-background-color has-background">
<li><strong>安全性の確保</strong>：プログラム実行中に誤って値を書き換えられる心配がない</li>



<li><strong>変更管理が容易</strong>：消費税率などを1か所変更すればプログラム全体に反映できる</li>



<li><strong>可読性の向上</strong>：「0.1」より「TAX_RATE」のような名前を使うことで意味が明確になる</li>



<li><strong>保守性の向上</strong>：長期的に見ても管理がしやすく、他人がコードを読んだときも理解しやすい</li>
</ul>



<h3 class="wp-block-heading">定数の書き方</h3>



<p class="wp-block-paragraph">VBAで定数を宣言する場合の基本形は&#8221;<span class="marker-under">Const 変数名 As データ型 = 値</span>&#8220;です</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Const score As Integer = 100
Const name As String = &quot;ジャベ雄&quot;</code></pre></div>



<p class="wp-block-paragraph">変数と違って宣言と同時に値を決めてその後編集不可になります</p>



<h4 class="wp-block-heading">定数の命名規則</h4>



<p class="wp-block-paragraph">変数と同じように一般的に使われる命名規則がありまして、全て大文字のスネークケースで一見して意味が分かる単語を結合します</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Const MAX_USER_COUNT As Integer = 100
Const DEFAULT_FONT_SIZE As Double = 12.5
Const API_ENDPOINT_URL As String = &quot;https://example.com/api&quot;</code></pre></div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">結構初歩の部分ですがまとめ始めるとなかなかのボリュームになってしまいました</p>



<p class="wp-block-paragraph">良くも悪くもシステムとしての制限がないので自分でやチームでルールを作って安定運用できるプログラム作成を心がけましょう！</p>


<p>[temp id=2]</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/variables-constants/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA入門】今から始めるVBA</title>
		<link>https://javeo.jp/vba-beginner-001/</link>
					<comments>https://javeo.jp/vba-beginner-001/#respond</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Sat, 30 Aug 2025 09:52:53 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=2673</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2025/08/VBA入門-1-1024x538.jpg" class="webfeedsFeaturedVisual" /></p>VBAを始める前に VBAを始める前にまずVBAの概要とExcelの準備です VBAとは VBA（Visual Basic for Applications）は、Microsoft 365・Office製品（Excel、 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2025/08/VBA入門-1-1024x538.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box info-box">
<p class="wp-block-paragraph">皆さんプログラミングしていますか？</p>



<p class="wp-block-paragraph">プログラミングなんて簡単！・・とは言いませんが、これだけITが発展した現代においては一定の知識を持っていて損はないですし、業務効率の代名詞と言える&#8221;システム化&#8221;を担当するには必須レベル</p>



<p class="wp-block-paragraph">IT職ではない人でも身近でトライ＆エラーし放題、身に着けたスキルがすぐに活かせるEXCELとVBAがいいんじゃないかと言うことで今さらではありますがVBA入門を私なりにまとめます</p>
</div>



<h2 class="wp-block-heading">VBAを始める前に</h2>



<p class="wp-block-paragraph">VBAを始める前にまずVBAの概要とExcelの準備です</p>



<h3 class="wp-block-heading">VBAとは</h3>



<p class="wp-block-paragraph"><strong>VBA</strong>（<strong>V</strong>isual <strong>B</strong>asic for <strong>A</strong>pplications）は、Microsoft 365・Office製品（Excel、Accessなど）で使用できるプログラミング言語です</p>



<p class="wp-block-paragraph">よくVBAとマクロの違いみたいな話を見ますがマクロは機能名でVBAはその中身って感じで会話の中では同じものとして扱って大丈夫かなと</p>



<p class="wp-block-paragraph">VBAを使いこなせば、これまで何時間もかかっていた作業が<strong>ボタン一つで一瞬で終わる</strong>、なんてことも夢ではありません</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">VBAでできる作業例</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>定型的なメールの作成・送信</li>



<li>毎月のレポート作成</li>



<li>大量のデータ整形・転記</li>



<li>ブラウザを自動操作してエクセル情報の転記</li>
</ul>
</div></div>



<h3 class="wp-block-heading">開発者タブを表示しよう</h3>



<p class="wp-block-paragraph">ExcelでVBA始めるならまず開発タブを表示しましょう</p>



<p class="wp-block-paragraph">正直慣れるとVBEの画面は&#8221;<strong>Alt+F11</strong>&#8220;で開くしマクロは&#8221;<strong>Alt+F8</strong>&#8220;で実行しちゃうので使う頻度は減りますが最初はあったほうが便利です</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">開発者タブの表示手順</span></div><div class="tab-caption-box-content block-box-content box-content">
<ol style="border-radius:20px" class="wp-block-list">
<li>「ファイル」タブ → 「オプション」をクリック</li>



<li>「リボンのユーザー設定」を開く</li>



<li>右側の「メインタブ」の一覧から「開発」にチェックを入れ、「OK」をクリック</li>
</ol>
</div></div>



<figure class="wp-block-image size-large"><a href="https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1.png"><img decoding="async" width="1024" height="555" src="https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1-1024x555.png" alt="" class="wp-image-2680" srcset="https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1-1024x555.png 1024w, https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1-300x163.png 300w, https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1-150x81.png 150w, https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1-768x416.png 768w, https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1-1536x832.png 1536w, https://javeo.jp/wp-content/uploads/2024/10/2024-10-06_21h55_20-1.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">VBAで押さえておきたい基本</h2>



<p class="wp-block-paragraph">VBAを学ぶ上で、最低限知っておきたい基本的な概念をいくつか紹介します</p>



<p class="wp-block-paragraph">最初は難しく感じるかもしれませんが、深堀は別でやりますので今は「こういうものがあるんだな」くらいの気持ちで読み進めてください</p>



<h3 class="wp-block-heading">変数と定数</h3>



<p class="wp-block-paragraph">プログラミングでは、データ（数値や文字列など）を一時的に保存しておくための「箱」のようなものを使いますが、この箱のことを<strong>変数</strong>や<strong>定数</strong>と呼びます</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">変数と定数について</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li><strong>変数</strong>: 中身を自由に入れ替えられる箱</li>



<li><strong>定数</strong>: 一度入れたら中身を変えられない箱</li>
</ul>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Sub test()
Const tax_rate As Double = 0.1 &#39;---税率
Dim price_excluding_tax As Long &#39;---税抜き価格
Dim price_including_tax As Long &#39;---税込み価格

price_excluding_tax = 1980
price_including_tax = price_excluding_tax * (1 + tax_rate)
Debug.Print (price_including_tax)
End Sub
</code></pre></div>
</div></div>



<h3 class="wp-block-heading">データ型</h3>



<p class="wp-block-paragraph">変数や定数には、どんな種類のデータを入れるかをあらかじめ決めておく必要があり、これを<strong>データ型</strong>と呼びます</p>



<p class="wp-block-paragraph">例えば、数値を扱うのか、文字を扱うのか、日付を扱うのか、といった区別です</p>



<figure class="wp-block-table is-style-regular"><table class="has-fixed-layout" style="border-width:1px"><thead><tr><th>データ型</th><th>内容</th><th>例</th></tr></thead><tbody><tr><td>Long</td><td>整数</td><td>1, 100, -50</td></tr><tr><td>String</td><td>文字列</td><td>&#8220;こんにちは&#8221;, &#8220;Excel&#8221;</td></tr><tr><td>Date</td><td>日付・時刻</td><td>2025/08/30</td></tr><tr><td>Boolean</td><td>真偽値 (True/False)</td><td>True, False</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">条件分岐、ループ処理などのフロー制御</h3>



<p class="wp-block-paragraph">プログラムは基本的に上から下へ順番に実行されますが、<strong>フロー制御</strong>を使うことで状況に応じて処理の流れを変えることができます</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">フロー制御の例</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li><strong>ループ処理 (For, Do Whileなど)</strong>: 同じ処理を何度も繰り返したい場合に使います<br>例えば「○○を10回繰り返す」「△△という条件が満たされるまで繰り返す」といった処理が可能です</li>



<li><strong>条件分岐 (If)</strong>: 「もし○○ならAの処理、そうでなければBの処理をする」というように、条件によって処理を分けます</li>
</ul>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>&#39; A1～A10のセルの中で300以上の数字だったら文字を赤くする
Sub test()
Dim i As Long
For i = 1 To 10
    If Cells(i, 1).Value &gt;= 300 Then
        Cells(i, 1).Font.Color = RGB(255, 0, 0)
    End If
Next
End Sub</code></pre></div>
</div></div>



<h3 class="wp-block-heading">メインプロシージャとサブプロシージャ</h3>



<p class="wp-block-paragraph">VBAでは、一連の処理のまとまりを<strong>プロシージャ</strong>と呼びます</p>



<p class="wp-block-paragraph">機能や仕組みではなく、役割や考え方みたいな位置づけなので必ずしもこの二つが必要ってわけではなく簡単なプログラムならプロシージャー1つなんてことも多々ありますし、サブプロシージャーのさらにサブプロシージャーを作ったりすることもあります</p>



<p class="wp-block-paragraph">車でいうとメインプロシージャが車の組み立て、サブプロシージャーが各部品の作成のイメージですね</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">プロシージャーについて</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li><strong>メインプロシージャ</strong>: 一連の処理を始めて完了させる主たるプログラム</li>



<li><strong>サブプロシージャ</strong>: 特定の処理（例えば、ボディを作る、エンジンを作る）を部品として独立させたプログラム※メインプロシージャから呼び出して使います</li>
</ul>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Sub MainProcedure()
    Debug.Print (&quot;これがメインプロシージャーです&quot;)
    Call SubProcedure1
    Call SubProcedure2
End Sub
Sub SubProcedure1()
    Debug.Print (&quot;これがメインプロシージャー1です&quot;)
End Sub
Sub SubProcedure2()
    Debug.Print (&quot;これがメインプロシージャー2です&quot;)
End Sub

</code></pre></div>
</div></div>



<h3 class="wp-block-heading">可読性の重要性</h3>



<p class="wp-block-paragraph">VBAは自分だけでなく、他の人がコードを読む（または将来の自分が見返す）可能性もあります</p>



<p class="wp-block-paragraph">誰が見ても分かりやすい、<strong>可読性の高いコード</strong>を書くことは非常に重要です</p>



<h4 class="wp-block-heading">インデントについて</h4>



<p class="wp-block-paragraph"><strong>インデント</strong>とは、行頭の字下げのことで処理の塊（ブロック）を視覚的に分かりやすくするために行います</p>



<p class="wp-block-paragraph">If文やFor文などフロー制御の中の処理は、インデントを下げるのが一般的です</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">インデントについて</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">処理の塊で行頭にタブキーかスペース（一般的には半角スペース×4）を付けます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>&#39; 悪い例
If Range(&quot;A1&quot;).Value &gt; 10 Then
MsgBox &quot;10より大きいです&quot;
End If

&#39; 良い例
If Range(&quot;A1&quot;).Value &gt; 10 Then
    MsgBox &quot;10より大きいです&quot;
End If</code></pre></div>
</div></div>



<h4 class="wp-block-heading">変数などの命名規則について</h4>



<p class="wp-block-paragraph">変数やプロシージャの名前は、その役割がひと目で分かるように付けることが大切です</p>



<p class="wp-block-paragraph">例えば、&#8221;<code>a"</code>や&#8221;<code>b"</code>のような無意味な名前ではなく、<code>"userName"</code>（ユーザー名）や<code>"calculateTotalPrice"</code>（合計金額を計算する）のように一見して意味が分かるようにすることが望ましいです</p>



<p class="wp-block-paragraph">書き方にも規則性がありまして&#8221;定数は全て大文字にする&#8221;、&#8221;プレフィックスでデータ型を示す&#8221;、&#8221;単語を特定の文字で繋ぐ&#8221;などなど言語や時代によって変化はありますが少なくとも一つのプログラムの中では一貫したルールにすべきです</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">代表的な命名規則</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>キャメルケース</li>



<li>スネークケース</li>



<li>ケバブケース</li>
</ul>
</div></div>



<h3 class="wp-block-heading">モジュールの種類</h3>



<p class="wp-block-paragraph">VBAのコードを記述する場所を<strong>モジュール</strong>と呼びます</p>



<p class="wp-block-paragraph">モジュールにはいくつか種類がありますが、初心者がまず覚えておくべきなのは以下の2つです</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-green-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#3eb370"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">モジュールについて</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li><strong>標準モジュール</strong>: 一般的なプロシージャ（SubやFunction）を記述する、最も基本的なモジュールです</li>



<li><strong>クラスモジュール</strong>: 小規模なプログラムになりがちなVBAの世界では見かける頻度は低いですが、いわゆるオブジェクト指向という考え方に基づいたもので、より複雑で大規模なプログラムを作る際に役立ちます。</li>
</ul>
</div></div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">今回は、VBAの魅力とその基本的な概念についてお話ししました。最初は覚えることが多くて大変に感じるかもしれませんが、一つ一つは決して難しいものではありません。</p>



<p class="wp-block-paragraph">VBAを学ぶ最大のメリットは、<strong>日々の業務に直結するスキル</strong>であるということです。学習したことがすぐに実践で活かせ、成果が目に見えやすいので、モチベーションを維持しやすいのも特徴です。</p>



<p class="wp-block-paragraph">このブログでは、今後もVBAの具体的な書き方や便利なテクニックをどんどん紹介していきます。ぜひ、次回の記事もチェックして、退屈な繰り返し作業から解放され、より創造的な仕事に時間を使えるようになりましょう！<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<p>[temp id=2]</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-beginner-001/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA】再帰処理について解説</title>
		<link>https://javeo.jp/recursion-processing/</link>
					<comments>https://javeo.jp/recursion-processing/#respond</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Tue, 16 Jul 2024 23:00:00 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[エクセル]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=2478</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p>再帰処理とは 一言で表すと関数やプロシージャが自分自身を呼び出す処理のこと 処理方法の話なので当然VBAだけでなく他のプログラム言語でも使われる処理ですが、私が一番しっくりきたパソコンのフォルダ潜りながらフォルダ情報を収 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p class="wp-block-paragraph"><a href="https://javeo.jp/vba-file-list-maker/" target="_blank" rel="noreferrer noopener">別のページ</a>で再帰処理を使ったプログラムを作ったわけですが、昔再帰処理を一生懸命後輩に教えたことを思い出したので個別に解説ページを作ってみました</p>



<p class="wp-block-paragraph">利用シーンはあまり多くないものの、知っておくと便利な処理なので是非一読を</p>
</div>



<h2 class="wp-block-heading">再帰処理とは</h2>



<p class="wp-block-paragraph">一言で表すと<strong><span class="marker-under">関数やプロシージャが自分自身を呼び出す処理の</span></strong>こと</p>



<p class="wp-block-paragraph">処理方法の話なので当然VBAだけでなく他のプログラム言語でも使われる処理ですが、私が一番しっくりきたパソコンのフォルダ潜りながらフォルダ情報を収集するプログラムを例に解説します</p>



<h2 class="wp-block-heading">サンプルプログラム</h2>



<p class="wp-block-paragraph">メチャメチャシンプルなサンプルプログラムです</p>



<p class="wp-block-paragraph">何をやっているかと言うとファイルが保存されているフォルダを起点にサブフォルダを照会して、今度はそのフォルダを起点にしてサブフォルダを照会して・・・を繰り返します</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-file="RecursionProcessing" data-lang="Visual Basic + VBA"><code>Sub AddFolderList()
&#39;------------------------------
&#39; メインプロシージャ
&#39;------------------------------
Dim objFso As New Scripting.FileSystemObject

Debug.Print &quot;RootFolder：&quot; & ThisWorkbook.Path
Call SearchFolder(objFso.GetFolder(ThisWorkbook.Path), 1)
End Sub
&#39;------------------------------------------------------------------------------------------
Function SearchFolder(TargetFolder As Scripting.Folder, FolderLv As Long)
&#39;------------------------------
&#39; 再帰処理用プロシージャ
&#39;------------------------------
Dim objFld As Scripting.Folder

Call GetFolderInfo(TargetFolder, FolderLv)
For Each objFld In TargetFolder.SubFolders
    Call SearchFolder(objFld, FolderLv + 1)
Next
End Function
&#39;------------------------------------------------------------------------------------------
Function GetFolderInfo(TargetFolder As Scripting.Folder, FolderLv As Long)
&#39;------------------------------
&#39; フォルダ情報をイミディエイトに表示
&#39;------------------------------
Debug.Print String(FolderLv, &quot;　&quot;) & &quot;FolderName：&quot; & TargetFolder.Name
Debug.Print String(FolderLv + 2, &quot;　&quot;) & &quot;├FileCount：&quot; & TargetFolder.Files.Count
Debug.Print String(FolderLv + 2, &quot;　&quot;) & &quot;├TotalSize：&quot; & TargetFolder.Files.Count
Debug.Print String(FolderLv + 2, &quot;　&quot;) & &quot;├CreateDate：&quot; & TargetFolder.DateCreated
Debug.Print String(FolderLv + 2, &quot;　&quot;) & &quot;└UpdateDate：&quot; & TargetFolder.DateLastModified
End Function</code></pre></div>



<h2 class="wp-block-heading">再帰処理のイメージ</h2>



<div class="wp-block-media-text is-stacked-on-mobile is-vertically-aligned-top"><figure class="wp-block-media-text__media"><a href="https://javeo.jp/wp-content/uploads/2024/07/2024-07-14_01h12_52.png"><img decoding="async" width="727" height="900" src="https://javeo.jp/wp-content/uploads/2024/07/2024-07-14_01h12_52.png" alt="" class="wp-image-2485 size-full" srcset="https://javeo.jp/wp-content/uploads/2024/07/2024-07-14_01h12_52.png 727w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-14_01h12_52-242x300.png 242w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-14_01h12_52-121x150.png 121w" sizes="(max-width: 727px) 100vw, 727px" /></a></figure><div class="wp-block-media-text__content">
<p class="wp-block-paragraph">まず再帰処理を使わずに再現しようとした時のプログラムがこちら</p>



<p class="wp-block-paragraph">フォルダ1-Aを起点とするとその中にフォルダ2-A/2-Bがある、2-Aの中にフォルダ3-Aがあってさらにその中にフォルダ4-A/4-B/4-Cがある</p>



<p class="wp-block-paragraph">事前に構造がわかっていれば↓の別サンプルのようにFor Nextを必要回数入れ子にして対応することもできますが例えば4-Aの中に新しいフォルダが作成された時、階層がもう一段階深くなるので入れ子が足りず取得できません</p>



<p class="wp-block-paragraph">無理矢理運用するなら10回くらい入れ子にしておけば大体大丈夫ですがそれではイマイチ</p>
</div></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Function SearchFolder(main As Scripting.Folder)
&#39;------------------------------
&#39; 再帰処理しない時のプログラム例
&#39;------------------------------
Dim sub1 As Scripting.Folder, sub2 As Scripting.Folder, sub3 As Scripting.Folder

Call GetFolderInfo(main, 1)
For Each sub1 In TargetFolder.SubFolders
    Call SearchFolder(sub1, 2)
    For Each sub2 In sub1.SubFolders
        Call SearchFolder(sub2, 3)
        For Each sub3 In sub2.SubFolders
            Call SearchFolder(sub3, 4)
        Next
    Next
Next
End Function</code></pre></div>



<div class="wp-block-media-text is-stacked-on-mobile is-vertically-aligned-top"><figure class="wp-block-media-text__media"><a href="https://javeo.jp/wp-content/uploads/2024/07/2024-07-15_01h13_40.png"><img decoding="async" width="432" height="566" src="https://javeo.jp/wp-content/uploads/2024/07/2024-07-15_01h13_40.png" alt="" class="wp-image-2492 size-full" srcset="https://javeo.jp/wp-content/uploads/2024/07/2024-07-15_01h13_40.png 432w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-15_01h13_40-229x300.png 229w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-15_01h13_40-114x150.png 114w" sizes="(max-width: 432px) 100vw, 432px" /></a></figure><div class="wp-block-media-text__content">
<p class="wp-block-paragraph">そしてこちらが再帰処理のイメージ</p>



<p class="wp-block-paragraph">Mainフォルダに1-Aを代入すると2-A/2-BがSubフォルダとして取得できる</p>



<p class="wp-block-paragraph">Subフォルダ2-AをMainフォルダに代入すると次は3-AがSubフォルダに、続いて3-AをMainフォルダにすると4-A/4-B/4-CがSubフォルダになる</p>



<p class="wp-block-paragraph">ポイントはここでさらに下の階層があればループが続くし、なければここで処理が終わるところ</p>



<p class="wp-block-paragraph">プログラムも短くスッキリした感じになります</p>
</div></div>



<h2 class="wp-block-heading">再帰処理のメリット・デメリット</h2>



<p class="wp-block-paragraph">結局のところ再帰処理って必要な処理なの？メリット・デメリットは？ってことでまとめてみます</p>



<h3 class="wp-block-heading">メリット</h3>



<p class="wp-block-paragraph">繰り返すべき回数が可変なプログラムでも対応することができます</p>



<p class="wp-block-paragraph">今回のフォルダであれば起点から3階層潜ったわけですが当然もっと深い階層がある可能性もありますが<strong><span class="marker-under">サブフォルダがあればループする</span></strong>仕様になるのでプログラムとして最適化できます</p>



<h3 class="wp-block-heading">デメリット</h3>



<p class="wp-block-paragraph">再帰処理は処理の途中で別のことに手を付けるようなことなのでループする度メモリを使うことになり、やり過ぎはメモリ不足を招く可能性があります</p>



<p class="wp-block-paragraph">もう一点はデメリットと言うより注意点になりますが、処理方法については無限ループになってしまいます</p>



<p class="wp-block-paragraph">例えばこんな処理</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>&#39;==============================
&#39; 無限ループになるプログラム
&#39;==============================
Sub sample()
Dim i As Long

i = 1
Call AdditionFunc(i)
End Sub
&#39;-------------------------------
Function AdditionFunc(i As Long)
Debug.Print i
Call AdditionFunc(i + 1)
End Function</code></pre></div>



<p class="wp-block-paragraph">加算し続けるだけで終わりのない無限処理になってしまうのでループに条件を付けるもしくはループを抜ける分岐を付けてあげる必要があります</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>&#39;==============================
&#39; 無限ループを回避したプログラム
&#39;==============================
Sub sample()
Dim i As Long

i = 1
Call AdditionFunc(i)
End Sub
&#39;------------------------------
Function AdditionFunc(i As Long)
Debug.Print i
&#39;---10未満の時だけ再帰処理する
If i &lt; 10 Then
    AdditionFunc = AdditionFunc(i + 1)
End If
End Function</code></pre></div>



<h2 class="wp-block-heading">あとがき</h2>



<p class="wp-block-paragraph">再帰処理をフォルダ検索を例に解説してみました</p>



<p class="wp-block-paragraph">わかるようでわからない再帰処理も実例があるとしっくりきませんか？私はきましたw</p>



<p class="wp-block-paragraph">他の言語でも考え方や書き方は同じなので参考にしてみてください</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/recursion-processing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA】マクロでファイルリストを作る</title>
		<link>https://javeo.jp/vba-file-list-maker/</link>
					<comments>https://javeo.jp/vba-file-list-maker/#respond</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Thu, 11 Jul 2024 23:00:00 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=2449</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p>ツールの仕様 VBAのことはいいからツールを使ってみたい！って方向けにまずはツールの仕様から 設定項目 絵が合った方が早いのでまずはエクセルの切り抜きから 対象フォルダ指定（グレー背景箇所） まずは取得対象とするフォルダ [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-1024x512.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p class="wp-block-paragraph">突然ですが本業でマクロを使ったファイルリスト作成機を作りました！</p>



<p class="wp-block-paragraph">この時は動けばOK程度の荒めの仕様だったのですが、せっかくなので汎用的に使えるようにもうちょっとカスタマイズしたので説明付きでこのサイトに保管します</p>



<p class="wp-block-paragraph">こうやって残しておけば次必要な時にダウンロードするだけの半分自分向けですが良かったら使ってください</p>
</div>



<h2 class="wp-block-heading">ツールの仕様</h2>



<p class="wp-block-paragraph">VBAのことはいいからツールを使ってみたい！って方向けにまずはツールの仕様から</p>



<h3 class="wp-block-heading">設定項目</h3>



<p class="wp-block-paragraph">絵が合った方が早いのでまずはエクセルの切り抜きから</p>



<figure class="wp-block-image size-full has-custom-border is-style-shadow"><a href="https://javeo.jp/wp-content/uploads/2024/07/2024-07-10_22h57_23.png"><img decoding="async" width="849" height="405" src="https://javeo.jp/wp-content/uploads/2024/07/2024-07-10_22h57_23.png" alt="" class="has-border-color has-grey-border-color wp-image-2462" style="border-width:1px;object-fit:cover" srcset="https://javeo.jp/wp-content/uploads/2024/07/2024-07-10_22h57_23.png 849w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-10_22h57_23-300x143.png 300w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-10_22h57_23-150x72.png 150w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-10_22h57_23-768x366.png 768w" sizes="(max-width: 849px) 100vw, 849px" /></a></figure>



<h4 class="wp-block-heading">対象フォルダ指定（グレー背景箇所）</h4>



<p class="wp-block-paragraph">まずは取得対象とするフォルダの指定</p>



<p class="wp-block-paragraph">サブフォルダも取得するようにすると対象フォルダ以下全てのフォルダが取得対象に</p>



<p class="wp-block-paragraph">ちなみにフォルダ名のところでダブルクリックするとダイアログで対象フォルダを選べる仕様にしています</p>



<h4 class="wp-block-heading">フォルダ名の指定（青背景箇所）</h4>



<p class="wp-block-paragraph">次はフォルダ名の指定</p>



<p class="wp-block-paragraph">各項目の入力条件で取得対象を制限できます</p>



<figure class="wp-block-table"><table><tbody><tr><th>フォルダ名検索</th><td>検索したい名前を指定※パイプ文字で区切って複数指定可</td></tr><tr><th>一致パターン</th><td>&#8220;部分一致&#8221;、&#8221;完全一致&#8221;、&#8221;前方一致&#8221;、&#8221;後方一致&#8221;の中から選ぶ</td></tr><tr><th>指定 or 除外</th><td>&#8220;フォルダ名検索&#8221;,&#8221;一致パターン&#8221;に該当した時に対象とするか対象外にするか</td></tr></tbody></table></figure>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-memo block-box">
<p class="wp-block-paragraph">パイプ文字は&#8221;|&#8221;のことでキーボードで言うと右上の&#8221;\&#8221;をshift押しながら押下で入力できます</p>



<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2024/07/キーボード_パイプ.png"><img decoding="async" width="801" height="340" src="https://javeo.jp/wp-content/uploads/2024/07/キーボード_パイプ.png" alt="" class="wp-image-2455" srcset="https://javeo.jp/wp-content/uploads/2024/07/キーボード_パイプ.png 801w, https://javeo.jp/wp-content/uploads/2024/07/キーボード_パイプ-300x127.png 300w, https://javeo.jp/wp-content/uploads/2024/07/キーボード_パイプ-150x64.png 150w, https://javeo.jp/wp-content/uploads/2024/07/キーボード_パイプ-768x326.png 768w" sizes="(max-width: 801px) 100vw, 801px" /></a></figure>
</div>



<h4 class="wp-block-heading">ファイル名の指定（緑背景箇所）</h4>



<p class="wp-block-paragraph">ファイル名の指定もフォルダと同じ方法</p>



<p class="wp-block-paragraph">このファイル名に拡張子は含まないので注意</p>



<h4 class="wp-block-heading">拡張子の指定（オレンジ背景箇所）</h4>



<p class="wp-block-paragraph">フォルダ名、ファイル名の指定と同じ</p>



<p class="wp-block-paragraph">.（ドット）はいらないのでエクセルなら&#8221;xlsx&#8221;でOK</p>



<h2 class="wp-block-heading">プログラムについて</h2>



<p class="wp-block-paragraph">ここからVBAの説明に移ります</p>



<p class="wp-block-paragraph">コピペでそのまま使えるプログラムと各プロシージャの説明を</p>



<h3 class="wp-block-heading">必要な参照設定</h3>



<p class="wp-block-paragraph">フォルダ・ファイルの情報を扱うので必須レベルな&#8221;<strong>FileSystemObject</strong>&#8220;を使用しますから&#8221;<strong><span class="marker-under">Microsoft Scripting Runtime</span></strong>&#8220;の参照をどうぞ</p>



<p class="wp-block-paragraph">その他はありませんので魔改造する時に必要に応じて</p>



<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2024/07/2024-07-07_23h49_05.png"><img decoding="async" width="455" height="317" src="https://javeo.jp/wp-content/uploads/2024/07/2024-07-07_23h49_05.png" alt="" class="wp-image-2457" srcset="https://javeo.jp/wp-content/uploads/2024/07/2024-07-07_23h49_05.png 455w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-07_23h49_05-300x209.png 300w, https://javeo.jp/wp-content/uploads/2024/07/2024-07-07_23h49_05-150x105.png 150w" sizes="(max-width: 455px) 100vw, 455px" /></a></figure>



<h3 class="wp-block-heading">コピペ用 プログラムの全貌</h3>



<p class="wp-block-paragraph">説明なんぞ不要でファイルがあればいい、プログラムがあればいいって方向けに最初にVBAの全プログラムとそのまま使えるマクロファイルです</p>



<p class="wp-block-paragraph">長ったらしいので畳んでますが見たい方は広げてください</p>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box has-border-color has-key-color-border-color not-nested-style cocoon-block-toggle is-style-default" style="--cocoon-custom-border-color:#008dcb"><input id="toggle-checkbox-202410050013430" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-202410050013430">VBA 全プログラム</label><div class="toggle-content">
<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Option Explicit
Enum lngCol
    file_name = 1
    ext_name
    file_size
    create_date
    mod_date
    file_path
    file_path_split
End Enum
Dim objFso As New Scripting.FileSystemObject
Sub GetFileList()
Dim ws As Worksheet
Dim target_folder As String

&#39;---起点フォルダの確認
target_folder = Trim(Range(&quot;TARGET_FOLDER&quot;).Value)
If objFso.FolderExists(target_folder) = False Then
    MsgBox &quot;対象フォルダが見つかりません&quot;, vbCritical
    Exit Sub
End If

&#39;---フォルダ名の一致判定
If Len(Trim(Range(&quot;FOLDER_NAME&quot;).Value)) &gt; 0 Then
    If Len(Trim(Range(&quot;FOLDER_MATCH_TYPE&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致タイプ を入力してください&quot;, vbCritical
        Exit Sub
    End If
    If Len(Trim(Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致パターン を入力してください&quot;, vbCritical
        Exit Sub
    End If
Else
    Range(&quot;FOLDER_NAME&quot;).Value = Trim(Range(&quot;FOLDER_NAME&quot;).Value)
End If

&#39;---ファイル名の一致判定
If Len(Trim(Range(&quot;FILE_NAME&quot;).Value)) &gt; 0 Then
    If Len(Trim(Range(&quot;FILE_MATCH_TYPE&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致タイプ を入力してください&quot;, vbCritical
        Exit Sub
    End If
    If Len(Trim(Range(&quot;FILE_MATCH_PATTERN&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致パターン を入力してください&quot;, vbCritical
        Exit Sub
    End If
End If

&#39;---拡張子の一致判定
If Len(Trim(Range(&quot;EXT_NAME&quot;).Value)) &gt; 0 Then
    If Len(Trim(Range(&quot;EXT_MATCH_TYPE&quot;).Value)) = 0 Then
        MsgBox &quot;拡張子の一致タイプ を入力してください&quot;, vbCritical
        Exit Sub
    End If
    If Len(Trim(Range(&quot;EXT_MATCH_PATTERN&quot;).Value)) = 0 Then
        MsgBox &quot;拡張子の一致パターン を入力してください&quot;, vbCritical
        Exit Sub
    End If
End If


Set ws = Sheet2
&#39;---テーブルをリセットする
With ws
    .Select
    &#39;---テーブルが空だとエラーになるのでエラーを無視するようにする
    On Error Resume Next
    .Range(Range(&quot;FILE_TABLE&quot;).Address).EntireRow.Delete
    On Error GoTo 0
End With

&#39;---まず指定フォルダのファイルを収集する
If Len(Trim(Range(&quot;FOLDER_NAME&quot;).Value)) &gt; 0 Then
    &#39;---指定の場合一致したらファイル情報を取得する
    If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;指定&quot; Then
        If in_array(objFso.GetFolder(target_folder).Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = True Then
            Call GetFileData(ws, Range(&quot;FOLDER_NAME&quot;).Value)
        End If
    End If
    &#39;---除外の場合は不一致ならファイル情報取得して再帰処理する
    If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;除外&quot; Then
        If in_array(objFso.GetFolder(target_folder).Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = False Then
            Call GetFileData(ws, Range(&quot;FOLDER_NAME&quot;).Value)
        End If
    End If
Else
    Call GetFileData(ws, Range(&quot;TARGET_FOLDER&quot;).Value)
End If


&#39;-サブフォルダを対象とするか
If Range(&quot;TARGET_SUBFOLDER&quot;).Value = &quot;する&quot; Then
    Call GetSubFoler(ws, target_folder)
End If
Set ws = Nothing
Application.StatusBar = False

&#39;---先頭行が空白だったら（絶対空白のはず）削除する
If Len(Trim(Range(&quot;FILE_TABLE&quot;).Item(1).Value)) = 0 Then
    On Error Resume Next
    Range(&quot;FILE_TABLE&quot;).ListObject.ListRows(1).Delete
    On Error GoTo 0
End If

Range(&quot;FILE_TABLE&quot;).Item(1).Select
MsgBox &quot;終了しました&quot;
End Sub
Sub DeleteFileList()
Dim ws As Worksheet
Set ws = Sheet2
&#39;---テーブルをリセットする
With ws
    .Select
    On Error Resume Next
    .Range(Range(&quot;FILE_TABLE&quot;).Address).EntireRow.Delete
    On Error GoTo 0
End With
Set ws = Nothing

Range(&quot;FILE_TABLE&quot;).Item(1).Select
MsgBox &quot;終了しました&quot;
End Sub
Private Function GetFileData(ws As Worksheet, target_folder As String)
&#39;======================================================================
&#39; 指定フォルダの中にあるファイル情報を取得してリストに反映する
&#39;======================================================================
Dim lngRow As Long
Dim file_path As String
Dim objFile As Scripting.File
Dim get_file_bool As Boolean

Application.StatusBar = target_folder & &quot; のファイル情報を取得中・・・&quot;
For Each objFile In objFso.GetFolder(target_folder).Files
    &#39;---ファイルの取得判定の初期値を設定（True）
    get_file_bool = True
    &#39;---ファイル名検索に指定があったら
    If Len(Trim(Range(&quot;FILE_NAME&quot;).Value)) &gt; 0 Then
        &#39;---ファイル名（拡張子除く）が条件と一致しているか確認
        If in_array(objFso.GetBaseName(objFile.Name), Split(Range(&quot;FILE_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FILE_MATCH_TYPE&quot;).Value) = IIf(Range(&quot;FILE_MATCH_PATTERN&quot;).Value = &quot;指定&quot;, True, False) Then
            get_file_bool = True
        Else
            get_file_bool = False
            GoTo continue
        End If
    End If
    
    &#39;---拡張子に指定があったら
    If Len(Trim(Range(&quot;EXT_NAME&quot;).Value)) &gt; 0 Then
        If in_array(objFso.GetExtensionName(objFile.Name), Split(Range(&quot;EXT_NAME&quot;).Value, &quot;|&quot;), Range(&quot;EXT_MATCH_TYPE&quot;).Value) = IIf(Range(&quot;EXT_MATCH_PATTERN&quot;).Value = &quot;指定&quot;, True, False) Then
            get_file_bool = True
        Else
            get_file_bool = False
            GoTo continue
        End If
    End If
    
    &#39;---取得対象と判定されたら情報を取得して書き出す
    If get_file_bool = True Then
        With ws
            .Select
            &#39;---テーブルに行を追加する
            Range(&quot;FILE_TABLE&quot;).ListObject.ListRows.Add AlwaysInsert:=False
            lngRow = Range(&quot;FILE_TABLE&quot;).Item(Range(&quot;FILE_TABLE&quot;).Cells.Count).Row
            .Cells(lngRow, lngCol.file_name).Value = objFile.Name
            .Cells(lngRow, lngCol.ext_name).Value = objFso.GetExtensionName(objFile.Path)
            .Cells(lngRow, lngCol.file_size).Value = objFile.Size
            .Cells(lngRow, lngCol.create_date).Value = objFile.DateCreated
            .Cells(lngRow, lngCol.mod_date).Value = objFile.DateLastModified
            file_path = Replace(objFile.Path, &quot;\&quot; & objFile.Name, &quot;&quot;)
            .Cells(lngRow, lngCol.file_path).Value = Replace(objFile.Path, &quot;\&quot; & objFile.Name, &quot;&quot;)
            .Cells(lngRow, lngCol.file_path_split).Resize(, UBound(Split(file_path, &quot;\&quot;)) + 1) = Split(file_path, &quot;\&quot;)
        End With
    End If
continue:
Next
End Function
Private Function GetSubFoler(ws As Worksheet, target_folder As String)
&#39;======================================================================
&#39; 再帰処理でフォルダを潜りながらそのフォルダのファイルを取得する
&#39;======================================================================
Dim objFld As Scripting.Folder

For Each objFld In objFso.GetFolder(target_folder).SubFolders
    &#39;---フォルダ名検索に指定があったら
    If Len(Trim(Range(&quot;FOLDER_NAME&quot;).Value)) &gt; 0 Then
        &#39;---指定の場合一致したらファイル情報を取得する
        If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;指定&quot; Then
            If in_array(objFld.Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = True Then
                Call GetFileData(ws, objFld.Path)
            End If
            &#39;---どちらにしても再帰処理はかける
            Call GetSubFoler(ws, objFld.Path)
        End If
        &#39;---除外の場合は不一致ならファイル情報取得して再帰処理する
        If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;除外&quot; Then
            If in_array(objFld.Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = False Then
                Call GetFileData(ws, objFld.Path)
                Call GetSubFoler(ws, objFld.Path)
            End If
        End If
    Else
        Call GetFileData(ws, objFld.Path)
        Call GetSubFoler(ws, objFld.Path)
    End If
Next
End Function
Private Function in_array(target_str As String, target_array As Variant, Optional match_type As String = &quot;完全一致&quot;) As Boolean
&#39;======================================================================
&#39; パターンに合わせて一致判定を返す
&#39;======================================================================
Dim arr As Variant

For Each arr In target_array
    Select Case match_type
        Case &quot;完全一致&quot;
            If LCase(target_str) = LCase(arr) Then
                in_array = True
                Exit Function
            End If
        Case &quot;部分一致&quot;
            If LCase(target_str) Like &quot;*&quot; & LCase(arr) & &quot;*&quot; Then
                in_array = True
                Exit Function
            End If
        Case &quot;前方一致&quot;
            If LCase(target_str) Like LCase(arr) & &quot;*&quot; Then
                in_array = True
                Exit Function
            End If
        Case &quot;後方一致&quot;
            If LCase(target_str) Like &quot;*&quot; & LCase(arr) Then
                in_array = True
                Exit Function
            End If
        Case Else
    End Select
Next
in_array = False
End Function</code></pre></div>
</div></div>



<div class="wp-block-file"><a id="wp-block-file--media-fa4f42ab-9453-4581-a200-bc3ef4b36a2a" href="https://javeo.jp/wp-content/uploads/2024/07/FileListMaker_v1.0.xlsm">FileListMaker_v1.0</a><a href="https://javeo.jp/wp-content/uploads/2024/07/FileListMaker_v1.0.xlsm" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-fa4f42ab-9453-4581-a200-bc3ef4b36a2a">ダウンロード</a></div>



<p class="wp-block-paragraph">ここからはプログラムをプロシージャ別に解説していきます</p>



<h4 class="wp-block-heading">共通変数</h4>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Option Explicit
Enum lngCol
    file_name = 1
    ext_name
    file_size
    create_date
    mod_date
    file_path
End Enum
Dim objFso As New Scripting.FileSystemObject</code></pre></div>



<p class="wp-block-paragraph">個人的な話ですが、昔はプロシージャ―の外に書く共通変数にしたがっていた時期がありましたが最近はなるべく共通変数は減らして値格納する変数はNGにしています</p>



<p class="wp-block-paragraph"><strong>Enum（列挙型）</strong>はExcelならではですが、列番号を宣言してあげると後から項目追加・削除したり編集する可能性があるなら便利ですよね</p>



<h4 class="wp-block-heading">GetFileList（メインプロシージャ―）</h4>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Sub GetFileList()
Dim ws As Worksheet
Dim target_folder As String

&#39;---起点フォルダの確認
target_folder = Trim(Range(&quot;TARGET_FOLDER&quot;).Value)
If objFso.FolderExists(target_folder) = False Then
    MsgBox &quot;対象フォルダが見つかりません&quot;, vbCritical
    Exit Sub
End If

&#39;---フォルダ名の一致判定
If Len(Trim(Range(&quot;FOLDER_NAME&quot;).Value)) &gt; 0 Then
    If Len(Trim(Range(&quot;FOLDER_MATCH_TYPE&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致タイプ を入力してください&quot;, vbCritical
        Exit Sub
    End If
    If Len(Trim(Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致パターン を入力してください&quot;, vbCritical
        Exit Sub
    End If
Else
    Range(&quot;FOLDER_NAME&quot;).Value = Trim(Range(&quot;FOLDER_NAME&quot;).Value)
End If

&#39;---ファイル名の一致判定
If Len(Trim(Range(&quot;FILE_NAME&quot;).Value)) &gt; 0 Then
    If Len(Trim(Range(&quot;FILE_MATCH_TYPE&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致タイプ を入力してください&quot;, vbCritical
        Exit Sub
    End If
    If Len(Trim(Range(&quot;FILE_MATCH_PATTERN&quot;).Value)) = 0 Then
        MsgBox &quot;フォルダ名の一致パターン を入力してください&quot;, vbCritical
        Exit Sub
    End If
End If

&#39;---拡張子の一致判定
If Len(Trim(Range(&quot;EXT_NAME&quot;).Value)) &gt; 0 Then
    If Len(Trim(Range(&quot;EXT_MATCH_TYPE&quot;).Value)) = 0 Then
        MsgBox &quot;拡張子の一致タイプ を入力してください&quot;, vbCritical
        Exit Sub
    End If
    If Len(Trim(Range(&quot;EXT_MATCH_PATTERN&quot;).Value)) = 0 Then
        MsgBox &quot;拡張子の一致パターン を入力してください&quot;, vbCritical
        Exit Sub
    End If
End If


Set ws = Sheet2
&#39;---テーブルをリセットする
With ws
    .Select
    &#39;---テーブルが空だとエラーになるのでエラーを無視するようにする
    On Error Resume Next
    .Range(Range(&quot;FILE_TABLE&quot;).Address).EntireRow.Delete
    On Error GoTo 0
End With

&#39;---まず指定フォルダのファイルを収集する
If Len(Trim(Range(&quot;FOLDER_NAME&quot;).Value)) &gt; 0 Then
    &#39;---指定の場合一致したらファイル情報を取得する
    If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;指定&quot; Then
        If in_array(objFso.GetFolder(target_folder).Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = True Then
            Call GetFileData(ws, Range(&quot;FOLDER_NAME&quot;).Value)
        End If
    End If
    &#39;---除外の場合は不一致ならファイル情報取得して再帰処理する
    If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;除外&quot; Then
        If in_array(objFso.GetFolder(target_folder).Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = False Then
            Call GetFileData(ws, Range(&quot;FOLDER_NAME&quot;).Value)
        End If
    End If
Else
    Call GetFileData(ws, Range(&quot;TARGET_FOLDER&quot;).Value)
End If


&#39;-サブフォルダを対象とするか
If Range(&quot;TARGET_SUBFOLDER&quot;).Value = &quot;する&quot; Then
    Call GetSubFoler(ws, target_folder)
End If
Set ws = Nothing
Application.StatusBar = False

&#39;---先頭行が空白だったら（絶対空白のはず）削除する
If Len(Trim(Range(&quot;FILE_TABLE&quot;).Item(1).Value)) = 0 Then
    On Error Resume Next
    Range(&quot;FILE_TABLE&quot;).ListObject.ListRows(1).Delete
    On Error GoTo 0
End If

Range(&quot;FILE_TABLE&quot;).Item(1).Select
MsgBox &quot;終了しました&quot;
End Sub</code></pre></div>



<p class="wp-block-paragraph">長いように見えてやっていることは</p>



<ol class="wp-block-list has-watery-yellow-background-color has-background is-style-border-radius-s-dotted has-border">
<li>エクセルで入力した内容（条件）をチェックする</li>



<li>出力先のシート（厳密にはテーブル）をリセットする</li>



<li>指定したフォルダのファイル情報を取得する</li>
</ol>



<p class="wp-block-paragraph">だけです</p>



<p class="wp-block-paragraph">当たり前ですがエクセルで設定できる項目に比例してソースが長くなってしまうのはやむなし</p>



<h4 class="wp-block-heading">GetFileData</h4>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Private Function GetFileData(ws As Worksheet, target_folder As String)
&#39;======================================================================
&#39; 指定フォルダの中にあるファイル情報を取得してリストに反映する
&#39;======================================================================
Dim lngRow As Long
Dim file_path As String
Dim objFile As Scripting.File
Dim get_file_bool As Boolean

Application.StatusBar = target_folder & &quot; のファイル情報を取得中・・・&quot;
For Each objFile In objFso.GetFolder(target_folder).Files
    &#39;---ファイルの取得判定の初期値を設定（True）
    get_file_bool = True
    &#39;---ファイル名検索に指定があったら
    If Len(Trim(Range(&quot;FILE_NAME&quot;).Value)) &gt; 0 Then
        &#39;---ファイル名（拡張子除く）が条件と一致しているか確認
        If in_array(objFso.GetBaseName(objFile.Name), Split(Range(&quot;FILE_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FILE_MATCH_TYPE&quot;).Value) = IIf(Range(&quot;FILE_MATCH_PATTERN&quot;).Value = &quot;指定&quot;, True, False) Then
            get_file_bool = True
        Else
            get_file_bool = False
            GoTo continue
        End If
    End If
    
    &#39;---拡張子に指定があったら
    If Len(Trim(Range(&quot;EXT_NAME&quot;).Value)) &gt; 0 Then
        If in_array(objFso.GetExtensionName(objFile.Name), Split(Range(&quot;EXT_NAME&quot;).Value, &quot;|&quot;), Range(&quot;EXT_MATCH_TYPE&quot;).Value) = IIf(Range(&quot;EXT_MATCH_PATTERN&quot;).Value = &quot;指定&quot;, True, False) Then
            get_file_bool = True
        Else
            get_file_bool = False
            GoTo continue
        End If
    End If
    
    &#39;---取得対象と判定されたら情報を取得して書き出す
    If get_file_bool = True Then
        With ws
            .Select
            &#39;---テーブルに行を追加する
            Range(&quot;FILE_TABLE&quot;).ListObject.ListRows.Add AlwaysInsert:=False
            lngRow = Range(&quot;FILE_TABLE&quot;).Item(Range(&quot;FILE_TABLE&quot;).Cells.Count).Row
            .Cells(lngRow, lngCol.file_name).Value = objFile.Name
            .Cells(lngRow, lngCol.ext_name).Value = objFso.GetExtensionName(objFile.Path)
            .Cells(lngRow, lngCol.file_size).Value = objFile.Size
            .Cells(lngRow, lngCol.create_date).Value = objFile.DateCreated
            .Cells(lngRow, lngCol.mod_date).Value = objFile.DateLastModified
            file_path = Replace(objFile.Path, &quot;\&quot; & objFile.Name, &quot;&quot;)
            .Cells(lngRow, lngCol.file_path).Value = Replace(objFile.Path, &quot;\&quot; & objFile.Name, &quot;&quot;)
            .Cells(lngRow, lngCol.file_path_split).Resize(, UBound(Split(file_path, &quot;\&quot;)) + 1) = Split(file_path, &quot;\&quot;)
        End With
    End If
continue:
Next
End Function</code></pre></div>



<p class="wp-block-paragraph">まず今回のようなループが多いプログラムはステータスバーに進捗状況を表示してあげると親切</p>



<p class="wp-block-paragraph">他の言語に慣れるとVBAのForループに<strong>continue</strong>が無いのが地味にストレスなんでGoToで無理矢理再現したことと、PHPで出会った<strong>in_array</strong>は後述していますがVBAにない関数は自作してしまえってことでこちらも再現しただけの関数を準備しました</p>



<p class="wp-block-paragraph">他には出力先をテーブル化しているので最下行の指定が通例とちょっと違うことと、フォルダパスを&#8221;\&#8221;で区切った配列を一気に反映させるために<strong>Resize</strong>を使っているところがミソ</p>



<p class="wp-block-paragraph">細かいこと書きましたがざっくりやっていることは↓↓だけ</p>



<ol class="wp-block-list is-style-default has-watery-yellow-background-color has-background is-style-border-radius-s-dotted has-border">
<li>引数にあるフォルダ内のファイルをFor Eachでサーチ</li>



<li>SETシートで指定したファイルと拡張子の条件と照合</li>



<li>条件一致していればLISTシートにあるテーブルへ書き込む</li>
</ol>



<h4 class="wp-block-heading">GetSubFoler</h4>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Private Function GetSubFoler(ws As Worksheet, target_folder As String)
&#39;======================================================================
&#39; 再帰処理でフォルダを潜りながらそのフォルダのファイルを取得する
&#39;======================================================================
Dim objFld As Scripting.Folder

For Each objFld In objFso.GetFolder(target_folder).SubFolders
    &#39;---フォルダ名検索に指定があったら
    If Len(Trim(Range(&quot;FOLDER_NAME&quot;).Value)) &gt; 0 Then
        &#39;---指定の場合一致したらファイル情報を取得する
        If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;指定&quot; Then
            If in_array(objFld.Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = True Then
                Call GetFileData(ws, objFld.Path)
            End If
            &#39;---どちらにしても再帰処理はかける
            Call GetSubFoler(ws, objFld.Path)
        End If
        &#39;---除外の場合は不一致ならファイル情報取得して再帰処理する
        If Range(&quot;FOLDER_MATCH_PATTERN&quot;).Value = &quot;除外&quot; Then
            If in_array(objFld.Name, Split(Range(&quot;FOLDER_NAME&quot;).Value, &quot;|&quot;), Range(&quot;FOLDER_MATCH_TYPE&quot;).Value) = False Then
                Call GetFileData(ws, objFld.Path)
                Call GetSubFoler(ws, objFld.Path)
            End If
        End If
    Else
        Call GetFileData(ws, objFld.Path)
        Call GetSubFoler(ws, objFld.Path)
    End If
Next
End Function</code></pre></div>



<p class="wp-block-paragraph">ここでもin_arrayが登場してるのですが、条件指定を複数できるようにしてるので重宝します</p>



<p class="wp-block-paragraph">ここでのポイントは<strong>再帰処理</strong>しているところだけで、これまで通りやっていることを並べると</p>



<ol class="wp-block-list has-watery-yellow-background-color has-background is-style-border-radius-s-dotted has-border">
<li>SETシートで指定したフォルダの条件と照合</li>



<li>一致しているもしくは条件指定していないならファイル情報を取得</li>



<li>次の階層のフォルダを同じことを繰り返す</li>
</ol>



<p class="has-cyan-bluish-gray-color has-text-color has-link-color is-style-clip-box has-box-style wp-elements-f4ffcff547898e71cd6090c41280740c wp-block-paragraph">再帰処理はその内説明ページ作ります</p>



<h4 class="wp-block-heading">in_array</h4>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Private Function in_array(target_str As String, target_array As Variant, Optional match_type As String = &quot;完全一致&quot;) As Boolean
&#39;======================================================================
&#39; パターンに合わせて一致判定を返す
&#39;======================================================================
Dim arr As Variant

For Each arr In target_array
    Select Case match_type
        Case &quot;完全一致&quot;
            If LCase(target_str) = LCase(arr) Then
                in_array = True
                Exit Function
            End If
        Case &quot;部分一致&quot;
            If LCase(target_str) Like &quot;*&quot; & LCase(arr) & &quot;*&quot; Then
                in_array = True
                Exit Function
            End If
        Case &quot;前方一致&quot;
            If LCase(target_str) Like LCase(arr) & &quot;*&quot; Then
                in_array = True
                Exit Function
            End If
        Case &quot;後方一致&quot;
            If LCase(target_str) Like &quot;*&quot; & LCase(arr) Then
                in_array = True
                Exit Function
            End If
        Case Else
    End Select
Next
in_array = False
End Function</code></pre></div>



<p class="wp-block-paragraph">本家のin_arrayは完全一致だけですが今回の使用目的的にも自作関数なので一致条件を分岐で作りましたが、指定の文字が配列の中にあるかをチェックする関数</p>



<p class="wp-block-paragraph">Dictionary型で無理矢理取り扱えばExistsもありますが、完全一致以外も処理したいので結局自作関数がベストかと</p>



<h2 class="wp-block-heading">余談 兼 フリーソフト紹介</h2>



<p class="wp-block-paragraph">今回せっかくVBAで作ったので分解して説明しましたが、ファイルリストを作りたいならフリーソフトのEverythingを使うと爆速で作成できます！</p>



<p class="wp-block-paragraph">個人的にはWindowsの標準ソフトとして搭載してほしいくらいの便利ソフトなので興味がある方は是非！</p>



<p class="wp-block-paragraph"><a href="https://forest.watch.impress.co.jp/library/software/everything" target="_blank" rel="noreferrer noopener nofollow">窓の杜へのリンク</a></p>



<p class="wp-block-paragraph"><a href="https://www.voidtools.com" target="_blank" rel="noreferrer noopener nofollow">本家サイトへのリンク</a></p>



<h2 class="wp-block-heading">あとがき</h2>



<p class="wp-block-paragraph">せっかく作ったので紹介してみましたが実のところ再帰処理さえ理解していれば9割くらい作れるお手軽プログラムに細かな設定を付け足しただけです</p>



<p class="wp-block-paragraph">他にもExcelでツール作った時は同じように公開してますのでたまに覗きに来てくれると嬉しいです！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-file-list-maker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【VBA】Gmailを送信する方法 CDOとアプリパスワード設定</title>
		<link>https://javeo.jp/vba-gmail-send/</link>
					<comments>https://javeo.jp/vba-gmail-send/#comments</comments>
		
		<dc:creator><![CDATA[ジャベ雄]]></dc:creator>
		<pubDate>Sun, 25 Sep 2022 23:00:00 +0000</pubDate>
				<category><![CDATA[Excel・VBA]]></category>
		<category><![CDATA[Gmail]]></category>
		<category><![CDATA[Mail]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=891</guid>

					<description><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2026/05/vba-gmail-send-1024x538.jpg" class="webfeedsFeaturedVisual" /></p>VBAでGmailを送りたいときの定番、CDOとアプリパスワードを使った送信方法をまとめました、2段階認証とアプリパスワードの設定からコピペで使える送信関数まで解説します]]></description>
										<content:encoded><![CDATA[<p><img src="https://javeo.jp/wp-content/uploads/2026/05/vba-gmail-send-1024x538.jpg" class="webfeedsFeaturedVisual" /></p><div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<p class="wp-block-paragraph">昔作ったVBAのメール送信ツールを引っ張り出してきたら、いつの間にか使えなくなっていたので、改善方法も含めて改めてプログラムや設定方法をまとめてみました</p>



<p class="wp-block-paragraph">結論から言うと、<strong>VBAからGmailを送るならCDO(Microsoft Collaboration Data Objects)を使うのが定番</strong>で、Gmail側で<strong><span class="swl-marker mark_yellow">アプリパスワードの生成</span></strong>さえ済ませておけば、件名・本文・宛先・添付ファイル付きのメールをマクロから送信できます</p>



<p class="wp-block-paragraph">OutlookならOutlook専用のライブラリがあるのでそちらを使ったほうが扱いやすいんですが、GmailはCDO経由で送ることになるので、今回はその方法になります</p>



<p class="wp-block-paragraph">この記事ではGmail側の事前設定から、コピペでそのまま使える送信関数まで、つまづきやすいところを補足しながら解説していきます</p>



<h2 class="wp-block-heading">最初にやる一番キモなGmailの事前設定</h2>



<p class="wp-block-paragraph">コードを書く前に、実はこのGmail側の設定が一番のキモなんですよね</p>



<p class="wp-block-paragraph">ここを飛ばすと、コードが正しくてもメールは送れないので、先に片付けておきましょう</p>



<h3 class="wp-block-heading">安全性の低いアプリのアクセス・・・が使用できない!?</h3>



<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h09_16.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="861" height="212" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h09_16.png" alt="" class="wp-image-896" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h09_16.png 861w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h09_16-300x74.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h09_16-150x37.png 150w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h09_16-768x189.png 768w" sizes="(max-width: 861px) 100vw, 861px" /></a></figure>



<p class="wp-block-paragraph">一昔前はこの「安全性の低いアプリのアクセス」を有効化するのがGmail側の設定だったのに、いつの間にか使用できなくなっていました</p>



<p class="wp-block-paragraph">(結局この部分が、昔は使えていたツールが動かなくなっていた原因でした)</p>



<p class="wp-block-paragraph">と言うか、気づいていなかっただけで、しっかりGoogleから<strong><span class="swl-marker mark_yellow">2022年5月30日</span></strong>より利用できなくなる事前アナウンスが出ていたのはうっかりでした</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h29_40.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="509" height="825" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h29_40.png" alt="" class="wp-image-898" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h29_40.png 509w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h29_40-185x300.png 185w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h29_40-93x150.png 93w" sizes="(max-width: 509px) 100vw, 509px" /></a></figure>
</div>


<p class="wp-block-paragraph">2026年現在もこの流れは変わっていなくて、個人のGmailでは「安全性の低いアプリのアクセス」はすでに廃止済みです</p>



<p class="wp-block-paragraph">そのかわりに用意されたのが、次に紹介する<strong>アプリパスワード</strong>という仕組みなんですね</p>



<h3 class="wp-block-heading">今は&#8221;アプリパスワード&#8221;の生成が必要</h3>



<p class="wp-block-paragraph">VBAのようなアプリからGmailへログインするには、普段ログインに使っている本来のパスワードではなく、<strong><span class="swl-marker mark_yellow" style="color:#e8313b">アプリパスワードの生成が必要</span></strong>になります</p>



<p class="wp-block-paragraph">2段階認証を有効にしていると、本来のパスワードはSMTPの認証で弾かれてしまうので、ここで作るアプリパスワードがログイン用のカギになるイメージです</p>



<p class="wp-block-paragraph">設定するページはこちらから</p>



<p class="wp-block-paragraph"><a href="https://myaccount.google.com/security" target="_blank" rel="noopener noreferrer">https://myaccount.google.com/security</a></p>



<p class="wp-block-paragraph">ちなみに、アプリパスワードの生成ページにはアカウント内検索だと出てこないことがあるので、その場合は <a href="https://myaccount.google.com/apppasswords" target="_blank" rel="noopener noreferrer">https://myaccount.google.com/apppasswords</a> に直接アクセスすると早いです</p>



<div class="wp-block-group is-style-big_icon_caution"><div class="wp-block-group__inner-container">
<ul class="wp-block-list">
<li>アプリパスワードは<strong>2段階認証が前提</strong>なので、先に2段階認証をオンにしないと生成の選択肢が出てきません</li>



<li>発行された16桁のパスワードは<strong>発行時に1度しか表示されない</strong>ので、その場で控えてください</li>



<li>アプリパスワードはアカウントへのログインに使えてしまうので、コードに直書きしたまま<strong>第三者に渡さない</strong>ように気をつけてください</li>
</ul>
</div></div>



<p class="wp-block-paragraph">それでは実際の流れを見ていきましょう、大まかには次の3ステップです</p>



<div class="swell-block-step" data-num-style="circle">
<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l">2段階認証プロセスをオンにする</div><div class="swell-block-step__body">
<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-25_15h26_42.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="854" height="327" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-25_15h26_42.png" alt="" class="wp-image-913" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-25_15h26_42.png 854w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-25_15h26_42-300x115.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-25_15h26_42-150x57.png 150w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-25_15h26_42-768x294.png 768w" sizes="(max-width: 854px) 100vw, 854px" /></a></figure>



<p class="wp-block-paragraph">初期状態では2段階認証プロセスがオフになっているので、まずはここをオンにします</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h25_17.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="679" height="823" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h25_17.png" alt="" class="wp-image-900" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h25_17.png 679w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h25_17-248x300.png 248w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h25_17-124x150.png 124w" sizes="(max-width: 679px) 100vw, 679px" /></a></figure>
</div>


<p class="wp-block-paragraph">オンにするのは、次のページで<strong>&#8220;使ってみる&#8221;ボタンを押すだけ</strong>です</p>



<p class="wp-block-paragraph">SMSや認証アプリ、セキュリティキーといった標準の2段階認証が有効になっていればOKで、ここが済むとアプリパスワードを作れるようになります</p>
</div></div>



<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l">アプリパスワードを生成する</div><div class="swell-block-step__body">
<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h27_08.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="855" height="329" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h27_08.png" alt="" class="wp-image-901" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h27_08.png 855w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h27_08-300x115.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h27_08-150x58.png 150w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h27_08-768x296.png 768w" sizes="(max-width: 855px) 100vw, 855px" /></a></figure>



<p class="wp-block-paragraph">2段階認証プロセスをオンにしたことで<strong><span class="swl-marker mark_yellow">アプリパスワードの選択肢が増えている</span></strong>ので、ここで設定していきます</p>



<div class="wp-block-columns">
<div class="wp-block-column" style="flex-basis:50%">
<div class="wp-block-group"><div class="wp-block-group__inner-container">
<div class="wp-block-columns">
<div class="wp-block-column" style="flex-basis:100%">
<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h53_33.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="671" height="351" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h53_33.png" alt="" class="wp-image-903" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h53_33.png 671w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h53_33-300x157.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h53_33-150x78.png 150w" sizes="(max-width: 671px) 100vw, 671px" /></a></figure>
</div>
</div>
</div></div>
</div>



<div class="wp-block-column" style="flex-basis:50%">
<div class="wp-block-columns are-vertically-aligned-center">
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:100%">
<div class="wp-block-columns">
<div class="wp-block-column" style="flex-basis:100%">
<figure class="wp-block-image size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h38_01.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="674" height="241" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h38_01.png" alt="" class="wp-image-902" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h38_01.png 674w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h38_01-300x107.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_23h38_01-150x54.png 150w" sizes="(max-width: 674px) 100vw, 674px" /></a></figure>
</div>
</div>
</div>
</div>
</div>
</div>



<p class="wp-block-paragraph">アプリ名はアプリパスワードの名前になるだけなので、それらしい選択をすればよくて、&#8221;その他&#8221;を選ぶとフリー入力に変わります</p>



<p class="wp-block-paragraph">名前を入れると<strong>&#8220;生成&#8221;ボタンが活性化する</strong>ので、そのままクリックします</p>
</div></div>



<div class="swell-block-step__item"><div class="swell-block-step__number u-bg-main"><span class="__label">STEP</span></div><div class="swell-block-step__title u-fz-l">発行された16桁を控える</div><div class="swell-block-step__body"><div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-20_00h00_53.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="655" height="556" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-20_00h00_53.png" alt="" class="wp-image-905" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-20_00h00_53.png 655w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-20_00h00_53-300x255.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-20_00h00_53-150x127.png 150w" sizes="(max-width: 655px) 100vw, 655px" /></a></figure>
</div>


<p class="wp-block-paragraph">ここで表示される16桁の文字列が、いわゆる<strong><span class="swl-marker mark_yellow">アプリパスワード</span></strong>です</p>



<p class="wp-block-paragraph">右下の完了をクリックすると<strong>2度と表示されない</strong>ので、忘れずにパスワードを控えておきましょう</p>



<p class="wp-block-paragraph">もし控えそびれても、また同じ手順で新しく生成し直せばいいので、そこは安心してくださいね</p>
</div></div>
</div>



<p class="wp-block-paragraph">ちなみに、画像は記事公開当時のものなので、今は項目名やレイアウトが少し違って見えることがあります</p>



<p class="wp-block-paragraph">とはいえ「2段階認証をオン → アプリパスワードを生成 → 16桁を控える」という骨子は変わっていないので、流れさえ押さえておけば迷わないと思います</p>



<h3 class="wp-block-heading">このCDO方式はいつまで使える?</h3>



<p class="wp-block-paragraph">長く使ってきた方式なので、これからも使えるのか気になるところですよね</p>



<p class="wp-block-paragraph">そのあたりの現況だけ、簡単に注意としてまとめておきます</p>



<div class="wp-block-group is-style-big_icon_caution"><div class="wp-block-group__inner-container">
<ul class="wp-block-list">
<li><strong>個人のGmail</strong>なら、2段階認証 + アプリパスワードの組み合わせで、2026年に確認した限りでは送信できます</li>



<li>ただし次のいずれかに当てはまるとアプリパスワードは作れません、<strong>2段階認証がセキュリティキーだけ</strong>の設定になっている場合、<strong>高度な保護機能プログラム</strong>に登録している場合、そして<strong>会社や学校などの組織アカウント</strong>でログインしている場合です</li>



<li><strong>Google Workspace(法人)</strong>は管理者の設定しだいで、レガシー認証を制限していると使えないことがあります</li>



<li>長期的にはOAuth2やGmail API、Microsoft Graph APIといった方式へ寄っていく流れで、<strong>CDOはOAuth2に非対応</strong>なので、いずれ移行が必要になるかもしれません</li>
</ul>
</div></div>



<p class="wp-block-paragraph">そうは言っても、個人利用の範囲ではまだまだ現役なので、まずは今回のCDO方式で送れるようにしておけば十分じゃないでしょうか</p>



<h2 class="wp-block-heading">VBAの参照設定</h2>



<p class="wp-block-paragraph">続いてVBA側の準備です、参照設定で次のライブラリにチェックを入れます</p>



<p class="wp-block-paragraph"><strong>Microsoft CDO for Windows 2000 Library</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h38_51-1.png" target="_blank" rel="noopener noreferrer"><img decoding="async" width="455" height="317" src="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h38_51-1.png" alt="" class="wp-image-895" srcset="https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h38_51-1.png 455w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h38_51-1-300x209.png 300w, https://javeo.jp/wp-content/uploads/2022/09/2022-09-19_22h38_51-1-150x105.png 150w" sizes="(max-width: 455px) 100vw, 455px" /></a></figure>
</div>


<p class="wp-block-paragraph">名前に「2000」と入っていて古そうに見えますが、これがCDO(CDO.Message)のライブラリで、今のWindowsにも標準で入っています</p>



<div class="wp-block-group is-style-big_icon_point"><div class="wp-block-group__inner-container">
<p class="wp-block-paragraph">実はこの参照設定は<strong>任意</strong>です</p>



<p class="wp-block-paragraph">あとで紹介するコードは<strong><span class="swl-marker mark_yellow">cdoMsgのデータ型をObjectにしている</span></strong>ので、参照設定をしなくてもコピペするだけで動きます、入力補完を効かせたいときだけチェックを入れる、くらいの感覚でOKです</p>
</div></div>



<h2 class="wp-block-heading">実際のVBAプログラム</h2>



<p class="wp-block-paragraph">お待たせしました、ここからが本体です</p>



<h3 class="wp-block-heading">プログラムソース</h3>



<p class="wp-block-paragraph">件名・本文・宛先(To/Cc/Bcc)・添付ファイルまで一通り扱える送信関数です、コードの上のほうにある<strong><span class="swl-marker mark_yellow">mailUser と mailPass を、自分のGmailアドレスと先ほどのアプリパスワードに書き換える</span></strong>だけで使えます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>Function sendMail(MailSubject As String, MailBody As String, ToAddress As String, _
                    Optional CcAddress As String = vbNullString, Optional BccAddress As String = vbNullString, Optional attFile As Variant = vbNullString)

Const mailUser As String = &quot;&lt;Gmailのメアド&gt;&quot;
Const mailPass As String = &quot;&lt;アプリパスワード&gt;&quot;

Dim cdoMsg As Object: Set cdoMsg = CreateObject(&quot;CDO.Message&quot;)
Dim objFso As Object: Set objFso = CreateObject(&quot;Scripting.FileSystemObject&quot;)
Dim i As Long

With cdoMsg
    With .Configuration.Fields
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/languagecode&quot;) = &quot;shift-jis&quot; &#39;---文字コード指定
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/sendusing&quot;) = 2 &#39;---外部SMTP指定
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpserver&quot;) = &quot;smtp.gmail.com&quot; &#39;---SMTPサーバ名
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpserverport&quot;) = &quot;465&quot; &#39;---ポート№
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpauthenticate&quot;) = True &#39;---SMTP認証
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpusessl&quot;) = True &#39;---SSL
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout&quot;) = 60 &#39;---タイムアウト
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/sendusername&quot;) = mailUser &#39;---ユーザー
        .Item(&quot;http://schemas.microsoft.com/cdo/configuration/sendpassword&quot;) = mailPass &#39;---パスワード
        .Update
    End With
    .Subject = MailSubject
    .TextBody = MailBody
    .TextBodyPart.Charset = &quot;ISO-2022-JP&quot;
    .From = mailUser
    .To = ToAddress
    .CC = CcAddress
    .BCC = BccAddress
    
    &#39;---添付ファイルが複数（配列形式）かの分岐
    If IsArray(attFile) = True Then
        For i = LBound(attFile) To UBound(attFile)
            &#39;---ファイルが存在してれば添付する
            If objFso.FileExists(attFile(i)) Then
                .AddAttachment attFile(i)
            End If
        Next
    Else
        &#39;---ファイルが存在してれば添付する
        If objFso.FileExists(attFile(i)) Then
            .AddAttachment attFile(i)
        End If
    End If
    .Send
End With

Set cdoMsg = Nothing
Set objFso = Nothing
End Function</code></pre></div>



<p class="wp-block-paragraph">送信に関わる設定は <code>.Configuration.Fields</code> のあたりに集まっていて、ポイントは<strong><span class="swl-marker mark_yellow" style="color:#e8313b">smtp.gmail.com / ポート465 / SSL</span></strong>の3点です、ここがGmailで送るための決まりごとになります</p>



<p class="wp-block-paragraph">余談ですが、参照設定をしたのになぜ&#8221;cdoMsg&#8221;のデータ型を&#8221;Object&#8221;にするのかと言うと、これならコピペするだけで(≒参照設定をしなくても)プログラムが利用できるからです</p>



<p class="wp-block-paragraph">自分好みに改修したいときは、Objectから具体的な型への変更をおススメします</p>



<h3 class="wp-block-heading">ざっくり説明</h3>



<p class="wp-block-paragraph">コード自体はコピペで動くので、ここでは使うとき用に引数だけ説明しておきます</p>



<p class="wp-block-paragraph">1点だけ補足すると、添付ファイルを1つ(配列ではなく単体の文字列)で渡したときは、お使いの環境によっては添付がスキップされることがあります、確実に添付したいときは <code>Array("C:\temp\a.pdf")</code> のように1件でも配列で渡すと安定しますよ</p>



<figure class="wp-block-table alignwide is-style-stripes"><table><thead><tr><th>必須 / 任意</th><th>変数名</th><th>備考</th></tr></thead><tbody><tr><td>必須</td><td>MailSubject</td><td>件名</td></tr><tr><td>必須</td><td>MailBody</td><td>本文</td></tr><tr><td>必須</td><td>ToAddress</td><td>宛先（To）</td></tr><tr><td>任意</td><td>CcAddress </td><td>宛先（Cc）</td></tr><tr><td>任意</td><td>BccAddress </td><td>宛先（Bcc）</td></tr><tr><td>任意</td><td>attFile</td><td>添付ファイル※複数なら配列型に</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">呼び出すときは、必須の3つを渡すだけでも送れます、たとえばこんな感じです</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-vba" data-lang="Visual Basic + VBA"><code>&#39;---件名・本文・宛先だけ渡すシンプルな呼び出し
Call sendMail(&quot;テスト送信&quot;, &quot;本文です&quot;, &quot;to@example.com&quot;)

&#39;---添付ファイルを1つ付けて送る
Call sendMail(&quot;見積書の件&quot;, &quot;ご確認ください&quot;, &quot;to@example.com&quot;, , , &quot;C:\temp\mitsumori.xlsx&quot;)

&#39;---複数の添付ファイルは配列で渡す
Call sendMail(&quot;資料一式&quot;, &quot;まとめてお送りします&quot;, &quot;to@example.com&quot;, , , Array(&quot;C:\temp\a.pdf&quot;, &quot;C:\temp\b.pdf&quot;))</code></pre></div>



<p class="wp-block-paragraph">CcやBccを飛ばしたいときは、引数をカンマで詰めて空けておけば、Optionalの初期値がそのまま使われます</p>



<h2 class="wp-block-heading">送信できないときに確認したいこと</h2>



<p class="wp-block-paragraph">実行してエラーになったり、送れているはずなのに届かなかったり、というのはよくあるので、つまづきやすいポイントをチェックリストにしておきます</p>



<ul class="wp-block-list is-style-check_list -list-under-dashed">
<li><strong>2段階認証がオンになっているか</strong>、オフのままだとアプリパスワード自体が作れません</li>



<li><strong>mailPassに入れたのがアプリパスワードか</strong>、普段ログインに使う本来のパスワードだと認証で弾かれます</li>



<li>アプリパスワードの16桁を、<strong>空白を入れずに</strong>貼り付けているか</li>



<li>サーバとポートが<strong>smtp.gmail.com / 465</strong>になっていて、SSLがTrueか</li>



<li>会社の回線などで、ポート465の通信がファイアウォールで止められていないか</li>



<li>Google Workspace(法人)の場合、管理者がレガシー認証を制限していないか</li>
</ul>



<p class="wp-block-paragraph">個人的には、エラーが出たときはまず<strong><span class="swl-marker mark_yellow">アプリパスワードを作り直して貼り直す</span></strong>のが手っ取り早い切り分けだと思います</p>



<h2 class="wp-block-heading">よくある質問(FAQ)</h2>



<p class="wp-block-paragraph">最後に、VBAでGmailを送るときによく聞かれるところをまとめておきます</p>



<div class="swell-block-accordion">
<details class="swell-block-accordion__item" data-swl-acc="wrapper"><summary class="swell-block-accordion__title" data-swl-acc="header"><span class="swell-block-accordion__label">アプリパスワードの選択肢が出てきません</span><span class="swell-block-accordion__icon c-switchIconBtn" data-swl-acc="icon" aria-hidden="true" data-opened="false"><i class="__icon--closed icon-caret-down"></i><i class="__icon--opened icon-caret-up"></i></span></summary><div class="swell-block-accordion__body" data-swl-acc="body">
<p class="wp-block-paragraph">ほとんどの場合、2段階認証がオフになっているのが原因です、先に2段階認証をオンにすると選択肢が出てきます</p>



<p class="wp-block-paragraph">それでも見当たらないときは、アカウント内の検索だと出ないことがあるので、<a href="https://myaccount.google.com/apppasswords" target="_blank" rel="noopener noreferrer">https://myaccount.google.com/apppasswords</a> に直接アクセスしてみてください</p>
</div></details>



<details class="swell-block-accordion__item" data-swl-acc="wrapper"><summary class="swell-block-accordion__title" data-swl-acc="header"><span class="swell-block-accordion__label">送信時にエラーになります</span><span class="swell-block-accordion__icon c-switchIconBtn" data-swl-acc="icon" aria-hidden="true" data-opened="false"><i class="__icon--closed icon-caret-down"></i><i class="__icon--opened icon-caret-up"></i></span></summary><div class="swell-block-accordion__body" data-swl-acc="body">
<p class="wp-block-paragraph">多いのは認証まわりで、mailPassに本来のパスワードを入れていたり、アプリパスワードに余計な空白が混ざっていたりするケースです</p>



<p class="wp-block-paragraph">あとはサーバ・ポートが <code>smtp.gmail.com</code> / <code>465</code> でSSLがTrueになっているか、会社の回線ならポート465が塞がれていないか、このあたりを確認してみてください</p>
</div></details>



<details class="swell-block-accordion__item" data-swl-acc="wrapper"><summary class="swell-block-accordion__title" data-swl-acc="header"><span class="swell-block-accordion__label">OAuth2を使わなくて大丈夫ですか?</span><span class="swell-block-accordion__icon c-switchIconBtn" data-swl-acc="icon" aria-hidden="true" data-opened="false"><i class="__icon--closed icon-caret-down"></i><i class="__icon--opened icon-caret-up"></i></span></summary><div class="swell-block-accordion__body" data-swl-acc="body">
<p class="wp-block-paragraph">個人のGmailなら、2段階認証 + アプリパスワードの組み合わせで、2026年に確認した限りでは送信できるので、CDOだけでも問題ありません</p>



<p class="wp-block-paragraph">ただ、CDOはOAuth2に非対応なので、長期的にはGmail APIやMicrosoft Graph APIといったOAuth2対応の方式に移っていくことになりそうです、セキュリティ要件が厳しい現場ではそちらも検討してみてください</p>
</div></details>



<details class="swell-block-accordion__item" data-swl-acc="wrapper"><summary class="swell-block-accordion__title" data-swl-acc="header"><span class="swell-block-accordion__label">Outlookでも同じように送れますか?</span><span class="swell-block-accordion__icon c-switchIconBtn" data-swl-acc="icon" aria-hidden="true" data-opened="false"><i class="__icon--closed icon-caret-down"></i><i class="__icon--opened icon-caret-up"></i></span></summary><div class="swell-block-accordion__body" data-swl-acc="body">
<p class="wp-block-paragraph">OutlookにはOutlook専用のライブラリがあるので、そちらを使ったほうが扱いやすいです</p>



<p class="wp-block-paragraph">今回のCDOはGmailなどSMTPで送りたいとき向け、という住み分けですね、Outlook版は別の記事で改めてまとめる予定です</p>
</div></details>
</div>



<h2 class="wp-block-heading">あとがき</h2>



<p class="wp-block-paragraph">今はAPIやWebhookでLINEなどにも通知できるので、メールの出番は減った気もしますが、メール通知もまだまだ現役で、きっとGmailが利用頻度が高いのではとまとめてみました</p>



<p class="wp-block-paragraph">ちなみにVBAは、外部とのデータ連携でもけっこう活躍してくれて、APIのレスポンスを扱う<a href="https://javeo.jp/vba-json/" target="_blank" rel="noopener noreferrer">VBAでJSONをパースする方法</a>もまとめているので、あわせて読んでみてください</p>



<p class="wp-block-paragraph">まずは今回のCDO方式でGmailが送れるようになれば、定型メールの自動化はだいぶ楽になるはずです、Outlook版もそのうちまとめるので、よかったらまた覗いてみてくださいね</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-gmail-send/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
