VBA技術解説
ダウンロードフォルダのExcelファイルブロック解除

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2025-04-24 最終更新日:2025-04-24

ダウンロードフォルダのExcelファイルブロック解除


VBAマクロは、マルウェアやランサムウェアの危険があります。
そのため、Officeのセキュリティを強化するために、インターネットからのファイル内のマクロをブロックするように Officeアプリケーションの既定の動作が変更されています。


ダウンロードフォルダ内の全Excelファイルのブロックを解除するVBAをGeminiに書いてもらいました。


ブロックの解除方法

マクロがブロックされる理由や、ブロックの解除方法についての詳細は以下をご覧ください。

インターネットからのマクロは、Office で既定でブロックされます

プロパティのセキュリティを変更

ファイルの右クリック → プロパティ

VBA マクロ ダウンロードフォルダのExcelファイルロック解除

「セキュリティ」をチェックし「OK」


PowerShell の Unblock-File コマンド

PowerShell の Unblock-File コマンドレットを使用して、ファイルから ZoneId 値を削除(ブロック解除)できます。
ZoneId 値を削除すると、VBA マクロを既定で実行できます。
コマンドレットを使用すると、ファイルの [プロパティ] ダイアログの [全般] タブの [ブロック解除] チェック ボックスをオンにした場合と同じ処理が実行されます。
PowerShell Unblock-File


Geminiにブロック解除するVBAを書いてもらいました

VBA マクロ ダウンロードフォルダのExcelファイルロック解除

プロンプト

以下のVBAを作成してください
・ダウンロードフォルダ内の全てのエクセルファイルを対象
・ファイルのロックを解除
コメントは日本語で

Geminiの応答

はい、承知いたしました。
ダウンロードフォルダにある全てのエクセルファイルに対して、セキュリティロック(Mark of the Web)を解除するVBAコードを作成します。

以下のコードをVBAエディタに貼り付けて実行してください。

