嗨,我是编写 VBA 代码的新手,需要帮助。只要我在事件工作表上,我的 VBA 代码和宏就可以正常工作。
我的问题:
当我在同一个工作簿中从事件工作表更改为另一个工作表时,我的 VBA 代码和宏会自动停止运行,并且
当我打开一个新的 Excel 工作簿时,我的 VBA 代码和宏自动停止运行
所需解决方案:
仅在所需的工作表上运行 VBA 代码和宏,并防止它在其他工作表和工作簿上运行。
背景:
我有一个 Excel 文件,名为“净重”,有两张纸。表 1 命名为:“重量”,表 2:命名为“基本数据”。
表 1 用作用户输入表单。
在工作表 1-单元格 B1 中:用户将输入产品代码,在单元格 E1 中:查找公式将使用工作表 2 中的数据放置产品代码的描述
我已经设置了执行以下操作的 VBA 代码和宏:
表 1 上没有按钮,一切都是自动完成的。
这是我当前的代码:
工作表 1:设置为工作表
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$1" Then
Call Macro1
End If
End Sub
模块 1 宏:设置为通用
Sub Macro1()
Application.DisplayAlerts = False
If ThisWorkbook.Name = "Nett Weight.xlsm" And ActiveSheet.Name = "Weight" Then
Sheets("Weight").ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\Nett weight\" & Range("B1 ").Text & Range(" E1").Text
Application.OnTime Now + TimeValue("00:00:10"), "Macro1"
Else
Exit Sub
End If
End Sub
最佳答案
首先,您需要创建一个公共(public)变量来保存您的计时器,否则您将永远无法取消它,因此即使您的工作簿关闭,它也会继续尝试触发。您还应该创建一个公共(public)变量来存储计时器运行的时间,以便在创建新计时器之前进行检查。
在 的顶部代码模块放:
Public nextTime As Date
然后在您的 Workbook_BeforeClose() 事件方法中(在 ThisWorkbook 内),禁用现有计时器,这样它就不会在工作簿关闭后继续尝试触发。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next ' Continue with next line of code if we encounter an error
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=False
On Error GoTo 0 ' Resume error-trapping
End Sub
在
Macro1()
您应该明确直接地引用您的工作簿组件 - ThisWorkbook
总是指运行代码的工作簿,所以你不需要你的 If
陈述。然后你设置nextTime
如果计时器尚未运行,则使用该变量激活计时器。Sub Macro1()
Dim sht As Worksheet ' Creates a variable to hold your Weight worksheet
Set sht = ThisWorkbook.Sheets("Weight") ' Sets the reference
Application.DisplayAlerts = False
sht.ExportAsFixedFormat Type:=xlTypePDF, Filename:="C:\Nett weight\" & sht.Range("B1").Text & sht.Range("E1").Text ' Remember to preceed Range with sht. to explicitly reference the range of your Weight worksheet
On Error Resume Next ' Continue with next line of code if we encounter an error
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=False
On Error GoTo 0 ' Resume error-trapping
nextTime = Now + TimeSerial(0, 0, 10) ' Adds 10 seconds to Now
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=True
timerIsRunning = True
Application.DisplayAlerts = True ' Remember to enable alerts at the end of code
End Sub
您的 Worksheet_Change() 事件方法可以保持原样。现在,如果 B1 发生变化,它将调用 Macro1()。无论工作簿或工作表是否处于事件状态,Macro1() 都会将权重工作表保存为 PDF,并在停用现有计时器后每 10 秒创建一个新计时器以重新运行 Macro1()。完成工作簿后,将其关闭,现有计时器也将停用。
编辑:
幸运的是(因为它修复了我自己的电子表格)我已经弄清楚为什么我最初提供的解决方案不起作用。放置
Public
ThisWorkbook
下的变量意味着它们在代码执行后不再保持它们的值。补救措施是将它们放在一个模块中。一旦解决了这个问题,我也意识到当计时器触发时调用 Macro1()
尝试取消调度现有计时器时会抛出错误(因为没有计时器,除非 Macro1()
被 Worksheet_Change()
事件临时调用)。长话短说:
Public
变量已移至代码模块,timerIsRunning
标志已被完全删除,如果没有计时器存在,则尝试取消调度计时器时的错误将被简单地忽略。
关于vba - 仅在一张纸上运行 excel 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42100784/