excel - 从在新窗口中打开的工作簿中删除保护时出现调试错误
问题描述
我有一本从网站创建的工作簿中导入数据的工作簿。当网站创建工作簿时,它们会自动在新窗口中打开,并且工作簿的名称总是会更改。我用
ActiveWindow.ActivateNext
其中一个工作簿必须在受保护的视图中打开,所以我使用
Application.ActiveProtectedViewWindow.Edit
允许在导入前对其进行编辑
我可以逐步执行宏并且它可以工作,但是当我运行它时,我总是得到“运行时错误'91':对象变量或未设置块变量。我点击调试并播放,程序完成没有问题。
完整的代码如下所示;
Sub Data()
Dim Here As String
Dim What As String
Dim Data As String
Dim DropIt As String
Dim StartBook As String
Application.DisplayAlerts = False
StartBook = ActiveWorkbook.Name
DropIt = "Data1"
ActiveWindow.ActivateNext
Application.ActiveProtectedViewWindow.Edit 'THIS IS WHERE THE DEBUG HAPPENS
Range("A1").Select
Here = ActiveSheet.Name
BookName = ActiveWorkbook.Name
Rows("1:3").Select
Selection.Delete Shift:=xlUp
Rows("2:2").Select
Selection.Delete Shift:=xlUp
Columns("E:E").Select
Selection.Delete Shift:=xlToLeft
Columns("C:C").Select
Selection.Delete Shift:=xlToLeft
Columns("A:A").Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
What = Range("A1", ActiveCell.SpecialCells(xlLastCell)).Address
Data = Range("A2", ActiveCell.SpecialCells(xlLastCell)).Address
ActiveWorkbook.Worksheets(Here).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(Here).Sort.SortFields.Add2 Key:=Range("A1") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets(Here).Sort
.SetRange Range(What)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range(Data).Copy
Workbooks(StartBook).Activate
Worksheets(DropIt).Select
Range("a10").Select
ActiveCell.End(xlDown).Select
Range(Selection, ActiveCell.End(xlToRight)).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.DisplayAlerts = False
Workbooks(BookName).Close savechanges:=False
Application.DisplayAlerts = True
End Sub
我只想让代码在没有调试的情况下运行
''''
解决方案
我无法测试,但我会提出一个未经测试的建议。尝试改变:
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
orSelection
,而是通过地址显式引用范围。 With
语句块主要是为了方便。.
在With
块中以 a 开头的每个对象都是With
关键字(在本例中为someWorksheet
)之后的对象的成员。
推荐阅读
- php - 遍历 simplexml 对象并附加它们
- amazon-web-services - 如何从 API Gateway 映射模板中排除某些标头
- automation - 了解 Isar 风格的证明何时在 Isabelle 中真正有效
- amazon-web-services - aws cli 创建快照失败
- r - 对于循环 t.test,按 R 中的因子类比较均值
- apache-flink - Apache Flink 是否支持具有相同时间戳的多个事件?
- jsonschema - JsonSchema:对二进制数据使用类型/格式
- ag-grid - 如何动态获取单元格的滚动容器?
- android - 前台服务会在打瞌睡模式的非唤醒时间工作吗
- jquery - 在haml中添加内联jquery时出现referenceerror