[[20190108084825]] 『マクロ実行後に再度開くと回復を強要され、ファイ』(mcx32503) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『マクロ実行後に再度開くと回復を強要され、ファイルが壊れている』(mcx32503)

Workbook_Open、Worksheet_Activate、Worksheet_SelectionChange、ActiveXのボタン等のイベント処理を含むブックでイベント処理を含む実行を行った後、上書き保存。再度、ブックを開くと以下の様に修復を強要され、開いて見るとWorksheetのマクロは元のシートに残るものの、シート自体は新しく作成されたシートに移動し、列幅はディフォルトの列幅に、元のシートに作成してあったActiveXのボタンはなくなる等、ブックは壊れてしまいます。

再度開いた時に表示されるダイアログ:
'xxxx.xlms'の一部の内容に問題が見つかりました。可能な限り内容を回復しますか?ブックの発行元が信頼できる場合は、[はい]をクリックして下さい。
はいをクリック:
読み取れなかった内容を修復または削除することより、ファイルを開くことができました。

ちなみにExcelのバージョンは以下の通りです。
Microsoft Office 365 ProPlus バージョン1708(ビルド 8431.2316 クイック実行)

問題の回避方法や、情報等がおありであれば、提供願えませんか?
宜しくお願いします。

< 使用 Excel:Excel2016、使用 OS:Windows7 >


コード拝見しないと(わたしはみても解らないかも^^;)何ともいえませんが
Worksheet_SelectionChange、ActiveX
などが
あやしげ。。。そぉお
m(_ _)m

(隠居じーさん) 2019/01/08(火) 11:52


ExcelとWindowsは、それぞれ32/64bitどちらでしょう? 64bit版Windowsは、問題が発生しやすいです。
あと、マクロの名前やモジュール名、ユーザーフォーム名に、日本語を使っていると、問題が発生しやすいです。

問題発生は、OSのバージョンアップがきっかけになる事がよくあります。 OSとOffice、共に最新版にアップデートしてみてください。

これらを全て整えても直らない場合、新しいブックで同様のボタンを貼ってみて、保存してみてください。新規ブックならば正常であれば、ブックを作り直すしかないでしょう。
(???) 2019/01/08(火) 12:01


マクロ全体だと長いので、関係ありそうな部分をアップします。ブックは壊れてしまうので何度も作り直してテストしていますが、いつも同じメッセージで同じ壊れ方をします。
Windows7、Office 365 ProPlus共に32ビットです。

Dim current_workbook As Workbook
Dim current_worksheet As Worksheet
Dim current_row As Long
Dim current_column As Long

Private Sub Worksheet_Activate()

    Open_Workbooks_in_List
    ThisWorkbook.Activate
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Application.EnableEvents = False
    If Application.CutCopyMode <> False Or IsArray(Target.Value) Or IsNull(Target.Value) Then
        GoTo EXIT_LABEL
    End If
    current_row = Target.Row
    current_column = Target.Column
    Select Case current_column
        Case Column_Number("C"), Column_Number("F")
            Put_Valid_Workbooks current_row, current_column             ' データの入力規則設定 ワークブック
        Case Column_Number("D"), Column_Number("G")
            Put_Valid_Worksheets current_row, current_column            ' データの入力規則設定 ワークシート
        Case Column_Number("E"), Column_Number("H")
            Activate_Worksheet current_row, current_column              ' ワークシートのアクティベイト
    End Select
EXIT_LABEL:
    Application.EnableEvents = True
End Sub

Sub Put_Valid_Workbooks(r As Long, c As Long) ' データの入力規則設定 ワークブック

    Dim wb As Workbook, name_list As String
    For Each wb In Workbooks                                            ' リストの作成
        If wb.name <> ThisWorkbook.name Then
            If name_list <> "" Then
                name_list = name_list & ","
            End If
            name_list = name_list & wb.name
        End If
    Next wb
    If name_list <> "" Then
        Valid_List_String Me, r, c, name_list
    Else
        Valid_Any_Value Me, r, c
    End If
End Sub

Sub Put_Valid_Worksheets(r As Long, c As Long) ' データの入力規則設定 ワークシート

    Dim ws As Worksheet, book_name As String, name_list As String
    book_name = Cells(r, c - 1).Value
    If Exist_Workbook(book_name) Then
        For Each ws In Workbooks(book_name).Worksheets                  ' リストの作成
            If name_list <> "" Then
                name_list = name_list & ","
            End If
            name_list = name_list & ws.name
        Next ws
        Valid_List_String Me, r, c, name_list
    Else
        Valid_Any_Value Me, r, c
    End If
End Sub

Sub Activate_Worksheet(r As Long, c As Long) ' ワークシートのアクティベイト

    Dim book_name As String, sheet_name As String
    book_name = Cells(r, c - 2).Value
    sheet_name = Cells(r, c - 1).Value
    If Exist_Workbook(book_name) And Exist_Worksheet(Workbooks(book_name), sheet_name) Then
        Set current_workbook = Workbooks(book_name)
        Set current_worksheet = current_workbook.Worksheets(sheet_name)
        current_workbook.Activate
        current_worksheet.Select
    End If
