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

<channel>
	<title>マクロ</title>
	<atom:link href="https://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>Mon, 13 Oct 2025 05:56:39 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://javeo.jp/wp-content/uploads/2025/08/cropped-ExcelPython_future-32x32.jpg</url>
	<title>マクロ</title>
	<link>https://javeo.jp</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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[VBA・Excel]]></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[目次 待機処理が必要な理由WebDriverWaitクラスでできることVBA版WebDriverWaitの実装例使い方サンプルまとめ 待機処理が必要な理由 SeleniumでWebサイトを操作するときにありがちな内容がこ [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p>PythonでSeleniumを利用するときに利用必須ともいえるWebDriverWaitとexpected_conditionsですが、残念ながらVBAにはありません</p>



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



<p>※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">

<a rel="noopener follow noreferrer" target="_blank" href="https://javeo.jp/python_wait/" title="【Python】Seleniumの待機処理はWebDriverWaitを使おう" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img fetchpriority="high" decoding="async" width="320" height="198" src="https://javeo.jp/wp-content/uploads/2023/07/python-320x198.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://javeo.jp/wp-content/uploads/2023/07/python-320x198.png 320w, https://javeo.jp/wp-content/uploads/2023/07/python-240x148.png 240w, https://javeo.jp/wp-content/uploads/2023/07/python-640x396.png 640w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Python】Seleniumの待機処理はWebDriverWaitを使おう</div><div class="blogcard-snippet internal-blogcard-snippet">PythonのSeleniumには条件を満たすまで待機する便利なWebDriverWaitがあります。ですが実質的に重要なのはexpected_conditionsの方でこちらの詳細をまとめてみました。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://javeo.jp" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">javeo.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.09.22</div></div></div></div></a>
</div></figure>
</div>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">待機処理が必要な理由</a></li><li><a href="#toc2" tabindex="0">WebDriverWaitクラスでできること</a></li><li><a href="#toc3" tabindex="0">VBA版WebDriverWaitの実装例</a></li><li><a href="#toc4" tabindex="0">使い方サンプル</a></li><li><a href="#toc5" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

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



<p>SeleniumでWebサイトを操作するときにありがちな内容がこちら</p>



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



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



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



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



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



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



<figure class="wp-block-table"><div class="scrollable-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></div></figure>



<p>ポイント：</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"><span id="toc3">VBA版WebDriverWaitの実装例</span></h2>



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



<figure class="wp-block-image size-large"><a rel="follow noopener noreferrer" target="_blank" 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 undefined-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"><span id="toc4">使い方サンプル</span></h2>



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



<p>ポイントはInit部分で引数は下記の通りです</p>



<div class="hcb_wrap"><pre class="prism undefined-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 undefined-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"><span id="toc5">まとめ</span></h2>



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