VBA
Sub ダウンロードフォルダのExcelファイルロック解除()
' ---------------------------------------------------------------------
' 作成者: AIアシスタント (Gemini)
' 目的: ダウンロードフォルダ内の全てのエクセルファイルのロックを解除する
' (例: インターネットからダウンロードしたファイルに付与されるセキュリティ情報を解除)
' 備考: このマクロを実行するには、Microsoft Scripting Runtimeへの参照設定は必須ではありませんが、
'    より安全で効率的なコードのために設定することをお勧めします。
'    設定方法: VBAエディタのメニュー -> ツール -> 参照設定 -> "Microsoft Scripting Runtime" にチェックを入れる。
'    参照設定を行わない場合は、FileSystemObjectは遅延バインディングされます。
' ---------------------------------------------------------------------

  ' ファイルシステムオブジェクトを宣言します。
  ' これを使ってフォルダやファイルを操作します。
  Dim fso As Object
  Set fso = CreateObject("Scripting.FileSystemObject")

  ' ダウンロードフォルダのパスを取得します。
  ' Environ("USERPROFILE") はユーザーのプロファイルフォルダのパスを返します。
  Dim downloadsFolderPath As String
  downloadsFolderPath = Environ("USERPROFILE") & "\Downloads"

  ' ダウンロードフォルダが存在するか確認します。
  If Not fso.FolderExists(downloadsFolderPath) Then
    MsgBox "エラー: ダウンロードフォルダが見つかりません。" & vbCrLf & downloadsFolderPath, vbCritical
    Exit Sub ' フォルダが見つからない場合は処理を終了します。
  End If

  ' フォルダオブジェクトを取得します。
  Dim downloadsFolder As Object
  Set downloadsFolder = fso.GetFolder(downloadsFolderPath)

  ' フォルダ内のファイルコレクションを取得します。
  Dim fileCollection As Object
  Set fileCollection = downloadsFolder.Files

  ' ファイルごとの処理に必要な変数を宣言します。
  Dim targetFile As Object
  Dim filePath As String
  Dim shellCommand As String
  Dim fileExtension As String
  Dim unblockedCount As Long ' ロック解除処理を実行したファイルの数をカウントします。
  unblockedCount = 0

  ' ダウンロードフォルダ内の各ファイルに対してループ処理を行います。
  For Each targetFile In fileCollection

    ' ファイルのフルパスを取得します。
    filePath = targetFile.Path

    ' ファイルの拡張子を取得し、小文字に変換します。
    fileExtension = LCase(fso.GetExtensionName(filePath))

    ' Excelファイルの拡張子かどうかを判定します。
    ' (xls, xlsx, xlsm, xlsb など、必要に応じて追加/修正してください)
    Select Case fileExtension
      Case "xls", "xlsx", "xlsm", "xlsb"
        ' Excelファイルの場合

        ' PowerShellコマンド文字列を作成します。
        ' PowerShellの Unblock-File コマンドレットを使用してロックを解除します。
        ' -ExecutionPolicy Bypass はスクリプト実行ポリシーを一時的に緩和します(Cmdlet なので不要な場合もあります)。
        ' -Command の後ろの文字列全体をダブルクォートで囲み、ファイルパス内のダブルクォートはエスケープ(二重にする "")します。
        shellCommand = "PowerShell.exe -ExecutionPolicy Bypass -Command ""Unblock-File """ & filePath & """"""

        ' Shell関数を使ってPowerShellコマンドを実行します。
        ' vbHide を指定すると、コマンドプロンプトのウィンドウが表示されません。
        On Error Resume Next ' エラーが発生してもマクロが停止しないようにします(例: ファイルが開かれている場合など)。
        Shell shellCommand, vbHide
        ' Shell関数の実行結果やエラーコードを直接取得することは難しいですが、
        ' このコマンドレットは成功してもエラーを返さないため、ここでは単純に実行します。

        If Err.Number <> 0 Then
          ' ロック解除に失敗した場合の処理(例: デバッグウィンドウに表示)
          Debug.Print "注意: ファイルのロック解除に失敗した可能性があります。 " & filePath & " (エラーコード: " & Err.Number & ", 説明: " & Err.Description & ")"
          ' 処理を続行します。
        Else
          ' ロック解除処理が実行されたとみなしてカウントします。
          unblockedCount = unblockedCount + 1
          ' 必要に応じて、デバッグウィンドウに表示することも可能です。
          ' Debug.Print "ロック解除処理を実行しました: " & filePath
        End If
        On Error GoTo 0 ' エラーハンドリングをリセットします。

      Case Else
        ' Excelファイル以外の拡張子の場合、何もしません。
        ' Debug.Print "Excelファイルではありません: " & filePath ' 必要に応じて表示
    End Select

  Next targetFile ' 次のファイルへ

  ' 処理完了のメッセージを表示します。
  MsgBox downloadsFolder.Files.Count & "個のファイルの中から、" & unblockedCount & "個のExcelファイルに対してロック解除処理を実行しました。", vbInformation

  ' 使用したオブジェクトを解放します。
  Set fileCollection = Nothing
  Set downloadsFolder = Nothing
  Set fso = Nothing

End Sub

使い方:
  1. Alt + F11 キーを押してVBAエディタを開きます。
  2. 左側のプロジェクトエクスプローラーで、このコードを実行したいブックを選択します(通常は「ThisWorkbook」または新しい標準モジュール)。
  3. メニューバーの「挿入」から「標準モジュール」を選択します。
  4. 表示された白いウィンドウ(コードウィンドウ)に上記のコードをコピー&ペーストします。
  5. VBAエディタを閉じます(Alt + F11 または右上のXボタン)。
  6. Excelに戻り、Alt + F8 キーを押してマクロダイアログを開きます。
  7. 「ダウンロードフォルダのExcelファイルロック解除」を選択し、「実行」ボタンをクリックします。

補足:
  1. このコードは、WindowsのPowerShellコマンドである Unblock-File を内部的に呼び出しています。このコマンドは、ファイルの代替データストリームに記録されているセキュリティ情報を削除します。
  2. ロック解除処理に成功しても、Excelでファイルを開く際にセキュリティ警告が表示される場合があります。その場合は、Excelのトラストセンター設定を確認してください。
  3. ファイルが開いている場合や、ファイルへのアクセス権限がない場合は、ロック解除に失敗する可能性があります。その場合は、エラーメッセージがデバッグウィンドウ(VBAエディタのメニュー -> 表示 -> イミディエイトウィンドウ)に表示されますが、マクロの実行は停止しません。
  4. 対象とするExcelファイルの拡張子を変更したい場合は、Select Case 部分を編集してください。

プロンプト

powershellの実行部分をWScript.Shell.Runに変更して

Geminiの応答

