ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

EXCEL VBAコミュの最小値の背景色を変更するプログラムについて

  • mixiチェック
  • このエントリーをはてなブックマークに追加
VBAを始めたばかりなんですけど、"最小値の背景色を変更するプログラム"を卒研で作る必要が出来まして、自分なりにつくったのですが、上手く行きません。
実行すると、
________________________________________________________

実行時エラー'91':
オブジェクト変数またはWithブロック変数が設定されていません。
________________________________________________________

とエラー情報が表示されます。
セルを選択する時にエラーが出ているみたいなのですが、いまいち理解できません。

下に現在のプログラムを参考に記述しておきます。どこが間違っているのかご指導お願いします。



Sub 色付け()

Dim i As Integer
Dim Range1 As Range
Dim Range2 As Range
Dim Range3 As Range
Dim Min1 As Integer
Dim Min2 As Integer
Dim Min3 As Integer

For i = 4 To 23

Min1 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 1)
Set Range1 = Range("Bi:Mi").Find(what:=Min1)
Range1.Select
Selection.Interior.ColorIndex = 1

Min2 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 2)
Set Range2 = Range("Bi:Mi").Find(what:=Min2)
Range2.Select
Selection.Interior.ColorIndex = 3

Min3 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 3)
Set Range3 = Range("Bi:Mi").Find(what:=Min3)
Range3.Select
Selection.Interior.ColorIndex = 5

Next

For i = 28 To 47

Min1 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 1)
Set Range1 = Range("Bi:Mi").Find(what:=Min1)
Range1.Select
Selection.Interior.ColorIndex = 1

Min2 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 2)
Set Range2 = Range("Bi:Mi").Find(what:=Min2)
Range2.Select
Selection.Interior.ColorIndex = 3

Min3 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 3)
Set Range3 = Range("Bi:Mi").Find(what:=Min3)
Range3.Select
Selection.Interior.ColorIndex = 5

Next

For i = 52 To 71

Min1 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 1)
Set Range1 = Range("Bi:Mi").Find(what:=Min1)
Range1.Select
Selection.Interior.ColorIndex = 1

Min2 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 2)
Set Range2 = Range("Bi:Mi").Find(what:=Min2)
Range2.Select
Selection.Interior.ColorIndex = 3

Min3 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 3)
Set Range3 = Range("Bi:Mi").Find(what:=Min3)
Range3.Select
Selection.Interior.ColorIndex = 5

Next


End Sub

コメント(22)

今ここに張ってはる関数「色付け」プロシジャの他にも
関数とクラスがある様に見えますけども。

「オブジェクト変数またはWithブロック変数が設定されていません。」
このエラーはWorksheetFunctionクラスが初期化されてないから出てるんやと思います。

無論、これだけでは何とも言えません(笑)
質問の仕方を工夫してください。丸投げは嫌われるもとです。

ヒント:
 ステップ実行
 Rangeの引数 
個人的にはココがくさそうな気がする。
> Set Range1 = Range("Bi:Mi").Find(what:=Min1)
セル範囲に"Bi:Mi"って名前をつけているってことはないだろうから、
きっと "B" & i & ":M" & i なんでしょうな。

で、それを解決したとしても次にはFindで検索結果がなかった場合に、ないものをSelectしたら、またエラーになるかと…

ココまでの数行ちらっと見ただけですが、とりあえず気付いたので書いておきます。
>[羽]e-bowさん
「色付け」プロシジャの他に関数は作ってません。
>このエラーはWorksheetFunctionクラスが初期化されてないから出てるんやと思います。
ありがとうございます。参考にして、調べなおしてみます。

>ムチオさん
そうですね。一度最小構成のプログラムを作成してから考え直して見ます。
Subを日本語で書くのは本を参考にして、全く気に留めていなかったんですが、普通に考えたらそうですよね。以後気をつけます。

>ofさん
>質問の仕方を工夫してください。丸投げは嫌われるもとです。
そうですね。何度か卒研や課題の丸投げをして叩かれている人を見て、自分がトピを立てる時は気をつけようと思っていたのですが、今客観的にトピを見直してみると全然ダメですね。申し訳ございません。
ヒントはありがとうございます。考えなおして見ます。

