VB内でライブラリ関数のsleep関数を使いたいのですが、どこにあるのでしょうか?"kernel32"というDLLファイルにあると聞いたのですがどうやらない模様です。どなたか知っている方いらっしゃいますでしょうか。お願いします。

A 回答 (2件)

VB6 での話ですが… kernel32 の中にありますよ。



標準モジュールの中で
  Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
と宣言すれば、使えるはずです。(今、サンプルプログラムを書いて確認しました。)
    • good
    • 2
この回答へのお礼

お返事遅れました。おっしゃる通りプログラムの間違いだったようです。

お礼日時:2002/01/30 16:24

ライブラリ関数というのは、一般にCのランタイム関数のことを示します。


求めているのは、ysk6406さまのいうとおり、APIで実現できるのですが、APIでないCのランタイム関数をVBから使うことは、VBの機能だけではできません。
    • good
    • 0

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

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

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

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

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
...続きを読む

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

QExcelVBAでのkernel32(64bit)

今までExcel2000のVBAから、以下のようなコードを使ってC++で作ったコマンドプロンプトで動くプログラムを動かすプログラムを作っていましたが、これを64bitのWindows7上で動いているExcel2010で使おうとしたらメッセージが出ました。いろいろ調べてみたところ、たぶんDeclareにPtrSafeを付ければ良いようなのですが、その際、他のコードはそのままで良いのでしょうか。特に、コード中のLongはそのままで良いのか気になるのですが...。ちなみに、下記コードの条件コンパイルはネットで調べて見よう見まねで付けたもので、Excel2000のときには付けていないものでした。ご存じの方がいらっしゃいましたらご教授ください。

'------------------------------------------------------------------------------
' Win32 API関数・定数の宣言
'------------------------------------------------------------------------------
#If VBA7 And Win64 Then '64bit

Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _
  ByVal dwMilliseconds As Long) As Long

Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _
  ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

#Else '32bit

Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _
  ByVal dwMilliseconds As Long) As Long

Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _
  ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

#End If

Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Private Const INFINITE As Long = &HFFFF

'------------------------------------------------------------------------------
' Run
'------------------------------------------------------------------------------
Public Sub Run(ByVal project_name As String)
  Dim program As String
  Dim task_id As Long
  Dim h_proc As Variant

  program = mdlFunc.ProgramPath() & mdlFunc.ProgramOption(project_name) 'プログラム名

  task_id = Shell(program, vbHide)
  h_proc = OpenProcess(PROCESS_ALL_ACCESS, False, task_id)

  If OpenProcess(PROCESS_ALL_ACCESS, False, task_id) <> vbNull Then
    Call WaitForSingleObject(h_proc, INFINITE)
    CloseHandle h_proc
  End If

End Sub

今までExcel2000のVBAから、以下のようなコードを使ってC++で作ったコマンドプロンプトで動くプログラムを動かすプログラムを作っていましたが、これを64bitのWindows7上で動いているExcel2010で使おうとしたらメッセージが出ました。いろいろ調べてみたところ、たぶんDeclareにPtrSafeを付ければ良いようなのですが、その際、他のコードはそのままで良いのでしょうか。特に、コード中のLongはそのままで良いのか気になるのですが...。ちなみに、下記コードの条件コンパイルはネットで調べて見よう見まねで付けた...続きを読む

Aベストアンサー

LongPtrの補足ですが、
32bit環境で動かした場合は、LongPtrは32bit、
64bit環境で動かした場合は、LongPtrは64bitとして扱われます。

上記の通りポインタは大きさが変わる物で、他言語ではある程度流動的に変わる仕様なのですが、
VB(VBA)の整数型(int, long)は常に大きさが変わらない仕様であったため、
今回のような事になったのでしょう。

>> OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある
はい、そうです。

>> 1. かつてのVBAではポインタ(32bit)を扱う型が無かったので、同じ32bitであるLongで代用していた。
>> 2. 64bit環境ではアドレスが64bitになるので、32bitのLongに格納するとデータが欠落する。
>> 3. これの対策としてポインタとしてのLongPtrという型が追加された。
>> 4. 今回のプログラムの場合、OpenProcessがプロセスハンドルとしてアドレスを返す。
はい、そうです。

>> 5. これを受け取るデータ型はVariantなので問題ないが(自動で判別するから?)、
>> WaitForSingleObjectの第1引数及びCloseHandleには64bitのポインタを渡す必要がある。
Variantで問題があるかどうかは分かりませんが、
OpenProcess関数はHANDLE型を返しますので、受け側(h_proc)はLongPtrが適切だと思います。

