うまくいけば、これは簡単なものです。同じワークシートのデータを指す一連のグラフがMSExcelにあります。ワークシートのデータは、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が数分後に更新をトリガーしているためなのかわかりません。
変更が終了したら、ブックを閉じて再度開きます。それは私にとってすべてを更新するための最も簡単で信頼できる方法のようです。
私は同じ問題に苦しんでいたので、ちょうどこの問題の解決策を見つけました。
印刷またはエクスポートする前に「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
このサブを呼び出すとうまくいくことがわかりました...
Sub DoAllEvents()
DoEvents
DoEvents
End Sub
[〜#〜] but [〜#〜] Microsoftは、最初のDoEventsが完了する前に、次のDoEventsの実行に巻き込まれることについて警告しています。したがって、DoEventsはマスク不可割り込みの一種として機能しているように見え、マスク不可割り込みをネストするとすると、他の回復なしに複数の理由でマシンがフリーズする可能性があります。再起動するより。
(注:上記のルーチンを頻繁かつ迅速に呼び出さない場合、ネストは問題にならない可能性があります。)
私が彼らの提案から修正した以下のサブを使用すると、これが起こるのを防ぎます。
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
必要なDoEventの数は、マシンで実行されているバックグラウンドタスクの数に基づいているようです。グラフの更新は、アプリケーションのバックグラウンドタスクのようです。ルーチンを頻繁に呼び出すため、必要なDoEventは2つだけです。ただし、必要に応じて後でそれを上げることになるかもしれません。また、Microsoftが提案するように、各DoEvent間のラグを変更しないように、Modを1000に維持して、ネストを防ぎます。数値を2000からより高い数値に増やしたい理由の1つは、システムがグラフを更新しない場合です。この数を増やすと、マシンは、DoEventsがおそらくスタック上にあるため、複数の呼び出しを通じて発生する可能性のある多数のバックグラウンドイベントを処理できます。また、DoEventsイベントは、スタック内の場所をマークする前に、特定のサイクル数のみ実行できます。未処理のイベントと戻りを許可し、次の呼び出しで処理されるようにします。したがって、複数の呼び出しが必要です。これを150000の例に変更しても、マシンの速度がそれほど遅くなることはないようです。安全にプレイするには、150000にすることをお勧めします。
注:2つのDoEventを持つ最初の例のSubは、Subを呼び出す頻度によってはおそらく安全ですが、頻繁に呼び出すと、マシンがフリーズする可能性があります。あなたの呼び出し。 ;-)
PS:ネストされたループをたくさん作成し、プログラムが期待どおりに動作しない場合、DoEventsは最良の呼び出しの1つになります。幸い、これはVBAを使用するすべてのアプリで利用できます。
この解決策は私のために働いた。問題のあるワークシートに次を追加します。
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
例えば:
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
問題は、週番号とデータストリームのみを含むgetWeekValueの引数リストである可能性があります。
3番目の引数worksheetDateを追加すると、getWeekValueがworksheetDateに保持されている値を使用するという事実により、Excelの再計算エンジンが頭の側面でヒットします。現在の実装では、この事実はVBAコードでのみ保持されており、再計算エンジンからはおそらく見えません。
私は再計算エンジンの内部動作に精通していないので、これを非常に慎重に書いています。 (おそらく、私の推測についてコメントするよりも、これについてよく知っている人がいます)しかし、getWeekValueに3番目の引数があり、グラフが適切に再計算されるテストを実行しました。このアプローチの優れた追加の利点:他のすべてのVBAイベント管理を削除できます。 -HTH
Excel2019を実行しています。
マクロコードに以下を追加しました。
ActiveSheet.ChartObjects(1).Chart.Refresh
DoEvents
マクロの実行中にチャートが更新されるようになりました