>ビリーさん
指摘していただいた構文は、セル範囲をFor Nextでセル範囲をまわそうと思ったのですが、文法が間違っていると言う事でしょうか?
現在の状況を追加で記述しておきます。
解決はしていませんが、最小構成のプログラムにしました。

Sub color()

Dim i As Integer
Dim Range1 As Range
Dim Min1 As Integer

For i = 4 To 23

Min1 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 1)
Set Range1 = Range(Cells(i, 2), Cells(i, 13)).Find(what:=Min1)
Range1.Select
Selection.Interior.ColorIndex = 1

Next
End Sub

超初心者な者ですから、セルの選択方法が間違っているのかと思い、Range("Bi:Mi")をRange(Cells(i, 2), Cells(i, 13))に変えたり、Range("RiR2:RiR13")に変えたりしてみましたが、上手く動きません。

エラーはRange1.Selectの部分で

実行時エラー'91':
オブジェクト変数またはWithブロック変数が設定されていません。

と出るので、Range1にMin1のセルの場所が入っていないのかと思うのですが、分かりません。

Min1 = WorksheetFunction.Small(Range(Cells(i, 2), Cells(i, 13)), 1)
の部分で(i, 2), Cells(i, 13)の中から最小値を探し出し、
Set Range1 = Range(Cells(i, 2), Cells(i, 13)).Find(what:=Min1)
の部分でRange1に探し出した最小値のセルの場所を代入しているので、「最小値を探す時に指定した範囲」と、「見つけた最小値のセルの場所を探す範囲」は同じにしているので、矛盾は無いと思うのですが、なかなか思うように動きません。
Excel97だからなのかどうかよく分かりませんが、どうもSmall
関数は調子が悪いので、Min関数に変えました。
多分、コレなら少なくともエラーにはならずに動作するかと思
います。

Sub Test1()
  Dim i As Long
  Dim Range1 As Range
  Dim Min1 As String
  Dim rngU As Range

  For i = 4 To 23
    Set rngU = Range(Cells(i, 2), Cells(i, 13)) ' …?
    'Set rngU = Range("B" & i & ":M" & i) ' …?
    'Set rngU = Range("Bi:Mi") ' …?
    MsgBox rngU.Address, , "DD 確認用 DD"
    Min1 = WorksheetFunction.Min(rngU)
    Set Range1 = rngU.Find(What:=Min1 _
               , LookIn:=xlValues _
               , LookAt:=xlWhole _
               , MatchCase:=False)
    If Not Range1 Is Nothing Then
      Range1.Interior.color = vbRed
    End If
  Next i
End Sub

セルの指定方法については、?,?,?それぞれをコメントアウト
して試してみてください。

Findメソッドの引数は、安易に削ってはいけません。Findメソッ
ドは一般操作の「検索」です。引数は検索のオプションと同じもの
です。そして、いくつかの引数はデフォルトを持っているのでは
なく、前回に行った「検索」の指定を引き継ぎます。
つまり、安易に引数を削ってFindメソッドを実行するということ
は、検索方法をそのとき任せにすることになり、正しい結果を得
られなくなる可能性があります。
---状況---
'ココでRange1を取得・・・(1)
Set Range1 = Range(Cells(i, 2), Cells(i, 13)).Find(what:=Min1)

'ココで実行時エラー91・・・(2)
Range1.Select
----------
ってコトですね。

(2)で91エラーが出てるってコトは"Range1"が指してるオブジェクトには"Select"メソッドが実装されていないってコトです。
でも、RengeオブジェクトにはSelectメッソドありますよね。
デバッグもしくは、ウォッチ式でこの状態の"Range1"を見てみると多分値は"Nothing"値が入っていると思われます。

つまり、
「"Range1"がNothing値である」
 ↓
「有効なRangeオブジェクトが取得できていない」
 ↓
「FindがRange1にNothingを設定している。」
 ↓
「Findが失敗している。」

と言う事になりそうですな。

※91エラーはそのオブジェクトが実装していないメンバーを参照した場合に出るエラーです。
>ビリーさん
>[羽]e-bowさん

ピリーさんに
教えていただいた通りに、Findメソッドの引数も全て記述したのですが、上手く行きません。というか、プログラム自体は動くのですが、最小値の背景色を変えるという結果を伴っていません。

ビリーさんが作ってくれたプログラムで確認したのですが、

