嗨,我刚接触编写VBA代码并需要帮助。只要我在活动工作表上,我的VBA代码和宏就能正常工作。
我的问题: 当我从同一工作簿中的活动工作表更改为另一个时,我的VBA代码和宏将自动停止运行 当我打开一个新的Excel工作簿时,我的VBA代码和宏会自动停止运行
需要解决方案: 仅在所需的工作表上运行VBA代码和宏,并防止它在其他工作表和工作簿上运行。
背景 我有一个excel文件,名为“净重”,有两张纸。表1命名为:“weight”,表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
答案 0 :(得分:1)
首先,您需要创建一个公共变量来保存您的计时器,否则您将永远无法取消它,因此即使您的工作簿已关闭,它也会继续尝试触发。您还应该创建一个公共变量,以便在计时器运行时进行存储,这样您就可以在创建新计时器之前进行检查。
在代码模块的顶部放置:
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()
,否则不存在{1}}事件)。
长话短说:Public
变量已移至代码模块,并且timerIsRunning
标志已被完全删除,并且在尝试取消计划定时器时的错误在没有计时器的情况下被忽略存在。