EXCEL VBA 事件的问题。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EXCEL VBA 事件的问题。相关的知识,希望对你有一定的参考价值。

Private Sub Worksheet_Change(ByVal Target As Range) 这是当工作表内容发生改变时产生的事件。

(ByVal Target As Range)的意思是什么?将发生变化的单元格记录在Target变量里,然后在代码中使用Target就能表示发生改变的单元格吗?

如果改为Byref有什么后果?

理解正确
Target返回的就是发生改变的单元格集合对象,就是一个完全的Range对象

ByRef:默认情况下,VBA按地址(关键字ByRef)给Function过程(或Sub子过程序)传递信息,这时被调用的函数相用函数参数中特定的原始数据。因此,如果函数改变了参数的值,原始的数值也被改变了。如果想要Function过程改变原始数值,则不必专门在参数前加关键字ByRef,因为,变量数值的传递默认就是ByRef。

ByVal: 当在参数名称前使用关键字ByVal时,VBA按值传递参数,这意味着VBA复制了一份原始数据,然后将复制的值传递给函数,如果函数改变了参数的数值,原始数据不会改变——只有复制的值变化。

参考资料:http://blog.csdn.net/ruokle/article/details/4887715

参考技术A Microsoft 窗体中的 ByVal 关键词表示将首选参数作为数值传递。这是 Visual Basic 中 ByVal 的标准含义。但是,在 Microsoft 窗体中可以将 ByVal 用于 ReturnBoolean、ReturnEffect、ReturnInteger 或 ReturnString 对象。当您如此使用时,传递的数值不是简单的数据类型;而是一个指向对象的指针。

当用于以上对象时,ByVal 将引用对象本身而非传递参数的方法。上文列出的每个对象都具有可以设置的 Value 属性。您还可以将此值传递进或传递出函数。因为您能够改变对象成员的值,所以即使该事件语法说明此参数是 ByVal,事件仍然产生与 ByRef 一致的效果。

给与 ReturnBoolean、ReturnEffect、ReturnInteger 或 ReturnString 相关的参数赋值,与给任何其他参数赋值没有区别。例如,如果事件语法指明一个用于 ReturnBoolean 对象的 Cancel 参数,语句 Cancel=True 仍然是合法的,就像对于其他数据类型一样。

插入代码时,打开事件中的 Excel 2010 vba EnableEvent 不起作用

【中文标题】插入代码时,打开事件中的 Excel 2010 vba EnableEvent 不起作用【英文标题】:Excel 2010 vba EnableEvent in Open event not working when code inserted 【发布时间】:2019-03-28 03:38:58 【问题描述】:

当我尝试在具有 100 多个宏的复杂 Excel 模型中提高效率时,我想确保在模块运行以将带有公式的模板转换为仅值文件后启用事件。使用下面的代码,我希望插入到其他没有 VBA 的 Excel 文件中的其他事件代码可以工作,但是下面的 Open 事件代码不会启用事件。我进行了搜索,发现 EnableEvents 很棘手。我的目标是使用我在网上找到的一些其他代码来“优化”或加速代码的运行将更广泛地成为可能。它包括 EnableEvent 语言(在代码开头将其关闭并在代码末尾打开)。

这是我为获取模板的“VALUES”版本而调整的​​代码以启用一般事件,一旦我导航到另一个选项卡并使用名为 Private Sub Worksheet_SelectionChange(ByVal Target作为范围)

Sub AddSheetCodeToAuto_Open()
' To turn on events
Dim Startline As Long, HowManyLines As Long
With ThisWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
    Startline = 1
    HowManyLines = .CountOfLines
    .DeleteLines Startline, HowManyLines
.InsertLines 1, "Private Sub Workbook_Open()"
.InsertLines 2, vbNewLine
.InsertLines 3, "Sheets(Sheet7).Select
.InsertLines 4, "Application.EnableEvents = True"
.InsertLines 5, "End Sub"
End With
End Sub

当我使用即时窗口并单步执行代码时,Application.EnableEvents 值在打开相关文件后始终为 FALSE,但鉴于打开工作簿事件的事件处理程序如上所示,为什么事件不会转在? 提前感谢您的专业知识。

【问题讨论】:

该代码应该放在ThisWorkbook 代码模块中,而不是工作表模块中。 没错,我忘了提到 Workbook_Open 代码已移入该模块。这是修改后的代码: With ThisWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule 麻烦的是,如果我在“转换为值”过程结束时关闭事件,则自动打开事件处理程序在启用时无效事件。 通常,您可以通过在关闭事件的任何过程中包含错误处理来管理此问题,以确保您的代码不会崩溃并关闭事件。 【参考方案1】:

我认为第 3 行遇到错误。更改 3 即可解决问题

.InsertLines 3, "Sheets(" & Chr(34) & "Sheet7" & Chr(34) & ").Select"

这也取决于“Sheet7”的存在。

但最好的解决方案仍然是@Tim Williams 的建议

【讨论】:

您是正确的,第 3 行需要引用特定的工作表名称,而不是 Excel 工作表 # (Sheet7)。我确实做了那个改变。我没有使用“Sheet7”作为工作表选项卡上的工作表名称。 按照 Tim 的建议,我一直在考虑如何使用错误处理来打开事件,但我没有收到自动打开事件未运行或正常工作的错误消息。它只是不启用事件。我会更加努力地思考如何安排组件以确保在 a) 删除 VBA 代码(除了重新插入所需事件代码以导航到其他工作表的代码之外)之后启用事件,b) 将文件保存为“VALUES”文件,并且c) 重新打开 VALUES 文件,其中 Open 事件将打开事件并使其保持打开状态。

以上是关于EXCEL VBA 事件的问题。的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 VBA 将事件添加到运行时在 Excel 中创建的控件

插入代码时,打开事件中的 Excel 2010 vba EnableEvent 不起作用

更新事件触发输入事件后VBA Excel退出

Excel VBA - 在用户窗体上手动调用文本框退出事件?

Excel vba中怎样填写数值改变单元格后触发事件

Excel VBA复选框单击和更改事件相同吗?