Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


5945 / 13645 ツリー ←次へ | 前へ→

【47959】配列の値のmax minについて GG 07/3/28(水) 10:20 質問[未読]
【47961】Re:配列の値のmax minについて ウッシ 07/3/28(水) 10:30 発言[未読]
【47963】Re:配列の値のmax minについて GG 07/3/28(水) 10:47 お礼[未読]
【47964】Re:配列の値のmax minについて Jaka 07/3/28(水) 10:52 発言[未読]
【47967】Re:配列の値のmax minについて GG 07/3/28(水) 11:48 お礼[未読]
【47969】Re:配列の値のmax minについて ウッシ 07/3/28(水) 13:50 発言[未読]
【47981】Re:配列の値のmax minについて GG 07/3/28(水) 22:54 お礼[未読]
【47984】Re:配列の値のmax minについて JuJu 07/3/29(木) 10:09 発言[未読]
【48010】Re:配列の値のmax minについて ichinose 07/3/30(金) 10:11 発言[未読]
【48011】Re:配列の値のmax minについて ウッシ 07/3/30(金) 10:29 発言[未読]
【48012】Re:配列の値のmax minについて Jaka 07/3/30(金) 11:11 発言[未読]
【48043】Re:配列の値のmax minについて JuJu 07/4/1(日) 13:37 発言[未読]
【48058】Re:配列の値のmax minについて ichinose 07/4/2(月) 8:09 発言[未読]
【48063】結果発表 Jaka 07/4/2(月) 13:31 発言[未読]

【47959】配列の値のmax minについて
質問  GG  - 07/3/28(水) 10:20 -

引用なし
パスワード
   御世話になります
配列の値のmax minについて簡単に求める
アイテム等無いでしょうか

例)
AAA(1)=223
AAA(2)=123
AAA(3)=423
AAA(4)=323

で maxは、 423
  minは、 123
が知りたいのですが
配列内の個数が1,000,000個近くあるのでループでまわすのは、
なかなか厳しいと思い
質問さしてもらいました

宜しくお願いします

【47961】Re:配列の値のmax minについて
発言  ウッシ  - 07/3/28(水) 10:30 -

引用なし
パスワード
   こんにちは

Sub test()
  Dim AAA(1 To 4)
  AAA(1) = 223
  AAA(2) = 123
  AAA(3) = 423
  AAA(4) = 323
  With Application.WorksheetFunction
    Debug.Print .Max(AAA)
    Debug.Print .Min(AAA)
  End With
End Sub

で、どうでしょうか?

【47963】Re:配列の値のmax minについて
お礼  GG  - 07/3/28(水) 10:47 -

引用なし
パスワード
   ウッシ さん 有り難うございました
Application.WorksheetFunctionは、
Rangeだけでなく配列にも使えるのです
大変、役に立ちます


▼ウッシ さん:
>こんにちは
>
>Sub test()
>  Dim AAA(1 To 4)
>  AAA(1) = 223
>  AAA(2) = 123
>  AAA(3) = 423
>  AAA(4) = 323
>  With Application.WorksheetFunction
>    Debug.Print .Max(AAA)
>    Debug.Print .Min(AAA)
>  End With
>End Sub
>
>で、どうでしょうか?

【47964】Re:配列の値のmax minについて
発言  Jaka  - 07/3/28(水) 10:52 -

引用なし
パスワード
   補足
配列の要素数に限界があるので注意。
TRANSPOSEと同じで5800ん個ぐらいだったような。
by 97 、2000
2002では、まだ確かめてない。

【47967】Re:配列の値のmax minについて
お礼  GG  - 07/3/28(水) 11:48 -

引用なし
パスワード
   Jaka さん有り難うございます
2002では、65536個が限界のようです
工夫して使ってみようかと思います


▼Jaka さん:
>補足
>配列の要素数に限界があるので注意。
>TRANSPOSEと同じで5800ん個ぐらいだったような。
>by 97 、2000
>2002では、まだ確かめてない。

【47969】Re:配列の値のmax minについて
発言  ウッシ  - 07/3/28(水) 13:50 -

引用なし
パスワード
   こんにちは

>配列の要素数に限界があるので注意。
でした。(..)

配列ならループしてもそんなに時間掛からないですね。

Sub test1()
  Dim AAA(1 To 1000000)
  Dim i  As Long
  Dim maxD As Long
  Dim minD As Long
  For i = 1 To UBound(AAA)
    AAA(i) = i
  Next
  maxD = AAA(1): minD = AAA(1)
  For i = 2 To UBound(AAA)
    maxD = IIf(AAA(i) > maxD, AAA(i), maxD)
    minD = IIf(AAA(i) < minD, AAA(i), minD)
  Next
  Debug.Print maxD
  Debug.Print minD
  Erase AAA