>> 6. 結果、WaitForSingleObjectの第1引数とCloseHandleの引数をLongPtrにする必要がある。
はい、そうです。

参考URL:http://msdn.microsoft.com/ja-jp/library/ee691831.aspx

LongPtrの補足ですが、
32bit環境で動かした場合は、LongPtrは32bit、
64bit環境で動かした場合は、LongPtrは64bitとして扱われます。

上記の通りポインタは大きさが変わる物で、他言語ではある程度流動的に変わる仕様なのですが、
VB(VBA)の整数型(int, long)は常に大きさが変わらない仕様であったため、
今回のような事になったのでしょう。

>> OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある
はい、そうです。

>> 1. かつてのVBAではポインタ(32bit)を扱う型が無かったので、同じ32bitであるL...続きを読む

QVB上で実行中の無限ループの止め方

今まで、CUIベースのBASICでのプログラムの経験はあるのですが
Visual系のBASICは初心者です。
原因はわかっているのでプログラムの修正はできるのですが
VB上でコンパイルして実行したときに無限ループに陥ってしまって
どうにもプログラムをとめられなくなります。
そんなことがないように、実行前に全てのプロジェクトを保存して
いますので、そんなに実害はないのですが、どうすればとめられるのでしょう・・
今現在は、タスクマネージャーから強制終了させています。

Aベストアンサー

無限ループの一番内側に
DoEvents
を入れておくと、ウィンドウ切替え->デバッガ終了操作が出来ますよ

危なそうなとこにも入れておくと、何かと安心です。

QEXCEL VBAでApplication.waitを使わずに一時停止させたい

マクロの実行中に、その処理を、条件分岐によってある一定時間だけ止めて、また再開させるようなプログラムを作りたいと考えています。
Application.Waitを使えば、可能というとこまではわかったのですが、それだとマクロ停止中にEXCEL上での一切の操作(たとえばスクロール)ができなくなるので、マクロだけ停止させておいて、他の操作はできるようなやり方はありませんでしょうか?
ちなみに、当方の使用OSはXP、EXCELは2007です。VBAは、はじめて取り組む超初心者で、以下のコードもネットやこちらのサイトを探しまくって、ようやくここまでできました。
なお、本マクロで具体的にやりたいことは、楽天証券のRSSというアプリケーションから、EXCELの特定の列に、1行目から順番に、リアルタイムで株価が書き込まれていきます。その株価を監視して、ある一定以上になったら、音で知らせるということをやりたいのです。その際、株価が書き込まれていく間隔は、数秒~数分です。
長々と書きましたが、ご教授いただけると助かります。
<参考:現在のマクロ>
Sub Test()
Dim waitTime As Variant
Dim 繰り返し As Long
For 繰り返し = 1 To 10
If Cells(繰り返し, 1).Value >= 10000 Then
Shell "mplay32.exe /play /close C:\WINDOWS\Media\notify.wav"
ElseIf Cells(繰り返し, 1).Value = Empty Then
waitTime = Now + TimeValue("0:00:05")
Application.Wait waitTime
End If
Next 繰り返し
End Sub

マクロの実行中に、その処理を、条件分岐によってある一定時間だけ止めて、また再開させるようなプログラムを作りたいと考えています。
Application.Waitを使えば、可能というとこまではわかったのですが、それだとマクロ停止中にEXCEL上での一切の操作(たとえばスクロール)ができなくなるので、マクロだけ停止させておいて、他の操作はできるようなやり方はありませんでしょうか?
ちなみに、当方の使用OSはXP、EXCELは2007です。VBAは、はじめて取り組む超初心者で、以下のコードもネットやこちらのサイトを...続きを読む

Aベストアンサー

こんばんは。

Microsoft のサポートには、そのものズバリの内容がありますが、少し古い内容です。実際、以下のプロパティで、楽天RSSの前バージョン(約2年前)では私は成功していますが、現行ツールでは知りません。RSSは、バージョンがあがりました。

http://support.microsoft.com/support/excel/content/onevent/onevent.asp?SD=gn&LN=ja&gssnb=1#ondata

それから、外部ツールを使って、音を鳴らすのはあまり賛成しません。一応、書いておきますが、本来は、内部コマンドのBeep やパターンの色付けでよいと思います。

