質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

10551閲覧

VBAで日本語が文字化けしないZIPファイルを作成したい

jyansinkai

総合スコア66

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2021/09/14 02:07

編集2021/09/15 03:23

いつもお世話になっております。

VBAで、PowerShellを用いて、ファイルの入ったフォルダをZIP形式で圧縮させようとしています。
そうしますと、解凍した時に出来上がるフォルダと中身のファイル名が一斉に文字化けしてしまいます。フォルダ名もファイル名もアルファベットにすれば解決するのですが、どうしてもひらがなや漢字を使用したいのです。

あれこれ調べましたところ、VBAエディターはSHIFT-JIS、PowerShellはUTF-8と、取り扱う文字コードが違う為に起こる文字化けとのことで、ファイル名を事前にUTF-8にエンコードすれば良いのだろうと、以下のようなコードを作成しました。

VBA

1***略*** 2a_sPath = moji_Encode(a_sPath) 3a_sZipPath = moji_Encode(a_sZipPath) 4sCmd = "Compress-Archive -Path " & a_sPath & " -DestinationPath " & a_sZipPath & " -Force" 5Set ex = sh.Exec("powershell -NoLogo -ExecutionPolicy RemoteSigned -Command " & sCmd) 6***略*** 7 8 9Function moji_Encode(ByVal strOrg As String) As String 10 With CreateObject("ScriptControl") 11 .Language = "JScript" 12 moji_Encode = .CodeObject.encodeURI(strOrg) 13 End With 14End Function

ところが、これだとZIPファイルが生成されません。PowerShellが「そんなファイルはない」と言っているようです。文字をエンコードしたら文字列も変
わりますから、当然といえば当然なのですが…。
PowerShellに、UTF-8でエンコードされた変数を渡すには、どのようにすれば良いのでしょうか?

以上、何卒宜しくお願い申し上げます。

2021/09/15追記
具体的にはこのような文字化けが起こります。

フォルダ名
わさび
を圧縮した所、解凍されたフォルダ名は
繧上&縺ウ
となりました。

また、フォルダ名
ボランティアリスト
を圧縮した所、解凍されたフォルダ名は
ボランティアリスト
となりましたが、中身のファイル名の前に
繝懊Λ繝ウ繝・ぅ繧「繝ェ繧ケ繝・
という余計な文字が追加されました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/09/14 02:17 編集

utf-8じゃなくてURLエンコードしてるように見えますが。文字化けだけじゃ何がどうおかしいか全く判らないので、元の文字列と出力後の文字列を載せた方が良いのでは。
jyansinkai

2021/09/14 02:18

ご指導有難うございます。 URLエンコードでもUTF-8に変換されればそれで良いと考えておりましたが、似て非なるものなのでしょうか? Powershell側で処理が実装できることは存じませんでした。しかし、VBAを軸として、VBAの処理の中のひとつにフォルダー圧縮を加えたいのです。
退会済みユーザー

退会済みユーザー

2021/09/14 02:23

URLエンコードは、生のバイト配列をテキストデータとして送れるようにするものなので、utf-8変換とは完全に別物です。
jyansinkai

2021/09/14 02:30

ご指導有難うございます。 なるほど、それは完全に別物ですね…。Functionを見直します。その前に、このように「変数内の文字コードを変換してPowerShellに渡す」という方針自体は合っておりますでしょうか?
退会済みユーザー

退会済みユーザー

2021/09/14 02:34 編集

まず解凍ソフトがutf-8に対応していない古いものであれば、utf-8にするだけ無駄です。解凍ソフトに何を使用するか、という所から始まります。ファイル名にShift_JISで使用できない文字を格納したい、とかであれば、utf-8を使わざるを得ないのですが。
jyansinkai

2021/09/14 02:35

ソフトに依存するのですね。解凍に使用するソフトはWIN10に標準装備されたもののみ使用します。WIN10のデスクトップ上でダブルクリックした際に正しい名前で解凍が完了するようにしたいです。
Daregada

2021/09/14 04:09 編集

