• ベストアンサー

excel VBA プログレスバーについて(初心者)

VBA初心者の質問です… excelで入力されている値を用いて、グラフ作成する簡単なデータを作りました。 特に問題なくグラフは出来たのですが、グラフ作成が1つではなく数個同時(順番)に作成しているため時間が掛かってしまいます。 この処理中にプログレスバーを表示出来ればと思い質問を致します。 私なりに調べ(goo内)下記サンプルを発見し、簡単なのでこれを使をうかと思うのですが、UserForm1の処理前にUserForm2.showだけでは UserForm2の処理が終わらないと処理をしません…当然ですよね… 本当に初心者で申し訳ないのですが、UserForm1の処理最中にUserform2のプログレスバーを表示するのにはどうすればいいのでしょうか… 【サンプル】 Private Sub UserForm_Activate() With Label1 .SpecialEffect = 2 .BackColor = vbBlue www = .Width .Width = 0 End With For i = 1 To 1000 Me.Caption = i Label1.Width = i / 1000 * www Me.Repaint Next End Sub また他におすすめなやり方があれば教えて頂ければ… 初心者な質問で申し訳御座いません。

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

  • ベストアンサー
  • Nayuta_X
  • ベストアンサー率46% (240/511)
回答No.5

いいえ ☆下記のループに、入れては、だめです。 For j = 1 To 10000 Next は、削除するか コメント行にしてください。 ' ---------------------------------------------------- For j = 1 To 10000 'デバッグ用タイミング(実際はここに実行マクロを入れる) ↑↑ ここの部分に私で言うグラフ作成マクロを組み込めばいいのでしょうか? Next '----------------------------------------------------- ☆正確には、下記の中です。 ' ---------------------------------------------------- '(実際はここに実行マクロを入れる) ' 例えば、   Call グラフ作成処理プログラム ' とします。 '----------------------------------------------------- また、 For i = 1 To cend j = i / cend * 100 With UserForm1 .Label2.Caption = Int(j) & "%" .Label1.Width = tsiz * j / 100 End With の中の、cend = 1500 'デバッグ用数値を独自に設定する必要があるでしょう。 例えば、処理時間が、プログレスバーの最後にならない内に処理が終わってしまうとか、その反対にプログレスバーが、早く終わってしまうとかです。 私の場合は、処理する セルの数を算出して 設定しています。 参考として、変形させた コードを乗せます。 詳しいことは、省略します。[ ご自分で、考えてください。 ] ' 以下は 標準モジュールです。 Sub 123() Dim tsiz As Integer, K As Integer, N As Integer Dim Memorys As Long, Memorys_Cunt As Long, Memoryss As Long Do ' 実際はここに実行マクロを入れる)  Call My_Progress_bar(Memorys_Cunt, RoW, Memoryss) Loop UserForm1.Hide End Sub Function My_Progress_bar(I As Long, tsiz As Integer, cend As Long) Dim J As Integer J = I / cend * 100 If J >= 100 Then J = 100 With UserForm2 .Label2.Caption = Int(J) & "%" .Label1.Width = tsiz * J / 100 End With DoEvents End Function UserForm1.Show vbModeless 注意:これは、VBA には、プログレスバーの機能(コマンド)が、ないので、プログレスバー風に考えられたものです。

sometime7
質問者

お礼

またお答え頂き本当にありがとう御座います。 教えて頂いたプログラムまだ試していませんが(他の仕事で手があかず…)、実際に使わせて頂きます。 初心者な私に丁寧に教えていただきありがとう御座いました。もっと勉強したいと言う気持ちになっていますので、 今後また質問させて頂くことがあれば教えて頂ければ幸いです。

その他の回答 (4)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

# もしかするとプログレスバーは開発者ライセンスが必要かも ... フォームにプログレスバーを貼り付けることは出来ているのでしょうか? 出来ているのであればそのプログレスバーを選択して プロパティウィンドウの『オブジェクト名』を確認しましょう プログレスバーが貼り付け出来ないのであれば ツール > その他のコントロールで表示されるダイアログで 『Microsoft ProgressBar Control Version x.x』を探してチェックをつけます これで ツールボックスにプログレスバーのアイコンが表示されますので フォームに貼り付けてみてください

sometime7
質問者

お礼

