Ошибка автосохранения файла в файле Excel с поддержкой макросов

Я использую файл с поддержкой макросов (двоичный лист), который имеет много модулей/форм, и иногда, когда что-то идет не так с моим ноутбуком, и Excel внезапно отключается, мои файлы автосохранения не работают.

Я получаю эту ошибку в каждом автосохраненном файле:

Ошибка выполнения '9'

Индекс вне диапазона

Моя частота автосохранения составляет 5 минут, чтобы сохранить мою спину, но, что интересно, это не работает для этого файла.

Я даже не могу понять, где ошибка, потому что в этом автосохраненном файле открывается только белая пустая страница. (Вот почему другие вопросы об ошибке времени выполнения 9 на SO не были ответом на мой вопрос) Что может быть причиной и каково возможное решение?

ОБНОВЛЕНИЕ: события Workbook_Open, которые у меня есть в этой книге

Private Sub Workbook_Open()
    Application.ScreenUpdating = False
    ActiveWindow.Visible = False
    SplashUserForm.Show
    Windows(ThisWorkbook.Name).Visible = True
    Application.ScreenUpdating = True
    

   With Sheet5
        .Unprotect Password:=""
        .Protect DrawingObjects:=False, Contents:=True, Scenarios:= _
        False, AllowFormattingCells:=True, AllowFormattingColumns:=True, _
        AllowFormattingRows:=True, AllowInsertingColumns:=True, AllowInsertingRows _
        :=True, AllowInsertingHyperlinks:=True, AllowDeletingColumns:=True, _
        AllowDeletingRows:=True, AllowSorting:=True, AllowFiltering:=True, _
        AllowUsingPivotTables:=True, UserInterfaceOnly:=True
        .EnableOutlining = True
    End With
    With Sheet16
        .Unprotect Password:=""
        .Protect DrawingObjects:=False, Contents:=True, Scenarios:= _
        False, AllowFormattingCells:=True, AllowFormattingColumns:=True, _
        AllowFormattingRows:=True, AllowInsertingColumns:=True, AllowInsertingRows _
        :=True, AllowInsertingHyperlinks:=True, AllowDeletingColumns:=True, _
        AllowDeletingRows:=True, AllowSorting:=True, AllowFiltering:=True, _
        AllowUsingPivotTables:=True, UserInterfaceOnly:=True
        .EnableOutlining = True
    End With
 
    
End Sub

А вот что у моего SplashUserForm:

Private Sub UserForm_Activate()
    Application.Wait (Now + TimeValue("00:00:01"))
    SplashUserForm.Label1.Caption = "Loading Data..."
    SplashUserForm.Repaint
    Application.Wait (Now + TimeValue("00:00:01"))
    SplashUserForm.Label1.Caption = "Creating Forms..."
    SplashUserForm.Repaint
    Application.Wait (Now + TimeValue("00:00:01"))
    SplashUserForm.Label1.Caption = "Opening..."
    SplashUserForm.Repaint
    Application.Wait (Now + TimeValue("00:00:01"))
    Unload SplashUserForm
End Sub


Private Sub UserForm_Initialize()

HideTitleBar Me
With Me
.StartUpPosition = 0
.Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
.Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
End With

End Sub

Option Explicit
Option Private Module

