痔になりやすい生活習慣とは?

こんにちは。
タイトルの件で、投稿いたします。

【現状】
・EXCEL20007を使用しています。
・シート構成は、カテゴリ選択シート、メニューシート、その他20シート程度。
---

現在マクロを使用して、ある機能を実装しています。
【機能】
 カテゴリシートでカテゴリを選択し、メニューシートへ遷移します。
 この遷移時に、カテゴリ名をその他20シートのオートシェイプに反映させた状態で、
 メニューシートを表示したいのです。

以下のマクロでそれは実現しました。
しかし、20シート中数シートで、オートシェイプのテキストが更新されていない場合がありました。
この場合、「カテゴリ名表示」のオートシェイプをクリックすることにより、
オートシェイプのテキストが更新されます。
なぜ、クリックしないと更新されないのでしょうか。
以下のマクロでのテキスト代入後、再度オートシェイプをselectするようにするなど、
そういった1文を追加してみたりしましたが、変化はありませんでした。

'==================================================================
'== '各シートのオートシェイプ「カテゴリ名表示」にカテゴリ名をセット
'==================================================================
カテゴリ名 = カテゴリシート..Range("A1").Value

 For Each sht In Worksheets
   If sht.Visible = True Then
     sht.Activate
     For Each objShp In ActiveSheet.Shapes
       'カテゴリ名表示というオートシェイプがあるかチェック
       If objShp.Name = "カテゴリ名表示" Then
         '存在すれば、カテゴリ名をセット
         sht.Shapes("カテゴリ名表示").Select
         Selection.Characters.Text = カテゴリ名
       End If
     Next
   End If
 Next

'==================================================================

以上、原因をご存じの方や思い当たる節がある方、どうかご教示ください。
わかりにくい部分などがありましたら、ご指摘いただければ追記させていただきます。
よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

ふむ...


最低限の再現コードとしては

Sub test()
  With Workbooks.Add(xlWBATWorksheet).Sheets(1)
    .TextBoxes.Add(100, 100, 100, 20).Text = "aaa"
    .Copy .Parent.Sheets(1)
    .Copy .Parent.Sheets(1)
  End With
End Sub

これでできたBookをActiveにして

Sub test2()
  Dim ws As Worksheet
  Dim s As String

  s = "bbb"
  For Each ws In Worksheets
    With ws.TextBoxes(1)
      .Text = s
      '.Visible = False
      '.Visible = True
    End With
  Next
End Sub

これで再現しますかね?
winVista.Ult.sp2/xl2007sp2.12.0.6565.5003
の環境では確認できます。

winXPsp3/xl2007sp2(詳細未詳)の環境では、同一現象ではないですが
別シートに切り替える時にシートタブをマウスダウンしたままだと
"aaa"でマウスアップのタイミングで"bbb"に更新されます。
先ほどの私のレスはこのXP環境だったので適切な対策ではなかったです。

結論としては
test2のコメントアウト行を活かしてもらうとなんとかなるかな..と。
VisibleプロパティのFalse/Trueの切り換えで対処できるのではないでしょうか。
    • good
    • 0
この回答へのお礼

ありがとうございました、解決いたしました。
オートシェイプのVisibleプロパティのFalse/Trueの切り換えで、対応できました。
再現コードなど、ご助言ありがとうございました。

お礼日時:2011/10/03 10:28

コードに不備があるとすれば、


sht.Activate
sht.Shapes("カテゴリ名表示").Select
の2箇所。
Active系とかSelect系の命令は失敗しやすいので
使わないようにし、オブジェクトに直接命令します。

まぁ、ただし、失敗した場合はデータが更新されないでしょう
から、クリックしようが何しようが更新されないはず。
> この場合、「カテゴリ名表示」のオートシェイプをクリックすることにより、
> オートシェイプのテキストが更新されます。
更新されないから「何度もプログラムを実行して、その後に
クリックしてみた」というのでもないと当てはまらない。

プログラムからは、いつ、どのシートの更新に命令したのか
確認しないと、プログラムの問題なのか、Excel の仕様に
よるものかの切りわけが出来ないです。自分でログを出力して
すべてのシートに命令を出しているか確認して下さい。

