VBAでリアルタイムで計算結果をグラフに表示する方法

このQ&Aのポイント
  • Excel2010でVBAを使っています。30分くらいかかる計算があるのですが、計算が終了するまで待っていたのでは、計算結果がどのようなものになるのか分からないためリアルタイムで計算結果をグラフに表示してくれるプログラムを書きたいと考えています。
  • VBA上でユーザーフォーム上でグラフを表示させることはできないようです。しかし、シート上でのグラフを画像として表示させることは可能です。その方法は、計算結果が更新される度にシート上のグラフをキャプチャし、画像として表示するというものです。
  • 以下の方法でリアルタイムで計算結果を表示させることができます。1. VBAで計算処理を行う2. 計算結果が更新される度にシート上のグラフをキャプチャする3. キャプチャした画像を別のシートに貼り付ける4. 貼り付けた画像を表示する5. 一定の時間をおいて2~4の処理を繰り返す
回答を見る
  • ベストアンサー

VBAでリアルタイムで計算結果をグラフに表示

Excel2010でVBAを使っています。 30分くらいかかる計算があるのですが、 計算が終了するまで待っていたのでは、計算結果がどのようなものになるのか分からないため リアルタイムで計算結果をグラフに表示してくれるプログラムを書きたいと考えています。 検索したところ、 http://www.johoka.net/vbsin.htm VBの場合には、Picture1.Line を使えば、うまくいきそうだということが分かりました。 同様のことをVBA上でやりたいのですが、 http://pasokoma.jp/xp_bto/a_333563 のページにはVBAにはそのような機能はないと書かれています。 本当にユーザーフォーム上でグラフを表示させることはVBAではできないのでしょうか? http://www.asahi-net.or.jp/~zn3y-ngi/YNxv9d92.html そのほか、シート上でのグラフを画像として表示させるという方法も見つかりました。 この方法でリアルタイムで計算結果を表示させるにはどうしたら良いですか?

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

#3です。 下記の様なコードで普通にグラフは書き換わりますので、何が問題なのかわかりかねます。 ☆ワークシートモジュールに記載、コマンドボタンを2個もうけている。 Dim stopFlag As Boolean Private Sub CommandButton1_Click() Dim i As Long Dim j As Double stopFlag = False i = 1 Do While Not stopFlag j = i ^ 2 + 3 * i + 4   ’グラフのデータ範囲のセル一個だけ変更している Me.Range("B3").Value = j i = i + 1 DoEvents: DoEvents: DoEvents Loop End Sub Private Sub CommandButton2_Click() stopFlag = True End Sub

MOUIIKAO
質問者

お礼

ありがとうございます。 簡単なプログラムだとリアルタイムでグラフを更新されることに気がつきました。 いま少し複雑なプログラムを書いているのですが このプログラムだとなぜか更新されません。 Do eventsとなっているところを DoEvents: DoEvents: DoEvents にしたり、 Application.Wait [Now() + "0:00:00.1"] を書いてタイムラグを発生させたりすると リアルタイムで更新されるようになりました。 Do eventsと DoEvents: DoEvents: DoEvents って何が異なるのでしょうか?

その他の回答 (4)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.5

