我在文件服务器上的同一个共享文件夹中有许多Excel工作簿。在每个工作簿中都有一些数据和一个“更新图表”按钮,可以根据数据生成/更新工作簿中的图表。
这一切都已实现并且有效,但我遇到了维护问题......如果我必须在宏中更改或修复某些内容,我必须更新所有工作簿中的宏。
我希望有一个额外的工作簿,不包含任何其他内容,但我的宏用于生成/更新图表。按下按钮时,所有其他工作簿应调用这些宏。这样,当我必须改变图表生成时,我可以在一个地方完成。如果用户甚至不必打开宏工作簿,那将是最好的。
是否有最佳实践/建议?如果多个用户同时更新工作簿并使用“更新图表”按钮生成图表,这可以安全地实现吗?
谢谢。
答案 0 :(得分:2)
您需要使用代码创建加载项。用户加载外接程序一次,它将保持加载到Excel中,直到它被删除。代码总是准备好执行。
加载项需要能够识别工作簿何时是代码的正确工作簿。我在所有对加载项“适用”的工作簿中使用了一个已定义的名称。如果activeworkbook具有该名称,则代码将运行。否则就不会。
在加载项中,您需要一个自定义类模块,用于标注Application变量WithEvents。然后,您将使用Workbook_Open或Workbook_Activate事件来确定特定工作簿是否具有已定义的名称。
我不喜欢使用on-worksheet按钮来做这种事情。当控件位于与代码不同的工作表上时,ActiveX控件很不稳定(您会遇到很多自动化错误)。而表单按钮没有事件,因此它们更难以连接。
我通常使用带回调的功能区按钮。回调根据活动工作簿是否适用启用/禁用功能区。
你没有给出很多细节,所以我也不能。但希望这会让你走上正确的道路。
功能区回调
您可以确保代码仅在正确条件下运行的方法之一是检查过程顶部的条件。但是,我喜欢这样做的方法是使用户界面元素不可用,除非条件合适。
在过去,这意味着设置CommandBarButton的Enabled属性。我会使用应用程序级事件,以便每次激活工作簿窗口时,这样的代码都会运行
Application.Commandbars("mybar").Controls("PrintInvoice").Enabled = IsInvoice(ActiveWorkbook)
使用功能区,它是不同的。功能区控件(以XML定义)具有enabled属性。您可以将其设置为True或False。但您也可以选择不使用enabled属性,而是使用getEnabled属性。
getEnabled="InvoiceAppBtnPrintGetEnabled"
然后在您的VBA中,您仍然可以使用应用程序级事件。但是,您只需使功能区无效,而不是操纵CommandBarButton。当您使功能区无效时,它会强制它运行InvoiceAppBtnPrintGetEnabled过程,然后启用或禁用功能区按钮。
有关更多信息,请参阅Ron de Bruin的网站:http://www.rondebruin.nl/win/s2/win013.htm