質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

703閲覧

VBA フォームを複数表示した際、繰り返し実行マクロが停止する

soepu

総合スコア41

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2018/05/31 20:07

前提・実現したいこと

vbaでユーザーフォームにトグルボタンが配置してあります。
トグルボタンがONの時間を計測するプログラムを作りました。
(押されている間、1秒毎に数字が加算されていく)

この状態で、もう一つ別のフォームを表示し、フォームをドラッグしようとすると
ドラッグ状態では繰り返しタイマーがストップ(数字が加算されない)してしまう
のですが、何が原因でしょうか?
解決策はありますでしょうか?

該当のソースコード

vba(ユーザーフォーム上)

1Private Sub tog1_Click() 2 If tog1.Value = True Then 3 Dim waitTime As Variant 4 5 waitTime = Now + TimeValue("0:00:01") 6 Application.Wait waitTime 7 8 Call macro1 9 End If 10 11End Sub 12 13---標準モジュール上 14Sub macro1() 15'一定間隔で実行する 16'OnTimeメソッドを使う 17 18 If frmStopTIme.tog1.Value = True Then 19 '1秒後にmacro100810aを実行 20 Worksheets("工程表").Range("A11") = Worksheets("工程表").Range("A11") + 1 21 frmStopTIme.Label1.Caption = Worksheets("工程表").Range("A11") 22 Application.OnTime Now() + TimeValue("00:00:01"), "macro1" 23 24 End If 25 26End Sub 27

試したこと

フォームのモーダル表示

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

VBAはシングルスレッドなので、2つのコードを並行して実行できません。
また、ドラッグなどのマウス操作をしているとき、OnTime の指定時間になってもマクロは実行されません。

トグルボタンがONの時間を計測するプログラムを作りました。

上記の仕様上、OnTime では正確な時間は計測できません。

下記なら、Onの時間を正確に表示できます。

VBA

1Option Explicit 2Dim sTime As Date 3 4Private Sub tog1_Click() 5 If Tog1.Value Then 6 sTime = Now 7 Else 8 Me.Label1.Caption = DateDiff("s", sTime, Now) & "秒間Onでした。" 9 End If 10End Sub 11

投稿2018/06/01 00:23

編集2018/06/01 01:09
hatena19

総合スコア33620

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

VBAのプログラム等は、Excelのメインスレッド(単一のスレッド)で実行されます。
同時に2つ以上の動作が行われることは無いということです。

質問に書かれているのは、以下のような経緯で起きたものと考えられます。
1)1つ目のフォームでマクロの実行が行われていた
2)ドラッグされたことでマクロの実行が中断した
3)ドラッグ動作のほうが実行された

フォームのマクロを実行する事と、ドラッグ動作の間に依存関係がないのであれば、
・元のExcelファイルのコピーを作る(同一ファイル名にならないようにコピーしたほうのファイル名を変更する)
・それぞれのExcelファイルを開き、マクロの実行とドラッグ動作を行う(別のExcelファイルなので、それぞれのメインスレッドで実行される)
・必要があれば、コピーしたほうのファイルから必要なデータを元のExcelに反映する。
という手順が可能だと思います。

<参考情報>
Excel でのマルチスレッド再計算 のページには、以下のように説明されています。

Excel は、次の項目の実行に単一のメイン スレッドを使用します。

組み込みコマンド
XLL コマンド
アドイン マネージャー インターフェイス関数 (xlAutoOpen 関数など)
Microsoft Visual Basic for Applications (VBA) のユーザー定義コマンド (通常はマクロと呼ばれま)
VBA のユーザー定義関数
組み込みのスレッド セーフではないワークシート関数 (次のセクションに一覧を示します)
XLM マクロ シートのユーザー定義コマンドとユーザー定義関数
COM アドインのコマンドと関数
条件付きフォーマット式内の関数と演算子
ワークシートの式で使用された定義済みの名前定義内の関数と演算子
数式編集ボックス内の式の強制的な評価 (F9 キーを使用)

ちなみに、セルに書かれたワークシート関数の再計算はマルチスレッドで行われます。

投稿2018/06/01 00:29

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

VBAの性質上、複数のイベントを同時に発生させることは不可能と思われます。
なのでドラッグ中の画面更新はあきらめるとして、カウントだけは正しく行われるような方向にするべきかと思います。
方法としては、ボタンクリックに開始時の時間を保持しておいて、1秒ごとのイベントでは現在時間と開始時間の差分で秒数を算出します。
以下サンプルです。

VBA

1' フォーム 2Private Sub tog1_Click() 3 If tog1.Value = True Then 4 Dim waitTime As Variant 5 togSt = Now ' 開始時間を保持 6 waitTime = togSt + TimeValue("0:00:01") 7 Application.Wait waitTime 8 Call macro1 9 End If 10End Sub 11 12' 標準モジュール 13Public togSt 14Sub macro1() 15 If frmStopTIme.tog1.Value = True Then 16 '1秒後にmacro100810aを実行 17 Dim cnt 18 cnt = DateDiff("s", togSt, Now) ' 経過秒数を計算 19 Worksheets("工程表").Range("A11") = cnt 20 frmStopTIme.Label1.Caption = cnt 21 Application.OnTime Now() + TimeValue("00:00:01"), "macro1" 22 End If 23End Sub 24

投稿2018/06/01 00:44

編集2018/06/01 01:13
ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問