End Sub

Private Sub Paste_Address_Click() ' アドレスの取得ボタンで実行

    current_workbook.Activate
    current_worksheet.Select
    If TypeName(Selection) = "Range" Then
        Cells(current_row, current_column).Value = Replace(Selection.Address, "$", "")
    End If
End Sub

Private Sub Perform_Copy_Click() ' コピーボタンで実行

    Perform_Copy_Procedure
End Sub

Function Exist_Workbook(name As String) As Boolean
' シートがあるかどうか確認する
' name: ワークブックの名前

    Dim wb As Workbook
    Exist_Workbook = False
    For Each wb In Workbooks
        If wb.name = name Then
            Exist_Workbook = True
            Exit For
        End If
    Next wb
End Function

Function Exist_Worksheet(wb As Workbook, name As String) As Boolean
' シートがあるかどうか確認する
' wb: ワークブック
' name: ワークシートの名前

    Dim ws As Worksheet
    Exist_Worksheet = False
    For Each ws In wb.Worksheets
        If ws.name = name Then
            Exist_Worksheet = True
            Exit For
        End If
    Next
End Function

Sub Valid_List_String(ws As Worksheet, r As Long, c As Long, str As String)
' 入力規則として名前ボックスを指定する
' ws: ワークシート
' r: 指定する列
' c: 指定する行
' str: 入力規則

    With ws.Cells(r, c).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=str
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = "リストから選択して下さい"
        .IMEMode = xlIMEModeNoControl
        .ShowInput = True
        .ShowError = True
    End With
End Sub

Sub Valid_Any_Value(ws As Worksheet, r As Long, c As Long)
' 入力規則として名前ボックスを指定する
' ws: ワークシート
' r: 指定する列
' c: 指定する行

    With ws.Cells(r, c).Validation
        .Delete
        .Add Type:=xlValidateInputOnly, AlertStyle:=xlValidAlertStop, Operator:=xlBetween
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = "リストから選択して下さい"
        .IMEMode = xlIMEModeNoControl
        .ShowInput = True
        .ShowError = True
    End With
End Sub

(mcx32503) 2019/01/08(火) 13:29


なんだマルチか
https://www.moug.net/faq/viewtopic.php?t=77820

ブックの破損ということなので、ユーザー定義書式設定の数、スタイル定義の数、シェイプの数、入力規則の設定数、名前定義なんかも怪しいかと。

シート状にある上記のようなオブジェクトを順番に消していって、何を消したときに治るかを特定すると良いかと。

あとxlsで保存してからxlsmで保存し直してみたり、xlsbで保存してみたり、マクロだけ一旦抜き取ってxlsxで保存してみるのもアリです。

新規ブックを作ってセルの内容とマクロだけ引っ越しするというのも一つの手です。
(名無し) 2019/01/08(火) 14:51


あと壊れる前と後のxlsmをzipで展開して、WinMergeでxmlの差分を取れば、何が原因か特定できるかもね
(名無し) 2019/01/08(火) 14:56

32bit環境であれば、OSのアップデートが原因の線は薄いですね。

全部のコードではないとの事ですが、ブックを閉じる際に動作するコードは無いのでしょうか? 作成した関数の中には、ブックのオブジェクトを参照していたりしているので、閉じようとしている際に呼び出すと、そのコードが自動的にまたブックを開いてしまい、イベントの連鎖が発生して、ぐちゃぐちゃになる可能性を秘めているように見えます。

あとは、マクロを実行せず開いて、保存して、開きなおした場合にも壊れるでしょうか? 保存前に、マクロが変更する箇所を手動で書き換えてから保存、とかも試してみてください。 マクロを動かさなくても壊れるようならば、セルのスタイル定義等が壊れていて、復旧できない状態になっている可能性があります。
(???) 2019/01/08(火) 16:07


皆様、お世話になりました。 マルチですみません。

たぶん、原因は特定できました。ありがとうございます。

先程アップしたマクロのリストにあるPut_Valid_Worksheetsはブックの中に含まれるシートの一覧(データの入力規則のリストの元の値)を作成し、該当セルにデータの入力規則を設定するものです。
今回のテストに使ったブックはかなり多くのシートを含んでいたために元の値を保持する領域を超えてしまったため、ブックが破壊された様です。

多くのシートを含むブックに対応するためにはシートの一覧をどこかのシート上にに作成し、元の値にはそのアドレスを指定する方法をとる必要がある様です。

ネットを見ると過去に類似のバグに関する報告があり、短絡的にアップデートで改善するのではと思ってしまいました。前にも同じ問題があり、その様な対応をしたことを忘れてました。
(mcx32503) 2019/01/08(火) 16:30


Excel2003の場合、データの入力規則の元の値は最長255文字の様です。Excel2016では何文字までか?お分かりであればお教え下さい。

Excel2003に関する情報:
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1120122456
(mcx32503) 2019/01/08(火) 16:49


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.