MsgBox rngU.Address, , "DD 確認用 DD"

によって選択範囲であるrngU(ビリーさんのプログラムで言うと)には期待どおりの値が入っています。

しかし、Set Range1を行ったあとに、Range1の内容を確認するif文とメッセージボックスを出すと、Rangeの中に何も入ってないんです。

と言う事は結論として

Set Range1

の構文がどこか間違っていると言う事になると思います。
[羽]e-bowさんの言う通りFindが失敗している様です。

あと、Small関数は最小値から2番目に小さい値と3番目に小さい値を後々使いたいので、Min関数に変える事は出来ません。


Sub color()

Dim i As Integer
Dim Range1 As Range
Dim Min1 As Integer
Dim rngU As Range

For i = 4 To 23

Set rngU = Range(Cells(i, 2), Cells(i, 13))
MsgBox rngU.Address, , "DD 確認用 DD"
Min1 = WorksheetFunction.Small(rngU, 1)
Set Range1 = rngU.Find(What:=Min1 _
, After:=Cells(i, 2) _
, LookIn:=xlValues _
, LookAt:=xlWhole _
, SearchOrder:=xlByRows _
, SearchDirection:=xlNext _
, MatchCase:=False _
, MatchByte:=False)

If Range1 Is Nothing Then
MsgBox "NG"
Else
MsgBox "OK"
Range1.Interior.ColorIndex = 1
End If

Next
End Sub
どうしてもマクロを使わないといけないのでしょうか?
ワークシート関数のRANKと条件付書式を使えば1分足らずでできると思いますが
>ofさん
どうしてもマクロを使わないとダメって事は無いです。
ただ、同じ処理をしたいファイルが大量にあるので、マクロで作業を行う事しか頭に浮かびませんでした。

EXCEL自体が初心者なので、ワークシート関数にどういったものがあるかも知識といて持ち合わせていなかったのも原因ですが…

ofさんの言う通り、ワークシート関数のRANKと条件付書式を使ってやってみます。

アドバイスありがとうございます。

今後もこのプログラムのどこが間違っているのか分かった方は教えていただけると助かります。純粋に気になるので。
先に書いたとおり、Findメソッドは「検索」です。
絶対にヒットする値で「検索」をして、その操作を自動記録した
コードをココにUPしてみてください。
>ビリーさん
最高のヒントありがとうございます!!!

絶対にヒットする値で「検索」してみて、自動記録するのはすごい有効な手段ですね!

検索にヒットしなかった最大の理由は、検索する数値は小数点以下8桁あるのですが、最小値を見つけた値をIntgerで宣言していたことです。簡単なミスで本当に申し訳ございません。

ですが、新しい問題が浮上しまして、singleyやdoubleで少数を表現するとどうしても近似値になってしまい、同じ値を検索してもヒットする事がありません。

excelのセルの書式設定で有効桁を少なくし、Findメソッドの引数LookAtを"部分的に一致するセルを検索"であるxlPartにしてもヒットしません。

検索する前にMsgBoxで検索にかける数値を表示させ、その値と実際にexcelに表示されている値が見た目で同じなんですけど、ダメみたいです。

こういった場合はexcelのデータ自体を10の何乗倍かして、整数にしてから検索するしか方法は無いんでしょうか?

質問ばかりですいません。

下に現在のプログラムコードを記述しときます。


Sub color()

Dim i As Integer
Dim Range1 As Range
Dim Min1 As Double
Dim rngU As Range

For i = 4 To 23
Set rngU = Range(Cells(i, 2), Cells(i, 13))
MsgBox rngU.Address, , "DD 確認用 DD"
Min1 = WorksheetFunction.Small(rngU, 1)
MsgBox Min1
rngU.Select
Selection.Find(What:=Min1, After:=Cells(i, 2), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False).Activate
If Range1 Is Nothing Then
MsgBox "NG"
Else
MsgBox "OK"
Range1.Interior.ColorIndex = 1
End If
Next
End Sub
私が先に提示したコードでもダメでしたか?
Stringにしているのですが…

あと、数値全体が表示されるようにセルの幅を広くしてみて
ください。

部分一致で検索するのは言うまでもなく論外です。
>>7のビリーさんの書き込み、

> Excel97だからなのかどうかよく分かりませんが、どうもSmall
> 関数は調子が悪いので、Min関数に変えました。