Windows 10のバージョン、VBAを動かしているOfficeのバージョン、PowerShellのバージョンを書いてください。 こちらで試したところ、ファイル名のエンコーディングを変更することなしに、日本語を含むファイル名・フォルダー名のフォルダーから、文字化けせずにZIPファイルを作成できました。
退会済みユーザー

退会済みユーザー

2021/09/14 05:24

私も試してみましたが、確かに文字化けしませんね。
jyansinkai

2021/09/14 05:48

ご指導誠に有難うございます。 使用しているソフトの各バージョンは以下の通りです。 Win10Pro バージョン1909 Microsoft Office Home and Business 2016 PowerShell 5-1-18362-1171
Daregada

2021/09/14 06:29 編集

こちらは、 Windows 10 Home 21H1 Microsoft Office 365 PowerShell 7.1.1 ですね。違いすぎてどれが原因だかわかりませんが。
退会済みユーザー

退会済みユーザー

2021/09/14 07:10 編集

Win10なので、環境的には問題なさそうに見えますけどね。文字化け時の、実際の入力文字列と出力結果を提示してください。
jyansinkai

2021/09/15 02:37

フォルダ名 わさび を圧縮した所、解凍されたフォルダ名は 繧上&縺ウ となりました。 また、フォルダ名 ボランティアリスト を圧縮した所、解凍されたファイル名は ボランティアリスト となりましたが、中身のファイル名の前に 繝懊Λ繝ウ繝・ぅ繧「繝ェ繧ケ繝・ という余計な文字が追加されました。
退会済みユーザー

退会済みユーザー

2021/09/15 02:47 編集

ここは追記修正依頼欄なので、環境やテストデータ等の追加情報は質問文を編集して追記してください。回答者はここ読まない場合もあるので。
Daregada

2021/09/15 02:50

これは、Shift_JISと見なす文字列に実際にはUTF-8のバイト列が入っていて、それをUTF-8に変換したときの文字化け、かな。
jyansinkai

2021/09/15 03:26

ご指導有難うございます。 UTF-8をSHIFT-JISと勘違いし、余計なことをしているということですか…。 すると、圧縮されたフォルダの圧縮データに手を加えて、「これはUTF-8ですよ」と教えてあげれば解決、ということに相成りますでしょうか?
退会済みユーザー

退会済みユーザー

2021/09/15 06:33 編集

こちらの環境では、テストで "わさび.txt" を格納したZIPのutf-8フラグをバイナリエディタで書き換えてエクスプローラーで読ませてみましたが、フラグのON/OFFに関係なく正しいファイル名を読む事が出来ました。7-Zipだと、フラグをOFFにすると、"繧上&縺ウ.txt" となります。理由は判りませんが、そちらの環境的な問題で、エクスプローラーがutf-8のファイル名を解釈出来ていないような気がします。 Shift_JISファイル名のZIPファイル、utf-8ファイル名のZIPファイルを作ってみたりして、それぞれ解凍出来るかテストしてみてください。 また、他の解凍ソフトでは普通に解凍できたりしませんか?
jyansinkai

2021/09/16 03:35

7ZIPですと全く文字化けを起こさずに解凍することが出来ました。 Shift_JISファイル名のZIPファイル、utf-8ファイル名のZIPファイルというのは、どのように作成するのでしょうか?
退会済みユーザー

退会済みユーザー

2021/09/16 07:37 編集

私の回答のコメントと、サンプルコード追記したの全く読んでないんですか…? 最低限サンプルコードの動作確認と結果の報告くらいはしてください。(追記修正依頼欄なので、回答のコメントにお願いします)
guest

回答1

0

ベストアンサー

解凍時の文字化けは、ZIPファイルのヘッダか、解凍ソフトのどちらかに問題があると思われます。ZIPのヘッダには、utf-8を使用しているかのビットフラグが存在し、そこを見て解凍ソフト側が文字コード処理を切り替えるように実装しているかどうかです。7-Zip辺りは、Shift_JISでファイル名を突っ込んでも、そのビットがOFFなら正しいファイル名で解凍してくれると思いますが。
割と根が深い問題なので、ヘッダをアテにせず、独自に文字コード判定を行っている解凍ソフトもあります。