命令を出している事が確実に分かったなら、何らかの設定が
違うのでしょう。怪しいのは、
・設定する文字列に含まれる特殊コード
・設定する文字列の長さ
・シェイプのサイズ
・シートの保護、ロックとの組合せ
・Excelの表示更新設定
・Excelの自動計算設定
とか。

テスト用コードを書いて地道に調べるしかないですね。
    • good
    • 0
この回答へのお礼

ありがとうございました。
次回より、ログ出力なども視野に入れて取り組もうと思います。

お礼日時:2011/10/03 10:29

質問のコードをシート小数例でシェイプの四角でやってみましたが、おかしいところは発見できない。


For Each objShp In ActiveSheet.Shapes  の後に
MsgBox objShp.Name
または  MsgBox sht.Name & " " & objShp.Name  
を入れて問題の個所のオブジェクトの名前が「カテゴリ名表示」かチェックする。
もちろんシートの表示・表示しないを勘案すること。
またはそのオブジェクトをとらえて、シートの左上の名前ボックスに「カテゴリ名表示」と出るかどうかチェックしては。
ーー
こういうバグの質問は、所詮原因究明は無理でしょう。
パソコンにも触っつて確認したり出来ず、データやオブジェクトもわからないから。
読者側で追試行が出来る状態を示せなければ。
数日置いておいて適当な解答が付かなければ、あきらめてください。
    • good
    • 0
この回答へのお礼

ご助言、ありがとうございました。

お礼日時:2011/10/03 10:30

画面描画更新がおいついていないのかもしれませんね。


実行中ちらつきますが、下記コードだとどうなりますか?
For Each sht In Worksheets
  If sht.Visible = True Then
    For Each objShp In sht.Shapes
      'カテゴリ名表示というオートシェイプがあるかチェック
      If objShp.Name = "カテゴリ名表示" Then
        sht.Activate
        '存在すれば、カテゴリ名をセット
        objShp.TextFrame.Characters.Text = カテゴリ名
        Application.ScreenUpdating = True
        Exit For
      End If
    Next
  End If
Next
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。

マクロを含むエクセル(EXCEL2000)をHTMLのページからハイパーリンクで呼び出しています。そのエクセルでボタン操作に従い罫線やセルの着色を行っています。しかし、着色結果が更新されません。スクロールバー等で画面を移動すると正しく着色されています。このエクセルを通常に起動した場合は、問題なく動作するのですが、シート全体を更新する方法を教えて下さい。
各関数では、以下のスクリーンアップデータの処理を入れています。
Application.ScreenUpdating = False
    (処理)
Application.ScreenUpdating = False

Aベストアンサー

たぶん、EXCEL独特の問題だと思うのですが、HTML の場合、すでに色の部分を表面上で使用しているので、それでメモリが占有させているのではないかと私は思っています。

他にも、

 ActiveWorkbook.HTMLProject.RefreshDocument True

というのがありますね。
ホスト アプリケーション内のブックに含まれる HTML プロジェクトを更新する、というのがありますね。

Q連続で印刷すると画像が更新されない(Excelのイメージコントロール)

いつもお世話になります。
エクセルのイメージコントロールを使用しているのですが、
なかなかうまく行かないので、アドバイスをお願いします。

シートにイメージコントロールをいくつか(8個)配置しました。
マクロで LoadPicture を使用し画像を読み込ませました。
Rangeで範囲を指定して印刷しました。
一旦、Sheet1.Image1.Picture = Nothing と開放しました。
そのイメージコントロールに別画像を LoadPicture させました。
同様に印刷させましたが、画像は最初に読み込ませたもののままです。
マクロが終了して見ると、最新の画像に更新されているのですが、
印刷したものでは(プリビューでも)更新されません。
Redraw させたり Refresh させるコマンドはないかと思いましたが見つかりません。
同じマクロで画像のコメントをセルに表示させているのですが、
こちにはどんどん更新しています。
画像だけが、最初に読み込んだ画像のままで印刷されてしまいます。
印刷範囲は常に同じです。