を見てもしやと思ったので書き込みします。
話の流れにそっていないのでしょうが、
VBA知識の共有だと思って聞き流してみてください。

参照範囲となるセルの値の中に数値が1つも存在しない状態を
「Xの状態」と仮称します。(適当に名づけただけです)
全て空白とか、どこかに文字列があるだけとかの状態です。

small()関数は、第一引数の参照範囲がXの状態だとエラーが発生します。

1年ぐらい前に自分の書いたコードでエラーが発生し、コードは合ってるのになぜだ!?と思って解析していった結果、初めてこのことを知りました。
a1〜c1までがXの状態で実際にシート上の標準関数で=small(a1:c1,1)と入力すると #num!エラーとなります。(maxやminでは0が返る)

Xの状態でminやmaxで 0 が返るってことは、Xの状態ではそれぞれのセルが 0 として評価されている?
だったらsmallで「1番小さいやつ」を調べら 0 を返してくれてもええやん!ってMicrosoftに腹を立てたことがあったのを思い出しましたw(未だに納得できませんが)

large()関数でも同様です。
small、largeの#num!になる他の場合もあるのですが、
それは確かヘルプに書いてあったと思うので省略します。

以上です。
ちょっと時間あったんで、この件検証してみました。
最終的な原因はrange.findメッソッドの仕様の様です。

検証した結果だと、Findでひっかけられる少数の値は10^-1までつまり、小数点一桁目 0.*までの様です。
以下のデータで行にFindで検索をかけると0.1がヒットしました。
0.1 0.2 0.3 0.4

以下の場合検索結果はNothingです
0.01 0.02 0.03 0.04

こうなるとこの場合、Findは使えませんが、自前でFindに変わる物を実装してやれば良い訳です。
Findとの置き換えに重点を置いて関数化しましたが、
実用的にはこれくらいならベタ書きでもいいですね。
ちなみにベタ書きする場合、それぞれ条件が一致している場合の動作(ループ抜けたり、コレクション追加したり)の部分でセルの色の書き換えやったったらええだけです。

--実装例--
'1.同じ値が複数あっても前の値を返す(既存実装と同等)
Private Function myFind(Key As Single, Fields As Range) As Range
  Dim CarCell As Range

  For Each CarCell In Fields
    If CarCell.Value = Key Then
      Exit For
    End If
  Next
  Set myFind = CarCell
End Function
---
'2.その行の検索条件にヒットするものは全て返す。
Private Function myFind(Key As Single, Fields As Range) As Collection
  Dim CarCell As Range

  Set myFind = New Collection
  For Each CarCell In Fields
    If CarCell.Value = Key Then
      myFind.Add CarCell
    End If
  Next
End Function
---
2の場合戻り値がRangeでなくコレクションなんで上位でFor eachで回してやる必要ありますな。
よっちゃんさんへ

私がいい加減にさっくり切り捨てた所を調べて頂いてありがと
うございます。
ただ、私が切り捨てた理由は、そういうことではないのです。

もう昨日のことなので忘れてしまったのですが、、、
会社のPC(Excel97)では、ワークシート上のSMALL関数ではき
ちんと数値が返ってくるのに、VBAでWorksheetFunction.Small
とするとエラーになったような気がします。
# 既に忘却の彼方に飛ばしてしまったので、勘違いかもしれません。
うちのPC(Excel2003)では、再現しないのでもしかしたら昨日
の朝はどーにかしていたのかもしれません。
ワークシート上でエラーになるのがVBAでもエラーになるという
話だけなら、そりゃそうだろうと納得します。

月曜日にでも、もう一度確認してみます。
その結果、ワークシート上でエラーにならないのに、
VBAでエラーになるようなら、新たに別にトピックを立てて、
報告します。
# このトピックであまりこの件について突っ込むと本筋から脱線
# しすぎの感がするので。

余談ですが、実行時エラーを発生させたくないなら、
Application.Smallを使うって手もありますね。
ま、どっちみち返ってくるのは、エラーですが。(-_-;)

これは、他のワークシート関数でもWorksheetFunctionで実行時
エラーになるケースで使えるので、知っておくと便利かも?
On Error Resume Next等が要らない分だけ、すっきりするという
メリットしかないかもしれませんが。

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

[羽]e-bow さんへ