考えられる解決策としては、

  • 何とかしてPowerShellにファイル名を渡す(PowerShellのスクリプトファイルを出力して実行するとか?)

エンコードせずにpowershellコマンドに渡して、文字化けしない事を確認しました。(Windows10)

  • Compress-Archiveの代替手段を探す
  • 出力されたZIPを何らかの手段で修復・変換する

(ヘッダがおかしいか、ファイル名がおかしいかを特定する必要あり)

こんなもんでしょうか。

これで解消!「KB2704299」でCompress-Archiveの文字化け対処
こんな記事がありましたが、上記環境に該当してないですか?

こちらで動作確認したコードを載せておきます。日本語のフォルダ名やファイル名でも、特に問題ありませんでした。
[2021/09/15 15:51]
Shift_JISファイル名のZIP出力処理を追記しました。

vba

1Option Explicit 2 3Private Declare PtrSafe Function ShellExecuteW Lib "shell32.dll" ( _ 4 ByVal hwnd As LongPtr, _ 5 ByVal lpOperation As LongPtr, _ 6 ByVal lpFile As LongPtr, _ 7 ByVal lpParameters As LongPtr, _ 8 ByVal lpDirectory As LongPtr, _ 9 ByVal nShowCmd As Long _ 10) As LongPtr 11 12Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As Long) 13 14Const SW_HIDE = 0 'ウィンドウを表示しない 15Const SW_SHOW = 5 'ウィンドウを現在の位置とサイズで表示 16 17Private Sub CommandButton1_Click() 18 Dim src As String 19 src = "c:\test\あいうえお" 20 21 Call CreateZipWsh(src, "c:\test\test_wsh.zip") 22 Call CreateZipShellExecuteW(src, "c:\test\test_shellw.zip") 23 Call CreateZipShellExecuteW_SJIS(src, "c:\test\test_shellw_sjis.zip") 24End Sub 25 26'WScript.Shellで実行 27Private Sub CreateZipWsh(ByVal src As String, ByVal dest As String) 28 Dim parameter As String 29 Dim oWsh As Object 30 Dim oExec As Object 31 32 parameter = "-NoLogo -ExecutionPolicy RemoteSigned -Command Compress-Archive -Path '" & src & "' -DestinationPath '" & dest & "' -Force" 33 Set oWsh = CreateObject("WScript.Shell") 34 Set oExec = oWsh.Exec("powershell.exe" & " " & parameter) 35 Do While oExec.Status = 0 36 Sleep 1 37 Loop 38 Set oExec = Nothing 39 Set oWsh = Nothing 40End Sub 41 42'ShellExecuteWで実行 43Private Sub CreateZipShellExecuteW(ByVal src As String, ByVal dest As String) 44 Dim exe As String 45 Dim operation As String 46 Dim parameter As String 47 48 operation = "open" 49 exe = "powershell.exe" 50 parameter = "-NoLogo -ExecutionPolicy RemoteSigned -Command Compress-Archive -Path '" & src & "' -DestinationPath '" & dest & "' -Force" 51 Call ShellExecuteW(0, StrPtr(operation), StrPtr(exe), StrPtr(parameter), 0, SW_HIDE) 52End Sub 53 54'ShellExecuteWで実行(Shift_JIS出力) 55Private Sub CreateZipShellExecuteW_SJIS(ByVal src As String, ByVal dest As String) 56 Dim exe As String 57 Dim operation As String 58 Dim cmd As String 59 Dim parameter As String 60 61 operation = "open" 62 exe = "powershell.exe" 63 cmd = "Add-Type -AssemblyName System.IO.Compression.FileSystem;" 64 cmd = cmd & "[IO.Compression.ZipFile]::CreateFromDirectory('" & src & "', '" & dest & "', [IO.Compression.CompressionLevel]::Optimal, $true, [Text.Encoding]::GetEncoding('Shift_JIS'));" 65 parameter = "-NoLogo -ExecutionPolicy RemoteSigned -Command " & cmd 66 Call ShellExecuteW(0, StrPtr(operation), StrPtr(exe), StrPtr(parameter), 0, SW_HIDE) 67End Sub