原因なり対処法なりをお教え下さいますようお願いします。

いつもお世話になります。
エクセルのイメージコントロールを使用しているのですが、
なかなかうまく行かないので、アドバイスをお願いします。

シートにイメージコントロールをいくつか(8個)配置しました。
マクロで LoadPicture を使用し画像を読み込ませました。
Rangeで範囲を指定して印刷しました。
一旦、Sheet1.Image1.Picture = Nothing と開放しました。
そのイメージコントロールに別画像を LoadPicture させました。
同様に印刷させましたが、画像は最初に読み込ませたもののままです。
...続きを読む

Aベストアンサー

こんにちは。

原因はお分かりのようなので回避策を。。

再描画させてから印刷させる為にPrintOut (or PrintPreview)の前に次の2行を挿入


 For i = 1 To 1000: DoEvents: Next i

 Application.Wait Now() + TimeValue("00:00:03")


Forのカウンターの上限は適宜変更。
また、Application.Waitはなくても上手くいくとは思いますが念のため。。

DoEvents,Waitはご自分でお調べください。
以上です。

QVBAマクロで、図形等のオブジェクトを選択(特定)する方法ってありますか

こんにちは。VBAマクロを少しかじっています。
顔写真付きの従業員の検索システムを作りました。名前を入力(選択)したら、データシートから職員コード、住所、電話番号などの情報を検索し検索画面に表示します。この際、別のシートに顔写真を貼り付けたもの(1セルに1枚。セルに従業員名を入力してある。)から、VLOOKUP関数を使ってセル照会することで、画像も同時に表示することができます。
別の職員に切り換えたり、クリアする場合の画像の処理は、削除用のシートを用意し、そこにセルごと移動し、終了時にシートごと削除する方法をとりました。(当然、確認用のダイアログボックスが表示されます。)
前置きが長くなりましたが、問題は、用済みの画像を選択するプロシージャがあれば、あえて削除用のシートを用意する必要はありません。セルの場合は、Rangeプロパティやcellsプロパティで特定できますが、画像などのオブジェクトをセル番地などを使って特定する方法ってあるのでしょうか。
因みに、画像の選択処理を、マクロ記録でプロシージャを作成したら、
ActiveSheet.Shapes("Picture 1").Select などとなります。
よろしくお願いします。

こんにちは。VBAマクロを少しかじっています。
顔写真付きの従業員の検索システムを作りました。名前を入力(選択)したら、データシートから職員コード、住所、電話番号などの情報を検索し検索画面に表示します。この際、別のシートに顔写真を貼り付けたもの(1セルに1枚。セルに従業員名を入力してある。)から、VLOOKUP関数を使ってセル照会することで、画像も同時に表示することができます。
別の職員に切り換えたり、クリアする場合の画像の処理は、削除用のシートを用意し、そこにセルごと移動し、終了時...続きを読む

Aベストアンサー

検索シートにシェイプが1つしかなければ
ActiveSheet.Shapes(1).Select
で選択
ActiveSheet.Shapes(1).Delete
で削除できます。

QVBA オブジェクトが空かどうか判定する

皆様のお知恵を拝借させてください。

エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト
が入っているかどうか検査したいのですがどうしたらいいでしょうか。

例えば---
Dim a As Workbook
If a <> nothing then ←この部分が分からない。このままだとエラー。
処理
End if
---------
環境
エクセル2003
WinXPsp1

Aベストアンサー

もし、aが空だったら
If a Is Nothing Then 

もし、aが空じゃなかったら
If Not a Is Nothing Then

Qバーコードコントロールが印刷時に反映されない

いつもご丁寧な回答をくださりありがとうございます

エクセルにバーコードを埋めて書類を作っているのですが
(主に上紙に使用)

バーコードのリンクセルで指定したセルに新しい番号を入れ
デザインモードを終了すると

画面上は新しいバーコードが表示されるのですが
印刷プレビューと印刷そのものにうまく反映してくれません

なにか設定的なものが間違えているのでしょうか

