ここから本文です

VBScriptでのOnTime 1秒ごとに処理を繰り返し、Excelファイルにデータを記録す...

hir********さん

2016/2/1012:44:05

VBScriptでのOnTime

1秒ごとに処理を繰り返し、Excelファイルにデータを記録するVBScriptを書いています。

VBScriptは初心者で、ネットを見ながら書いていたのですがOnTimeメソッドでの繰り返し処理がうまく動きません。
自力で解決できないため質問しました。

お分かりになる方、どうか教えて頂けないでしょうか。よろしくお願いします。


セル"A1"に"1"が入力された状態で即"END"が表示されてしまいます。

Test.vbs------------

Set Excel = WScript.CreateObject("Excel.Application")
Dim i
i = 1

Excel.Application.Visible = True
Excel.Application.DisplayAlerts = False
Excel.Application.Workbooks.Add
Set Sheet = Excel.Worksheets(1)

Repeat
Sub Repeat()
If i >= 3000 Then
Exit Sub
End If

Sheet.Cells(i, 1).Value = i
i = i + 1

Excel.Application.OnTime Now + TimeValue("00:00:01"), "Repeat"
End Sub

MsgBox "END"
Excel.Quit
--------------------

閲覧数:
1,174
回答数:
2
お礼:
500枚

違反報告

ベストアンサーに選ばれた回答

por********さん

2016/2/1014:42:11

こんにちは。
VBSとエクセルVBAを、ごちゃごちゃにしたら、だめですよ。

ontimeを使いたい、

という場合は、ontimeの記述をしているエクセルxlsmファイルを作成し、VBSから開くだけにします。
ブックが開いたら、application.runで、エクセルVBAに実行制御をまかせます

ontimeは使わない

という場合は、vbsで時間を見ながら、制御します。
doeventsに相当する命令も、必要ですし、時間の「秒」の変化を測定するvbsステップにする必要があります。

いずれにしても、「エクセルの新規ブック」で、というのは、すんなりできません。

  • 質問者

    hir********さん

    2016/2/1108:45:42

    迅速で的確な回答ありがとうございました。
    確かにVBScriptとエクセルVBAをほぼ同一視していました。
    Timer関数の値を参照してLoop処理することにしました。

    Test.vbs------------

    Option Explicit
    Dim Excel, Sheet
    Set Excel = WScript.CreateObject("Excel.Application")

    Dim i, Time, Time_End

    Excel.Application.Visible = True
    Excel.Application.DisplayAlerts = False
    Excel.Application.Workbooks.Add
    Set Sheet = Excel.Worksheets(1)

    Time = Int(Timer)
    i = 1



    Do While True
    Time = Int(Timer) + 1
    If Time > 86400 Then
    Time = Time - 86400
    End If

    While Timer < Time
    wscript.sleep 10
    Wend

    If i > 30 Then
    Exit Do
    End If
    Sheet.Cells(i, 1).Value = i
    i = i + 1
    Loop

    MsgBox "END"
    Excel.Quit

    --------------------

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

ベストアンサー以外の回答

1〜1件/1件中

プロフィール画像

カテゴリマスター

glo********さん

2016/2/1018:20:28

VBS は
「与えられた実行命令の実行が終了すると自分自身を閉じてしまう」
というのが基本仕様です。

VBS コードの最後には
書きもしないし見えもしないだけで
WScript.Quit
が書かれてあると思えばわかりやすいかと思います。

また,
書かれていらっしゃるコードの場合は
その前に
MsgBox "END"
があるため
2回目の関数 Repeat が実行される前に
メッセージボックスが出てしまいます。

ですから
「○○後に何かをせよ」
と言ってもその前に
MsgBox "END"
が働き
その「OK」クリック直後に見えない
WScript.Quit
が働くため
Excel の Application.OnTime が効かないように見えるだけだと思われます。

したがってココは
Excel の Application.OnTime を使うのではなく
普通に
WScript.Sleep
を使えば良いのではないかと思います。

WScript.Sleep ○○ は
「○○ミリ秒間は何もせず停止せよ」
という意味です。

ですから
次の動作命令(MsgBox "END")も行わず
自分自身を閉じてしまうという動作(WScript.Quit)も行わないため
「起動している」という状態を保持します。

その代わり WScript.Sleep の場合
Sleep している間 VBS は別の処理もしませんけどね。。。
そこが大きな違いです。

というわけで
書き換え例です↓。



'Test.vbs------------
Set Excel = WScript.CreateObject("Excel.Application")
Dim i
i = 1

Excel.Application.Visible = True
Excel.Application.DisplayAlerts = False
Excel.Application.Workbooks.Add
Set Sheet = Excel.Worksheets(1)

Repeat

Sub Repeat()

    If i >= 3000 Then
        MsgBox "END"
        Excel.Quit
        Exit Sub
    End If

    Sheet.Cells(i, 1).Value = i
    i = i + 1

    WScript.Sleep 1000

    Repeat

End Sub
'--------------------



なお,
If i >= 3000 Then の 3000 は
動作検証するコードとしては数が大き過ぎるため
If i >= 30 Then くらいに変更して動作検証した方が良いと思います。


.


==================================


ちなみに他の言語でも
次の関数実行前にインターバルをとると
次の関数実行前に別の動作をするという仕様は同じですよ。
ただ WScript.Quit みたいなのが最後に動作しないことが多いだけです。


例えば JavaScript での例です。

「Test.hta」(←拡張子は .html でなく .hta)として
次のコードを保存しても同じような動きになると思います。


Test.hta------------
<html>
<head>
<meta charset="shift_jis">
<title>HTA JS Test</title>
</head>
<body>

<!-- ココ↓に 1 2 3 4 … を表示させる-->
<p id="prg"></p>

<script type="text/javascript">

//変数 i の宣言 初期値 1
var i = 1;

//関数 Repeat を実行
Repeat();

//関数 Repeat の定義
function Repeat(){
    //もし i が 30 (以上)になれば
    if(i >= 30){
        //この関数を抜ける
        return;
    }
    //1 2 3 4 … を表示させる
    document.getElementById("prg").innerHTML += i + "<br>";
    //変数 i に 1 を加算
    i += 1;
    //1000ミリ秒(1秒)後に関数 Repeat を実行
    setTimeout("Repeat()",1000);
}

//↓先にコレが動作するように見える
alert("END");

//↓先頭の「//」を削除すると先に終了してしまう
//window.close();

</script>

</body>
</html>
--------------------

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる