• ベストアンサー

列の数値群の数値の抽出方法(VBA)

エクセルVBAでお願いします。 今、B列にRange(Cells(3,2),Cells(I.2))の範囲にランダムな実数値が 格納されているとします。(Iは変数) この数値群から、正の実数で最小値、または負の実数で最大値を抽出したいのですが、どのようなコードを組めばよいでしょうか。 数値群は大小順ではなくランダムに並んでいるとします。お願いいたします。数値群の数は約20000個あります。

質問者が選んだベストアンサー

  • ベストアンサー
  • onlyrom
  • ベストアンサー率59% (228/384)
回答No.3

オーソドックスにやるなら先ずデータ全てを配列に入れたあと ForとかDo Loopで回しながら比較、という感じでしょうが 正、負でオートフィルターをかけた後、ワークシート関数のMax,Minを使う方法もあるということで。。   (条件) B2に必ず見出し(適当でいい)があること データの範囲は、B3~~任意の行までとする '-------------------------------------------- Sub Test()  Dim MaxValue As Double  Dim MinValue As Double  Dim LastRow As Long  Dim myRange As Range Application.ScreenUpdating = False  LastRow = Cells(Rows.Count, "B").Row  Set myRange = Range(Cells(2, "B"), Cells(LastRow, "B"))  myRange.AutoFilter Field:=1, Criteria1:=">=0", Operator:=xlAnd  MinValue = WorksheetFunction.Min(myRange.SpecialCells(xlCellTypeVisible))  myRange.AutoFilter Field:=1, Criteria1:="<0", Operator:=xlAnd  MaxValue = WorksheetFunction.Max(myRange.SpecialCells(xlCellTypeVisible))  myRange.AutoFilter  MsgBox "最小値: " & MinValue & vbLf & "最大値: " & MaxValue Application.ScreenUpdating = True End Sub '--------------------------------------------- (データ) -200 ■最大値 5555 -300 2222 ●最小値 -500 3333 上記のデータなら、最小値:2222 最大値;-200 を取得します。 以上。  

catshoes01
質問者

お礼

ありがとうございます。助かります。次の方の求め方をみても、いろいろ あるのですね。お礼の点付けに悩みます。返信の速度優先とさせて頂きます。

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 本当には、以下の文章の意味が良く分からないです。 >正の実数で最小値、または負の実数で最大値を抽出したいのですが、 正の実数で最小値、 -> 0より以上で、最小値ということかな? 負の実数で最大値  -> 0より以下で、最大値ということかな? 抽出? 同じものを、やり方を変えて作ってみました。 ただし、両方とも「0」を抜きました。2番は、VBらしく作りました。 もしも、0を入れるなら、片方の不等号の記号を変更すればよいです。 Sub Test1() Dim mMin As Variant Dim mMax As Variant Dim rng As Range   Set rng = Range("B3", Range("B65536").End(xlUp))   mMin = Evaluate("MIN(IF(" & rng.Address & "<=0,""""," & rng.Address & "))")   mMax = Evaluate("MAX(IF(" & rng.Address & ">=0,""""," & rng.Address & "))")   Set rng = Nothing   MsgBox "最小値: " & mMin & vbNewLine & "最大値: " & mMax   End Sub '-------------------------------------------- Sub Test2()   Dim mMin As Variant   Dim mMax As Variant   Dim rng As Range   Dim c As Variant   mMin = Empty   mMax = Empty   Set rng = Range("B3", Range("B65536").End(xlUp))   For Each c In rng     If c.Value > 0 Then       If IsEmpty(mMin) Then         mMin = c.Value       ElseIf c.Value < mMin Then         mMin = c.Value       End If     ElseIf c.Value < 0 Then       If IsEmpty(mMax) Then         mMax = c.Value       ElseIf c.Value > mMax Then         mMax = c.Value       End If     End If   Next c   Set rng = Nothing   MsgBox "最小値: " & mMin & vbNewLine & "最大値: " & mMax End Sub

catshoes01
質問者

お礼