#4です 理由は存じませんが、(検索してみても、経験談くらいしか見つからないのですが) xl2010になってから(VBA7になってから?) 従来は一個で十分であったDoEventsが、3回以上続けないと思うように機能しない様です。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#2です。お役に立つかどうか分かりませんが、「シート上のグラフを画像として表示する」の応用編です。 ファイルを介さずメモリ上で処理します。xl2010でグラフをCopyすると、Picture Objectもクリップボード内にあるのですが、直接取り出す方法が大分探しましたが見つけられませんでした。BitmapもしくはEMFからPictureに変換しています。 Userformに、Imageコントロールと、CommandButton2個を置いています ☆UserForm1モジュール Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Dim stopFlag As Boolean Private Sub UserForm_Initialize() Me.Image1.PictureSizeMode = fmPictureSizeModeStretch End Sub Private Sub CommandButton1_Click() Dim i As Long stopFlag = False i = 1 Do While Not stopFlag '単に既存のグラフの範囲のセル一個の値を変更しているだけ(すなわち単純な状況でしか試験してないです)   'この代わりに計算結果をセルに入れれば良いと思いますが、毎回セルにアクセスすると遅くなると思いますので、   '1000回毎にとかにする方が良いと思います。 Sheets(1).Range("C7").Value = i i = i + 1 Sheets(1).ChartObjects(1).Copy Me.Image1.Picture = PastePicture   ’今回の課題ではCPU100%占有しても良さそうなので入れなくても可 Sleep 10 DoEvents: DoEvents: DoEvents Loop End Sub Private Sub CommandButton2_Click() stopFlag = True End Sub ☆標準モジュール Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type Private Type uPicDesc Size As Long Type As Long hPic As Long hPal As Long End Type Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long Declare Function CopyImage Lib "user32" (ByVal handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long Const CF_BITMAP = 2 Const CF_PALETTE = 9 Const CF_ENHMETAFILE = 14 Const IMAGE_BITMAP = 0 Const LR_COPYRETURNORG = &H4 'メインルーチンはこれだけ Sub test() UserForm1.Show End Sub Function PastePicture(Optional lXlPicType As Long = xlPicture) As IPicture Dim h As Long, hPicAvail As Long, hPtr As Long, hPal As Long, lPicType As Long, hCopy As Long lPicType = IIf(lXlPicType = xlBitmap, CF_BITMAP, CF_ENHMETAFILE) hPicAvail = IsClipboardFormatAvailable(lPicType) If hPicAvail <> 0 Then h = OpenClipboard(0&) If h > 0 Then hPtr = GetClipboardData(lPicType) If lPicType = CF_BITMAP Then hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG) Else hCopy = CopyEnhMetaFile(hPtr, vbNullString) End If h = CloseClipboard If hPtr <> 0 Then Set PastePicture = CreatePicture(hCopy, 0, lPicType) End If End If End Function Private Function CreatePicture(ByVal hPic As Long, ByVal hPal As Long, ByVal lPicType) As IPicture Dim r As Long, uPicInfo As uPicDesc, IID_IDispatch As GUID, IPic As IPicture Const PICTYPE_BITMAP = 1 Const PICTYPE_ENHMETAFILE = 4 With IID_IDispatch .Data1 = &H7BF80980 .Data2 = &HBF32 .Data3 = &H101A .Data4(0) = &H8B .Data4(1) = &HBB .Data4(2) = &H0 .Data4(3) = &HAA .Data4(4) = &H0 .Data4(5) = &H30 .Data4(6) = &HC .Data4(7) = &HAB End With With uPicInfo .Size = Len(uPicInfo) .Type = IIf(lPicType = CF_BITMAP, PICTYPE_BITMAP, PICTYPE_ENHMETAFILE) .hPic = hPic .hPal = IIf(lPicType = CF_BITMAP, hPal, 0) End With r = OleCreatePictureIndirect(uPicInfo, IID_IDispatch, True, IPic) If r <> 0 Then MsgBox "Create Picture Error" Set CreatePicture = IPic End Function

MOUIIKAO
質問者

お礼

丁寧なご回答ありがとうございます。 しかしながら、難しすぎて私には手に負えないと思います。 代替案なのですが、 シート上に存在するグラフをリアルタイムで更新することはできないのでしょうか? Doeventsを実行することで一瞬だけWindowsの制御をactiveにするわけですが グラフの更新も同時にactiveにすることってできないのでしょうか?

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

UserFormに自前で描画するご参考になるかもしれません。 http://okwave.jp/qa/q7331192.html 昔々C言語でWindowsの基本的な機能で描画していた頃と同じ事をVBAでやろうという事なので面倒臭いです。 http://www.kumei.ne.jp/c_lang/sdk/sdk_23.htm

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

>ユーザフォーム ということはExcelでしょうか? 安直なのはStatusBarを使う方法があります。 表示:Application.StatusBar = String(10, "□") 消去:Application.StatusBar = False 左から■を増やしていくとか・・・ これはDoEventsをやらないでも表示が変わる ので、安全な処理です。 その他、プログレスバーコントロールや、 グラフ系の処理は全てウィンドウの メッセージを処理するため、計算処理の スレッドが走っている間はメッセージが 処理されないので、画面は変化しません。 これを処理させるには描画毎にDoEventsを 実行します。 ただ、このステートメントは全てのイベントを 拾うので、画面を閉じる操作も受け付けます。 処理中にバッタリ画面が閉じても問題が無い というなら良いのですが、そうでない場合は 制御が面倒です。

MOUIIKAO
質問者

お礼

計算結果というのは、計算過程を表示したいという意味ではなく http://www.johoka.net/vbsin02.gif のような計算した結果を表示したいという意味です。