> 最終的な原因はrange.findメッソッドの仕様の様です。

> 検証した結果だと、Findでひっかけられる少数の値は10^-1まで
> つまり、小数点一桁目 0.*までの様です。
これは本当に本当ですか?

私が検証した限りでは、
=VALUE(TEXT(RAND()*0.001,"0.00000000"))
でサンプルデータを作っても大丈夫でしたが?
念のため解説しますと、実際に↑の関数を作れば分かりますが、
0.1よりも小さな値になります。

さすがにExcelの仕様ぎりぎりの桁数で大丈夫かといわれると
未確認ですが、少なくとも今回は「小数点以下8桁」とのことな
のでいけるかと。
ちなみに2006年02月04日 04:53のレスでも仄めかしましたが、
ヒットするかどうかはセルの幅にも依存します。
(LookIn:=xlValues の場合は!)

# 「WorksheetFunctionクラスが初期化されてないから」のレスと
# いい どうも信憑性にかけるレスを連発している印象を受けま
# すが、気のせいでしょうか?

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

Yozさんへ

昨日からの私のレスをすべて反映した上で、それでも正しく色
がつかないようでしたら、ブックを送ってもらえればちょっと
調べてみます。
それで差し支えなければ、とりあえずメッセージをください。

さて、書き込むついでに、Findメソッドと同じ用途でよく使わ
れるMATCH関数を利用したコードを書いておきます。

Sub Test2()
  Dim i As Long
  Dim Min1 As Double
  Dim MatchRe As Variant
  Dim rngU As Range

  Cells.Interior.ColorIndex = 0
  For i = 4 To 23
    Set rngU = Range(Cells(i, 2), Cells(i, 13))
    Min1 = WorksheetFunction.Min(rngU)
    MatchRe = Application.Match(Min1, rngU, 0)
    If Not IsError(MatchRe) Then
      rngU(MatchRe).Interior.Color = vbRed
    End If
  Next i
End Sub
Yozさんから実際のブックを貰って調べてみました。

まず、小数点以下8桁とレスにありましたが、これは違いました。
実際には何も加工されていないので、フルに桁数を値として持
っていました。
ただ、表示上は小数点以下9桁までしか表示されていませんで
したが。

そして、Findメソッドでひっかからない理由はやはり実際の表
示と検索値の不一致が原因でした。

例えば、B4:M4の最小値(MIN関数またはSMALL関数の戻り値)は
-2.27530864197531
でしたが、セル上の表示は、
-2.275308642
です。
これは、一般操作の「検索」でも-2.27530864197531ではヒットせず、
-2.275308642でヒットします。
ということは…
>    Min1 = WorksheetFunction.Min(rngU)
の直後に
    Min1 = WorksheetFunction.Round(Min1, 9)
と一発かませばいいはずです。
Sub Test1R()
  Dim i As Long
  Dim Range1 As Range
  Dim Min1 As Double
  Dim rngU As Range
  Dim shtA As Worksheet

  Set shtA = Worksheets("傾きの比較表")
  For i = 4 To 23
    Set rngU = shtA.Range(shtA.Cells(i, 2), shtA.Cells(i, 13))
    rngU.Interior.ColorIndex = 0
    Min1 = WorksheetFunction.Min(rngU)
    Min1 = WorksheetFunction.Round(Min1, 9)
    Debug.Print rngU.Address; Min1
    Set Range1 = rngU.Find(What:=Min1 _
               , LookIn:=xlValues _
               , LookAt:=xlWhole _
               , MatchCase:=False)
    If Range1 Is Nothing Then
      MsgBox "nothing"
    Else
      MsgBox Range1.Address, , "DD 確認用 DD"
      Range1.Interior.Color = vbRed
    End If
  Next i
End Sub


ついでなので、MATCH関数の方も少々手直ししておきます。
MATCH関数の方は四捨五入をする必要がなくそのままの値で評価
するので、今回はコチラを使った方が適切かもしれません。
Sub Test2R()
  Dim i As Long
  Dim Min1 As Double
  Dim MatchRe As Variant
  Dim rngU As Range
  Dim shtA As Worksheet

  Set shtA = Worksheets("傾きの比較表")
  For i = 4 To 23
    Set rngU = shtA.Range(shtA.Cells(i, 2), shtA.Cells(i, 13))
    rngU.Interior.ColorIndex = 0
    Min1 = WorksheetFunction.Min(rngU)
    MatchRe = Application.Match(Min1, rngU, 0)
    If Not IsError(MatchRe) Then
      rngU(MatchRe).Interior.Color = vbRed
    End If
  Next i
