破損後のExcelファイルの高速リカバリ用スクリプト

このメモは、Excelファイルを開こうとしたときに、次の形式のエラーメッセージを受け取った人を対象としています。









私の場合、このようなエラーにより、xlsxファイル(以降1.xlsx)が開かれ、「Petya」などのウイルス攻撃の後にR-Saverを使用して復元されました。



1.xlsxファイルの内容をフォルダ「\ 1」に解凍した後、コンテキストメニューから次のエラーが発行されました。









これらのサービスファイルのサイズはゼロであることが判明しました。 作業中の2.xlsxファイルを使用して同様の手順を実行し、ゼロ以外の[Content_Types] .xmlおよび.relsファイルを「\ 1」フォルダーから「\ 2」フォルダーからコピーしました。 次に、「\ 1」フォルダーの内容を.zipアーカイブに追加し、名前を3.xlsxに変更しました。 その結果、3.xlsxファイルは、警告はありますが、正しいデータで既に開かれています。









上記の手順を自動化するために、「現状のまま」で配布されるvbscriptが開発されました。



スクリプトソースコードST1_XLSX_FIXER_v1
option explicit Const THIS_SCRIPT_NAME = "ST1_XLSX_FIXER_v1.vbs" Const SUBDIR_XLS_SRC = "ST1_XLSX_FIXER_DATA_v1" Const SUBDIR_OUT = "ST1_XLSX_FIXED" Const RES_SUFFIX = "_fixed_ST1_v1" Dim fso: Set fso = CreateObject("Scripting.FileSystemObject") '    if WScript.ScriptName = THIS_SCRIPT_NAME then if WScript.Arguments.Count > 0 then Dim fname for each fname in WScript.Arguments if fso.GetExtensionName(fname) = "xls" then WScript.Echo "  Excel 2003   (.xls)  " else FixCorruptedExcel fname end if next else WScript.Echo "    xlsx-  " end if end if Set fso = Nothing Sub FixCorruptedExcel(fpath) Dim out_dir: out_dir = fso.GetParentFolderName(fpath) & "\" & SUBDIR_OUT if Trim(out_dir) <> "" then '   If not fso.FolderExists(out_dir) Then fso.CreateFolder(out_dir) end if End If 'c  xlsx-   .zip Dim extract_dir: extract_dir = out_dir & "\" & fso.GetBaseName(fpath) Dim fpath_zip: fpath_zip = extract_dir & ".zip" fso.CopyFile fpath, fpath_zip '  Dim fpath_fixed: fpath_fixed = extract_dir & RES_SUFFIX & ".xlsx" if fso.FileExists(fpath_fixed) then fso.DeleteFile fpath_fixed ' zip UnzipFile fpath_zip, extract_dir ' zip- fso.DeleteFile fpath_zip '     Dim script_path: script_path = fso.GetParentFolderName(Wscript.ScriptFullName) fso.CopyFolder script_path & "\" & SUBDIR_XLS_SRC, extract_dir ' zip CreateEmptyZipFile fpath_zip ' extract_dir Dim shell: set shell = CreateObject("Shell.Application") Dim extract_dir_obj: set extract_dir_obj = fso.GetFolder(extract_dir) shell.NameSpace(fpath_zip).CopyHere shell.NameSpace(extract_dir).Items do until shell.namespace(fpath_zip).items.count = shell.namespace(extract_dir).items.count wscript.sleep 1000 loop 'zip -> xlsx fso.MoveFile fpath_zip, fpath_fixed ' unzip- fso.DeleteFolder extract_dir, true WScript.Echo " : " & vbCrLf & fpath_fixed Set shell = Nothing end sub sub UnzipFile(fpath_zip, extract_dir) '    If not fso.FolderExists(extract_dir) Then fso.CreateFolder(extract_dir) End If ' xlsx -     "  ..." Dim shell: set shell = CreateObject("Shell.Application") Dim sub_files: set sub_files = shell.NameSpace(fpath_zip).items Const FOF_SILENT = &H4& Const FOF_RENAMEONCOLLISION = &H8& Const FOF_NOCONFIRMATION = &H10& Const FOF_ALLOWUNDO = &H40& Const FOF_FILESONLY = &H80& Const FOF_SIMPLEPROGRESS = &H100& Const FOF_NOCONFIRMMKDIR = &H200& Const FOF_NOERRORUI = &H400& Const FOF_NOCOPYSECURITYATTRIBS = &H800& Const FOF_NORECURSION = &H1000& Const FOF_NO_CONNECTED_ELEMENTS = &H2000& Dim args: args = FOF_SILENT + FOF_NOCONFIRMATION + FOF_NOERRORUI shell.NameSpace(extract_dir).CopyHere sub_files, args Set shell = Nothing end sub sub CreateEmptyZipFile(fname) if fso.FileExists(fname) then WScript.Echo " " & fname & "  ", vbCritical, WScript.ScriptFullName end if Const ForWriting = 2 Dim fp: set fp = fso.OpenTextFile(fname, ForWriting, True) fp.Write "PK" & Chr(5) & Chr(6) & String(18, Chr(0)) fp.Close end sub
      
      







アーカイブ内のスクリプト加えて、ST1_XLSX_FIXER_DATA_v1フォルダーが添付されます。このフォルダーには、置換用の参照ファイルがあります。 スクリプトの範囲を破損したファイルの他のバージョンに拡張するために、その内容を変更できます。 たとえば、そこにあるヌルファイルオプションを追加します。



スクリプトが機能するには:



  1. ST1_XSLX_FIXER_v1.zipアーカイブを任意のフォルダーにダウンロードして解凍します
  2. 左クリックして、1つ以上のxlsxファイルをスクリプトST1_XLSX_FIXER_v1.vbsに転送します
  3. 各ファイルの処理プロセスが開始されます。







  4. 各ファイルが正常に処理されると、次の形式のメッセージが表示されます。











スクリプトの原理:



  1. 入力ファイルを変更せずに保持します。
  2. サブフォルダーST1_XLSX_FIXEDを作成します
  3. ST1_XLSX_FIXEDに名前変更されたxlsx zipを作成します
  4. zipをフォルダーに解凍し、その上にST1_XLSX_FIXER_DATA_v1をコピーします
  5. 結果のフォルダーをzipでアーカイブし、結果のファイルの名前をxlsxに変更します


おわりに



これらの実験は一般的な使用であるとは主張しておらず、ご自身の責任で提案されたソリューションを使用してください。 私は、より広範な実験を実施し、結果に基づいてスクリプトを改良する予定です。 現在の明示的な制限は、ST1_XLSX_FIXER_DATA_v1からコピーするときに、スクリプトが置換されたファイルのサイズを分析しないため、どのサービスファイルが空であることが判明して置換が必要かを判断できないことです。 最も可能性が高いのは、サービスファイルが失われ、「\ 1 \ xl \ worksheets」のワークシートではなく、この方法が適用される場合です。



また、このスクリプトは、Excel 2003以前のバージョンで作成されたxls拡張子を持つファイルには適していません。異なるデータストレージ形式を使用しているためです。



All Articles