Excel 组合框仅在宏结束后显示值
我有一个带有一些图表和许多组合框(activex控件)的应用程序。 当用户更改任何组合框的值时,图表将更新。没问题 因此,我制作了一个代码,将应用程序的整个屏幕导出为图像。这用于模拟多个场景 但是,问题就从这里开始 此代码中有一些“for…next”循环用于更改这些组合框的值。导出图像时,图表将按预期更新,但组合框不会更改其值。它们在每个场景中显示相同的值,即使图表正在更新 所以,问题是:有没有办法在代码结束前刷新组合框的值Excel 组合框仅在宏结束后显示值,excel,vba,combobox,Excel,Vba,Combobox,我有一个带有一些图表和许多组合框(activex控件)的应用程序。 当用户更改任何组合框的值时,图表将更新。没问题 因此,我制作了一个代码,将应用程序的整个屏幕导出为图像。这用于模拟多个场景 但是,问题就从这里开始 此代码中有一些“for…next”循环用于更改这些组合框的值。导出图像时,图表将按预期更新,但组合框不会更改其值。它们在每个场景中显示相同的值,即使图表正在更新 所以,问题是:有没有办法在代码结束前刷新组合框的值 Sub example() For Each elem In myA
Sub example()
For Each elem In myArray
Sheets("App").ComboBox1.Value = elem
Sheets("Temp").Shapes.AddChart
Set cht = Sheets("Temp").ChartObjects(1)
Sheets("App").Range("A1:AM103").CopyPicture Appearance:=xlScreen, Format:=xlBitmap
With cht.Chart
.Paste
.export Filename:="test.jpg", FilterName:="jpg"
.Parent.Delete
End With
Next
End Sub
解释
首先,祝贺你:你发现了一个非常讨厌的bug。
我试着复制你的问题,我可以很容易地做到
- 如果在更新组合框后设置断点(即线程暂停)=>ActiveX组件将刷新
- 如果您设置了
(即,您可视地停止执行5秒,但从技术上讲线程仍在运行)=>您可以清楚地看到ActiveX组件没有得到更新,这就是错误生成图像的原因Application.Wait(TimeSerial(小时(现在())、分钟(现在())、秒(现在())+5))
Application.screenUpdate=True
,DoEvents
,Application.EnableEvents=True
,Application.Calculate
等),但无论如何都没有成功
似乎只有当VBA线程结束时,ActiveX组件才会被Microsoft Excel刷新。哇
我能想到的唯一解决这个问题的方法
我能想到的唯一方法是在更新ActiveX组件后从技术上停止执行,然后再继续执行,就是使用Excel的应用程序。OnTime
方法:
Application.OnTime
计划在将来的指定时间(在一天中的特定时间或经过特定时间后)运行一个过程
从技术的角度来看,它看起来有多难看,您可以更新组合框,然后将代码的其余部分安排在完成后的第二秒。从技术角度来看:
- VBA线程1:更新组合框并结束=>ActiveX组件被刷新
- 在没有VBA线程的情况下暂停1秒
- VBA线程2:使用更新的ActiveX组件创建图表并导出图像
Dim myArray(2) 'declare your array as global so that it can be accessed by all the macros - in my example I assume it contains 3 elements
Dim currentElem As Integer 'declare this index as global so it remains in memory even after the code ended execution
Sub example()
'call this macro.
'you first initialize your values:
myArray(0) = "test 1"
myArray(1) = "test 2"
myArray(2) = "test 3"
currentElem = 0
'and then call the first update of your activeX component
first_step_set_activeX
End Sub
Sub first_step_set_activeX()
If currentElem < UBound(myArray) Then
'for each element not treated yet
'(that's why the If currentElem < UBound(myArray)
elem = myArray(currentElem) 'get current element from array
Sheets("App").ComboBox1.Value = elem 'update your ActiveX component
currentElem = currentElem + 1 'increase the currentElem index
Application.OnTime TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 1), "second_step_make_chart_and_print" 'schedule the call of the printing part
End If
End Sub
Sub second_step_make_chart_and_print()
'here do the job of the printing part
Sheets("Temp").Shapes.AddChart
Set cht = Sheets("Temp").ChartObjects(1)
Sheets("App").Range("A1:AM103").CopyPicture Appearance:=xlScreen, Format:=xlBitmap
With cht.Chart
.Paste
.Export Filename:="test.jpg", FilterName:="jpg"
.Parent.Delete
End With
'and reschedule the call for the next activeX component
Application.OnTime TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 1), "first_step_set_activeX"
End Sub
Dim myArray(2)'将数组声明为全局数组,以便所有宏都可以访问它-在我的示例中,我假设它包含3个元素
Dim currentElem As Integer'将此索引声明为全局索引,以便即使在代码结束执行后它仍保留在内存中
子示例()
'调用此宏。
'首先初始化值:
myArray(0)=“测试1”
myArray(1)=“测试2”
myArray(2)=“测试3”
currentElem=0
'然后调用activeX组件的第一次更新
第一步设置activeX
端接头
子第一步设置activeX()
如果currentElem
添加单行工作表(“应用”).ComboBox1.Activate after设置组合框的值也起到了作用。如果导出的图片中还需要一个清晰的组合框图片,则可以选择任何类似“工作表”(“应用”).Range(“A1”)的单元格。在行工作表(“应用”).Combox1.Activate之后选择`则图片中也有一个清晰的组合框