问题
我有一本工作簿(A),其中包括一些宏以及与另一个Excel文件(数据源)的链接。如果我仅打开此单独的工作簿,则该工作簿可以完美地工作并且没有问题。如果我打开另一个随机的xlsx文件,那么一开始一切都看起来不错。但是,只要我在工作簿A中进行任何更新(例如,在空单元格中按F2然后输入),这两个工作簿就好像都死了。我仍然可以按照正常过程关闭工作簿,并且工作簿A中的宏按钮可以正常工作(并会触发宏),但是我无法更改wb A中的选项卡,第二个工作簿中的选项卡也消失了。我可以看到光标,但是两个工作簿中目标单元格周围的绿色Excel边框/框都消失了。我也无法更新工作簿中的任何单元格...
我尝试过的事情
我试图;
删除所有数据源连接
删除所有宏(一个接一个,但是在wb A中没有任何宏的情况下仍然存在问题)
遍历宏以查看它们是否引起任何错误(据我所知,它们不会出现)
另外两个xlsm文件(与wb A无关)不会导致这种类型的错误
我尝试使用application.ScreenUpdating = False,.EnableEvents = False,.Calculation = xlCalculationManual,并在最后将它们设置回原始值。
代码
-Range(“ B4”)是一个没有空格的下拉列表。以下宏位于Sheet1中:
Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ApplicationON:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
If Intersect(Target, Range("B4")) Is Nothing Then Exit Sub
Call conditionalFormatting.conditionalFormatting
ApplicationON:
On Error Resume Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
-以下宏位于名为“ conditionalFormatting”的模块中:
Sub conditionalFormatting()
On Error GoTo ApplicationON:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Dim DASHBOARD As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Dim cel As Range
Dim col1 As Integer
Dim col2 As Integer
Set DASHBOARD = Sheets("DASHBOARD")
Set rng1 = Range("R15:R45")
Set rng2 = Range("R15:Z45")
col1 = 18
col2 = 26
With rng2
.Cells.Font.Bold = False
.Cells.Font.Italic = False
.Cells.Font.Size = 11
End With
For Each cel In rng1
Select Case cel.Value
Case _
"Case1", _
"Case2"
Range(Cells(cel.Row, col1), Cells(cel.Row, col2)).Font.Bold = True
Case _
"Case3", _
"Case4"
Range(Cells(cel.Row, col1), Cells(cel.Row, col2)).Font.Size = 8
Case _
"Case5", _
"Case6"
Range(Cells(cel.Row, col1), Cells(cel.Row, col2)).Font.Italic = True
End Select
Next
ApplicationON:
On Error Resume Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
-以下宏位于名为“ ExportToPDF”的模块中,并在工作表“仪表板”(第1页)中具有一个按钮:
Sub ExportToPDF()
On Error GoTo ApplicationON:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Dim pt As Range
dateStamp = Format(Now(), "yyyymmdd\_hhmm")
workbookPath = ActiveWorkbook.Path & "\"
workbookName = ActiveWorkbook.Name
file_Name = dateStamp & "_" & Sheets("DASHBOARD").Range("A1") & ".pdf"
filePath = workbookPath & file_Name
With Worksheets("DASHBOARD").PageSetup
.PrintArea = "A6:O42"
.Orientation = xlLandscape
End With
Set pt =
Worksheets("DASHBOARD").Range(Worksheets("DASHBOARD").PageSetup.PrintArea)
pt.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=filePath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
MsgBox "PDF file has been created: " _
& filePath
ApplicationON:
On Error Resume Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
经过一些其他测试
似乎与循环和模块Workbook_change +我的下拉列表有关,该列表不包含任何空白值。但是仍然奇怪的是,它在没有打开任何其他wb的情况下都能完美工作,但是仅在打开其他wb时才成为问题。两个wb都冻结时,都看不到代码正在运行...
1)复制并删除数据连接(以免干扰),并保存并关闭工作簿
2)打开工作簿(不进行任何错误处理和应用程序声明),而无需在电子表格中进行任何更改/更新,然后打开第二个文件(slsx)-发生错误
3)打开工作簿(没有任何errorHandling和应用程序声明),并在随机的空单元格中写入“ = 1 + 1”,然后打开第二个文件(slsx)-发生错误
4)打开工作簿(没有任何errorHandling和应用程序声明),并一次更改下拉列表(调用worksheet_change宏),然后打开第二个文件(slsx)-发生错误
5)打开工作簿(处于发布时的原始状态),而不在电子表格中进行任何更改/更新,并打开第二个文件(slsx)-发生错误
6)打开工作簿(处于发布时的原始状态),并在随机的空单元格中写入“ = 1 + 1”,然后打开第二个文件(slsx)-不会发生错误
7)打开工作簿(处于发布时的原始状态),并一次更改下拉列表(调用worksheet_change宏),然后打开第二个文件(slsx)-发生错误
8)如果我在下拉列表(已发布的原始状态的工作簿)中插入空白值并选择该空白值,然后打开第二个文件(slsx)-不会发生错误
9)在下拉列表中选择一个值-发生错误
8)删除ExportToPDF和conditionalFormatting模块,并建议对Worksheet_change模块进行调整(即,从sheet1中删除代码并将其插入到模块中)。
答案 0 :(得分:1)
如果您在这些功能的 任何 中引起错误,请设置Application.EnableEvents = True
。因此...如果这些事件是由事件处理程序内部的调用触发的,则您将失去重入保护。您还可以无条件地在所有操作的顶部执行此操作:
Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Application.EnableEvents = False
有cargo-cult behavior的痕迹。您应该仅在必要时执行此工作,并在必要时靠近 place 。无论您认为通过此操作获得的性能提升,都可能只是虚幻的。实际上,从性能的角度来看,反复弄乱Application
状态可能带来的危害多于好处。
解决方案是不依赖Excel来防止重新进入事件处理程序-手动执行:
Private reentryFlag As Boolean 'Module level
Sub Worksheet_Change(ByVal Target As Range)
If reentryFlag Then Exit Sub
reentryFlag = True
On Error GoTo Handler
If Intersect(Target, Range("B4")) Is Nothing Then Exit Sub
conditionalFormatting.conditionalFormatting
Handler:
reentryFlag = False
End Sub
答案 1 :(得分:0)
似乎Excel文件存在一个神秘错误。我重建了仪表板,它按预期工作。为了安全起见,我跳过了链接到过滤器的“ Workbook_change”代码,而只是使用一个简单的按钮来执行代码。感谢大家的投入。