仅在一个工作表上运行excel宏

时间:2017-02-07 21:56:54

标签: vba excel-vba excel

嗨,我刚接触编写VBA代码并需要帮助。只要我在活动工作表上,我的VBA代码和宏就能正常工作。

我的问题: 当我从同一工作簿中的活动工作表更改为另一个时,我的VBA代码和宏将自动停止运行 当我打开一个新的Excel工作簿时,我的VBA代码和宏会自动停止运行

需要解决方案: 仅在所需的工作表上运行VBA代码和宏,并防止它在其他工作表和工作簿上运行。

背景 我有一个excel文件,名为“净重”,有两张纸。表1命名为:“weight”,表2:命名为“基础数据”。 表1用作用户输入表单。

在工作表1-单元格B1中:用户将在单元格E1中键入产品代码:查找公式将使用工作表2中的数据放置产品代码的描述

我已经设置了一个VBA代码和宏来执行以下操作:

  1. 一旦用户将产品代码输入到单元格B1中,在工作表1中,工作表1将作为PDF文件保存到单元格B1和E1中的预定义文件夹位置数据中
  2. 宏每10秒钟保存并覆盖PDF文件。
  3. 每次输入新产品代码时都会重复此过程
  4. 表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
    

1 个答案:

答案 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标志已被完全删除,并且在尝试取消计划定时器时的错误在没有计时器的情况下被忽略存在。