Public Const GWL_STYLE = -16
Public Const WS_CAPTION = &HC00000
Public Declare Function GetWindowLong _
                       Lib "user32" Alias "GetWindowLongA" ( _
                       ByVal hWnd As Long, _
                       ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong _
                       Lib "user32" Alias "SetWindowLongA" ( _
                       ByVal hWnd As Long, _
                       ByVal nIndex As Long, _
                       ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar _
                       Lib "user32" ( _
                       ByVal hWnd As Long) As Long
Public Declare Function FindWindowA _
                       Lib "user32" (ByVal lpClassName As String, _
                       ByVal lpWindowName As String) As Long

Sub HideTitleBar(frm As Object)
    Dim lngWindow As Long
    Dim lFrmHdl As Long
    lFrmHdl = FindWindowA(vbNullString, frm.Caption)
    lngWindow = GetWindowLong(lFrmHdl, GWL_STYLE)
    lngWindow = lngWindow And (Not WS_CAPTION)
    Call SetWindowLong(lFrmHdl, GWL_STYLE, lngWindow)
    Call DrawMenuBar(lFrmHdl)
End Sub

person Mertinc    schedule 01.03.2017    source источник
comment
Можете ли вы показать свой код автоматического сохранения vba?   -  person 0m3r    schedule 01.03.2017
comment
Возможно, вам следует начать добавлять текстовый файл журнала, записывая в первую очередь в каждую подпрограмму/функцию, чтобы отслеживать, где что-то пошло не так. Болезненно, но я нахожу ошибку, которая приводит к сбою Excel. Затем добавьте больше журнала или поставьте точки останова в этой аварийной подпрограмме/функции.   -  person PatricK    schedule 01.03.2017
comment
0m3r, у меня нет кода автоматического сохранения в моем файле, я говорю о собственной системе автоматического восстановления Excel. Этот работает очень хорошо со всеми другими файлами (когда что-нибудь происходит), но не работает с этим. PatricK, спасибо за объяснение, но, честно говоря, я не знаю, как создать эти треки, чтобы понять, где что-то идет не так. И дело в том, что у меня есть много модулей и форм, которые не знают, где найти эти точки останова. И мне нужно дождаться следующего сбоя Excel (который вызывает автовосстановление), чтобы отследить это, и мы не знаем, когда это произойдет снова.   -  person Mertinc    schedule 01.03.2017
comment
Пожалуйста, покажите свои функции BeforeSave или AfterSave, возможно, у функции автосохранения Excel есть проблема с одной из них.   -  person Julian Kuchlbauer    schedule 01.03.2017
comment
Если вы получаете эту ошибку при открытии файла, есть ли у вас какие-либо события Workbook_Open?   -  person YowE3K    schedule 01.03.2017
comment
@YowE3K YowE3K Правильно, у меня также есть события Workbook_Open. Один из них предназначен для открытия пользовательской формы-заставки при первом открытии, другой — для защиты двух листов, если они не защищены. Может быть что-то из-за них?   -  person Mertinc    schedule 03.03.2017
comment
@JulianKuchlbauer, как и где я могу показать функции BeforeSave или AfterSave?   -  person Mertinc    schedule 03.03.2017
comment
@PatricK, спасибо за объяснение, но, честно говоря, я не знаю, как создавать эти треки, чтобы отслеживать, где что-то идет не так. И дело в том, что у меня есть много модулей и форм, которые не знают, где найти эти точки останова. И мне нужно дождаться следующего сбоя Excel (который вызывает автовосстановление), чтобы отследить это, и мы не знаем, когда это произойдет снова.   -  person Mertinc    schedule 03.03.2017
comment
Если ошибка возникает, когда вы открываете файлы снова, и у вас есть события Workbook_Open, отредактируйте вопрос и вставьте в него код из этих событий, чтобы мы могли увидеть, может ли что-то быть причиной индекса ошибка. (Возможно, что-то пытается получить доступ до полного завершения загрузки - я слышал, что это часто проблема с Workbook_Open, и открытие из автоматически восстановленной версии может замедлять работу и усугублять проблему.)   -  person YowE3K    schedule 03.03.2017
comment
@ YowE3K Я только что отредактировал вопрос. Поскольку событие Workbook_Open запускает пользовательскую форму и некоторые макросы, связанные с этой формой, я также написал другие коды.   -  person Mertinc    schedule 03.03.2017
comment
Я не эксперт по формам, но мне кажется странным, что вы пытаетесь скрыть строку заголовка, все еще инициализируя форму, что, как я предполагаю, происходит как предшественник ее отображения. Я бы подумал, что FindWindowA(vbNullString, frm.Caption) не сможет найти окно, пока оно не будет создано.   -  person YowE3K    schedule 03.03.2017
comment
@YowE3K Спустя 2 месяца снова привет! Я все еще сталкивался с той же проблемой, и сегодня я вспомнил ваше предложение и попытался удалить все части этого процесса заставки, принадлежащие событию Workbook_Open. Наконец-то я придумал причину: Windows(ThisWorkbook.Name).Visible = True я не знаю, как это стало False, но, когда я пытаюсь открыть файл автовосстановления, я понимаю, что файл открывается нормально, моя форма открывается нормально, но когда форма исчезает , вылазит ошибка. Причина в том, что Excel почему-то не может превратить Windows(ThisWorkbook.Name).Visible в True. Что вы думаете?   -  person Mertinc    schedule 02.05.2017
comment
@ YowE3K, я думаю, вам лучше написать свое предложение (проблема будет в событии Workbook_Open) в качестве ответа, я приму его. Затем, поскольку лучше задать новый вопрос для этого вопроса Windows(ThisWorkbook.Name).Visible = True, обратитесь к новой ссылке [stackoverflow.com/questions/43732367/   -  person Mertinc    schedule 02.05.2017
comment
@Mertinc - я бы предпочел не публиковать свое предположение в качестве ответа, поскольку это действительно предположение, и отсутствие моего ответа должно сделать (немного) более вероятным, что кто-то может заметить вопрос и дать реальный ответ. P.S. Разве ваш Windows(ThisWorkbook.Name).Visible не установлен в False вашим оператором ActiveWindow.Visible = False? (Еще раз подчеркну, что я не эксперт в таких вопросах, поэтому легко могу ошибаться.)   -  person YowE3K    schedule 02.05.2017
comment
Наконец проблема решена. Вы можете проверить ответ, спасибо за ваши усилия, пытаясь помочь мне.   -  person Mertinc    schedule 03.05.2017


Ответы (1)


После обсуждения со многими людьми из многих блогов, наконец, я нашел два решения. (Первый похож на обработку ошибок, а второй точно решает проблему.) Особая благодарность YowE3k, jkpieterse и Ryan Wells.

Прежде всего, я хотел бы упомянуть причину, почему это произошло:

Код дает сбой, потому что, когда Excel восстанавливает файл, он добавляет некоторый текст в заголовок окна, так что «FileName.xlsx» становится чем-то вроде «FileName.xlsx [Версия, сохраненная последним пользователем]» (jkpieters).

Решения:

1) Базовая обработка ошибок (Райан Уэллс)

Если мы знаем, какая строка вызывает ошибку, мы можем закомментировать эту строку, чтобы защитить нашу книгу. Итак, если вы закомментируете (или просто удалите) :

ActiveWindow.Visible = False

Windows(ThisWorkbook.Name).Visible = True

линии, которые остановят проблему.

2) Оригинальное решение (jkpieters)

используйте приведенную ниже процедуру в листе объектов ThisWorkbook.

Sub ShowaWindow(sFileName As String)
    Dim oWb as Workbook
    For Each oWb In Workbooks
        If lCase(owb.Name) = lCase(sFileName) Then
            oWb.Windows(1).Visible = True
            Exit For
        End If
    Next
End Sub

Затем, в событии Workbook_Open,

Вместо Windows(ThisWorkbook.Name).Visible = True

ИспользоватьShowaWindow(ThisWorkbook.Name)

Тогда это будет работать как шарм!

person Mertinc    schedule 03.05.2017