End Sub

配列(↓では単純に数値)を空のレコードセットに読み込んでソートしてって
試しましたけど遅かった。(AddNewがネックでした。)

Sub test2()
  Dim i   As Long
  Dim c   As Long
  Dim v   As Variant
  Dim rs   As Object
  Dim s   As String

  Set rs = CreateObject("ADODB.Recordset")

  With rs
    With .Fields
      .Append "data", 14   'adDecimal
    End With
    .CursorLocation = 2
    .Open
    For i = 1 To 1000000
      .AddNew
      !data = i
    Next
    .MoveFirst
    If .RecordCount > 0 Then
      .Sort = "[data] DESC"
      Debug.Print "最大値   ---" & .GetRows(1, 0, "data")(0, 0)
      .Sort = "[data] ASC"
      Debug.Print "最小値   ---" & .GetRows(1, 0, "data")(0, 0)
    End If
    .Close
  End With
  Set rs = Nothing
End Sub

【47981】Re:配列の値のmax minについて
お礼  GG  - 07/3/28(水) 22:54 -

引用なし
パスワード
   助かります
TEST1の方使って試して見ます
有り難うございました

【47984】Re:配列の値のmax minについて
発言  JuJu  - 07/3/29(木) 10:09 -

引用なし
パスワード
   みなさんこんにちわ

ある程度速度を要求されるのでしたら、

>    maxD = IIf(AAA(i) > maxD, AAA(i), maxD)
>    minD = IIf(AAA(i) < minD, AAA(i), minD)

    If AAA(i) > maxD Then maxD = AAA(i)
    If AAA(i) < minD Then minD = AAA(i)

にしたほうが若干速くなります。

ループ回数が多くないと、速度差は実感できませんが...

【48010】Re:配列の値のmax minについて
発言  ichinose  - 07/3/30(金) 10:11 -

引用なし
パスワード
   おはようございます。

>
>ある程度速度を要求されるのでしたら、
>
>>    maxD = IIf(AAA(i) > maxD, AAA(i), maxD)
>>    minD = IIf(AAA(i) < minD, AAA(i), minD)
>
>    If AAA(i) > maxD Then maxD = AAA(i)
>    If AAA(i) < minD Then minD = AAA(i)
>
>にしたほうが若干速くなります。
>
>ループ回数が多くないと、速度差は実感できませんが...
ではさっそく 検証。

'===========================================================
Sub test()
  Dim AAA(1 To 1000000)
  Dim i  As Long
  Dim maxD As Long
  Dim minD As Long
  Dim tm As Double
  For i = 1 To UBound(AAA)
    AAA(i) = CLng(Rnd() * 3000000) + 1
  Next
  MsgBox "ready"
  tm = [now()]
  maxD = AAA(1): minD = AAA(1)
  For i = 2 To UBound(AAA)
    maxD = IIf(AAA(i) > maxD, AAA(i), maxD)
    minD = IIf(AAA(i) < minD, AAA(i), minD)
  Next
  Debug.Print maxD
  Debug.Print minD
  Debug.Print Application.Text([now()] - tm, "hh:mm:ss.00")
  '**********************************************************
  tm = [now()]
  maxD = AAA(1): minD = AAA(1)
  For i = 2 To UBound(AAA)
    If AAA(i) > maxD Then maxD = AAA(i)
    If AAA(i) < minD Then minD = AAA(i)
  Next
  Debug.Print maxD
  Debug.Print minD
  Debug.Print Application.Text([now()] - tm, "hh:mm:ss.00")
End Sub


私の環境で3秒ほど差がありました。

【48011】Re:配列の値のmax minについて
発言  ウッシ  - 07/3/30(金) 10:29 -

引用なし
パスワード
   ▼ichinose さん:JuJu さん
こんにちは

最初はIf...Then...Else ステートメントとかSelect Case ステートメントしか知らなくて
IIFを知ってこれはいいと思って時々使うようになったのですが遅いとは・・・・

なんか1行でサクっと書けると処理自体速くなるような気もしてたのですが、あまり速度を
気にしないせいか、考えも試しもしてなかったです。

と言いつつichinoseさんのコードを試して見たら、私の環境ではどちらも1秒掛からなかったです。

でも、0.5秒位遅かったので、ループ回数が増えればどんどん遅くなりますね。
遅いって言われる前にIIF使うのやめた方がいいいかな。

【48012】Re:配列の値のmax minについて
発言  Jaka  - 07/3/30(金) 11:11 -

引用なし
パスワード
   ウッシ さん、ichinose さん、JuJu さん
こんにちは、
JuJu師匠ひさしぶりです。