End Sub

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

オリジナルのYozさんのコードはコレです。
Sub color()

  Dim i As Long
  Dim Range1 As Range
  Dim Min1 As String
  Dim rngU As Range
  
  For i = 4 To 23
    Set rngU = Range(Cells(i, 2), Cells(i, 13))
    MsgBox rngU.Address, , "DD 確認用 DD"
    Min1 = WorksheetFunction.Small(rngU, 1)
    MsgBox Min1
    rngU.Select
    Selection.Find(What:=Min1, After:=Cells(i, 2), LookIn:=xlValues, _
    LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
    MatchCase:=False).Activate
    If Range1 Is Nothing Then
      MsgBox "NG"
    Else
      MsgBox "OK"
      Range1.Interior.ColorIndex = 1
    End If
  Next
End Sub

せっかくなので、コレについても気付いた点をコメントして
おきます。

・プロシージャ名にcolorを使うのは止めた方がいいです。
・Range1へのセットをしていないので、Findの結果に関わらず
 常にRange1はNothihgになります。(私のコードとの違いを
 良く見て、意味を理解してください。)
・Interior.ColorIndex = 1 はデフォルトでは黒です。
当事者以外の方への補足
検索範囲のセルには計算式が入っていました。
従って、Findメソッドの引数LookInはxlValuesである必要が
ありました。

直接、値が入っていたなら、、、分かりますね?
# 書くのがめんどくさくなってきたので、説明は割愛します。
>ビリーさん
ありがとうございます!!

>・プロシージャ名にcolorを使うのは止めた方がいいです。
分かりました。

>・Range1へのセットをしていないので、Findの結果に関わらず
> 常にRange1はNothihgになります。(私のコードとの違いを
> 良く見て、意味を理解してください。)
理解しました。初期の段階ではRange1へセットしていたのですが、色々なアドバイスや自分で調べた事を反映して行く過程でRange1へセットしない状態になったみたいです。
ちゃんと確認しないとダメですね。すいませんでした。

>・Interior.ColorIndex = 1 はデフォルトでは黒です。
色は何でも良いのでとりあえず動く様にだけしようと思ったので、何にも考えずに1にしました。
ここまではとりあえずエラーにならないコードを作ることを目
的にいろいろ見てきましたが、本来の目的である最小値に色を
つけることに着目すると実は↑のTest1RもTest2Rも正しくあり
ません。

どのようなケースにおいて、誤りが生じるかというと…
1.最小値が複数ある場合
2.小数点以下10桁以降のみに差異がある場合
です。
なお、Test2Rでは、2.の誤りは生じません。

ま、百聞は一見に如かずということで、、、
新規ブックを作って、そこに↓のコードでサンプルデータを作
ってください。
Sub テスト用データ作成()
  Dim shtA As Worksheet
  Dim aryA(1 To 2) As Variant

  ' 最小値は4番目の要素
  aryA(1) = Array("=1/9", "=1000/2345678", "=1/7", "=1000/2345679", "=1/3")
  ' 最小値は2番目と4番目の要素
  aryA(2) = Array("=1/9", "=1/11", "=1/7", "=1/11", "=1/3")
  Set shtA = Worksheets("Sheet1")
  shtA.Range("A1:E1").Value = aryA(1)
  shtA.Range("A2:E2").Value = shtA.Range("A1:E1").Value
  shtA.Range("A3:E3").Value = aryA(2)
  shtA.Range("A4:E4").Value = shtA.Range("A3:E3").Value
End Sub

そして、このTestMainで?〜?を順番にコメントを外して有効
な状態にして、試してみてください。

?.Test1Rと本質的に同じもの
?.最小値が複数の場合にも対応できるように?を修正したもの
?.?からRound関数を除き、検索方法を変えたもの
?.Test2Rと本質的に同じもの
?.単純なループを使ったもの