ありがとうございます。ご提示いただいた案をじっくり調べてマスターしたいと思います。特に第一案。繰返し処理のなかで使うのでコードが短いのは大きな魅力です。お礼は回答順とさせて頂きますが、動作すれば多分、第一案 を使いたいと思います。

回答No.2

☆参考まで(無視してもかまいません) 1. [Ctrl]+[F3]名前の定義    名前 : 対象  参照範囲 : =$B$3:$B$65536 2. [Ctrl]+[F3]名前の定義    名前 : 桜  参照範囲 : =$B$3:INDEX($B:$B,COUNT(対象)+2) 3. 希望の値を求める数式    =LARGE(桜,MAX(COUNTIF(桜,">=0"),1)) 抽出はオートフィルタ か フィルタオプションかな

catshoes01
質問者

補足

ありがとうございます。エクセルVBAで考えたいと思います。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

配列にいれて、quick sortするのはいかがでしょうか。負の実数も存在して無視したいなら、配列に転記する時に行えば良いと思います。 http://www5d.biglobe.ne.jp/~tomoya03/shtml/algorithm/QSort.htm http://japan.internet.com/column/developer/20080418/26.html

catshoes01
質問者

補足

ありがとうございます。配列に入れて関数で処理することを考えていました。例えば下記 Dim S As Worksheet Dim NumA As Variant, NumB As Variant Dim Kmin As Double,Kmax As Double Dim I as Integer,Im As Integer,Iq As Integer Set S = Worksheets("Sheet1") Iq = 1 If Cells(Iq, 2) > 0 Then ----------------- Next Iq NumA = S.Cells(1).Resize(I).Value Kmin=Application.MIN(Range(Cells(1,2),Cells(I,2))) Else ------------------ NEXT Im   NumB = S.Cells(1).Resize(Im).Value Kmax=Application.MAX(Range(Cells(1,2),Cells(Im,2))) End IF   IF Cells(I, 2) = 0 Then    以下 略 ここで -----------の行で条件に合致したセルの中味をNumA,NumBに追加する方法(コード)が不明なのです。 (可能かどうかを含めて)関数処理で求める方法を知りたいのです。 空白のセルにいれることはNGで、あくまでもVBAのコードで求めたいのです。

