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

このQ&Aのポイント
  • 動作が重いマクロ、プログラムが多いため、プログレスバーを表示させたいと思っています。
  • フォームを20個以上準備しており、それに対しプログレスバーを使いたいのが10個程度であり、今後増えるかもしれません。
  • プログレスバーを設定するための標準モジュールを利用したいと考えています。Excelの標準ラベルなどを使用して、簡単にプログレスバーを設定したいです。
回答を見る
  • ベストアンサー

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

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

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

#2ですが、LabelはFrameの中に入れる必要があります。位置はコードで設定しますので、Frameの中に収まっていればOKです。 Label位置はFrame内の座標で設定してありますので、Frameに属していないと判断されると、UserFormの左上に配置されると思います。 ところで、コードはお望みの事を行っているつもりです。標準モジュールの場合との違いを画像として添付します。UserForm側からは、クラスのインスタンス(クラスから生成したオブジェクト)にFrameとその中にあるLabel2個を渡し、ループの最大数を設定してやれば、以降For ~ Nextの重たい処理のループを回す毎にCountUpだけしてやれば、変数はインスタンス側で管理してくれるのが、標準モジュールの場合との違いです。

satoron666
質問者

お礼

返事が遅くなり申し訳ありません。 回答ありがとうございました! 試すのに時間がかかりそうなので、 これで回答を締め切りたいと思います。 また何かあったら質問させて頂きます^^ ありがとうございました!

その他の回答 (2)

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

#1です。 UserFormにはフレームと、ラベル2個を置くだけで、設定はすべてクラスモジュール側で行う様にしてみました。メンバーは最小限に抑えていますが、プロパティを外部に出せば、インスタンス毎に文字色を変えるとかも出来ます。 '☆Class1 モジュール '出典http://www.h3.dion.ne.jp/~sakatsu/ProgressBarTopic.htm Private myFrame As Object Private myLabel1 As Object Private myLabel2 As Object Private myLoopCount As Long Private myCount As Long Private sngBarMaxWidth As Single Private intPercent As Integer Private intBeforePercent As Integer Public Sub setObjects(newFrame As Object, newLabel1 As Object, newLabel2 As Object) Set myFrame = newFrame Set myLabel1 = newLabel1 Set myLabel2 = newLabel2 myCount = 0 intBeforePercent = 0 With myFrame .Height = 22 .Width = 150 .Caption = "" .SpecialEffect = fmSpecialEffectSunken .BorderStyle = fmBorderStyleNone End With sngBarMaxWidth = myFrame.Width - 2 With myLabel1 .Caption = "" .Top = 1 .Left = 1 .Height = myFrame.Height - 2 .Width = 0 .BackColor = &H800000 End With With myLabel2 .Caption = "" ' %表示用ラベル .Top = 0 .Left = 0 .Width = myFrame.InsideWidth .Height = myFrame.InsideHeight .TextAlign = fmTextAlignCenter .BackStyle = fmBackStyleTransparent .Font.Size = 18 .ForeColor = RGB(&HFF, &HCC, &H0) End With End Sub Public Property Let setLoopCount(newLoopCount As Long) myLoopCount = newLoopCount End Property Public Sub countUp() If myFrame Is Nothing Then MsgBox "Objectがセットされていません" Exit Sub End If myCount = myCount + 1 intPercent = Int(myCount * 100 / myLoopCount) If (intPercent <> intBeforePercent) Then myLabel1.Width = sngBarMaxWidth * intPercent / 100 myLabel2.Caption = intPercent & "%" myFrame.Repaint ' バーの再描画 End If intBeforePercent = intPercent End Sub

satoron666
質問者

お礼

補足をさらにします。 プログレスバー用のフォームを作成しましたが、 バーが毎回上に表示されます。 ウィンドウの上の部分です。 その部分には特に何も無く、 Label1、Label2共にフォーム下のほうに置いたのですが 毎回同じ部分で表示され、 添付して頂いた画像のようになりません。 設定方法が悪いのでしょうか;

satoron666
質問者

補足

