在子例程

时间:2016-06-30 11:59:44

标签: excel vba excel-vba

这不是一个特定于代码的问题,而是更多的东西来满足好奇心(并避免将来的问题),所以我认为这将是一个适合它的地方。

我的问题的基础是:VBA如何处理来自子程序中调用的子程序的Application.ScreenUpdating和其他此类调用?

为了举例说明,我有一个方法BackupData,它可以非常快速地从活动表中获取数据并将其复制到具有相同名称的隐藏表单并附加“备份”(我用它来提供我的用户使用“撤消”宏,因为您无法使用常规方法来撤消子例程的操作)。在BackupData中,我将ScreenUpdating切换为False和True,以便操作完全隐藏在最终用户之外。有问题的原因在于,我允许用户自由访问运行宏,但也选择从其他宏调用它,这也会切换ScreenUpdating属性。

因此,如果在之后的宏中调用BackupData该宏已将ScreenUpdating属性切换为False,那么BackupData调用是否会设置属性为True覆盖“外部”例程的调用,从而使该宏的其余部分在屏幕更新时运行?

现在,显然,我知道这个问题有很多简单的解决方案。我可以在BackupData中存储一个布尔值,用于检查ScreenUpdating是否已经为假,如果是这种情况则不会返回true,或者我可以在运行后始终重复ScreenUpdating = False次调用BackupData,或者我甚至可以写一个相同的子BackupData,它不会切换我在其他宏中运行的值,但这个问题的关键是找不到解决方案。

我想这更像是一个关于VBA如何与嵌套子程序调用一起工作的问题,但是我希望这里的某个人能够通过一个明确的答案满足我的好奇心,看看VBA是否会为我处理这个问题,或者是否我需要使用前面提到的解决方法之一。

TL; DR

我不是在寻找一种解决方案,因为我已经有很多选择。我很好奇是否有人确切知道VBA如何处理这些类型的调用(甚至不仅仅针对ScreenUpdating属性,还有其他应用程序属性)

2 个答案:

答案 0 :(得分:3)

Application.ScreenUpdating是应用程序的设置,在设置和取消设置时全局激活/停用。

您的假设是正确的,如果您在子例程中将其设置为False,那么该例程调用BackupData再次将其设置为false,然后在将范围返回给调用者之前将其设置为True,然后ScreenUpdating对于调用子例程的其余部分为真。

将其视为具有全局范围的变量;无论在何处设置,该值都是全局设置的。它是Application级别的全局设置,它是在程序实例中打开的所有工作簿的父对象(在本例中为excel.exe)。设置它会影响实例中的所有工作簿;但如果您正在运行另一个excel.exe进程,则不会影响该实例中的工作簿。

答案 1 :(得分:2)

这很简单,使用这样的东西。它将简单地保存以前的屏幕更新状态,而不是将screenupdating设置为false,当你想要将screenupdating设置回来时,它将从备份中恢复它。因此,如果你已经将屏幕更新设为FALSE,那么它将会是假的。

Dim previousScreenUpdating as boolean
previousScreenUpdating = application.screenUpdating

application.screenUpdating = false

// your code

application.screenUpdating = previousScreenUpdating