はい、承知いたしました。PowerShellの実行部分をWScript.Shell.Runメソッドを使用するように変更したVBAコードを作成します。

VBA
Option Explicit

Sub DownloadFolderExcelFilesUnblock_WSHRun()
  ' ファイルシステム操作のためのオブジェクトを宣言
  Dim objFSO As Object
  ' Shell操作のためのオブジェクトを宣言 (ダウンロードフォルダパス取得用)
  Dim objShell As Object
  ' WScript.Shellオブジェクトを宣言 (コマンド実行用)
  Dim objWSH As Object
  ' ダウンロードフォルダのパスを格納する変数
  Dim DownloadsPath As String
  ' ダウンロードフォルダ内のファイルコレクションを格納する変数
  Dim colFiles As Object
  ' 処理中の個別のファイルを格納する変数
  Dim objFile As Object
  ' PowerShellコマンド文字列を格納する変数
  Dim PowerShellCmd As String
  ' 処理したExcelファイルの数をカウントする変数
  Dim processedCount As Long

  ' エラーが発生した場合の処理を設定
  On Error GoTo ErrorHandler

  ' FileSystemObjectを作成
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  ' Shell.Applicationオブジェクトを作成
  Set objShell = CreateObject("Shell.Application")
  ' WScript.Shellオブジェクトを作成
  Set objWSH = CreateObject("WScript.Shell")

  ' ダウンロードフォルダの特殊フォルダ定数 (&H11&) を使用してパスを取得
  ' 65537 は &H11& の10進数表現
  On Error Resume Next ' Namespaceメソッドのエラーは後で確認
  DownloadsPath = objShell.Namespace(65537).Self.Path
  On Error GoTo ErrorHandler ' エラーハンドリングを戻す

  ' ダウンロードフォルダのパスが取得できたか確認
  If DownloadsPath = "" Then
    MsgBox "ダウンロードフォルダのパスを取得できませんでした。", vbCritical
    Exit Sub
  End If

  ' ダウンロードフォルダが存在するか確認
  If Not objFSO.FolderExists(DownloadsPath) Then
    MsgBox "ダウンロードフォルダが見つかりません: " & DownloadsPath, vbCritical
    Exit Sub
  End If

  ' ダウンロードフォルダのオブジェクトを取得
  Set colFiles = objFSO.GetFolder(DownloadsPath).Files

  ' 処理カウンターを初期化
  processedCount = 0

  ' フォルダ内の各ファイルについてループ処理
  For Each objFile In colFiles
    ' ファイルの拡張子を取得し、小文字に変換
    Dim fileExtension As String
    fileExtension = LCase(objFSO.GetExtensionName(objFile.Path))

    ' Excelファイルであるか確認 (.xls, .xlsx, .xlsm, .xlsb)
    If fileExtension = "xls" Or fileExtension = "xlsx" Or fileExtension = "xlsm" Or fileExtension = "xlsb" Then
      ' PowerShellコマンドを作成
      ' Unblock-Fileコマンドレットを使用してファイルのブロックを解除
      ' -Path パラメータにファイルパスを指定。パスにスペースや特殊文字が含まれても良いように引用符で囲む
      PowerShellCmd = "powershell.exe -NoProfile -Command ""Unblock-File -Path """ & objFile.Path & """"""

      ' WScript.Shell.Runメソッドを使用してコマンドを実行
      ' 第2引数 0 はウィンドウを非表示にする (vbHide相当)
      ' 第3引数 False はコマンドの終了を待たない (非同期実行)
      On Error Resume Next ' Run実行時のエラーは無視する (ファイルがロックされている場合など)
      objWSH.Run PowerShellCmd, 0, False
      On Error GoTo ErrorHandler ' エラーハンドリングを戻す

      ' 処理したファイルの数をカウントアップ
      processedCount = processedCount + 1
      ' (オプション) 処理したファイル名をイミディエイトウィンドウに表示
      ' Debug.Print "Unblocked: " & objFile.Path

    End If
  Next objFile

  ' 処理完了メッセージ
  If processedCount > 0 Then
    MsgBox processedCount & "個のExcelファイルのブロック解除処理が完了しました。", vbInformation
  Else
    MsgBox "ダウンロードフォルダにExcelファイルは見つかりませんでした。", vbInformation
  End If


