FC2ブログ

Excelじゆうちょう

Excelのお絵描きツール『りっぷ2(りっぷつぅ)』のサポートページ、まずは「はじめに」をご覧ください。 [NewEntry] [Admin]

記事更新カレンダー

04 « 2019-05 « 06
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -

やたらに多いカテゴリ

比較的新しい記事

新しいコメント

ありがたいブログ拍手

拍手コメント一覧(拍手はしない)

さみしいトラックバック

申し訳ないプロフィール

申し訳ない

管理人  [ 申し訳ない ]

pxivもやってます
リンクの一番上からのぞきに来てください
※閲覧にはユーザー登録が必要です

RSSってなんぞ?

広告は消せないらしい

FC2Ad

        --------       スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

        2009-09-13       [ ]もEvaluate( )も使いよう

さんざん苦労させられたEvaluate()ですが、よくよく考えるとすごいメソッドです。
VBAからワークシート関数が使えるなら、かなり強力な武器になります。
検索系を中心に、ワークシート関数には便利な関数がたくさんそろっています。
例えば、COUNTIFなんてよくお世話になるんじゃないでしょうか?

そんなわけで、私からひとつジミテク。
★精度の高い乱数を取得する方法★


【イミディエイトウインドウ】
?Rnd()
 0.7055475
?Evaluate("RAND()")
 0.387542995779785


VBA関数のRnd()ではSingle型が戻り値となり、Evaluate("RAND()")とすればDouble型を取得することができます。
※私は省略せずにEvaluateと記述することを推奨します。
  ヘルプも効けば、ちゃんとパラメタヒントも出ますしね。
スポンサーサイト

        2009-09-12       [ ]の正体

結論を出す前に、手がかりをもうひとつ。
[time()]でイミディエイトに返された、エラー 2015。
ヘルプで調べてみると、「セルのエラー値」という項目がHITしました。

定数     エラー番号 セルのエラー値
xlErrDiv0   2007    #DIV/0!
XlErrNA     2042    #N/A
xlErrName   2029    #NAME?
XlErrNull   2000    #NULL!
XlErrNum    2036    #NUM!
XlErrRef    2023    #REF!
XlErrValue  2015    #VALUE!

なんと、VBAではなくセルのエラーとのこと、ナゾは深まるばかりです。
とにかく、Googleでひたすら検索します。
記号を検索するのがいかに大変か、ここにきてようやく[]は角括弧と呼ぶことを知りました。(数学の授業では()が小括弧、{}が中括弧、[]が大かっこと習ったのに、あれはいったい?)
そしてついに、それらしいヤツが見つかりました。

ヘルプ(Evaluateメソッド)

ヘルプを簡単にまとめると、
・Evaluateメソッドの省略形が[]
・A1形式で名前を指定してセルを操作できる
・省略形を使うとコードの記述が簡単になる
こんな感じ。

確かに、[time()]ではセルのエラーが出てたのでそれっぽい感じがしますが、これはセルではありません。
再度Googleへ戻ります。
今度は名前がわかっているので、あっという間です。

Evaluateメソッドの引数には、ワークシート関数も指定できる

決定です、[]の正体はEvaluateメソッドに他ありません!
すべてのナゾがひとつにつながりました。