回答頂きありがとう御座います。 おっしゃるとうりツールボックスになかったので、『Microsoft ProgressBar Control Version x.x』を探してチェックをつけ、 ツールボックスにプログレスバーが追加されたのですが…使い方がよく分からず、プログレスバー風の処理を見つけ そちらを使おうとしています…もっと勉強してから質問するようにします。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

モーダルフォームだと方法は無いのですが モードレスフォームなら別のフォームを表示して内容を交信することも可能です ただ、呼び出し元のフォームもモードレスフォームでないといけません ユーザーフォームのプロパティウィンドウのShowModalプロパティをFalseに設定して   ' Showメソッド引数を FALSEにするとモードレスフォームになる   UserForm2.Show False   For i = 1 to 1000     if int( i/10 ) <> Userform2.Progress1.value then       UserForm2.Progress1.Value = i/10     End if    ' 何かの処理   Next といった具合ですよ

sometime7
質問者

お礼

お返事いただきありがとう御座います。 教えて頂いたとうりモードレスフォームにすると、処理するようになりました。 しかし私の組み込み方が悪くプログレスバーは何も動作しませんでした。 教えて頂いているコードを組み込んでみましたが”Progress1”と言う命令が存在しません・・・ 私の使っているexcel97がだめなんでしょうか・・・ せっかく教えていただいて私が理解出来ず申し訳ないです。

  • Nayuta_X
  • ベストアンサー率46% (240/511)
回答No.2

方法は、 UserForm1を作成してください。 つぎに UserForm1の上に Label1を作成します。 つぎに Label2をLabel1に重て、同じサイズで作成します。 サイズは、適当で良いです。(後で修正してくださいね。) つぎに 下記コードを 標準モジュールを挿入して コピペします。 Sub プログレスバー() cend = 1500 'デバッグ用数値 '準備:ダイアログへ入力 With UserForm1 .Caption = "マクロ実行中:しばらくお待ち下さい" .Label1.BackColor = RGB(255, 255, 0) .Label2.TextAlign = fmTextAlignCenter .Label2.BackStyle = 0 .Label1.Width = 0 tsiz = .Label2.Width End With ' Application.ScreenUpdating = False UserForm1.Show vbModeless For i = 1 To cend j = i / cend * 100 With UserForm1 .Label2.Caption = Int(j) & "%" .Label1.Width = tsiz * j / 100 End With ' ---------------------------------------------------- For j = 1 To 10000 'デバッグ用タイミング(実際はここに実行マクロを入れる) Next '----------------------------------------------------- DoEvents Next Unload UserForm1 End Sub 参考までに別の方法として: 処理の完了までに長い時間がかかる場合は、何らかの方法でユーザーに「現在処理中です...」と伝えたいものです。Windowsの標準機能などでは、ファイルを削除したりコピーしたりするとき、バーが右に伸びることで処理の進捗状況を伝えます。このバーを「プログレスバー」と呼びますが、こうした仕組みをExcelで実現するときは、ステータスバーを使うのが簡単です。 ステータスバーはExcelの最下部に表示されるバーで、通常は「コマンド」とか「編集」「入力」などと表示されます。また、セルのコピー中には「コピー先を選択して~」などと操作の手順をナビゲートしてくれます。ステータスバーにメッセージを表示するには、ApplicationオブジェクトのStatusBarプロパティに表示したい文字列を設定します。次のコードは「○回目の処理をしています...」をステータスバーに表示します。 Sub Sample01() Dim i As Long For i = 1 To 100 Application.StatusBar = i & "回目の処理をしています..." Next i Application.StatusBar = False End Sub 表示が一瞬で変化して読みとれないときは、Forステートメントの繰り返し回数100を増やしてください。なお、ステータスバーを使い終わったら、Excelが自由に使えるように戻してやります。それには、StatusBarプロパティにFalseを設定します。 徐々に伸びるプログレスバーを真似るなら次のようにします。実際にバーが伸びるわけではありませんが、現在作業しているというメッセージをユーザーに伝えるという本来の目的は果たせます。 Sub Sanple02() Dim i As Long For i = 1 To 20000 If i Mod 1000 = 0 Then Range("A1") = i Application.StatusBar = "処理中..." & String(Int(i / 1000), "■") End If Next i Application.StatusBar = False End Sub 表示が速すぎるときは、Range("A1") = iの代わりに時間のかかる処理などを行ってください。 なお、ステータスバーに表示する文字列の色や大きさを変更することはできません。

