Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 组合框仅在宏结束后显示值_Excel_Vba_Combobox - Fatal编程技术网

Excel 组合框仅在宏结束后显示值

Excel 组合框仅在宏结束后显示值,excel,vba,combobox,Excel,Vba,Combobox,我有一个带有一些图表和许多组合框(activex控件)的应用程序。 当用户更改任何组合框的值时,图表将更新。没问题 因此,我制作了一个代码,将应用程序的整个屏幕导出为图像。这用于模拟多个场景 但是,问题就从这里开始 此代码中有一些“for…next”循环用于更改这些组合框的值。导出图像时,图表将按预期更新,但组合框不会更改其值。它们在每个场景中显示相同的值,即使图表正在更新 所以,问题是:有没有办法在代码结束前刷新组合框的值 Sub example() For Each elem In myA

我有一个带有一些图表和许多组合框(activex控件)的应用程序。 当用户更改任何组合框的值时,图表将更新。没问题

因此,我制作了一个代码,将应用程序的整个屏幕导出为图像。这用于模拟多个场景

但是,问题就从这里开始

此代码中有一些“for…next”循环用于更改这些组合框的值。导出图像时,图表将按预期更新,但组合框不会更改其值。它们在每个场景中显示相同的值,即使图表正在更新

所以,问题是:有没有办法在代码结束前刷新组合框的值

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组件将刷新
  • 如果您设置了
    Application.Wait(TimeSerial(小时(现在())、分钟(现在())、秒(现在())+5))
    (即,您可视地停止执行5秒,但从技术上讲线程仍在运行)=>您可以清楚地看到ActiveX组件没有得到更新,这就是错误生成图像的原因
我尝试了所有明显的技巧(
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之后选择`则图片中也有一个清晰的组合框