1番目の場合は、最初に、Auto_Open を実行してください。一旦、ファイルを閉じて、再び開いても自動的に設定されています。

なお、Microsoft サポートの注にも書かれていますが、DDEやOLEではない場合に、ハンドラーが取れないこともあります。その場合は、OnEntry や Change イベントを使用してください、と書かれています。つまり、1番のマクロは、データがインポートされたときにのみ、起動するマクロです。ともかく、最初のマクロだけでも試してみてください。まだ、そういう古い方式が可能なのか、こちらでも知りたいのです。

-----------------------------------------
'標準モジュール
'Option Explicit

Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, ByVal lpstrReturnString As String, _
ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long

'一旦、閉じて開くか、最初に実行してください。
Sub Auto_Open()
 '実際のシート名を入れてください。
 Worksheets("Sheet1").OnData = "Test1"
End Sub

Sub Test1()
  Dim i As Long
  Dim rt As Long
  Static j As Long
  Const sSOUND As String = "C:\WINDOWS\Media\notify.wav"

  i = Cells(Rows.Count, 1).End(xlUp).Row
  If i <> j Then
    If Cells(i, 1).End(xlUp).Value > 10000 Then
      rt = mciSendString("Play " & sSOUND, "", 0, 0)
      'Beep 'ビープ
      'Cells(Rows.Count, 1).End(xlUp).Interior.ColorIndex = 34 '色づけ
    End If
  End If
  j = i
End Sub

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

OnTime メソッドを使う場合は、LastTime を数秒の間の設定をしたほうがよいです。LastTime を入れないと、待機状態の後に、立て続けに、マクロの起動をしてしまい意味のないものになってしまいます。また、行数が単にインクリースしても、そこにデータがなければ、意味のないチェックになってしまいますから、必ず、実際に存在するデータに連動していなければなりません。また、データが増えなければ、チェックはしません。