結果報告。
私のトロイ環境では、こんなでした。

2999990
2
00:00:07.25
2999990
2
00:00:01.55

2999999
13
00:00:07.26
2999999
13
00:00:01.53

【48043】Re:配列の値のmax minについて
発言  JuJu  - 07/4/1(日) 13:37 -

引用なし
パスワード
   こんにちわ

速度優先なら、

> If AAA(i) > maxD Then maxD = AAA(i)
> If AAA(i) < minD Then minD = AAA(i)

tmp = AAA(i)
If tmp > maxD Then maxD = tmp
If tmp < minD Then minD = tmp

と書くべきなんでしょうが、その辺の最適化はコンパイラのお仕事ですね。
(VBAはコンパイラは付いていませんが)

▼ウッシ さん:
> でも、0.5秒位遅かったので、ループ回数が増えればどんどん遅くなりますね。
> 遅いって言われる前にIIF使うのやめた方がいいいかな。

最近のパソコンは速いので、速度より書き易さ見易さを優先したほうが良いですよ。
処理が思ったほど時間がかかるときに、たまには思い出してあげてください。


ちょっと余談

両方のIFが真になる事はないので、

If AAA(i) > maxD Then
  maxD = AAA(i)
ElseIf AAA(i) < minD Then
  minD = AAA(i)
End If

と書いた方が速くなるような気もしますが、実はこの条件下ではそうはなりません。
(最近は違うかも知れませんが...)
なぜだかわかるかな^^;

【48058】Re:配列の値のmax minについて
発言  ichinose  - 07/4/2(月) 8:09 -

引用なし
パスワード
   おはようございます。

>両方のIFが真になる事はないので、
>
>If AAA(i) > maxD Then
>  maxD = AAA(i)
>ElseIf AAA(i) < minD Then
>  minD = AAA(i)
>End If
>
>と書いた方が速くなるような気もしますが、実はこの条件下ではそうはなりません。
>(最近は違うかも知れませんが...)
>なぜだかわかるかな^^;
'==============================================================
Sub test()
  Dim AAA(1 To 1000000)
  Dim i  As Long
  Dim maxD As Long
  Dim minD As Long
  Dim tm As Double
  For i = 1 To UBound(AAA)
    AAA(i) = CLng(Rnd() * 3000000) + 1
  Next
  'MsgBox "ready"
  '**********************************************************
  'ブロック形式のIF文
  tm = [now()]
  maxD = AAA(1): minD = AAA(1)
  For i = 2 To UBound(AAA)
    If AAA(i) > maxD Then
      maxD = AAA(i)
      End If
    If AAA(i) < minD Then
      minD = AAA(i)
      End If
  Next
  Debug.Print maxD
  Debug.Print minD
  Debug.Print Application.Text([now()] - tm, "hh:mm:ss.00")
  '**********************************************************
  'IF ELSEIFのブロック
  tm = [now()]
  maxD = AAA(1): minD = AAA(1)
  For i = 2 To UBound(AAA)
    If AAA(i) > maxD Then
      maxD = AAA(i)
    ElseIf AAA(i) < minD Then
      minD = AAA(i)
      End If
  Next
  Debug.Print maxD
  Debug.Print minD
  Debug.Print Application.Text([now()] - tm, "hh:mm:ss.00")
  '**********************************************************
  'IF Else ステートメント
  tm = [now()]
  maxD = AAA(1): minD = AAA(1)
  For i = 2 To UBound(AAA)
    If AAA(i) > maxD Then maxD = AAA(i)
    If AAA(i) < minD Then minD = AAA(i)
  Next
  Debug.Print maxD
  Debug.Print minD
  Debug.Print Application.Text([now()] - tm, "hh:mm:ss.00")
End Sub

上記のコードの結果は、私が20回ほど実行しましたが、全て

ブロック形式のIF文 > IF ELSEIFのブロック > IF Else ステートメント

という処理時間でした。
(Dim AAA(1 to 3000000) にすると、顕著な差になるかも・・・)


詳細の解説を待ちます。

【48063】結果発表
発言  Jaka  - 07/4/2(月) 13:31 -

引用なし
パスワード
   2999990
2
00:00:01.61
2999990
2
00:00:01.53
2999990
2
00:00:01.50
-------------
2999999
13
00:00:01.57
2999999
13
00:00:01.54
2999999
13
00:00:01.51
-------------
2999999
5
00:00:02.00
2999999
5
00:00:01.56
2999999
5
00:00:01.54

こういう風な一見解りずらそうなのが、やっぱしコンピュータには解りやすいんでしょうね。
    If AAA(i) > maxD Then maxD = AAA(i)
    If AAA(i) < minD Then minD = AAA(i)

5945 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free