Я не могу проверить, но я сделаю непроверенное предложение. Попробуйте изменить:
ActiveWindow.ActivateNext
Application.ActiveProtectedViewWindow.Edit
до:
Dim someWorkbook as Workbook
Set someWorkbook = Application.ProtectedViewWindows(1).Edit
Я думаю, что есть другие потенциальные проблемы с вашим кодом.
Ошибки, которые «исчезают» при отладке / пошаговом выполнении кода, обычно указывают на то, что ваш код ожидал, что что-то будет активным во время выполнения, но он (по какой-либо причине) не был активным (отсюда и ошибка) - и теперь что вы шаг за шагом проходите через него, объект активен, и вы больше не получаете сообщение об ошибке. Это не всегда так, но я думаю, что это возможно.
Я не знаком с ActiveProtectedViewWindow
, но я бы посоветовал вам вместо этого обратиться к ProtectedViewWindow
более надежным способом (который не зависит от активности ProtectedViewWindow
).
Если вы уверены, что будет только 1 защищенное окно, вы можете попробовать что-то вроде Application.ProtectedViewWindows(1).Edit
. Если у вас есть несколько ProtectedViewWindows
, и вам нужен только конкретный, возможно, вы можете перебрать все ProtectedViewWindows
и проверить, соответствует ли их свойство SourcePath
пути защищенной книги, в которой вы хотите разрешить редактирование.
Из того, что я прочитал в Интернете, ProtectedViewWindow.Edit
возвращает рабочую книгу, поэтому вы можете тут же установить ссылку на нее Workbook
(как показано в начале моего ответа).
Я не проверял нижеприведенное, но я думаю, что ваш код может быть переписан примерно так. Я рекомендую сохранить копии рабочих книг / файлов перед запуском (или пройти по нему с помощью клавиши F8
):
Option Explicit
Sub Data()
Dim startWorkbook As Workbook ' Do you have better name for this variable?
Set startWorkbook = ActiveWorkbook ' Can you refer to this workbook by name, instead of assuming it will be active? Using ThisWorkbook is an option too, as long as you're storing the code in startWorkbook
Dim unprotectedWorkbook As Workbook ' This needs a better variable name.
Set unprotectedWorkbook = Application.ProtectedViewWindows(1).Edit ' I don't know if this will work for you (in your case), but I've taken it from Microsoft's documentation
Dim someWorksheet As Worksheet
someWorksheet = unprotectedWorkbook.Worksheets(1) ' If you know the worksheet's name, refer to it by name, please.
With someWorksheet
.Rows("1:3").Delete Shift:=xlUp
.Rows("2:2").Delete Shift:=xlUp
.Columns("E:E").Delete Shift:=xlToLeft
.Columns("C:C").Delete Shift:=xlToLeft
.Columns("A:A").Delete Shift:=xlToLeft
' xlCellTypeLastCell isn't always the best way to get the last cell.
Dim someRangeIncludingHeaders As Range ' This needs a better name.
Set someRangeIncludingHeaders = .Range("A1", .Cells.SpecialCells(xlCellTypeLastCell))
Dim someRange As Range ' This needs a better name.
Set someRange = .Range("A2", .Cells.SpecialCells(xlCellTypeLastCell))
With .Sort
.SortFields.Clear
.Sort.SortFields.Add2 Key:=.Range("A1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange someRangeIncludingHeaders
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
someRange.Copy
startWorkbook.Worksheets("Data1").Range("A10").PasteSpecial xlPasteValues
Application.CutCopyMode = False
unprotectedWorkbook.Close SaveChanges:=False
End Sub
Основные изменения, которые я сделал:
- ActiveSheet не используется, поэтому код должен выполняться одинаково (независимо от того, какой лист оказался активным).
- Ссылками на объекты являются
set
для рабочих книг, рабочих таблиц, диапазонов.
- Вместо использования
Select
или Selection
мы ссылаемся на диапазон по его адресу в явном виде.
- Блок операторов
With
в основном для удобства. Каждый объект, который начинается с .
внутри блока With
, является членом объекта после ключевого слова With
(в данном случае someWorksheet
).