VBAで圧縮と解凍を行うには
VBAでファイルやフォルダの圧縮や解凍を行いたい場合、残念ながらVBAに標準で圧縮や解凍を行う仕組みがないため、外部の機能を利用することになります。
ここでは7-Zipを使う方法を紹介します。
なお、Windowsの標準機能のみを使う方法については「VBAでZIP圧縮と解凍を行う」をご参照ください。
7-Zipとは?
7-Zipはオープンソース(フリー)の圧縮解凍ソフトです。zip、7z、tar、gzip、RAR、LZHなど様々な書庫形式に対応しています。
7-Zipの日本語公式サイトは「https://sevenzip.osdn.jp/」です。ダウンロードもここから可能です。
7-ZipのWindowsでの一般的な操作は、エクスプローラーで対象のフォルダやファイルを右クリックして、7-Zip→圧縮、または、展開(解凍の意味)で行います。バッチファイルやプログラムなどから利用できるようにコマンドラインも用意されているので、それを利用することでVBAからフォルダやファイルの圧縮や解凍を行うことができます。
以下では7-ZipのコマンドラインをVBAから利用して圧縮や解凍を行う方法を紹介します。利用の際には7-Zipがインストールされていることが前提です。
7-Zipのコマンドラインの基本的な考え方
7-Zipをインストールすると、インストール先のフォルダ(C:\Program Files\7-Zip など)に7z.exeが配置されます。コマンドラインはこの7z.exeを利用します。
7z.exeのコマンドラインは以下の形式になります。[ ~ ]は省略可能です。
「7z.exe コマンド文字 [スイッチ文字] アーカイブのパス [元データのパス]」
詳細は公式ページ「https://sevenzip.osdn.jp/chm/cmdline/syntax.htm」をご参照ください。
7z.exe | 7z.exeのフルパスを指定します。7z.exeに環境変数PATHが設定されていればフルパスを書く必要はありませんが、標準インストール時は設定されていないのでここでは設定されていないものとして説明します。 | ||||||||
コマンド文字 | どのような操作を行うのかを1文字で指定します。詳細は公式ページ「https://sevenzip.osdn.jp/chm/cmdline/commands/index.htm」をご参照ください。ここではよく使うものだけ紹介します。
|
||||||||
スイッチ文字 | 指定したコマンド文字の内容に加えて指定します。省略可能です。詳細は公式ページ「https://sevenzip.osdn.jp/chm/cmdline/switches/index.htm」をご参照ください。ここではよく使うものだけ紹介します。
|
||||||||
アーカイブのパス | 圧縮時や解凍時に圧縮ファイルのパスを指定します。ファイル名だけを指定することも可能ですが、VBAで利用する場合はフルパスを指定することをお勧めします。 | ||||||||
元データのパス | 圧縮する対象のファイルやフォルダを指定します。VBAで利用する場合はフルパスを指定することをお勧めします。 |
そもそもの「コマンドライン」とは? という話ですが、簡単に言うとWindowsでのマウス操作で行っていることを、コマンドプロンプトなどのコンソール画面(黒背景に文字しか打てない画面)に決められた規則に従って入力した命令文のことを指します。
7z.exeのコマンドラインヘルプ表示
7z.exeをコマンドプロンプト上で引数無しで実行すると、コマンドラインのヘルプが英語で表示されます。以下が実行結果です。これだけの種類のコマンド文字とスイッチ文字があります。
後述するマクロでは、一般的な圧縮や解凍を行う際に必要なコマンドに絞って説明しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
C:\Program Files\7-Zip>7z.exe 7-Zip 19.00 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21 Usage: 7z <command></command> [<switches>...] <archive_name> [<file_names>...] [@listfile] <commands> a : Add files to archive b : Benchmark d : Delete files from archive e : Extract files from archive (without using directory names) h : Calculate hash values for files i : Show information about supported formats l : List contents of archive rn : Rename files in archive t : Test integrity of archive u : Update files to archive x : eXtract files with full paths <switches> -- : Stop switches and @listfile parsing -ai[r[-|0]]{@listfile|!wildcard} : Include archives -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives -ao{a|s|t|u} : set Overwrite mode -an : disable archive_name field -bb[0-3] : set output log level -bd : disable progress indicator -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line -bt : show execution time statistics -i[r[-|0]]{@listfile|!wildcard} : Include filenames -m{Parameters} : set compression Method -mmt[N] : set number of CPU threads -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra) -o{Directory} : set Output directory -p{Password} : set Password -r[-|0] : Recurse subdirectories -sa{a|e|s} : set Archive name mode -scc{UTF-8|WIN|DOS} : set charset for for console input/output -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands -sdel : delete files after compression -seml[.] : send archive by email -sfx[{name}] : Create SFX archive -si[{name}] : read data from stdin -slp : set Large Pages mode -slt : show technical information for l (List) command -snh : store hard links as links -snl : store symbolic links as links -sni : store NT security information -sns[-] : store NTFS alternate streams -so : write data to stdout -spd : disable wildcard matching for file names -spe : eliminate duplication of root folder for extract command -spf : use fully qualified file paths -ssc[-] : set sensitive case mode -sse : stop archive creating, if it can't open some input file -ssw : compress shared files -stl : set archive timestamp from the most recently modified file -stm{HexMask} : set CPU thread affinity mask (hexadecimal number) -stx{Type} : exclude archive type -t{Type} : Set type of archive -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options -v{Size}[b|k|m|g] : Create volumes -w[{path}] : assign Work directory. Empty path means a temporary directory -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames -y : assume Yes on all queries </switches></commands></file_names></archive_name></switches> |
事前準備(WshShellの参照設定)
以下で紹介するマクロはWScript.Shellを利用します。WScript.Shellを参照設定をする場合としない場合で書き方が2通りあります。
参照設定をする場合は、ツールメニュー→参照設定で「Windows Script Host Object Model」にチェックを付けて、WshShellクラスの変数を利用します。
参照設定をしない場合は、「CreateObject(“WScript.Shell”)」でWshShellクラスのオブジェクト変数を作成して利用します。
どちらで実装しても問題ありませんが、処理速度は参照設定をした方が若干速いです。
その理由については興味があれば別ページ「VBAの高速化(クラスは参照設定+Newする)」をご参照ください。
VBAから7-Zipを使って圧縮を行うマクロ
以下のマクロは引数で指定されたファイルパスやフォルダパスを、指定した圧縮ファイルパスの名前で圧縮します。
7z.exeのパスを6行目で指定していますが、PCによって異なるため利用しているPCに合わせて書き換えてください。
第一引数(a_sPath):圧縮するファイルやフォルダのパス
第二引数(a_sZipPath):圧縮後のファイルパス
第三引数(a_sPassword):パスワード。省略可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Sub MakeZip7(a_sPath As String, a_sZipPath As String, Optional a_sPassword As String = "") Dim wsh As Object '// WshShellクラス Dim s7zPath As String '// 7z.exeのフルパス Dim sCmd As String '// コマンド文字列 s7zPath = """C:\Program Files\7-Zip\7z.exe""" '// 引数でパスワードが設定されていない場合 If a_sPassword = "" Then sCmd = s7zPath & " a " & a_sZipPath & " " & a_sPath '// 引数でパスワードが設定されている場合(-p + パスワード を付与) Else sCmd = s7zPath & " a -p" & a_sPassword & " " & a_sZipPath & " " & a_sPath End If '// WshShellオブジェクトを作成 Set wsh = CreateObject("WScript.Shell") '// 7-Zipの圧縮コマンドを実行 Call wsh.Run(sCmd) End Sub |
圧縮マクロの使い方1(パスワードなしで圧縮する場合)
MakeZip7関数の第3引数を省略するか、””(空文字)で指定するとパスワードが未設定として実行されます。
以下、見本として「Call MakeZip7」の行が2つ用意していますが、どちらも結果は同じです。
1 2 3 4 5 6 7 |
Sub MakeZip7Test() '// 第3引数を省略してパスワードなしで実行 Call MakeZip7("D:\7zTest\a.txt", "D:\7zTest\a.txt.zip") '// 第3引数を""で指定してパスワードなしであることを明示 Call MakeZip7("D:\7zTest\a.txt", "D:\7zTest\a.txt.zip", "") End Sub |
圧縮マクロの使い方2(パスワードありで圧縮する場合)
MakeZip7関数の第3引数に””以外の文字列を指定することで圧縮ファイル解凍時に必要なパスワードを設定することができます。
以下では”ABC111″というパスワードを設定しています。
1 2 3 |
Sub MakeZip7_PasswordTest() Call MakeZip7("D:\7zTest\a.txt", "D:\7zTest\pwABC.txt.zip", "ABC111") End Sub |
VBAから7-Zipを使って解凍を行うマクロ
解凍を行うマクロは上の圧縮のマクロとほとんど同じです。違うのは7z.exeのコマンドラインで解凍の場合はコマンド文字に「x」を指定することと、解凍先フォルダを指定できるようにしている点です。
解凍先フォルダが未設定の場合はカレントディレクトリが解凍先になりますが、VBAで実行する場合はコマンドプロンプトなどで実行する場合と異なり、コマンドを実行しているカレントディレクトリが分かりません。そのため、どこに解凍されるのはOSやツール任せになり行方不明になることがありえます。
そのため、解凍先フォルダが未設定の場合は、圧縮ファイルがあるフォルダに展開するようにしています。
第一引数(a_sZipPath):圧縮ファイルパス
第二引数(a_sMakeDirectory):解凍先フォルダパス。省略時は圧縮ファイルがあるフォルダに解凍される。
第三引数(a_sPassword):圧縮ファイルを解凍する際のパスワード。省略可。パスワードが設定されていない圧縮ファイルの場合は省略する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
Sub UnZip7(a_sZipPath As String, Optional a_sMakeDirectory As String = "", Optional a_sPassword As String = "") Dim wsh As Object '// WshShellクラス Dim s7zPath As String '// 7z.exeのフルパス Dim sCmd As String '// コマンド文字列 s7zPath = """C:\Program Files\7-Zip\7z.exe""" sCmd = s7zPath & " x " '// 引数で解凍先ディレクトリが設定されている場合 If a_sMakeDirectory <> "" Then sCmd = sCmd & "-o" & a_sMakeDirectory & " " '// 解凍先ディレクトリが設定されていない場合は圧縮ファイルがあるフォルダを解凍先とする Else sCmd = sCmd & "-o" & Left(a_sZipPath, InStrRev(a_sZipPath, "\")) & " " End If '// 引数でパスワードが設定されている場合(-p + パスワード を付与) If a_sPassword <> "" Then sCmd = sCmd & "-p" & a_sPassword & " " End If '// 「7z.exe x [-o解凍先フォルダ] [-pパスワード] -y 圧縮ファイルパス」のコマンド文字列を作成 '// -yは解凍時の問い合わせを全て「Yes」として扱う sCmd = sCmd & "-y " & a_sZipPath '// WshShellオブジェクトを作成 Set wsh = CreateObject("WScript.Shell") '// 7-Zipの解凍コマンドを実行 Call wsh.Run(sCmd) End Sub |
解凍マクロの使い方1(パスワードなしで解凍する場合)
解凍先フォルダを指定してないため、圧縮ファイルと同じ階層に解凍されます。
1 2 3 4 |
Sub UnZip7Test() '// 解凍先フォルダとパスワードを指定しない場合(zipファイルと同じ階層に中身が展開される) Call UnZip7("D:\7zTest\a\aa.zip") End Sub |
解凍マクロの使い方2(解凍先フォルダあり、パスワードありで解凍する場合)
1 2 3 4 |
Sub UnZip7Test() '// 解凍先フォルダとパスワードを指定する場合 Call UnZip7("D:\7zTest\b\pwABC.txt.zip", a_sMakeDirectory:="D:\7zTest\b\aaabbb", a_sPassword:="ABC111") End Sub |