
No.1ベストアンサー
- 回答日時:
こんにちは。
> 以下のようなコードを書くと timer2 < timer1となります。
> 不思議です。
> 幾らパソコンが速いといえどもおかしいのでは。
> 救える方法はあるのでしょうか。
特定の環境で起こる現象、ですので一般的なものではありませんが、、、。
以前某掲示板で話題にしたことありますが、原因は
「浮動小数点数の誤差」というものです。
二進数を基本に演算するPCと、十進数で考えることに慣れた人間と、
うまく付きあう為には、この誤差のことをよく理解した上で、
日頃から適切な対処を心掛けておいた方がいいと思います。
解決策としては、
Dim timer1 As Single
Dim timer2 As Single
のように適切なデータ型を定義しておいてから、
timer1 = Timer
timer2 = Timer
MsgBox timer2 - timer1
という扱い方をするか、CSng()関数などを使い、
Single型同士で比較演算するように記述することです。
人間の眼には同じ値の小数に見える場合でも、格納さるデータ型がSingle型かDouble型かによって、
PCが扱う数値は同じ値にはならないのです。
Variant型を介して比較演算すれば、型のキャストが働きますが、そのままでは、
Single型をDouble型に変換してからの演算になってしまう場合があり、そこに誤差が生じます。
Single型なのかDouble型なのか、違いをはっきり意識して演算させてあげればいい、ということです。
ただ、この問題については、滅多に再現できるものではありません。
大抵の場合、誤差が問題とならずに演算出来てしまうか、誤差が生じることに気が付かない、
ということもありますが、
特定の環境でしか再現できない現象です。
たまたま私は経験したことがある、というだけで、現在手元にある3台のPCでは、再現できません。
Excelのバージョン、SP、KB、OSのバージョン、などなど、
お使いの環境を書いてあれば、より専門的な回答を付けてくれる人もいるかも知れません。
経過時間を正確に得る為には一般的にAPIのGetTickCount関数などをよく使います。
Private Declare Function GetTickCount Lib "kernel32" () As Long
Sub Test()
MsgBox GetTickCount
End Sub
ミリ秒単位(1秒 = 1000)で比較的精度が高いですし、整数値を返しますから、
今回のような問題は決して起こりません。
ただ、APIの場合は、正しい扱い方をきちんと勉強してから、挑戦した方がいいです。
小さなミスを庇ってくれるVBAの親切設計とは違いますから、
例えばデータ型を間違えたりとか、基本的なミスには結構厳しいです。
エラーの種類によってはPC環境にも影響する、と警告する方もいらっしゃいますから、
扱いは慎重に越したことはないです。
例えば入門書で学んだ人の多くが読み飛ばしてしまうようなページに書かれているような
基本的な事を押えて、誰も書いていないような冒険的な記述を控えれば、
そんなに難しく考えなくても大丈夫かな、とは思います。
でもまぁAPI使えるようになると、VBAの可能性は飛躍的に拡大する、というのもありますね。
> そもそも、この質問は、
> 1秒ごとに、経過時間(hh:mm:ssのように)を表示したいと思い、、
> ロジックを考えていて発見しました。
> こちら(時計表示)についても合わせて教えていただけると嬉しいです。
> 宜しくお願いします。
APIの、SetTimerとKillTimer、とかを使うことになるかな?と思います。
【 VBA API SetTimer KillTimer 】
などで検索すれば色々サンプルは閲覧できますので、
どんなものかまず試してみる所から始めると好いと思います。
APIの中では、若干難度高めです。
他、ルーズなタイミング(ルーズな秒単位)でもよければ、Application.OnTime メソッドなども調べておくといいでしょう。
今回の目的に適さなかったとしても、必要な場面は出てくるでしょうから、覚えておいて損はないと思います。
タイマーを動かす間、一切の操作を無効にして待機するだけで良ければ、Application.Wait メソッドもあります。
以上、参考まで。
早速有り難うございました。
良くではありませんが、何となく分かりました。
>「浮動小数点数の誤差」というものです。
ということですね。
浮動小数点数というのは馴染みがないので、
そうかと思うしかありませんが、了解です。
色々な点も教えていただき、勉強になりました。
教えていただいたポイントで当たってみます。
お世話になりました。
No.2
- 回答日時:
解説は先達の方にお任せするとして
でも、ちょっぴり。
WindowsのTimer関数は少数第二位まで返すようです(当方では)。
で、CPUのクロックは3.3GHz(当方)
Timer関数が何クロックで終わるのか分かりませんが
CPUは一秒間に3300000000回働くので同タイムを返すのでしょう。
DoEventsを挟んで余計なことをさせればタマに違う値を返します。
でも、
>timer2 < timer1となります
とはならなんだ。
Sub testTimerFnc() ’当方だと12秒弱かかりました
Dim timer1 As Single, timer2 As Single, i As Integer
For i = 1 To 10000
timer1 = Timer
DoEvents
timer2 = Timer
'Debug.Print timer1, timer2
Debug.Print i, timer1 < timer2, timer1 > timer2, timer1 = timer2, IIf(timer1 < timer2, "★", "")
If timer1 > timer2 Then Stop
Next
MsgBox "10000回試したよ"
End Sub
Sub atTimer() 'タイマー中何もできない手抜きバージョン
Dim t As Double, a As Double, i As Integer
Range("A1").NumberFormatLocal = "h:mm:ss;@"
a = Now
Do
t = Now
Cells(1, 1) = CDate(t - a)
Application.Wait Now + TimeValue("0:0:1")
i = i + 1
If i > 30 Then Exit Do 'テキトーなところで終了
Loop
End Sub
お邪魔様でした。
早速有り難うございました。
例示いただいたプロックをやってみましたが、
逆転しませんでした。
やはりテクニックがあったのですね、
無知なモノで。
今後は大丈夫かと思います。
お世話になりました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
おそ松さんのpixivで見つけた漫...
-
「スクールデイズ」の桂言葉は...
-
ゲド戦記が腐女子に評判がよか...
-
オーラの泉にて「魔界の入り口...
-
ちょっとHなイラスト
-
エクセルVBA ユーザーフォーム...
-
腐女子の人は男性が苦手?
-
腐女子が嫌すぎて辛いです
-
行為をした際に相手の男性に 奥...
-
W不倫 長く続けたいという男性心理
-
前にアプローチしてくれたのを...
-
既読スルーから1ヶ月後に返信す...
-
デートにLINEで誘って2日近く返...
-
次に会う約束はしているけど、...
-
ヤリモクの人って一回したら終...
-
2週間後に会う約束をしている男...
-
気になる異性との日程調整連絡...
-
毎日連絡するのに会う約束はし...
-
性欲について。40歳主婦です。 ...
-
ケンカした時の 男性側の 「少...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
幽遊白書の疑問(躯について)
-
腐女子が嫌すぎて辛いです
-
エクセルVBA ユーザーフォーム...
-
VE管用のボックスコネクタのこ...
-
腐女子の人は男性が苦手?
-
[LOVELESS]について
-
REBORNについて・・
-
黒子のバスケはなぜ腐女子の方...
-
オーラの泉にて「魔界の入り口...
-
ボーイズラブ+ヤンデレ
-
秋元真夏に似てるって言われる...
-
このマンガのタイトルがわかり...
-
オススメのBL漫画を教えてください
-
腐女子です。腐女子の方に質問...
-
「freebird」のカップリング曲
-
シランカップリング剤について
-
RADWIMPS おっぱい
-
この絵師さんを教えてください
-
写真のモノニトロ化合物I、JはN...
-
BL系のマンガを好きな方へ質問...
おすすめ情報