Sub TestMain()
  Dim i As Long
  Dim Rtn As Boolean
  Dim Min1 As Double
  Dim rngU As Range
  Dim shtA As Worksheet

  Set shtA = Worksheets("Sheet1")
  For i = 1 To 4
    Set rngU = shtA.Cells(i, "A").Resize(, 5)
    rngU.Interior.ColorIndex = 0
    Min1 = WorksheetFunction.Min(rngU)
    Debug.Print rngU.Address; Min1; "TestMain"
    'Rtn = SubFindVer1(rngU, Min1) ' … ?
    'Rtn = SubFindVer2(rngU, Min1) ' … ?
    'Rtn = SubFindVer3(rngU, Min1) ' … ?
    'Rtn = SubMatchVer1(rngU, Min1) ' … ?
    'Rtn = SubLoopVer1(rngU, Min1) ' … ?
    If Not Rtn Then
      MsgBox i & " 行目は該当なし。"
    End If
  Next i
End Sub

Function SubFindVer1(ByRef ArngU As Range _
          , ByVal AMin As Double) As Boolean
  Dim rngF As Range

  AMin = WorksheetFunction.Round(AMin, 9) '誤りの原因A
  ' 値で検索する
  Set rngF = ArngU.Find(What:=AMin _
            , LookIn:=xlValues _
            , LookAt:=xlWhole _
            , MatchCase:=False)
  If Not rngF Is Nothing Then
    Debug.Print rngF.Address; rngF.Value; "SubFindVer1"
    rngF.Interior.Color = vbRed
    SubFindVer1 = True
  End If
End Function

Function SubFindVer2(ByRef ArngU As Range _
          , ByVal AMin As Double) As Boolean
  Dim rngF As Range
  Dim wKADRS1st As String

  AMin = WorksheetFunction.Round(AMin, 9) '誤りの原因A
  ' 値で検索する
  Set rngF = ArngU.Find(What:=AMin _
            , LookIn:=xlValues _
            , LookAt:=xlWhole _
            , MatchCase:=False)
  If Not rngF Is Nothing Then
    wKADRS1st = rngF.Address
    Do
      Debug.Print rngF.Address; rngF.Value; "SubFindVer2"
      rngF.Interior.Color = vbYellow
      Set rngF = ArngU.FindNext(After:=rngF)
    Loop Until wKADRS1st = rngF.Address
    SubFindVer2 = True
  End If
End Function

Function SubFindVer3(ByRef ArngU As Range _
          , ByVal AMin As Double) As Boolean
  Dim rngF As Range

  ' 数式で検索する 誤りの原因B
  Set rngF = ArngU.Find(What:=AMin _
            , LookIn:=xlFormulas _
            , LookAt:=xlWhole _
            , MatchCase:=False)
  If Not rngF Is Nothing Then
    Debug.Print rngF.Address; rngF.Value; "SubFindVer3"
    rngF.Interior.Color = vbCyan
    SubFindVer3 = True
  End If
End Function

Function SubMatchVer1(ByRef ArngU As Range _
          , ByVal AMin As Double) As Boolean
  Dim MatchRe As Variant
  Dim rngA As Range

  MatchRe = Application.Match(AMin, ArngU, 0) '誤りの原因C
  If Not IsError(MatchRe) Then
    Set rngA = ArngU(MatchRe)
    Debug.Print rngA.Address; rngA.Value; "SubMatchVer1"
    rngA.Interior.Color = vbMagenta
    SubMatchVer1 = True
  End If
End Function

Function SubLoopVer1(ByRef ArngU As Range _
          , ByVal AMin As Double) As Boolean
  Dim rngA As Range

  For Each rngA In ArngU
    If rngA.Value = AMin Then
      Debug.Print rngA.Address; rngA.Value; "SubLoopVer1"
      rngA.Interior.Color = vbBlue
      SubLoopVer1 = True
    End If
  Next rngA
End Function

実行すれば、どうなるのか分かるはずなので実行結果は書きませ
ん。
何故、そうなるのかは…もし分からなければ質問してください。
>Findの件
どうも僕の解析ミスやったみたいですね。
こないだ解析したブツが残ってないんでなんでかは不明ですが、その様な動作をしていたのは確かです。
さっき、再度やってみたら浮動小数点もきれいにマッチングしてますね。
失礼いたしやしたm(__)m

ログインすると、残り1件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

EXCEL VBA 更新情報

EXCEL VBAのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。