>各UserFormにフレーム+ラベルでプログレスバーもどきを設けたいけれど、個々にコードを書くのは面倒くさいというご趣旨でしょうか。 個々にコードを書くので大丈夫なのです。 ただ、標準モジュールで初期設定などが出来れば良いという考えでした。 標準モジュールに下記のようなデータをセット?することにより ●フォーム名、Label名やフレーム名などを取得 ●取得した場所のプログレスバー初期設定 ●プログレスバーのMax値なども設定 【標準モジュール 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 ’=================-- 上記のような感じです。 こうすると、初期設定の手間が省ける上に、 Labelの名前なども引用してしまうため気になりません。 (各フォームで使っているラベル個数が違います) 下手な説明で大変申し訳ないのですが、 伝わりましたでしょうか?

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

各UserFormにフレーム+ラベルでプログレスバーもどきを設けたいけれど、個々にコードを書くのは面倒くさいというご趣旨でしょうか。 クラスモジュールにするのが良いと思いますが、吟味している時間がとれません。とりあえず試験をしてみたというレベルですが投稿させていただきます。(プロパティのセット漏れ等のエラー処理も何もありません) クラスモジュールの作り方は下記等をご参照下さい。 http://codezine.jp/article/detail/499 '☆Userformモジュール Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Dim myClass As Class1 Dim countUp As Long 'あくまで動作試験用 Private Sub CommandButton1_Click() Dim i As Long For i = 1 To countUp DoEvents: DoEvents: DoEvents myClass.countUp Sleep 200 Next i End Sub Private Sub UserForm_Initialize() Set myClass = New Class1 countUp = 100 With myClass .setObjects Me.Frame1, Me.Label1, Me.Label2 .setLoopCount = countUp End With End Sub '☆Class1 モジュール 'http://www.h3.dion.ne.jp/~sakatsu/ProgressBarTopic.htmを若干アレンジさせていただきました。 Private myFrame As Object Private myLabel1 As Object Private myLabel2 As Object Private myLoopCount As Long Private myCount As Long Private sngBarMaxWidth As Single Private intPercent As Integer Private intBeforePercent As Integer Public Sub setObjects(newFrame As Object, newLabel1 As Object, newLabel2 As Object) Set myFrame = newFrame Set myLabel1 = newLabel1 Set myLabel2 = newLabel2 With myLabel1 .Top = 1 .Left = 1 .Height = myFrame.Height - 2 .Width = 0 .BackColor = &H800000 End With myLabel2.Caption = "" ' %表示用ラベル sngBarMaxWidth = myFrame.Width - 2 myCount = 0 intBeforePercent = 0 End Sub Public Property Let setLoopCount(newLoopCount As Long) myLoopCount = newLoopCount End Property Public Sub countUp() myCount = myCount + 1 intPercent = Int(myCount * 100 / myLoopCount) If (intPercent <> intBeforePercent) Then myLabel1.Width = sngBarMaxWidth * intPercent / 100 myLabel2.Caption = intPercent & "%" myFrame.Repaint ' バーの再描画 End If intBeforePercent = intPercent End Sub

satoron666
質問者

補足

回答ありがとうございます。 クラスの使い方の参考サイトまで、ありがとうございます! ひとつ言い忘れていたのですが、 プログレスバーを表示しているときなどに Excelファイルを操作 (シートをクリックしたり) 出来なくしたいと思っています。 現段階ではモーダレス?ではないので シートを操作することは出来なくなっています。 お恥ずかしい話ですが、 ActiveSheetを多用しておりまして、 編集最中なのです。 ActiveSheet ⇒ WorkSheet("Sheet1") のように変更中です。 (シート名が多量にあるため、  変更するのに時間がかかりそうです) これが終わり次第、教えて頂いたプログラムを やってみたいと思います! とても時間のかかる作業だったとは思いますが、 ありがとうございました! 毎回毎回、mitarashi様にはお世話になってます; 本当に、助かります!

