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

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

ただいまの
回答率

90.34%

  • VBA

    1903questions

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

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

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 533

soepu

score 6

 前提・実現したいこと

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

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

 該当のソースコード

Private Sub tog1_Click()
    If tog1.Value = True Then
        Dim waitTime As Variant

        waitTime = Now + TimeValue("0:00:01")
        Application.Wait waitTime

        Call macro1
    End If

End Sub

---標準モジュール上
Sub macro1()
'一定間隔で実行する
'OnTimeメソッドを使う

    If frmStopTIme.tog1.Value = True Then
        '1秒後にmacro100810aを実行
        Worksheets("工程表").Range("A11") = Worksheets("工程表").Range("A11") + 1
        frmStopTIme.Label1.Caption = Worksheets("工程表").Range("A11")
        Application.OnTime Now() + TimeValue("00:00:01"), "macro1"

    End If

End Sub

 試したこと

フォームのモーダル表示

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

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

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

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

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

Option Explicit
Dim sTime As Date

Private Sub tog1_Click()
    If Tog1.Value Then
        sTime = Now
    Else
        Me.Label1.Caption = DateDiff("s", sTime, Now) & "秒間Onでした。"
    End If
End Sub

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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 キーを使用)

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

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

' フォーム
Private Sub tog1_Click()
    If tog1.Value = True Then
        Dim waitTime As Variant
        togSt = Now     ' 開始時間を保持
        waitTime = togSt + TimeValue("0:00:01")
        Application.Wait waitTime
        Call macro1
    End If
End Sub

' 標準モジュール
Public togSt
Sub macro1()
    If frmStopTIme.tog1.Value = True Then
        '1秒後にmacro100810aを実行
        Dim cnt
        cnt = DateDiff("s", togSt, Now)    ' 経過秒数を計算
        Worksheets("工程表").Range("A11") = cnt
        frmStopTIme.Label1.Caption = cnt
        Application.OnTime Now() + TimeValue("00:00:01"), "macro1"
    End If
End Sub

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • VBA

    1903questions

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