投稿2021/09/14 02:28

編集2021/09/15 07:01
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jyansinkai

2021/09/14 02:33

ご指導有難うございます。 解凍ソフトは、WINDOWS10に標準装備されたもの一択となっておりまして、WIN10のデスクトップ上でZIPをダブルクリックした際に正しい名前で解凍されるように作成したいです。
退会済みユーザー

退会済みユーザー

2021/09/14 02:45 編集

https://qiita.com/tats-u/items/5336bc780a4361e7b780 このようなツールを作っている人もいますので、一度見てみるとよいかもしれません。 これで修復可能であれば、出力したファイルをツール通すようにしてみるというのも手かも。 utf-8のフラグをファイル書き換えでOFFにするだけで解凍できるなら、それだけでいいかもしれませんが。バイナリエディタでZIPのヘッダ覗いて見た方がいいですね。
退会済みユーザー

退会済みユーザー

2021/09/14 05:23 編集

回答に追記しました。
jyansinkai

2021/09/14 05:40

拝見致しました。ZIP形式というのは世の中のルールを相当に破っているもののようですね…。文字が化けるZIPの11ビット目は「シ」となっておりました。
退会済みユーザー

退会済みユーザー

2021/09/15 02:51

回答にこちらでテストしたサンプルコードを載せてみましたが、そちらで実行してみると結果はどうでしょう?(フォルダ名とかは適当にそちらに合わせて変えてください)
退会済みユーザー

退会済みユーザー

2021/09/15 07:13 編集

試験的に、ZipFileクラスを使用してShift_JISファイル名で出力する処理を追記しました。Compress-Archiveと全く同じ動作にはならないので注意してください。(同名ファイルが存在するとエラーになったりする)
jyansinkai

2021/09/17 03:04

C:\testというフォルダを作成し、その中に「あいうえお.txt」というファイルを入れ、ご提示頂いたマクロをsrc = "c:\test\あいうえお.txt"と変更して実行させた所、c:\test\の中に3つの圧縮ファイルができました。 WIN10標準機能のZIPで、出来上がった3つの圧縮ファイルを解凍した結果、名前の変化は以下の通りでした。 test_wsh : 縺ゅ>縺・∴縺・txt test_shellw : 縺ゅ>縺・∴縺・txt test_shellw_sjis : (解凍できず) また、7-Zipで解凍した結果は以下の通りでした。 test_wsh : あいうえお.txt test_shellw : あいうえお.txt test_shellw_sjis : (何も出てこない)
退会済みユーザー

退会済みユーザー

2021/09/17 04:01 編集

ZipFile.CreateFromDirectoryはフォルダに対してじゃないと機能しないので、Shift_JIS圧縮はフォルダにファイル入れて試してみてください。
jyansinkai

2021/09/17 08:22

src = "c:\test\あいうえお¥あいうえお.txt"とし、再度実行しました所、test_shellw_sjisはフォルダ名も中身も名前が化けることなく解凍することができました。test_wshとtest_shellwについては上と同様、文字化けした結果となりました。
退会済みユーザー

退会済みユーザー

2021/09/18 11:23 編集

そうなると、やはりそちらの環境の不具合かは判りませんが、エクスプローラーがShift_JISのZIPしか扱えない状態なのだと思われます。ZIPファイルそのものには、恐らく問題はありません。環境を修復するのが望ましいですが、原因を特定するのは困難だと思われますので、応急処置的な対処としては、Compress-Archiveの使用をやめて、CreateZipShellExecuteW_SJISの処理のようにShift_JISファイル名で出力する方法を取れば、ひとまず文字化けは解消されるでしょう。 もしくは、解凍時に7-Zip等のutf-8に対応した解凍ソフトを使用するようにしてください。
jyansinkai

2021/09/19 01:10

CreateZipShellExecuteW_SJISの処理が非常に参考になりました。この方法で環境をだましだまし使用していこうと思います。たくさんのご指導、誠に有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問