文章が稚拙で申し訳ありませんが回答のほどよろしくお願いします。

Aベストアンサー

エクセルにおいてはバーコード画像は、「セルの値」ではないという認識が質問者にはありますか。
いわゆる「オブジェクト」扱いです。セルの値とは別世界のものです。
エクセルは「セルの値」を中心に処理するソフトです(エクセルの進歩の沿革からも)。これはエクセルの基礎的なことです。
ですからエクセルに画像を印刷する機能があるにしても、特別な指定をしないとをしないとだめと考えるべきです。
画像で右クリクー図の書式設定ープロパティーオブジェクトを印刷するーOK です。
この後、印刷プレビューをだすー印刷するでどうなりますか。これで解決しますか。
http://pc.z-kikaku.jp/excel/logs/2007/04/post-7.php
など。
ーーー
>バーコードのリンクセルで指定したセルに新しい番号を入れ
の意味を、実例を出して、説明しておいたほうが良いのでは。

QExcelのシート上のShapeにイベントは設定できる?

タイトル通りですが、Shapeにイベントを発生させることは
できるのでしょうか?

Click、MouseMove とかですが・・・

よろしくお願いします。

Aベストアンサー

こんばんは。
私は、うまく言葉では説明できないので、以下のようなサンプルを作ってみました。
".OnAction"  で設定させます。ただ、これが、Sheet1 などのローカルモジュールですと、
マクロ名は、それぞれのシートを指定しないといけません。

'標準モジュール
Sub TestShape()
  Dim x1 As Double, y1 As Double
  Dim x2 As Double, y2 As Double
  Dim dWidth As Double, dHeight As Double
  'アクティブセルから、四角形の設定
  With ActiveCell
    x1 = .Left
    y1 = .Top
  End With
  With ActiveCell.Offset(5, 3)
    x2 = .Left
    y2 = .Top
  End With
  dWidth = x2 - x1
  dHeight = y2 - y1
  
  With ActiveSheet.Shapes.AddShape(msoShapeRectangle, x1, y1, dWidth, dHeight)
    .OnAction = "SubTest1"
  End With
End Sub
'--------------------------------
Sub SubTest1()
  MsgBox "SubTest1マクロが実行されました", 64
End Sub

こんばんは。
私は、うまく言葉では説明できないので、以下のようなサンプルを作ってみました。
".OnAction"  で設定させます。ただ、これが、Sheet1 などのローカルモジュールですと、
マクロ名は、それぞれのシートを指定しないといけません。

'標準モジュール
Sub TestShape()
  Dim x1 As Double, y1 As Double
  Dim x2 As Double, y2 As Double
  Dim dWidth As Double, dHeight As Double
  'アクティブセルから、四角形の設定
  With ActiveCell
    x1 = .Left
    y1...続きを読む

QExcelのVBA。public変数の値が消える

VBAについて。Excelの2003や2007を使っています。標準モジュールで public 変数を定義しました。 ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。全く同じマクロで、この現象が起こることと、起こらないことがあります。excelの2003でも2007でも、同じ現象が起こります。簡単なマクロで再現性のある具体的なものを示したいと思い、試しましたが、できませんでした。簡単なマクロでは、きちんとパブリック変数は保持されています。問題のあるマクロはかなり長いものなので、とても示せません。問題がどこにあるのかわかりません。このマクロで不都合があるという具体的なマクロを示すことができない状態での質問で、申し訳ありません。
また、このようなプログラミングをしていて思ったのですが、ユーザーフォームに対してユーザーが任意の引数を渡す方法あるいは、ユーザーフォームから引数を受け取る方法はあるのですか?今は、pubulic変数を用いたり、具体的なセルに値を代入したりしていますが、どう考えてもそれはエレガントではないし、汎用性もないと思います。引数で引き渡すのが一番綺麗でいいとは思うのですが、それが可能かどうかわかりません。

VBAについて。Excelの2003や2007を使っています。標準モジュールで public 変数を定義しました。 ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。全く同じマクロで、この現象が起こることと、起こらないことがあります。excelの2003でも2007でも、同じ現象が起こります。簡単なマクロで再現性のある具体的なものを示したいと思い、試しましたが、できませんでした。簡単なマクロでは、きちんとパブリック変数は保...続きを読む