関連するQ&A

  • (;゜д゜)ユーザーフォームでプログレスバーを使いたいが・・・存在していない!!(;゜д゜)

    お世話になっております。 プログレスバーについて教えて下さい。 ユーザーフォームを使いそこにプログレスバーが配置できるとネット上で調べたので使おうと思いました。 ところが・・・ツールボックスにプログレスバーがありません(;゜д゜)ァ.... 探してみたのですがどこにも見つかりません。エクセルが壊れているのでしょうか? また、プログレスバーについてどういう風にやったらできるのかというのを見ていたのですがどう動いているのか理解力が無いため理解が出来ません・・・ 下記のようなコードがあり作動している間はバーを動かしたいのですがどうしたらいいでしょうか・・・ Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range) Dim r As Range For Each r In Target MyProc r Next End Sub Sub MyProc(Target As Range) ・ ・ ・ ・ ・ End Sub

  • 標準モジュールにpublicで宣言するしかない?

    フォームモジュールと標準モジュールで同じ変数を使って値を行き来したい場合、 標準モジュールにpublicで宣言するしかないのでしょうか? 【フォームモジュール】 Private Sub cmd_コマンド0_Click() test = "aaa" Call 標準モジュールtest End Sub 【標準モジュール】 Public test As String Sub 標準モジュールtest() MsgBox test End Sub でいいのですか?

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

    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に現在のプログレスバーの値が表示されますが、進行中には表示されないのです。これを進行中も表示させるにはどうしたら良いのでしょうか?

  • VBA 標準モジュールとフォーム

    ある標準モジュール内で生成した変数の値をフォームのコマンドボタンをクリックしたら表示されるプログラムはどうやってつくるのですか? 標準モジュール sub test() dim a as integer dim b as integer dim sum as string a=5 b=1 sum=a+b End sub フォームのコマンドボタンクリック Sub CommandButton1_Click() MsgBox sum End Sub 標準モジュールで計算した答えがフォームのコマンドボタンをクリックしたら答え6が表示されるようにしたいのですが、どうしたらできますか?

  • 定義した関数がフォームで使用できません。

    Visual Basic初心者です。 VB6.0を使用しています。 標準モジュールで関数を定義したのですが、フォームでその関数を使用することができません。 標準モジュールで定義した関数をフォーム上で使用するには、どのような点を変更すればよろしいでしょうか。 フォーム上コード抜粋 Sub test() Dim stats As Long Dim vi As Long stats = viVPrintf(vi, "*RST" + Chr$(10), 0) End Sub 標準モジュール上コード抜粋 Global Const VI_SPEC_VERSION = &H400000 Declare Function viVPrintf Lib "VISA32.DLL" Alias "#270" (ByVal vi As Long, ByVal writeFmt As String, params As Any) As Long

  • ByVal Cancel As MSForms.R

    (ByVal Cancel As MSForms.ReturnBoolean)の意味を教えてください。 エクセルのユーザーフォームで、 クリックした場合は、フォームモジュールに Private Sub UserForm_Click() End Sub のひな形が出来て、 ダブルクリックした時は Private Sub UserForm_DblClick(ByVal Cancel As MSForms.ReturnBoolean) End Sub が出来上がります。 なぜ、DblClickの時はカッコの中に色々入るのでしょうか? それにByValは値渡しの時に使う言葉ですよね? DblClickの時は、何かの値を渡しているのですか?

  • 再度,ExcelVBA,public変数が消える

    大変申し訳ありません。一度、この件で質問し、その回答を締め切ったばかりなのですが、やはりもう少し知りたくて質問させていただきます。 ある方の回答への補足で、以下のマクロを具体例としてあげました。ただし、以下のマクロは、時にはpublic変数が消えてしまいますが、しかし、消えないこともあります。 消える理由として、 回答していただいたものから考えて、 1.End Sub を通っていないままに終了しているから 2.不完全なマクロ 3.きちんと作られたマクロの流れ(ルーチン)ではない流れがある 4.「Public 変数は、標準モジュールを経由して、ローカルのUserForm に供給、しかし、それを戻すということはしない。つまり、a.ローカルで発生した値 →標準モジュールのPublic 変数 →UserFormのローカルのプロシージャ b.標準モジュールのPublic 変数 → UserFormのローカルのプロシージャ   ※ただし、起動時の一回きり、それ以上の持ち回しはしない。逆もしない。」この件に関して、以下のマクロに問題がある。 この様なことを考えました。 4.の場合、testMainからtest1.showを呼び出し、a=10とするが、このaの値は、testMainには戻らない(戻らないことがある)のでしょうか、あるいは、testMainのend sub の後は値が保障されないのでしょうか。 あるいは、 Worksheet_SelectionChange でend sub で終わっているので、それ以降は値が保持されないのでしょうか。 あるいは、どこかに欠陥のあるマクロなのでしょうか。 http://okwave.jp/qa/q6420530.html への回答のno.6の例のマクロでendをコメントにするかしないかで、endをコメントにした場合はend subで終わった後、値が保持されています。このこととも合わせて考えると、どこに問題があるのか、どのような問題があるのか、よく分からなくなってしまいます。 よろしくお願いします。 標準モジュールにーーーーーーーーーーーーーーーーー Option Explicit Public a As String Sub ini() MsgBox "初期化します" a = "5" End Sub Sub testMain() If a = "" Then ini MsgBox a test1.Show End Sub test1 というフォームのモジュールにーーーーーーーーーーーーーー (このフォームに コマンドボタンがあります。) Private Sub CommandButton1_Click() a = "10" Unload Me End Sub シートのモジュールにーーーーーーーーーーーーーーーーー Option Explicit Private Sub Worksheet_SelectionChange(ByVal Target As Range) testMain End Sub

  • vb.net コピーの進捗をプログレスバーで

    質問ばかりでもうしわけないのですが タイトルにあるようにコピーの状況を プログレスバーで表示できたらなと思い作成したのですが うまく動きません。 プログレスバー自身単独では動くのですがコピーと合わせると フリーズしてしまいます。 プログラミング経験と発想力が乏しいのでご教授いただけたら幸いです Private Sub Bt_1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bt_1.Click Dim fname1 As String = "C:\フォルダ名A" Dim fname2 As String = "C:\フォルダ名B" Dim ber1 As Integer If IO.Directory.Exists(fname1) = True Then Me.Lb_1.Text = "テキスト文字" For ber1 = 0 To 20 Me.ProgressBar1.Value = ber1 System.IO.File.Copy("コピー元テキストファイルA", "コピー先テキストファイルA", True) My.Computer.FileSystem.CopyDirectory("コピー元フォルダA", "コピー先フォルダA", True) My.Computer.FileSystem.CopyDirectory("コピー元フォルダB", "コピー先フォルダB", True) Next ber1 If IO.Directory.Exists(fname2) = True Then System.IO.File.Copy("コピー元ファイルB", "コピー先ファイルB", True) End If MessageBox.Show("終了報告テキスト", "タブ名") ' System.IO.Directory.Delete("コピー元", True) Me.ProgressBar1.Value = 0 Application.Exit() こんな感じで作成しております。 ファイル自身が1GBぐらいあるので フリーズしていないかプログレスバーや%表示でしらせたいので 教えていただけると助かります。 よろしくお願いします。

  • 標準モジュールからフォームをコントロールしたい

    こんにちは。 標準モジュールからフォームのリストボックスに文字を追加したいんですが、うまくいきません。 まず、button1をクリックすると、共通モジュールのサブルーチンを呼び出します。そして引数"0"を渡すと、Form1のListBox1に"hello"を追加したいのです。 実行させると、エラーはでないのですが、追加されるはずの"hello"がListBox1に追加されません。 たぶん     frm1.ListBox1.Items.Add("hello") あるいは    Dim frm1 As New Form1() あたりの宣言の仕方がまずいのだと思うんですが... どなたか、ご教授よろしくお願いします。 ■共通モジュール Module Module1 Dim frm1 As New Form1() Sub PC(ByVal PCrecieve As String) If PCrecieve = "0" Then frm1.ListBox1.Items.Add("hello") End If End Sub End Module ■フォーム Public Class Form1 Inherits System.Windows.Forms.Form Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Call PC("0") End Sub End Class

  • エクセルVBA イベントプロシージャに引数を渡せま

    お世話になります。 エクセル2003/XP 使用です。 イベントプロシージャに引数を渡せまるかどうか教えていただけますでしょうか? 下記のコード中の変数mysheetnameを ユーザーフォーム、→ CommandButton1のプロシージャに 引数として渡して行きたいのですが、 実行すると、一番最初のWorkbook_SheetBeforeRightClickの時点で、 コンパイルエラー:  プロシージャの宣言が、イベントまたはプロシージャの定義と一致していません。 とエラー表示されます。 イベントプロシージャに引数を渡すことはできますでしょうか? ---------- ThisWorkBook内 ---------- Public mysheetname As String Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) mysheetname = ActiveSheet.Name UserForm1.Show (mysheetname)     '←変数mysheetnameの値をユーザーフォームに渡したい。 End Sub ---------- ユーザーフォーム ---------- Private Sub UserForm_Initialize(ByVal mysheetname As String ) 処理 End Sub Private Sub CommandButton1_Click(ByVal mysheetname As String ) 処理 End Sub ’--------- ここまで 引数について少し理解し始めたばかりの者です。 よろしくお願いします。

専門家に質問してみよう