<p>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[VBA・Excel]]></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[目次 やっていること必要な参照設定ファイルへの反映手順プロパティウィンドウを表示しておく標準モジュールを追加モジュール名を変更するプログラムの使い方Chromedriverの書き込み権限がない時サンプルファイル最後に実際 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p>以前に別で作成したVBAのChromedriver自動更新プログラムですが色々見直すと実はVBA-JSONなしでも十分ってことに気づいて別途作成しました</p>



<p>条件付きの簡略版ではありますのでご自身の環境に合わせて使い分けてください</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">

<a rel="noopener follow noreferrer" target="_blank" href="https://javeo.jp/vba-chromedriver-auto-update/" title="【VBA】SeleniumBasicのchromedriverを自動更新する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="320" height="198" src="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-320x198.jpg" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-320x198.jpg 320w, https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-240x148.jpg 240w, https://javeo.jp/wp-content/uploads/2024/07/ExcelVBA-640x396.jpg 640w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【VBA】SeleniumBasicのchromedriverを自動更新する</div><div class="blogcard-snippet internal-blogcard-snippet">Pythonではよくあるchromedriverの自動更新をVBAで再現できるように独自に作成したプログラムを紹介します！私も利用しているのでより良くなるご指摘あればコメントお願いします</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://javeo.jp" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">javeo.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.15</div></div></div></div></a>
</div></figure>
</div>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-4" checked><label class="toc-title" for="toc-checkbox-4">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">やっていること</a></li><li><a href="#toc2" tabindex="0">必要な参照設定</a></li><li><a href="#toc3" tabindex="0">ファイルへの反映手順</a><ol><li><a href="#toc4" tabindex="0">プロパティウィンドウを表示しておく</a></li><li><a href="#toc5" tabindex="0">標準モジュールを追加</a></li><li><a href="#toc6" tabindex="0">モジュール名を変更する</a></li><li><a href="#toc7" tabindex="0">プログラムの使い方</a></li></ol></li><li><a href="#toc8" tabindex="0">Chromedriverの書き込み権限がない時</a></li><li><a href="#toc9" tabindex="0">サンプルファイル</a></li><li><a href="#toc10" tabindex="0">最後に実際のソース</a></li><li><a href="#toc11" tabindex="0">あとがき</a></li></ol>
    </div>
  </div>

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



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



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



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



<p>このプログラムを実行するために設定した参照設定</p>



<figure class="wp-block-image size-full"><a rel="follow noopener noreferrer" target="_blank" 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>追加したのは下記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>ここは旧バージョンと変わりありません</p>



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



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



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



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



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



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



<figure class="wp-block-image size-large"><a rel="follow noopener noreferrer" target="_blank" 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"><span id="toc5">標準モジュールを追加</span></h3>



<p>自動更新プログラム用にモジュールを追加する</p>



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



<figure class="wp-block-image size-large"><a rel="follow noopener noreferrer" target="_blank" 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"><span id="toc6">モジュール名を変更する</span></h3>



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



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



<figure class="wp-block-image size-large"><a rel="follow noopener noreferrer" target="_blank" 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"><span id="toc7">プログラムの使い方</span></h3>



<p>「<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 undefined-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"><span id="toc8">Chromedriverの書き込み権限がない時</span></h2>



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



<p>画像の通りですが下記手順で権限設定ができます</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 rel="follow noopener noreferrer" target="_blank" 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"><span id="toc9">サンプルファイル</span></h2>



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





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



<p>まずはGithubをご利用の方向けはこちら</p>




<a rel="noopener noreferrer" target="_blank" href="https://github.com/javeo2022/webdriver_manager_VBA_Lite" title="GitHub - javeo2022/webdriver_manager_VBA_Lite: SeleniumBasic用のVBAでChromeDriverを自動更新するためのプログラムです" class="blogcard-wrap external-blogcard-wrap a-wrap cf"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img decoding="async" src="https://opengraph.githubassets.com/4854569a2cb6dba2b1062d618348a7196c7ab09cc88bba2176029d9baee800f9/javeo2022/webdriver_manager_VBA_Lite" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="320" height="198" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">GitHub - javeo2022/webdriver_manager_VBA_Lite: SeleniumBasic用のVBAでChromeDriverを自動更新するためのプログラムです</div><div class="blogcard-snippet external-blogcard-snippet">SeleniumBasic用のVBAでChromeDrive...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/javeo2022/webdriver_manager_VBA_Lite" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>



<p>例によってコピペ用はこちらです</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 undefined-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"><span id="toc11">あとがき</span></h2>



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



<p>今後改修するとしたらこちらになる予定です</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[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[目次 変数変数とは変数を使う目的変数の書き方変数の命名規則変数のスコープ宣言する場所による違い（プロシージャ内外）プロシージャ外で宣言する場合のPrivete/Publicステートメントデータ型について基本的なデータ型オ [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box info-box">
<p>VBAに限らずプログラミングにおいて変数と定数は基礎中の基礎</p>



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




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-6" checked><label class="toc-title" for="toc-checkbox-6">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">変数</a><ol><li><a href="#toc2" tabindex="0">変数とは</a></li><li><a href="#toc3" tabindex="0">変数を使う目的</a></li><li><a href="#toc4" tabindex="0">変数の書き方</a></li><li><a href="#toc5" tabindex="0">変数の命名規則</a></li><li><a href="#toc6" tabindex="0">変数のスコープ</a><ol><li><a href="#toc7" tabindex="0">宣言する場所による違い（プロシージャ内外）</a></li><li><a href="#toc8" tabindex="0">プロシージャ外で宣言する場合のPrivete/Publicステートメント</a></li></ol></li><li><a href="#toc9" tabindex="0">データ型について</a><ol><li><a href="#toc10" tabindex="0">基本的なデータ型</a></li><li><a href="#toc11" tabindex="0">オブジェクト型について</a></li><li><a href="#toc12" tabindex="0">なるべく使用を控えたいけど便利な万能データ型</a></li><li><a href="#toc13" tabindex="0">列挙型（Enum）とユーザー定義データ型（Type）</a></li></ol></li></ol></li><li><a href="#toc14" tabindex="0">定数</a><ol><li><a href="#toc15" tabindex="0">定数とは</a></li><li><a href="#toc16" tabindex="0">定数を使う目的</a></li><li><a href="#toc17" tabindex="0">定数の書き方</a><ol><li><a href="#toc18" tabindex="0">定数の命名規則</a></li></ol></li></ol></li><li><a href="#toc19" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

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



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



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



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



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



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



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



<p>変数を使うことで以下のメリットがあります</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"><span id="toc4">変数の書き方</span></h3>



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



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc5">変数の命名規則</span></h3>



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



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



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



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc6">変数のスコープ</span></h3>



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



<p>範囲の考え方はおおきくわけて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 rel="follow noopener noreferrer" target="_blank" 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"><span id="toc7">宣言する場所による違い（プロシージャ内外）</span></h4>



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



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



<figure class="wp-block-table"><div class="scrollable-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></div></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>変数は同一範囲内で重複して宣言することはできません</p>



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



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



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



<figure class="wp-block-table"><div class="scrollable-table"><table><thead><tr><th>修飾子</th><th>スコープ</th><th>他モジュールからアクセス</th></tr></thead><tbody><tr><td><code>Private</code></td><td>モジュール内限定</td><td>&#x274c; 不可</td></tr><tr><td><code>Public</code></td><td>プロジェクト全体</td><td>&#x2705; 可能</td></tr></tbody></table></div></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>※Privete/Publicの宣言をしていない場合はPrivateが適用されます</p>
</div></div>



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



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



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



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



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



<figure class="wp-block-table"><div class="scrollable-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></div></figure>



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



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



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



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



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



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc12">なるべく使用を控えたいけど便利な万能データ型</span></h4>



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



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



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



<figure class="wp-block-table"><div class="scrollable-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></div></figure>



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



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



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



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



<div class="hcb_wrap"><pre class="prism undefined-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 undefined-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"><span id="toc14">定数</span></h2>



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



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



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



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



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



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



<p>その他にも定数を使うことで以下のメリットがあります</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"><span id="toc17">定数の書き方</span></h3>



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



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



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



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



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



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc19">まとめ</span></h2>



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



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


<hr class="wp-block-separator has-alpha-channel-opacity" />
<p style="text-align: left;">何か聞きたいことがあれば <a rel="follow noopener noreferrer" target="_blank" href="https://javeo.jp/otoiawase/">お問い合わせページ</a> かLINEで友達追加してお気軽に連絡してください<br />
※普通の会社員なのでレスポンスはお察しください🙇</p>
<p style="text-align: center;">👇👇👇友達追加はこちらをタップ<br />
<a rel="noopener noreferrer" target="_blank" href="https://lin.ee/nxxNuNm"><img decoding="async" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0" class="aligncenter" /></a></p>
<p style="text-align: center;">👇👇👇QRを読み取る場合はこちら<br />
<img decoding="async" src="https://qr-official.line.me/gs/M_192lxynl_GW.png?oat_content=qr" class="aligncenter" /></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[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[目次 VBAを始める前にVBAとは開発者タブを表示しようVBAで押さえておきたい基本変数と定数データ型条件分岐、ループ処理などのフロー制御メインプロシージャとサブプロシージャ可読性の重要性インデントについて変数などの命名 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box info-box">
<p>皆さんプログラミングしていますか？</p>



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



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




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-8" checked><label class="toc-title" for="toc-checkbox-8">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">VBAを始める前に</a><ol><li><a href="#toc2" tabindex="0">VBAとは</a></li><li><a href="#toc3" tabindex="0">開発者タブを表示しよう</a></li></ol></li><li><a href="#toc4" tabindex="0">VBAで押さえておきたい基本</a><ol><li><a href="#toc5" tabindex="0">変数と定数</a></li><li><a href="#toc6" tabindex="0">データ型</a></li><li><a href="#toc7" tabindex="0">条件分岐、ループ処理などのフロー制御</a></li><li><a href="#toc8" tabindex="0">メインプロシージャとサブプロシージャ</a></li><li><a href="#toc9" tabindex="0">可読性の重要性</a><ol><li><a href="#toc10" tabindex="0">インデントについて</a></li><li><a href="#toc11" tabindex="0">変数などの命名規則について</a></li></ol></li><li><a href="#toc12" tabindex="0">モジュールの種類</a></li></ol></li><li><a href="#toc13" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

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



<p>VBAを始める前にまずVBAの概要とExcelの準備です</p>



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



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



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



<p>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"><span id="toc3">開発者タブを表示しよう</span></h3>



<p>ExcelでVBA始めるならまず開発タブを表示しましょう</p>



<p>正直慣れると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 rel="follow noopener noreferrer" target="_blank" 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"><span id="toc4">VBAで押さえておきたい基本</span></h2>



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



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



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



<p>プログラミングでは、データ（数値や文字列など）を一時的に保存しておくための「箱」のようなものを使いますが、この箱のことを<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 undefined-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"><span id="toc6">データ型</span></h3>



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



<p>例えば、数値を扱うのか、文字を扱うのか、日付を扱うのか、といった区別です</p>



<figure class="wp-block-table is-style-regular"><div class="scrollable-table"><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></div></figure>



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



<p>プログラムは基本的に上から下へ順番に実行されますが、<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 undefined-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"><span id="toc8">メインプロシージャとサブプロシージャ</span></h3>



<p>VBAでは、一連の処理のまとまりを<strong>プロシージャ</strong>と呼びます</p>



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



<p>車でいうとメインプロシージャが車の組み立て、サブプロシージャーが各部品の作成のイメージですね</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 undefined-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"><span id="toc9">可読性の重要性</span></h3>



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



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



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



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



<p>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>処理の塊で行頭にタブキーかスペース（一般的には半角スペース×4）を付けます</p>



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc11">変数などの命名規則について</span></h4>



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



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



<p>書き方にも規則性がありまして&#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"><span id="toc12">モジュールの種類</span></h3>



<p>VBAのコードを記述する場所を<strong>モジュール</strong>と呼びます</p>



<p>モジュールにはいくつか種類がありますが、初心者がまず覚えておくべきなのは以下の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"><span id="toc13">まとめ</span></h2>



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



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



<p>このブログでは、今後もVBAの具体的な書き方や便利なテクニックをどんどん紹介していきます。ぜひ、次回の記事もチェックして、退屈な繰り返し作業から解放され、より創造的な仕事に時間を使えるようになりましょう！&#x2728;</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />
<p style="text-align: left;">何か聞きたいことがあれば <a rel="follow noopener noreferrer" target="_blank" href="https://javeo.jp/otoiawase/">お問い合わせページ</a> かLINEで友達追加してお気軽に連絡してください<br />
※普通の会社員なのでレスポンスはお察しください🙇</p>
<p style="text-align: center;">👇👇👇友達追加はこちらをタップ<br />
<a rel="noopener noreferrer" target="_blank" href="https://lin.ee/nxxNuNm"><img decoding="async" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0" class="aligncenter" /></a></p>
<p style="text-align: center;">👇👇👇QRを読み取る場合はこちら<br />
<img decoding="async" src="https://qr-official.line.me/gs/M_192lxynl_GW.png?oat_content=qr" class="aligncenter" /></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[VBA・Excel]]></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[目次 再帰処理とはサンプルプログラム再帰処理のイメージ再帰処理のメリット・デメリットメリットデメリットあとがき 再帰処理とは 一言で表すと関数やプロシージャが自分自身を呼び出す処理のこと 処理方法の話なので当然VBAだけ [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p><a rel="noreferrer noopener follow" target="_blank" href="https://javeo.jp/vba-file-list-maker/">別のページ</a>で再帰処理を使ったプログラムを作ったわけですが、昔再帰処理を一生懸命後輩に教えたことを思い出したので個別に解説ページを作ってみました</p>



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




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-10" checked><label class="toc-title" for="toc-checkbox-10">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">再帰処理とは</a></li><li><a href="#toc2" tabindex="0">サンプルプログラム</a></li><li><a href="#toc3" tabindex="0">再帰処理のイメージ</a></li><li><a href="#toc4" tabindex="0">再帰処理のメリット・デメリット</a><ol><li><a href="#toc5" tabindex="0">メリット</a></li><li><a href="#toc6" tabindex="0">デメリット</a></li></ol></li><li><a href="#toc7" tabindex="0">あとがき</a></li></ol>
    </div>
  </div>

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



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



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



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



<p>メチャメチャシンプルなサンプルプログラムです</p>



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



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc3">再帰処理のイメージ</span></h2>



<div class="wp-block-media-text is-stacked-on-mobile is-vertically-aligned-top"><figure class="wp-block-media-text__media"><a rel="follow noopener noreferrer" target="_blank" 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>まず再帰処理を使わずに再現しようとした時のプログラムがこちら</p>



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



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



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



<div class="hcb_wrap"><pre class="prism undefined-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 rel="follow noopener noreferrer" target="_blank" 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>そしてこちらが再帰処理のイメージ</p>



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



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



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



<p>プログラムも短くスッキリした感じになります</p>
</div></div>



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



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



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



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



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



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



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



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



<p>例えばこんな処理</p>



<div class="hcb_wrap"><pre class="prism undefined-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>加算し続けるだけで終わりのない無限処理になってしまうのでループに条件を付けるもしくはループを抜ける分岐を付けてあげる必要があります</p>



<div class="hcb_wrap"><pre class="prism undefined-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"><span id="toc7">あとがき</span></h2>



<p>再帰処理をフォルダ検索を例に解説してみました</p>



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



<p>他の言語でも考え方や書き方は同じなので参考にしてみてください</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[VBA・Excel]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[マクロ]]></category>
		<guid isPermaLink="false">https://javeo.jp/?p=2449</guid>

					<description><![CDATA[目次 ツールの仕様設定項目対象フォルダ指定（グレー背景箇所）フォルダ名の指定（青背景箇所）ファイル名の指定（緑背景箇所）拡張子の指定（オレンジ背景箇所）プログラムについて必要な参照設定コピペ用 プログラムの全貌共通変数G [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="codoc-evacuations" style="display:none;" data-shortcode=""></div>
<div class="wp-block-cocoon-blocks-info-box block-box primary-box">
<p>突然ですが本業でマクロを使ったファイルリスト作成機を作りました！</p>



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



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




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-12" checked><label class="toc-title" for="toc-checkbox-12">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">ツールの仕様</a><ol><li><a href="#toc2" tabindex="0">設定項目</a><ol><li><a href="#toc3" tabindex="0">対象フォルダ指定（グレー背景箇所）</a></li><li><a href="#toc4" tabindex="0">フォルダ名の指定（青背景箇所）</a></li><li><a href="#toc5" tabindex="0">ファイル名の指定（緑背景箇所）</a></li><li><a href="#toc6" tabindex="0">拡張子の指定（オレンジ背景箇所）</a></li></ol></li></ol></li><li><a href="#toc7" tabindex="0">プログラムについて</a><ol><li><a href="#toc8" tabindex="0">必要な参照設定</a></li><li><a href="#toc9" tabindex="0">コピペ用 プログラムの全貌</a><ol><li><a href="#toc10" tabindex="0">共通変数</a></li><li><a href="#toc11" tabindex="0">GetFileList（メインプロシージャ―）</a></li><li><a href="#toc12" tabindex="0">GetFileData</a></li><li><a href="#toc13" tabindex="0">GetSubFoler</a></li><li><a href="#toc14" tabindex="0">in_array</a></li></ol></li></ol></li><li><a href="#toc15" tabindex="0">余談 兼 フリーソフト紹介</a></li><li><a href="#toc16" tabindex="0">あとがき</a></li></ol>
    </div>
  </div>

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



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



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



<p>絵が合った方が早いのでまずはエクセルの切り抜きから</p>



<figure class="wp-block-image size-full has-custom-border is-style-shadow"><a rel="follow noopener noreferrer" target="_blank" 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"><span id="toc3">対象フォルダ指定（グレー背景箇所）</span></h4>



<p>まずは取得対象とするフォルダの指定</p>



<p>サブフォルダも取得するようにすると対象フォルダ以下全てのフォルダが取得対象に</p>



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



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



<p>次はフォルダ名の指定</p>



<p>各項目の入力条件で取得対象を制限できます</p>



<figure class="wp-block-table"><div class="scrollable-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></div></figure>



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



<figure class="wp-block-image size-full"><a rel="follow noopener noreferrer" target="_blank" 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"><span id="toc5">ファイル名の指定（緑背景箇所）</span></h4>



<p>ファイル名の指定もフォルダと同じ方法</p>



<p>このファイル名に拡張子は含まないので注意</p>



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



<p>フォルダ名、ファイル名の指定と同じ</p>



<p>.（ドット）はいらないのでエクセルなら&#8221;xlsx&#8221;でOK</p>



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



<p>ここからVBAの説明に移ります</p>



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



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



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



<p>その他はありませんので魔改造する時に必要に応じて</p>



<figure class="wp-block-image size-full"><a rel="follow noopener noreferrer" target="_blank" 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"><span id="toc9">コピペ用 プログラムの全貌</span></h3>



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



<p>長ったらしいので畳んでますが見たい方は広げてください</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 undefined-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 rel="follow noopener noreferrer" target="_blank" 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 rel="follow noopener noreferrer" target="_blank" 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>ここからはプログラムをプロシージャ別に解説していきます</p>



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



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



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



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



<div class="hcb_wrap"><pre class="prism undefined-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>長いように見えてやっていることは</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>だけです</p>



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



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



<div class="hcb_wrap"><pre class="prism undefined-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>まず今回のようなループが多いプログラムはステータスバーに進捗状況を表示してあげると親切</p>



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



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



<p>細かいこと書きましたがざっくりやっていることは↓↓だけ</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"><span id="toc13">GetSubFoler</span></h4>



<div class="hcb_wrap"><pre class="prism undefined-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>ここでもin_arrayが登場してるのですが、条件指定を複数できるようにしてるので重宝します</p>



<p>ここでのポイントは<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">再帰処理はその内説明ページ作ります</p>



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



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



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



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



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



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



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



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



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



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



<p>他にもExcelでツール作った時は同じように公開してますのでたまに覗きに来てくれると嬉しいです！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://javeo.jp/vba-file-list-maker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
