vba - 仅在一张纸上运行 excel 宏

标签 vba excel

嗨,我是编写 VBA 代码的新手,需要帮助。只要我在事件工作表上,我的 VBA 代码和宏就可以正常工作。

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

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

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

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

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

  • 一旦用户在单元格 B1 中输入产品代码,在工作表 1 中,工作表 1 就会以 PDF 文件的形式保存到来自单元格 B1 和 E1 的预定义文件夹位置数据
  • 宏每 10 秒保存并覆盖 PDF 文件。
  • 每次输入新产品代码时都会重复此过程

  • 表 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/

    相关文章:

    vba - SendKeys 通过 Access 表单中的 VBA 代码弄乱了我的 NumLock 键

    vba - Excel与粘贴作为图片重复一列

    mysql - Excel VBA mysql 查询字符串变量

    excel - 在 B 列中获取 A 列中 `not in dictionary` 的单词

    regex - 这是用于匹配 Excel 公式中任何单元格引用的正则表达式吗?

    VBA 字符串插值语法

    sql - 获取SSAS立方体上次处理时间

    sql - 使用Excel生成SQL——问题处理日期字段

    excel - 为什么我的数组不包括预先存在的下拉值?

    Excel VBA : Range gives Argument Not Optional error message