希望这很简单。我在MS Excel中有一系列图表指向同一工作表上的数据。工作表上的数据使用VBA函数计算。当VBA函数更新数据时,新数字不会反映在指向它们的图表中。我试过调用Application.Calculate,但是没有做到这一点。有什么想法吗?
UDPATE:
我能够以更小的规模复制这个问题。方法如下:
在VBA编辑器中打开摘要表并粘贴以下代码:
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Parent.Range("worksheetDate") = Target Then Application.CalculateFull End If End Sub
创建新的VBA模块
将以下代码粘贴到新的VBA模块中(道歉 - 我不能让Stack Overflow在我的生活中正确地格式化 - 这是我能做的最好的事情):
。
Function getWeekValue (weekNumber As Integer, valuesRange As Range) As Integer
Dim aCell As Range
Dim currentDate As Date
Dim arrayIndex As Integer
Dim weekValues(1 To 6) As Integer
currentDate = ThisWorkbook.Names("worksheetDate").RefersToRange.Value
arrayIndex = 1
For Each aCell In valuesRange
If month(currentDate) = month(ThisWorkbook.Sheets("Data").Cells( _
aCell.Row - 1, aCell.Column)) Then
weekValues(arrayIndex) = aCell.Value
arrayIndex = arrayIndex + 1
End If
Next
getWeekValue = weekValues(weekNumber)
End Function
。
修改数据工作表以匹配以下图像:
。
= getWeekValue(1, Data!$A$2:$M$2)
每周将getWeekValue函数的第一个参数递增1(例如,第1周传递1,第2周传递2,第3周传递3,等等。
奇怪的是,经过一段时间(几分钟)后,图表终于更新了。我不确定这是否是因为我一直在执行其他触发更新的活动,或者因为Excel在几分钟后触发更新。
答案 0 :(得分:1)
在我的更改结束时,我关闭工作簿并重新打开它。这似乎是为我更新所有内容的最简单,最可靠的方式。
答案 1 :(得分:1)
刚刚想出了解决这个问题的方法,因为我也遭遇了同样的问题。
我刚刚添加了#34; DoEvents()"在打印或导出之前,图表已刷新。
例如
Sub a()
Dim w As Worksheet
Dim a
Set w = Worksheets(1)
For Each a In w.Range("a1:a5")
a.Value = a.Value + 1
Next
DoEvents
End Sub
答案 2 :(得分:0)
例如:
Sub a()
Dim w As Worksheet
Dim a
Set w = Worksheets(1)
For Each a In w.Range("a1:a5")
a.Value = a.Value + 1
Next
w.ChartObjects(1).Chart.Refresh
End Sub
答案 3 :(得分:0)
这个解决方案对我有用。对于违规工作表,请添加:
Private Sub Worksheet_Activate()
Dim rngSelection As Range
Dim objChartObject As ChartObject
Dim objChart As Chart
Dim objSeriesCollection As SeriesCollection
Dim objSeries As Series
Dim strFormula As String
Set rngSelection = Selection
For Each objChartObject In Me.ChartObjects
Set objChart = objChartObject.Chart
Set objSeriesCollection = objChart.SeriesCollection
For Each objSeries In objSeriesCollection
strFormula = objSeries.Formula
objSeries.Delete
Set objSeries = objSeriesCollection.NewSeries
objSeries.Formula = strFormula
Next objSeries
Next objChartObject
rngSelection.Select
End Sub
答案 4 :(得分:0)
问题可能是getWeekValue的参数列表,其中只包含周数和数据流。
如果你添加第三个参数,workheetDate,那么Excel的重新计算引擎将被击中头部,因为getWeekValue使用了worksheetDate中保存的值。在您当前的实现中,这个事实仅存在于VBA代码中,重新计算引擎可能看不到它。
我这样对冲是因为我不了解重新计算引擎的内部工作原理。 (也许有人比我对我的猜测更能了解这一点)但我确实做了一个测试,其中getWeekValue确实有第三个参数,并且图表确实重新计算了。这种方法的好处还有:您可以删除所有其他VBA事件管理。 -HTH
答案 5 :(得分:0)
我发现调用这个Sub工作......
Sub DoAllEvents()
DoEvents
DoEvents
End Sub
<强> BUT 强> 微软警告说,在第一个DoEvents完成之前,下一个DoEvents会被执行,这可能会发生,这取决于调用之间没有延迟调用的频率。因此,DoEvents似乎充当一种不可屏蔽的中断,并且嵌套不可屏蔽的中断可以导致机器因多种原因而冻结,除了重启之外没有任何恢复。
(注意:如果一个人没有经常快速地调用上面的例程,嵌套可能不会 是一个问题。)
使用下面的Sub,我从他们的建议中修改,可以防止这种情况发生。
Sub DoAllEvents()
On Error GoTo ErrorCheck
Dim i
For i = 1 To 4000 ' Start loop. Can be higher, MS sample shows 150000
'I've found twice is enough, but only increased it to four or 4000.
If i Mod 1000 = 0 Then ' If loop has repeated 1000 times.
DoEvents ' Yield to operating system.
End If
Next i
Exit Sub
ErrorCheck:
Debug.Print "Error: "; Error, Err
Resume Next
End Sub
我看来所需的DoEvents数量取决于您计算机上运行的后台任务的数量,更新图表似乎是应用程序的后台任务。我只需要两个DoEvent因为我经常调用例程;但是,如果需要的话,我可能会在以后提高它。 我还将Mod保持在1000,以便不像Microsoft建议的那样改变每个DoEvent之间的延迟,从而防止嵌套。如果您的系统不更新图表,您可能希望将数字从2000增加到更高的数字的一个可能原因。增加此数量允许机器处理DoEvents可能通过多次调用可能遇到的大量后台事件,因为它们可能在堆栈上,并且DoEvents事件只允许在将其在堆栈中的位置标记为之前运行特定数量的周期允许未处理的事件并返回,让它们在下次调用时处理。因此需要多次通话。将此更改为150000的示例似乎不会使机器运行太慢,为了安全起见,您可能需要将其设置为150000.
注意:第一个带有两个DoEvents的示例Sub可能是安全的,具体取决于您调用Sub的频率,但是,如果经常调用,您的计算机可能会冻结。你的来电。 ; - )
PS:如果你创建了很多嵌套循环并且程序没有按预期运行,那么DoEvents将成为你最好的调用之一。幸运的是,这在所有使用VBA的应用程序中都可用!
答案 6 :(得分:0)
运行Excel 2019。
在宏代码中添加了以下内容:
ActiveSheet.ChartObjects(1).Chart.Refresh
DoEvents
图表现在在宏执行期间更新
答案 7 :(得分:0)
UDF getWeekValue 必须标记为易失性。
Function getWeekValue (weekNumber As Integer, valuesRange As Range) As Integer
Application.Volatile '!!
Dim aCell As Range
Dim currentDate As Date
'...
答案 8 :(得分:-2)
只是一个想法:在你的Worksheet_Change Sub中,插入第一行:
Application.EnableEvents = False
为了避免自我射击事件.... 当然,在Sub的结尾处将其设置回True。