参考URL:
http://officetanaka.net/excel/vba/tips/tips13.htm
sometime7
質問者

お礼

お返事頂きありがとう御座います。 すごいですね・・・実際に教えて頂いたコードを入力し試してみました。 私が見つけてきたサンプルではバーが延びるだけでしたが、教えて頂いた方は%表示も表示されていて驚きました。 まだテストで使ってみただけですので実際に組み込んでみたいと思います。 ありがとう御座いました。 (追加質問に答えていただければ幸いです)

sometime7
質問者

補足

追加質問です。(初歩的なこともままならないのですみません・・・) ' ---------------------------------------------------- For j = 1 To 10000 'デバッグ用タイミング(実際はここに実行マクロを入れる) ↑↑ ここの部分に私で言うグラフ作成マクロを組み込めばいいのでしょうか? Next '----------------------------------------------------- 何度もすみませんが宜しくお願いします。

noname#169080
noname#169080
回答No.1

説明するのがめんどくさいので 参考になるサイトを紹介します。 (プログレスバーを使用しているわけではありませんがルーチン処理は参考になるかと) 「お待ちください」メッセージの表示 」 http://officetanaka.net/excel/vba/tips/tips23.htm

sometime7
質問者

お礼

お答え頂きありがとう御座います。 私のような初心者にはこちらの処理の方があっているかもしれませんね。 今回VBAを使ってみて勉強と言う意味でもプログレスバーに挑戦してみようと思います。 挫折したそのときはこの方法を使わせて頂きます。