以下の場合は、ワークシートの作業中とマクロのデータチェックがぶつかった場合は、作業のほうが必ず優先しますが、その待機状態は、数秒間しかありません。その時に無視したデータは、次のマクロで必ずフォローするように出来ています。なお、色づけとBeep という方式になっていますから、色づけが嫌いなら、コメントブロック(')を入れてください。

一列の最後尾に、文字「Q(大文字・小文字共通)」を入れれば、それで終了します。

------------------------------------------
'標準モジュール
'Option Explicit

Sub TimerMacro()
  Dim i As Long '行
  Dim n As Long
  Dim myTime As Date
Static j As Long
  '----------------------------------
  'チェックする値を以下に入れてください。
  Const MYLIMIT As Long = 10000
  '----------------------------------
  i = Cells(Rows.Count, 1).End(xlUp).Row
  '終了は、Q を入れる
  If StrComp(Cells(i, 1).Value, "Q", 1) = 0 Then
   MsgBox "終了しました。", 64
   Exit Sub
  End If
  If i > j And j > 0 Then
    For n = j To i
      '上限を超える場合
      If Cells(n, 1).Value > MYLIMIT Then
        Cells(n, 1).Interior.ColorIndex = 34 '水色
        Beep '音
      End If
    Next n
  ElseIf j = 0 Then
       If Cells(i, 1).Value > MYLIMIT Then
        Cells(i, 1).Interior.ColorIndex = 34 '水色
        Beep '音
        End If
  End If
  j = i
  myTime = Now + TimeSerial(0, 0, 5) '5秒
  Application.OnTime myTime, "TimerMacro", myTime + TimeSerial(0, 0, 2) '待機2秒
End Sub
----------------------------------------

こんばんは。

Microsoft のサポートには、そのものズバリの内容がありますが、少し古い内容です。実際、以下のプロパティで、楽天RSSの前バージョン(約2年前)では私は成功していますが、現行ツールでは知りません。RSSは、バージョンがあがりました。

http://support.microsoft.com/support/excel/content/onevent/onevent.asp?SD=gn&LN=ja&gssnb=1#ondata

それから、外部ツールを使って、音を鳴らすのはあまり賛成しません。一応、書いておきますが、本来は、内部コマンドのBeep やパターンの色付けで...続きを読む

QAPI Sleep関数について

Sleep()で指定できる最大値はいくつになりますか?

Aベストアンサー

ミリ秒(1/1000)で指定し、引数はas Longだから、長整数型で2,147,483,647(2^31)ミリ秒と、定義どおり考えて良いのではないでしょうか。
だだこのAPIの作用の性格から限度が自ずとあるでしょう。
大きい数字を与えてしまったばあい、Ctrl+Pause(Break)では、止めれないので注意との事です。

Qモーダルフォームとモードレスフォーム

この二つの違いはどういう違いがあるのでしょうか?
どなたか教えてください。お願いいたします。

Aベストアンサー

実際にフォーム1とフォーム2を作成し、フォーム1に二つのコマンドボタンを用意して、以下のコードを貼り付けて見てください。

Private Sub Command1_Click()
Form2.Show vbModal, Me
MsgBox "vbModal"
End Sub

Private Sub Command2_Click()
Form2.Show vbModeless, Me
MsgBox "vbModeless"
End Sub

Command1でもCommand2でもフォーム2が開きます。しかしMsgBoxが表示するタイミングが変わってるはずです。
Command1の場合はフォーム2が閉じたあと
Command2の場合はフォーム2が表示されたあと
にメッセージボックスが表示されます。
つまりCommand1はShowのあとのロジックを、フォーム2が閉じるまで、未処理のままとなるわけです。

画面上はフォーム2が前面、フォーム1が背面になるどちらも似たような表示に見えますが、
Command1の場合はフォーム1はフォームをクリックしても、フォーカスを持たない
Command2の場合はフォーム1はフォームをクリックすると、フォーカスを持ちえる
という点も違います。


簡単にまとめると、
vbModalの場合はフォーム2だけに作業処理を固定させたい時に使用します。vbModelessの場合はフォーム2はポップアップ的な使用方法の時に使います。

実際にフォーム1とフォーム2を作成し、フォーム1に二つのコマンドボタンを用意して、以下のコードを貼り付けて見てください。

Private Sub Command1_Click()
Form2.Show vbModal, Me
MsgBox "vbModal"
End Sub

Private Sub Command2_Click()
Form2.Show vbModeless, Me
MsgBox "vbModeless"
End Sub

Command1でもCommand2でもフォーム2が開きます。しかしMsgBoxが表示するタイミングが変わってるはずです。
Command1の場合はフォーム2が閉じたあと
Command2の場合はフォー...続きを読む

QVB6.0-整数と余りを求める

表題の通り、整数と余りを求める関数を教えてほしいです:例:100/60=1余り40
整数:1
余り:40
よろしくお願いいたします。

Aベストアンサー

Dim A,B,C,D as integer
A=100
B=60
C=Int(A/B) <---答は1
D=A mod B

●IntはAをBで割った時の整数部分を求める関数ですが、答が負の場合は
注意が必要です。 例 Int(-100/40)=-2
これを回避する場合 Fixがいいです

●mod は A を B で割った時の余りを求める関数

Q他言語で言うcontinue文

他言語で言うcontinue文に相当する命令はVBに用意されているのでしょうか?

continue文とはループ中の後続の処理をやめループの先頭に戻るという命令です。

なんか探したけど無かったもので…。どんな言語にも用意されてそうな基本的な命令なので質問してみました。

バージョンは
Winエクセル2002 SP3
VBA Retail:6.4.8869, Version:9969
です。基本エンジンはVB6です。

よろしくお願いします。

Aベストアンサー

> continue文の解説でも、貴方のご指摘の動作(ループの先頭に戻る)はしているようには思えません。

ループの最後へジャンプという感じですね。
VBなら、Nextへ飛ばすのと同じです。

For i = 1 To 5
    If i = 3 Then goto Next_i
    Debug.Print i
Next_i:
Next i

Q一時停止と再開

今、Visual Basic でスライドショーのプログラムを作っています。
その中で、プログラムの一時停止(それに伴う再開)という事をしたいのですが、どのようにすればよいかわかりません。
教えて下さい。お願いします。

Aベストアンサー

Enabledの操作で充分だと思いますよ。

ちなみに先ほどの方法の処理を書くと(フラグの1と0の値が変わってますが・・・)

Private bytFlg As Byte

Private Sub cmdPause_Click()
  bytFlg = 0
End Sub

Private Sub cmdPlay_Click()
  bytFlg = 1
End Sub

Private Sub Form_Load()
  bytFlg = 0
End Sub

Private Sub Timer1_Timer()
  If bytFlg = 1 Then
    'ここに画像読み込み処理
  End If
End Sub

とするとできます。
しかし、画像の読み込みを必要としないときもタイマーが動いているので、Windowsに負荷がかかります。

だからgotkatさんの今までのEnabledの操作で充分です


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

人気Q&Aランキング