【发布时间】:2018-10-31 13:44:48
【问题描述】:
问题
我有一个工作簿 (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”的模块中,并且在工作表“DASHBOARD”(sheet1)中有一个按钮:
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 时才会出现问题。当两个 wbs 都冻结时,也看不到代码正在运行...
1) 复制并删除数据连接(因此不会干扰),然后保存和关闭工作簿
2) 打开工作簿(没有任何错误处理和应用程序语句)而不在电子表格中进行任何更改/更新,并打开第二个文件 (slsx) - 发生错误
3) 打开工作簿(没有任何错误处理和应用程序语句)并在随机空单元格中写入“=1+1”,然后打开第二个文件 (slsx) - 发生错误
4) 打开工作簿(没有任何错误处理和应用程序语句)并更改下拉列表一次(调用 worksheet_change 宏),然后打开第二个文件 (slsx) - 发生错误
5) 打开工作簿(以发布的原始状态)而不在电子表格中进行任何更改/更新,并打开第二个文件 (slsx) - 发生错误
6) 打开工作簿(以发布的原始状态)并在随机空单元格中写入“=1+1”,然后打开第二个文件 (slsx) - 不会发生错误
7) 打开工作簿(以发布的原始状态)并更改下拉列表一次(调用 worksheet_change 宏),然后打开第二个文件 (slsx) - 发生错误
8) 如果我在下拉列表中插入一个空白值(工作簿处于发布的原始状态)并选择空白值,然后打开第二个文件 (slsx) - 不会发生错误
9) 在下拉列表中选择一个值 - 发生错误
8) 删除 ExportToPDF 和 conditionalFormatting-modules,并包括对 Worksheet_change 模块的建议调整(即从 sheet1 中删除代码并将其插入到模块中)。
- 8.1 只打开第二个文件而不更改 xlsm,并且在下拉列表中有值 - 发生错误
- 8.2 在随机空单元格中输入 1+1 - 出现错误
- 8.3 将下拉列表更改一次(更改为另一个值) - 发生错误
- 8.4 将下拉列表更改为空白 - 不会发生错误
【问题讨论】:
-
虽然我没有看到它,但它可能会导致一个无限循环,其中 Range("B2") 被 VBA 更改(可能通过公式间接)它再次调用 Worksheet_Change() 事件,触发相同的更改,触发相同的 Worksheet_Change()。为确保在您的 Worksheet_Change() 事件中不会发生这种情况,请关闭
EnableEvents,例如:Application.EnableEvents = False,然后在最后将其重新打开。 -
当工作簿冻结时,它看起来是否正在运行 vba(在 vba 编辑器窗口标题中带有“正在运行...”?如果是这样,您可以尝试使用 Ctrl + Pause 中断执行/休息?
-
在您的 worksheet_change 中,如果相交条件为 false,则您不会恢复 application.screenupdating 计算并启用事件。我实际上只会在 if 语句中将它们设置为 false、manual、false。
-
另外,你真的需要捕捉'worksheet_change'中的错误吗?您在 conditionalFormatting.conditionalFormatting 中捕捉到它。如果发生错误,您可能希望了解它并且您正在抑制它
-
我再说一遍,你的
set pt不正确