関連するQ&A

  • LabelとFrameでプログレスバー VBA

    お世話になっております。 Excel2003を使用しております。 LabelとFrameを使い、プログレスバー表示したいと思っております。 ユーザーフォーム上に、 Label と Frameを置き、 Frameの中にLabelを置きます。 (ここは上手くできているか不安です) UserFormInitializeに With Me.Label1 .Top = 1 .Left = 1 .Width = 1 .BackColor = vbBlue BarWidth = Me.Frame1.Width - 6 End With そして、ためしにコマンドボタンを設置して、 Dim i, 最大値 As Long 最大値 = 100000 BarWidth = Me.Frame1.Width - 6 Do If i = 0 Then Me.Label1.Width = BarWidth * 1 / 最大値 Else Me.Label1.Width = BarWidth * i / 最大値 End If i = i + 1 Loop Until i = 最大値 上記のように記入してみました。 一瞬で表示されてしまいますし、 一度処理が終わっても、青いバーが表示されたままで どうすればいいのか良く分かりません。 最後に Me.Label1.Width = 0 と書けばいいのは分かりましたが… どうしたら、バーの伸び具合をゆっくり見られますか? 回答よろしくお願い致します。

  • プログレスバーでの経過状況表示

    vb.netでのtimerのようなものをやりたくてvbaでプログレスバーを使用して経過状況を表示するプログラムを作りました。プログレスバー自体での視覚的な経過状況表示はできたのですが、現在のパーセンテージをlabelに表示することができません。 Private Sub CommandButton4_Click() Dim i As Long Application.Visible = False i = 1 For i = i To 1000000 UserForm1.ProgressBar1.Value = i / 1000000*100 UserForm1.Label1.Caption =UserForm1.ProgressBar1.Value i = i + 1E-44 Next Application.Visible = True End Sub 上記のようにするとプログラム終了時にlabel1に現在のプログレスバーの値が表示されますが、進行中には表示されないのです。これを進行中も表示させるにはどうしたら良いのでしょうか?

  • Labelでプログレスバーの表示

    いつも大変お世話になっております。 動作が重いマクロ、プログラムが多いため、 プログレスバーを表示させたいと思っています。 フォームを20個以上準備しており、 それに対し プログレスバーを使いたいのが10個程度であり、 今後増えるかもしれません。 そのため、標準モジュールを利用し、簡単に プログレスバーを設定できないかと思っています。 '=================== 【標準モジュール Module1】 Sub Bar_progressBarData(Byval UserFormName as string, Byval MaxData as Long,LabelName as string) 'UserFormName 引用するところ?のユーザーフォーム名 'MaxData バーの最大値設定 'LabelName バー表示するラベル名 'ProgressBarの初期設定などをやる End sub '------------------------- Sub Bar_progressBarInt(Byval UserFormName as string, Byval MaxData as Long,LabelName as string) 'UserFormName 引用するところ?のユーザーフォーム名 'MaxData バーの最大値設定 'LabelName バー表示するラベル名 'ProgressBarの値を増やしていく(増加させていくプログラム) End sub '================= 【UserForm Test】 Sub DataChangeGraph() 'ループが多いデータ Call Bar_progressBarInt(Me.Name,10,"Label1")'バーの値を増加させていく End Sub Private Sub UserForm_Initialize() Call Bar_progressBarData(Me.Name,10,"Label1")'初期設定(例として、max10にしました) End Sub Maxの値、プログレスデータに使用する値は グローバルに設定してしまうというのも楽かもしれません。 しかし、この続きの肝心なプログラムが分かりません。 「プログレスバーの作り方」 h ttp://www.h3.dion.ne.jp/~sakatsu/ProgressBarTopic.htm このサイトが良いと評判でしたので、 見ましたが何をしているのか良く分かりませんでした。 Widthを設定? Dim sngBarMaxWidth As Single? そして、私がやりたいこととは少し違うようです。 私がやりたいのは、フォーム上に毎回プログレスバー用のプログラムを書くのが面倒だったので、 標準モジュールとしてSubプロシージャを作成(日本語? そして、それを引用してプログレスバーの設定を簡単に終わらせる ということがしたかったのです。 できれば、ラベルなど Excelに標準で備わっているものを使用したいと思っています。 プログレスバー専用のツール(参照設定などを用いるもの) はその後にエラーが出たとき困るので、使いたくありません。 なんとなく伝わったでしょうか? 回答よろしくお願い致します。 Excel2003 VBA

  • VBA DoEvents関数の働きと使い方を知りたい

    下記のような UserForm上の Module コードを書いてももらったのですが、DoEvents の働きが分からないのです。どなたか分かりやすく説明していただけませんでしょうか? Private i As Integer Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Me.TextBox1.Value = Me.Label1.Caption Then Me.Label2.Caption = "正解です" Else Me.Label2.Caption = "不正解です" End If DoEvents If i < 20 Then i = i + 1 Label_Up Me.TextBox1.Value = "" Cancel = True Else MsgBox "終了です" End If End Sub Private Sub UserForm_Initialize() i = 1 Label_Up End Sub Private Sub Label_Up() Me.Label1.Caption = Sheets("Sheet1").Range("A1:A20").Cells(i).Value DoEvents End Sub

  • VBAでUserFormでProgressBarとLabelを同時表示できない理由は?

    VBAでUserFormをつかってProgressBarとLabelを同時に表示させる。つもりでしたが、ProgressBarが満たされた後Labelが表示されます。その理由と対策を教えて下さい。そのコードを以下に示します。 Sub a() With UserForm1 .Show vbModeless .Label1 = "始めのテキスト" End With s = 1 e = 20000 For i = s To e UserForm1.Label1 = "始めのテキスト" UserForm1.ProgressBar1.Value = i / e * 1000 Next i End Sub お願いします。

  • VBA:ユーザフォームのラベルの指定の仕方教えてください。

     今、ユーザフォームに20個のラベルがあります。それぞれのラベルは、条件によりラベルの表示内容が変更します。そこで、ラベルの表示変更が必要なときにすぐに変更できるようにしたいと考えています。しかし、例えば以下のようなコードを作成するとエラーになり困っています。  Label(i)で、iの番号によりラベルが呼び出されないだろうかと自分なりに作りましたがダメでした。以下のようなループ文中で特定のラベルを呼び出し処理することは不可能でしょうか?  やはり、UserForm1.Label3などのように番号をきちんと書かないとダメでしょうか?本当は、ラベルが82個ありその一つ一つにコードを割り当てるのが大変です。また、きれいなコードで書きたいと思うからです。宜しければ、ご教授願います。 -------------------------------------------- Sub セルの値をラベル表示する() For i = 1 To 20 With UserForm1.Label(i) .Caption = Cells(1, i) End With Next i End Sub

  • エクセルVBA フォームへ動的に貼り付けたボタンのクリックイベントを検知する方法を教えてください

    (1)excel97にのVBAでフォームを作成します。 デフォルトの場合はUserForm1という名前がつきます。 (2)標準モジュールとして下記のコードを作成します。 Sub ボタンを付けて表示() Dim btn As Control  With UserForm1       ’ボタンを"button"という名前で作成します   Set btn = .Controls.Add("Forms.CommandButton.1", "button")   ’ボタンの設定をします   With btn    .Top = 5    .Left = 5    .Height = 20    .Width = 200    .Caption = "push me!"   End With   ’フォームの設定をし、表示します   .Height = 60   .Width = 220   .Show  End With End Sub (3)マクロを実行するとフォームが表示されます。 そこでこのボタン("push me!"と表示されています)をクリックします。 このクリックを検知してマクロを動かしたいのですが可能でしょうか? なおUserForm1に下記のコードを付けてみたのですがクリックは検知できませんでした。 Private Sub button_Click()  MsgBox "You click the button." End Sub

  • エクセルVBA初心者です。

    エクセルVBA初心者です。 ユーザーフォームを使ったセルの上書きについて質問があります。(以下は自分が作成済みの内容)   A  B  りんご 1  みかん 2 これらがセルにあります。この中から上書きしたいものを取得します。 ユーザーフォーム1にリストボックスとコマンドボタンを1つずつ設置し、そのリストボックスにA列の文字を入れました。リストボックスの中から上書きしたい文字を選択し、コマンドボタンを押すと、ユーザーフォーム2が表れ、そこには2つのテキストボックスと1つのコマンドボタンがあります。 ここからが分からないのですが、例えば上書きしたい文字に「みかん」を選び、ユーザーフォーム2のテキストボックス1に「バナナ」、テキストボックス2に「3」といれると   A  B  りんご 1  バナナ 3 このようにしたいのです。 実際はもっと複雑な内容のものを作成しております。しかし上記の疑問が解決すれば、今自分が抱えている問題も解決すると思います。 以下はユーザーフォーム1のコードです。これを提示することにより回答される方が楽になるかどうかは分かりませんが、一応提示しておきます。(lstRowを使っている理由はA列とB列の文字・値が増加していく可能性があるため) Private Sub UserForm_Initialize() CommandButton1.Enabled = False    Dim lstRow As Long    Dim i As Long    Dim q As Long ListBox1.Clear ListBox1.ColumnCount = 2 ListBox1.ColumnWidths = "200 pt"    lstRow = Cells(Rows.Count, 1).End(xlUp).Row q = 0      For i = 2 To lstRow With ListBox1 .AddItem .List(q, 0) = Cells(i, "C").Value End With q = q + 1 Next End Sub ============================================================================ Private Sub CommandButton1_Click() UserForm2.TextBox1.Value = Me.ListBox1.Value Unload UserForm1 UserForm2.Show End Sub

  • Excel VBAについて

    Excel VBAにおいて、Sheetの選択した行によって値を表示するUserFormを変更したいと思っています。 現在以下のようにしたのですが、実行すると「SubまたはFunctionが定義されていません」というエラーが表示されます。 「Controls("UserForm" & x).Label1.Caption =」のところをどのようにしたらよいのでしょうか。 Private Sub CommandButton1_Click()   If ActiveCell.Row = 5 Then     UserForm1.Show     x = 1   ElseIf ActiveCell.Row = 6 Then     UserForm2.Show     x = 2   End If End Sub Private Sub Worksheet_Selection Change(Byval Target As Range)   Controls("UserForm" & x).Label1.Caption = ・・・

  • エクセルVBAのコンボボックス

    エクセル2002使用です。 生年月日とかを入力できるコンボボックスを作っているのですが、同じコンボボックスを5つ作ろうとしています。例えば和暦を入力するには Private Sub userform_initialize() With ComboBox(1) .AddItem "昭和" .AddItem "平成" End sub でうまくいくのですが、2個目から5つ目まで同じものを作成する場合、 With ComboBox(2) ・・・ With ComboBox(3) ・・・ と、コードを記述していかないと駄目なのでしょうか? できれば With ComboBox(1: 5) とか、 変数を使って Private Sub userform_initialize() Dim i As Integer For i = 1 To 5 With ComboBox(i) .AddItem "昭和" .AddItem "平成" End With Next End sub といった具合にまとめたいのですが、コンパイルエラーとなってしまいます。 初歩的な質問で申し訳ないのですが、よろしくお願いします。

専門家に質問してみよう