関連するQ&A

  • VBでリアルタイムにグラフを書きたいのですが。

    この度EXCELに入ってくるCSVデータをリアルタイムで折れ線グラフに変換することになりました。 何とかVBAで出来そうだ・・・まではわかったのですが、初めてVBの画面を開いた私ですので 命令語の意味すらわからず大変困っています。 ・約0.5秒に1回セルA1とB1にデータが入ってくる。 ・それを別々に折れ線グラフに表示する。 ・表示後、セルA1とB1の内容をクリアする。 以上の繰り返しで行いたいと思っています。 どなたか詳しい方がいらっしゃいましたらどのようなプログラムに なるのか教えて頂けませんでしょうか? どうかよろしくお願い致します。 OSはXP、Officeは2000を使用しております。

  • VBAで計算結果のみ表示させたい

    VBA作成中です。 SUMIF関数なのですが、 ActiveCell.FormulaR1C1 = "=SUMIF(R2C1:R14C1,RC[-1],R2C4:R14C4)"  このままだと計算式が入るので、これを計算結果のみ表示させたいのですが、値のみ貼り付け以外で方法はありますか?

  • ExcelでのVBA チェックボックスから印刷

    初心者です。お世話になります。Excel2003を利用しています。 ユーザフォームに、CheckBoxを配置してあります。 CheckBoxを選択し、印刷ボタンを押したら印刷できるようにしたいのですが、CheckBoxを選択したらの部分が分かりません。 ここのHPにあるhttp://www.asahi-net.or.jp/~zn3y-ngi/YNxv98b2.html のを参考にしています。 HPに書いてある、「Private Sub チェックボックスの選択結果を調べる()」をどう改造していいのか分かりません。 ご教授、よろしくお願い致します。

  • リアルタイムでForループを表示

    Excel2010でVBAを使っています。 一つのループの計算のために10秒くらいかかるForループを10000回繰り返すプログラムを作った場合、 計算が終了するまでに30分程度時間がかかります。 計算途中にどこまで計算が進んだか分かるようにするため ダイアログにリアルタイムで変数iを表示できるようなプログラムを書きたいのですが どのようにすれば良いですか? Matlabだと「;」をつけないといった方法があるのですが VBAでやり方を教えてください。

  • VB6.0で、グラフを複数表示させたいのですが。

    VB6.0で、Form1にある描画ボタンを押すたびに、 Form2のグラフを画面上に追加表示したいのですが、 同じフォームを複数表示させる方法がわかりません。 ご存知の方教えてください。 よろしくお願いします。 Form2は添付ファイルのような感じです。 ピクチャーボックスにグラフを描画します。

  • VB6.0で折れ線グラフに最大値を表示したいのですが

    VB6.0でピクチャーボックスに折れ線グラフを描画しています。グラフ上の最大値のところに数値を表示したいのですが、ピクチャーボックス上で任意の座標に、ラベルを表示させることはできるのでしょうか? やり方をご存知の方がいたら教えてください。 参考になるサイトを教えていただいても助かります。 どうぞお願いします。

  • グラフの作成について

    VB画面でグラフを表示する方法として MSChartを使う方法や Excelで作成したグラフを ピクチャーボックスに貼り付ける方法を ご紹介していただきました。 今回は縦棒グラフでかまわないのですが、 横軸を時間軸とした場合に、 非常に長いので、横スクロールバーを使って グラフ表示させる方法が分かる方、 ご教授ください。 よろしくお願いいたします。

  • グラフで0.0を表示しないようにしたい

    棒グラフで値を表示すると、計算式の結果が0の時も0と表示されます。 表示形式のユーザー定義で#とすると、表示されなくなります。 (0以外の時は、3.6のように小数点以下を表示したい時に、) 0.0はグラフには表示しないようにするにはどうしたら良いのでしょうか? データが変わって、計算結果0.0が1.2などになった場合は、1.2と表示されるようにしたいのですが。

  • Access2000のVBAでSHA-256ハッシュ値を計算

    Access2000のVBA上で任意の値からSHA-256ハッシュ値を計算したいと考えています。 VB.netやPHPなど、他言語でのハッシュ値計算方法はWeb上でも探すことができたのですが Access2000のVBA上で行う方法が分かりません。 何とかしてハッシュ値を簡単に求める方法はないでしょうか。よろしくお願いいたします。

  • 東証のマザーズ株価指数リアルタイムグラフ

    先週までは東証の株価指数リアルタイムグラフのページを 開いていれば、自働で最新のグラフを表示していましたが、 今日、新しくなった株価指数リアルタイムグラフでは 自働で表示されなかったような気がします。 皆さんはどうでしょうか? 自働で更新する方法はありますか?