関連するQ&A

  • VBA(多くの数値データの最小値5つを格納する方法)

    VBA(多くの数値データの最小値5つを格納する方法) 現在テキストファイルの数値データを取り出し最小値5つを書き出す動作をVBAで行うつもりでいます。 例  5    9    33    11    1    0.3    0.02     ・     ・     ・     ・ といった形の数値データ行がテキストファイルに存在します。 今現在すべての数値データを格納してエクセルに書き出しそれを並び替え最小値5つ(0を除く)を見て作業を行っております。 この作業をより効率化するために、VBAを用いて0を除いた最小値5つをエクセルシートに書き出すようにしたいのですが、VBAの知識が足らず対策が思い浮かびません。 ・VBAで行いたいこと(わからない部分) 格納するデータを5つに設定して、数値データを順次読み込み最終的に数値データ群の最小値5つ(0を除く)を配列に格納している状態にしたい。 初歩的かもしれませんが、ご回答お願いいたします。

  • VBA 文字列と数値の混在

    Excel VBA 独学中の初心者です。独学中の初心者です。 データ型に関する以下の疑問についてお答えいただける方、よろしくお願い致します。 疑問1.「文字列 & 数値」でエラーにならず、結果は文字列になるようですが、これはVBAの規則上当たり前のことでしょうか。 疑問2.InputBox関数の戻り値は、Typeを省略した場合文字列と思いますが、これを数値型の変数に代入してもエラーは発生しませんでした。これも当たり前のことでしょうか。 具体例は以下です。 ------------------ Option Explicit Sub 文字列と数値の疑問() '初期設定 Cells.Clear Range("A1").Select '本題はここから Dim i As Long Dim j As Long Dim strRange As String Dim strInput As String '------------------ '疑問1の例 i = 2 strRange = "A" & i '疑問1:文字列と数値変数(長整数型)を文字列連結演算子で連結してもエラーにならない。・・・なぜ? '結果は1つの文字列→strRange ="A2" '例 Range(strRange).Select '動作OK Range(strRange) = i '動作OK '------------------ '疑問2の例 strInput = InputBox("選択行を入力してください", , "4") 'strInputは文字列型変数 j = strInput '疑問2:数値変数(長整数型変数)に文字型変数を代入してもエラーにならない・・・なぜ? '結果は長整数型変数(数値) j=4 (Input BOX をデフォルトでOKしたとき) '例:以下の両方とも動作OK '1) strRange = "A" & strInput '文字列 & 文字列 →文字列 strRange ="A4";疑問なし Range(strRange).Select '動作OK Range(strRange) = strInput '2) Cells.Clear '確認用にクリアスクリーン Range("A1").Select '確認用にセル位置移動 strRange = "A" & j '文字列 & 数値 →文字列 strRange ="A4";疑問1と同じ Range(strRange).Select '動作OK Range(strRange) = j '動作OK End Sub

  • Excel VBAのInpuboxの文字列

    Inputboxにセル番地A1を入れ戻り値を変数に格納してその変数をRange またはCellsに組み込む場合、どう記述すればいいでしょうか。

  • VBAの変数の定義について

    いつもお世話になっております。 VBAでの変数の定義についてお尋ねします。 VBAの勉強を始めたばかりの超初心者です。 I.チェック:A列とC列の和をE列に記載してその正誤を判定。 II.リセット:E列をクリアし、A列、C列の数字をランダムに置き換える。 という練習問題のコードを私が書いたものです。 以下について質問させていただきます。 (1)下記はモジュールレベルでの変数の宣言になると思いますが、変数の定義?例えば、最終値 = Range("A4").End(xlDown).Rowはそれぞれのプロシージャで定義しなければならないのでしょうか? (2)モジュールレベルでの変数の宣言は,Dimではなく、Privateでやるべきなのでしょうか? (3)何か指摘事項があれば、教えてください。 超初歩的な質問で、申し訳ありませんが、よろしくお願いいたします。 Option Explicit Dim i As Integer '処理用カウンタ変数 Const 初期値 As Integer = 4 '表の最初 行 Dim 最終値 As Integer '表の最終 行 Sub チェック() 最終値 = Range("A4").End(xlDown).Row '表の最終行番号を取得 For i = 初期値 To 最終値 Step 1 If Cells(i, 1).Value + Cells(i, 3).Value = Cells(i, 5).Value Then 'A列+B列 Cells(i, 5).Font.Color = vbBlue '回答が正ならフォントを青 Else Cells(i, 5).Font.Color = vbRed '回答が誤ならフォントを赤 End If Next i End Sub Sub リセット() 最終値 = Range("A4").End(xlDown).Row '表の最終行番号を取得 For i = 初期値 To 最終値 Step 1 Cells(i, 5).ClearContents '回答をクリア Cells(i, 5).Font.Color = vbBlack '回答のフォントを黒 Cells(i, 1).Value = Int(Rnd * 100) 'A列にランダムな数値 Cells(i, 3).Value = Int(Rnd * 100) 'C列にランダムな数値 Next i End Sub

  • エクセルVBAで複数範囲の変数使用指定方法につい

    エクセルVBAの初心者です。複数の範囲を変数を使用して指定したいのですが、色々と調べてみましたがよくわかりません。 一つの範囲に対しては、下記の方法で正常に動きました。 i1=1 j1=3 i2=4 j2=8 Range(Cells(j1, i1), Cells(j2, i2)).Name = "範囲_全体" 異なる範囲に対して変数を使用せずに名前をつける場合は下記の方法で動くことがわかっています。 Range("A3:A8, C3:C8").Name = "範囲_分離" 但し、例えば Cellsを使用して Range(Cells(3, 1), Cells(8, 1)) と Range(Cells(3, 3), Cells(8, 3)) を まとめて「範囲_分離」と名前を付けたいのですが、よくわかりません。 どなたかご教授方、お願いいたします。

  • エクセル VBA の行選択

    エクセルVBAで行を選択する場合 Rows(1,1).select Range(Cells(2,2),Cells(5, 5)).EntireRow.Select の方法があると知りました。 この数値の部分に変数を入れるとエラーがでてしまいました。 どうすれば変数で行を選択することができるのか教えてください。 2003を使用しております。

  • 列に並んだ数字群から一致する数字の行番号を抽出

    下記のように B列に数字が縦に並んでいます。 28.11684736 28.12102177 28.12519803 28.12937616 28.13355614 28.13773798 28.14192168 28.14610723 28.15029464 28.15448391 28.15867503 28.16286801 28.16706285 28.17125955 28.1754581 この数字群から、例えば 28.15448391 に一致する数字の行を見つけて その行番号を抽出するコードはどのように記述したらよいのでしょうか。 番号はA1のセルに置きます。 但し、条件があって Excel2000~Excel2003の全てのバージョンに共通する こと。そして列のデータ数が約10000程度はあることです。どこから 手をつけてよいのか判らないので、よろしくお願いします。 簡単な例では下記でもよさそうですが。より早く求めるには???  A= Range("B65536").End(xlUp).Row I=0 Do I=I+1 Loop until Cells(I,2).value=28.15448391  Range("A1")=I

  • VBAでの最小値抽出

    ExcelのVBAにおいて,最小値の抽出方法の質問です. たとえばA1に変数nがあり,A2にnの関数(例えば=n^4-2n^3+5n-10とか)があるとします. A1を1から100まで動かしたときのA2の最小値を求めたいのですが,これはそのまま1から100まで値をズラっと出力すれば,あとはそこから最小値を探すだけで求まりますが,こういう方法はとらず,一発でこの最小値を1つのセルに出力させたいのです. いろいろわけあって,使用するセルを最小限におさえたく,この方法が知りたいのです. よろしくお願いします.

  • セルに多次元配列の値を入力する方法

     Dim A as Variant A = Range(Cells(1,1),Cells(10,2)) としてセルのデータを配列変数に格納した場合  Range(Cells(1,2),Cells(10,2)) を  Range(Cells(1,3),Cells(10,3)) に入力するとき  Aを用いて一発で入力する方法はないですか?  今は For i = 1 to 10 cells(i,3) = A(i,2) Next  という方法しか思いつかないのですが時間がかかります。 良い方法があれば教えてください!

  • 2つのVBAを組み合わせる方法

    お世話になります、2つのVBAを組み合わせる方法で迷っています。 1つ目が Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, k As Long, myNum As Long If Intersect(Target, Range("C1,B9:B39")) Is Nothing Or Target.Count > 1 Then Exit Sub Application.EnableEvents = False With Target If .Column = 3 Then myNum = WorksheetFunction.Max(Range("B9:B39")) If IsDate(.Value) Then For i = 9 To 39 If Cells(i, "A").Value = "" Then Cells(i, "B").Value = "" Else Cells(i, "B") = myNum + i - 8 End If Next i End If Else i = .Row If .Value = "" Then Range(Cells(i + 1, "B"), Cells(39, "B")).ClearContents Else For k = i + 1 To 39 If Cells(k, "A").Value = "" Then Cells(k, "B").Value = "" Else Cells(k, "B") = Cells(k - 1, "B") + 1 End If Next k End If End If End With Application.EnableEvents = True End Sub です。 2つめが Private Sub Worksheet_Change(ByVal Target As Range)  Application.EnableEvents = True If Intersect(Target, Range("R8:R38")) Is Nothing Then Exit Sub Application.EnableEvents = False Range(Cells(Target.Row, 18), Cells(39, 18)).Value = Target.Value Application.EnableEvents = True End Sub です。2つのPrivate Sub Worksheet_Change(ByVal Target As Range)イベントのVBAですが、どのようにして組み合わせれば良いのでしょうか?

専門家に質問してみよう