CleanUp:
  ' オブジェクトを開放
  Set objFile = Nothing
  Set colFiles = Nothing
  Set objFSO = Nothing
  Set objShell = Nothing
  Set objWSH = Nothing ' WScript.Shellオブジェクトも解放

  Exit Sub

ErrorHandler:
  ' エラー発生時のメッセージ
  MsgBox "エラーが発生しました: " & Err.Description, vbCritical
  Resume CleanUp ' クリーンアップ処理へジャンプして終了

End Sub

変更点:
  1. objWSH As Object を宣言し、Set objWSH = CreateObject("WScript.Shell") で WScript.Shell オブジェクトを作成しました。
  2. PowerShellコマンドの実行部分を Shell PowerShellCmd, vbHide から objWSH.Run PowerShellCmd, 0, False に変更しました。
    • objWSH.Run: WScript.Shell オブジェクトの Run メソッドを呼び出します。
    • PowerShellCmd: 実行するコマンド文字列です。(これは前バージョンと同じです)
    • 0: ウィンドウスタイルを指定します。0 は非表示です(VBAの vbHide に相当)。
    • False: コマンドが終了するのを待つかどうかを指定します。False を指定することで、VBAはPowerShellコマンドの完了を待たずに次のファイル処理に進みます(非同期実行)。
  3. Cleanupセクションに Set objWSH = Nothing を追加し、オブジェクトを適切に解放するようにしました。

その他の部分(ダウンロードフォルダの取得、ファイルのループ、Excelファイルの判定、エラーハンドリングの基本的な構造)は前バージョンと同様です。

使用方法:
前バージョンのコードと同様に、標準モジュールに貼り付けて実行してください。

この変更により、外部コマンドの実行方法がVBA組み込みの Shell 関数から WScript.Shell.Run に置き換わりました。どちらの方法も基本的な機能は同じですが、環境や細かい挙動が異なる場合があります。


あとがき

これはすばらしいですね。
コメントもしっかり書いてあり、もう完璧!!!
わざわざ人がVBAを書く機会はかなり減ってくるように感じます。

サイト内の関連ページ

第122回.Shell関数|VBA入門
・Shell関数の構文 ・Shell関数の使用例 ・起動したアプリの終了を待つ同期処理
特殊フォルダの取得(WScript.Shell,SpecialFolders)
・WScript.Shell ・SpecialFolders プロパティ ・WshShellのSpecialFoldersのマクロVBA使用例




同じテーマ「マクロVBA技術解説」の記事

VBAでメール送信する(CDO:Microsoft Collaboration Data Objects)
VBAでのOutlook自動操作
ADO(ActiveX Data Objects)の使い方の要点
特殊フォルダの取得(WScript.Shell,SpecialFolders)
参照設定、CreateObject、オブジェクト式の一覧
VBAのスクレイピングを簡単楽にしてくれるSelenium
VBA+SeleniumBasicで検索順位チェッカー作成
VBA+SeleniumBasicで検索順位チェッカー(改)
.Net FrameworkのSystem.Collectionsを利用
WshNetwork(ネットワークドライブの割り当て等)
ダウンロードフォルダのExcelファイルブロック解除


新着記事NEW ・・・新着記事一覧を見る

Geminiと100本ノック 11本目:セル結合の警告|VBA練習問題(5月1日)
AI(Gemini)とエクセル数式対決 その2|エクセル練習問題(2025-04-30)
Geminiと100本ノック 10本目:行の削除|VBA練習問題(4月30日)
AI(Gemini)とテーマを決めて議論|エクセル雑感(2025-04-30)
Geminiと100本ノック 9本目:フィルターコピー|VBA練習問題(4月29日)
Geminiと100本ノック 8本目:点数の合否判定|VBA練習問題(4月28日)
Geminiと100本ノック 7本目:日付データの扱い|VBA練習問題(4月27日)
AI(Gemini)とエクセル数式対決 その1|エクセル練習問題(2025-04-27)
Geminiと100本ノック 6本目:セルに計算式|VBA練習問題(4月26日)
Geminiと100本ノック 5本目:セルの計算|VBA練習問題(4月25日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
5.ひらがな⇔カタカナの変換|エクセル基本操作
6.RangeとCellsの使い方|VBA入門
7.メッセージボックス(MsgBox関数)|VBA入門
8.セルのクリア(Clear,ClearContents)|VBA入門
9.FILTER関数(範囲をフィルター処理)|エクセル入門
10.条件分岐(Select Case)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