Aベストアンサー

IDは違うけれども、同じ内容の質問のようですね。
http://oshiete.goo.ne.jp/qa/6420530.html

具体的にこんなことをしています、ということをおっしゃれば、話は変わるかとも思います。
今のままでは、いくら説明しても、たぶん納得いかないだろうと思います。

最初に、#3の方のMSのサポートの文章で、
>[VBA] Public 宣言された変数の有効期間
この内容、ご質問者さんは、意味を誤解しているようです。

「ほとんどの場合、プロシージャ終了後も値は保持されますが、
 ……Public 変数がアプリケーション終了時まで有効であること
 を期待する VBA マクロの実装は、推奨されません。」

どうして、保持した変数がなくなってしまうか、いろんな理由はあっても、完成したマクロでは、原因はひとつで、End Sub を通っていないままに終了しているからです。

 「ある Office ドキュメントが VBA のマクロを含む場合、…… Public 変数
  の値が有効である期間は、あるプロシージャの実行を開始
 し、そのプロシージャが "End Sub" で終了するまでの間のみです。」

この文章は間違いです。その話のままだったら、Public 変数など意味がなくなってしまいます。値だって確保しているし、変数は動的です。しかし、実務上、構造化マクロで、きちんと作られたマクロの流れ(ルーチン)が通る間だけだと思ってよいです。

>ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。

Public 変数が、リセットされるというのは、マイクロソフトの文章は間違いに近いです。これは、極論すると、不完全なマクロだということです。しかし、本当に完全なコードを提供出来るかというのは、それは誰も自信などありません。だから、そういう方法を避けるわけです。

Public 変数は、標準モジュールを経由して、ローカルのUserForm に供給を受けるけれども、それを戻すということはしないのです。

図式化するとこうなります。

・ローカルで発生した値 →標準モジュールのPublic 変数 →UserFormのローカルのプロシージャ
・標準モジュールのPublic 変数 → UserFormのローカルのプロシージャ

※ただし、起動時の一回きり、それ以上の持ち回しはしない。逆もしない。

「ユーザーフォームに対してユーザーが任意の引数を渡す方法
 ユーザーフォームから引数を受け取る方法はあるのですか?」
出来ないわけではありませんが、これらは、変数で渡すということはしないということです。

>ただ、ユーザーフォーム aUS 全体で参照し値を変更できる 変数a のようなものを、使えたらいいなあ、と思い、

理屈では、一旦、標準モジュールのPublic 変数に送っておいて、そこから他のプロシージャ等に送ればと思いますでしょうが、それはしないということです。ルーチンが別だからです。

私の基本的な設計の考え方を示しておくと、UserForm自身とか、その中にあるものは、OLEオブジェクトのインスタンスです。つまり、モノ(オブジェクト)がある限りは、値は確保しているのです。だから、UserFormが残っている以上は、変数ではなくて、モノから、値を取得するのです。そのためには、UserForm はModalモードを、Offにしておくのが良いわけです。

例えば、UserForm1.TextBox1.Value とかで取れるわけです。

これは、システム設計の話で、それを見れば分かっていただけます。非表示のワークシートのセルに書くような話は、それは状況(渡す変数の数)によります。ただ、わざわざワークシートのセルに代入する必要はないということです。そのような方法はシステム設計では全体にリスクを高くするので賛成出来ないです。

私の失敗の経験から、Public 変数については、ひとつのルーチン以上に用いないことです。また、動的には用いないことです。一回きりの静的な変数として使うべきです。静的といっても、Static 変数の意味ではなく、文字通り変数を変化させないということです。ただし、時間の間隔やカウントなどの単純なものは別です。

Public 変数が空かどうかチェックする方法も考えられますが、意味がありませんから、それなら、参照渡しにすればよいのです。

IDは違うけれども、同じ内容の質問のようですね。
http://oshiete.goo.ne.jp/qa/6420530.html