[now()]ではシリアル値が返ったのに[time()]ではエラーとなったのは、それぞれがワークシート関数だったからです。
Now()は、VBA関数でもワークシート関数でも引数を必要としません。
対してTime()は、VBA関数では引数を必要としませんが、ワークシート関数では時、分、秒の3つを引数とします。
エラー 2015(#VALUE!)は、引数が正しくない場合に発生するエラーです。

[now()]で先頭文字が大文字に変換されなかったのは、Evaluate()の引数が文字列であり、それがセル番地なのかワークシート関数なのかは実行されてから判定されていたからです。
そんな手間があったから、VBAの速度比較ではびっくりするほど遅かったんですね。

ようやくナゾが解けました。
いやはやExcelは実に奥が深いですね、私もまだまだ未熟です。
[a1]でセルを参照できることは(使ったことないにしろ)知っていたのに、セルのエラーという大きなヒントもあったのに、みんな見逃してました。
先入観にとらわれず、柔軟にものごとを考える力をつけないと。

        2009-09-12       ナゾの[ ]

前回先送りしていた、CDblと[]の処理速度を比較した結果を示します。


'【コードウインドウ】
'コメントはイミディエイトウインドウに表示された結果です
Private Sub testNow1()
Dim For0 As Long, For1, Tck0 As Long, Tck1 As Long
Dim D As Double
For For0 = 1 To 4
  Tck0 = GetTickCount
  For For1 = 1 To 1000000
    D = CDbl(Now())
  Next For1
  Tck1 = GetTickCount
  Debug.Print For0 & "回目 " & Tck1 - Tck0 & " ミリ秒"
Next For0
End Sub
'1回目 297 ミリ秒
'2回目 296 ミリ秒
'3回目 296 ミリ秒
'4回目 297 ミリ秒

Private Sub testNow2()
Dim For0 As Long, For1, Tck0 As Long, Tck1 As Long
Dim D As Double
For For0 = 1 To 4
  Tck0 = GetTickCount
  For For1 = 1 To 1000000
    D = [now()]
  Next For1
  Tck1 = GetTickCount
  Debug.Print For0 & "回目 " & Tck1 - Tck0 & " ミリ秒"
Next For0
End Sub
'1回目 26489 ミリ秒
'2回目 26006 ミリ秒
'3回目 26005 ミリ秒
'4回目 26021 ミリ秒


ものすごい差です、最初は自分の目を疑いました。
しかし、何度試してみても同じような結果が返ってきます。
さらに…


【イミディエイトウインドウ】
?[time()]
エラー 2015


何かがおかしい。
Time()はシリアル値の小数部分だけを返す関数で、Now()との違いは整数部分の有無だけのはずです。
少なくとも、[]はデータ型を変換するものではなさそうです。

ダメ押しにもうひとつ、testNow2プロシージャで変数Dに代入している式を見てください。


D = [now()]


「now」の先頭文字が自動的に大文字に変換されていません!
イミディエイトウインドウでは変換されませんが、コードウインドウでは「Now()」となるはずです。
ありえない…でも、シリアル値は返ってきている。
ナゾの[]、はたしてその正体は。
⇒さらに続く

        2009-09-09       日付をシリアル値へ変換

日付からシリアル値と取得したい時、普通はデータ型変換関数を使いますよね。


【イミディエイトウインドウ】
?CDbl(Now())
 40064.9765856481


ですが、他にも方法があるようです。

【イミディエイトウインドウ】
?[Now()]
 40064.9767572917


確かにシリアル値は求まりましたが、両者の違いは何なのでしょうか?(特に後者は何者なのでしょうか)
そこでいろいろ検索してみたのですが、なまじっか記号のためにぜんぜんHITしません。
仕方ないので、力ずくで調べてみました。


'【コードウインドウ】
Private Sub testCDbl()
Dim A As Variant
'Debug.Printのうしろのコメントは、返された値です
Debug.Print CDbl(1) '1
Debug.Print CDbl(0.1) '0.1
Debug.Print CDbl("a") '実行時エラー 13
Debug.Print CDbl("&Hff") '255
Debug.Print CDbl(Now()) '40065.8954861111
Debug.Print CDbl(Now() & "あ") '実行時エラー 13
'A =のうしろの値は、代入された後のAの変数の型です
Debug.Print [1] '1
  A = [1] 'Double
Debug.Print [0.1] '0.1
  A = [0.1] 'Double
Debug.Print ["a"] 'a
  A = ["a"] 'String
Debug.Print ["&Hff"] '&Hff
  A = ["&Hff"] 'String
Debug.Print [Now()] '40065.8954861111
  A = [Now()] 'Double
Debug.Print [Now() & "あ"] '40065.8954861111あ
  A = [Now() & "あ"] 'String
End Sub


【まとめ】
Double型へ変換する点では共通、CDblは数値に変換できなければNG、[]は文字列を素通しするようです。
微妙な違いはありますが、シリアル値を得るだけならどちらでも問題なさそうです。
では、どちらを使えばよいのでしょうか?

詳細のわからない[]よりも、一般的なCDblを使うのが無難ではありますが、ここは処理速度の速い方がうれしいですよね。
そこで、次回は速度比較をしてみることにします。

 | HOME | 

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。