具体的にこんなことをしています、ということをおっしゃれば、話は変わるかとも思います。
今のままでは、いくら説明しても、たぶん納得いかないだろうと思います。

最初に、#3の方のMSのサポートの文章で、
>[VBA] Public 宣言された変数の有効期間
この内容、ご質問者さんは、意味を誤解しているようです。

「ほとんどの場合、プロシージャ終了後も値は保持されますが、
 ……Public 変数がアプリケーション終了時...続きを読む

Qオートシェイプが消えたり出たりする

Windows 7+ Excel 2013を利用しています。
オートシェイプを200個位(四角、丸)入れています、重ね合わせはありません。
エクセルで職場のレイアウトを作成・更新しているのですが、
突然、全てのオートシェイプが表示されなくなり、オートシェイプがあるあたりの
セルをクリックしたら、幾つかのオートシェイプが表示され、マウスを動かすと
オートシェイプが消えてしまいます。
また、別のセルをクリックしたら、先とは、違うパターンで幾つかオートシェイプが
表示され、マウスを動かすと、何個かオートシェイプが表示されたまま、他のが消えます。

オブジェクトの選択と表示では、全て表示になっていますが、一旦、全て非表示にして、全て表示にしても、全く、オートシェイプが表示されません。
慌てて、保存せずに、終了して、パソコンを再起動、変になったエクセルブックを開いても直っていません。

仕方なく、先月のブックをコピーして、修正しています。

変になったエクセルブックですが、他のパソコン何台かで開いても同じようになります。

マクロでもあるのかと思い、Alt + F10を押してみましたが、コードは書かれていません。

諦めかけていたら、調べていないPCから開いたら、表示されています。
そこで、そのPCで上書き保存してから、変になったPCで開いたら、表示されています。

何故なんでしょうか?
エクセルブックは、壊れてなかったんでしょうか?

Windows 7+ Excel 2013を利用しています。
オートシェイプを200個位(四角、丸)入れています、重ね合わせはありません。
エクセルで職場のレイアウトを作成・更新しているのですが、
突然、全てのオートシェイプが表示されなくなり、オートシェイプがあるあたりの
セルをクリックしたら、幾つかのオートシェイプが表示され、マウスを動かすと
オートシェイプが消えてしまいます。
また、別のセルをクリックしたら、先とは、違うパターンで幾つかオートシェイプが
表示され、マウスを動かすと、何個かオートシェイ...続きを読む

Aベストアンサー

ご質問の現象は、おそらく画像などのオブジェクトが大量にあり描画に問題があるパターンのように思われます。
ひどます、Alt+T,OのショートカットでExcelのオプション画面を表示し「詳細設定」の表示の「ハードウェアグラフィックアクセラレータを無効にする」のチェックを入れてみてください。

#また、ご使用のファイルが互換モードで保存されているなら、2013形式で保存してみてください。
またオブジェクトの数は実際にシート上のオブジェクトの数と一致しているか(見えないオブジェクトがないか、ファイルサイズが異常に大きくないか)確認してみてください。

Qマクロで選択した図形の選択状態を解除するには

Excel97,Windows98SEを使用しています。

シート上に作成したコントロールツールのコマンドボタンをクリックすると、
シート上の全ての図形を選択して、順序を最背面にするというマクロを作成したのですが、
選択した図形のハンドルが消えません。
図形選択を解除して、B26セルを選択したいのですが、どうしたらよいでしょうか?

Private Sub CButton_gyou_Click()
ActiveSheet.DrawingObjects.Select
Selection.ShapeRange.ZOrder msoSendToBack
Range("B26").Select
End Sub

ご存知の方、どうぞよろしくお願いいたします。

Aベストアンサー

コントロールツールのコマンドボタンをクリックすると、そのクリックしたコマンドボタンにフォーカスが移ってしまうのが原因かと…
これではどうでしょうか?

Private Sub CButton_gyou_Click()
Range("B26").Select
ActiveSheet.DrawingObjects.Select
Selection.ShapeRange.ZOrder msoSendToBack
Range("B26").Select
End Sub

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

よろしくお願いいたします。

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報