Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
FindNextで検索したその合計をメッセージボックスに表示させたい
投稿日時: 21/07/07 07:16:29
投稿者: メロス

お世話になっております。
表題の件でお力頂きたく投稿させていただいております。
 
例えば、Findの検索値を「8」にしたら、メッセージボックスに「340」(270+70)が表示されるようにし、
Findの検索値を「7」にしたら、メッセージボックスに「5040」(340+50+120+4500+30)が表示されるようにしたいと考えています。
 
この方法を考えていたのですが、なかなかうまくいかず、困っております。
解決策についてご教示いただきたいです。
 
 
 
P列                T列     U列
合計値                    
                    
34417                3    3
                    
1500                5    4
17119                6    4
                    
150                8    5
5791                9    5
                    
4100                11    6
281                12    6
1320                13    6
30                14    6
60                15    6
                    
5010                17    5
                    
660                19    6
390                20    6
                    
340                22    7
                    
70                24    8
270                25    8
                    
50                27    7
                    
960                29    6
1140                30    6
420                31    6
840                32    6
120                33    6
420                34    6
60                35    6
                    
6168                37    5
                    
360                39    6
4650                40    6
                    
120                42    7
4500                43    7
30                44    7
                    
1002                46    6
36                47    6
120                48    6
                    
9000                50    4
                    
9000                52    5
                    
347                54    4
21                55    4
42                56    4
80                57    4
12                58    4
6000                59    4
296                60    4
[/code]
 
 
 
Sub 金額の確認()
     
    Dim SearchRng As Range
     
' 列レベルが同じセルを見つける
    Set SearchRng = .Range("U:U").Find(what:="8", Lookat:=xlWhole)
     
' セルが見つかったら実行
    If Not SearchRng Is Nothing Then
        Dim FirstRng As Range
         
' 一番最初に見つかったセルを変数に代入しておく
        Set FirstRng = SearchRng
         
        Dim SearchRngs As Long
        SearchRngs = SearchRng.Offset(0, -5).Value + SearchRng.Offset(0, -5).Value
         
        Do
            Set SearchRng = .Range("U:U").FindNext(SearchRng)
            SearchRng.Interior.ColorIndex = 6
            If SearchRng.Address = FirstRng.Address Then
                Exit Do
            End If
            SearchRngs = SearchRng.Offset(0, -5).Value
        Loop
        MsgBox SearchRngs
    Else
        MsgBox "検索対象が見つかりません"
    End If
     
End Sub

回答
投稿日時: 21/07/07 07:47:40
投稿者: simple

こんにちは。完成一歩手前ですね。
 
これは実際に動作させているものでしょうか。
そのままコピーペイストしたほうがよいと思います。
Withステートメントがないので、
最初の

Set SearchRng = .Range("U:U").Find(what:="8", Lookat:=xlWhole)
でエラーになります。
 
また、
 SearchRngs = SearchRng.Offset(0, -5).Value + SearchRng.Offset(0, -5).Value
と、Do..Loopの中の、
 SearchRngs = SearchRng.Offset(0, -5).Value
の意味を説明してもらえますか?

投稿日時: 21/07/07 07:57:37
投稿者: メロス

ご返信誠にありがとうございます。
実際のコードは下記になります
 
また、
SearchRngs = SearchRng.Offset(0, -5).Value + SearchRng.Offset(0, -5).Value
と、Do..Loopの中の、
 SearchRngs = SearchRng.Offset(0, -5).Value
こちらですが、イメージとしては、P列の値を格納するための変数と考えています。
ご連絡誠にありがとうございます。
 
 
With Worksheets("マクロ")
    Dim SearchRng As Range
     
' 列レベルが同じセルを見つける
    Set SearchRng = .Range("U:U").Find(what:="4", Lookat:=xlWhole)
     
' セルが見つかったら実行
    If Not SearchRng Is Nothing Then
        Dim FirstRng As Range
         
' 一番最初に見つかったセルを変数に代入しておく
        Set FirstRng = SearchRng
         
        Dim SearchRngs As Long
        SearchRngs = SearchRng.Offset(0, -5).Value + SearchRng.Offset(0, -5).Value
         
        Do
            Set SearchRng = .Range("U:U").FindNext(SearchRng)
            SearchRng.Interior.ColorIndex = 6
            If SearchRng.Address = FirstRng.Address Then
                Exit Do
            End If
            SearchRngs = SearchRng.Offset(0, -5).Value
        Loop
        MsgBox SearchRngs
    Else
        MsgBox "検索対象が見つかりません"
    End If
    End With

投稿日時: 21/07/07 07:58:37
投稿者: メロス

すいません。
先ほどのコメントの種類は「追記」です。
よろしくお願いいたします。

回答
投稿日時: 21/07/07 08:16:23
投稿者: simple

SearchRngsなどという謎な変数名にしているから誤解が生じるのでは?
変数の名前はとても重要ですよ。
 

total = SearchRng.Offset(0, -5).Value + SearchRng.Offset(0, -5).Value
total = SearchRng.Offset(0, -5).Value
としてそれぞれ意味が説明できますか?
 
なぜ二回足すのですか?
また、
total = SearchRng.Offset(0, -5).Value
はtotal変数に2回目以降に見つかった所のP列の値を「上書き」していますよね。
全然加算していっていないですよね。
いかがですか?

回答
投稿日時: 21/07/07 11:09:32
投稿者: simple

先走ってしまいますが、こういうことでしょうか。
(1)
最初 に見つかった時点では、単にP列の値を、合計のための変数totalに代入する
だけでよいはずです。

total = SearchRng.Offset(0, -5).Value

(2)
二回目以降に見つかったら、その都度、合計に加算していけばよいと思います。
total = total + SearchRng.Offset(0, -5).Value

このように書くと、両辺にtotalがでてくるので、
普通の数式と違って混乱するのかもしれません。
 
これは、右辺から読みます。
・現在の合計値変数(total)に、新たに見つかったマッチ行のP列の数値を加算し、
・この加算結果を、改めて合計値変数(total)に代入します、
と読みます。
 
以上を踏まえて、修正してみてはいかがですか?

回答
投稿日時: 21/07/07 17:58:13
投稿者: mattuwan44

findnextはLoopの直前がいいかなぁ?
 
処理の順番をもう一度整理しなおしてみてください。
 

Sub てすと()
    Const cSearchValue As String = "8"
    Dim rngTable As Range
    Dim rngFind As Range
    Dim rngTarget As Range
    Dim lngResults As Long
    Dim sfirst As String
    
    '初期値の設定
    Set rngTable = ActiveSheet.UsedRange
    Set rngFind = rngTable.Columns("U")
    lngResults = 0
     
    '最初の検索
    Set rngTarget = rngFind.Find(cSearchValue)
    If rngTarget Is Nothing Then GoTo ErrHandler 'なければ例外処理へ
    sfirst = rngTarget.Address                   '最初のセルのアドレスを記録
        
    '繰り返し
    Do
        rngTarget.Interior.ColorIndex = 6
        lngResults = lngResults + rngTarget.Offset(, -5).Value '累計
        
        '2回目以降の検索
        Set rngTarget = rngFind.FindNext(rngTarget)
    Loop Until rngTarget.Address = sfirst   '最初に戻ったら抜ける
    
    MsgBox lngResults
    Exit Sub

    '例外処理
ErrHandler:
    MsgBox "見つかりませんでした。"
End Sub

 
がんばっておられますが、エクセルのシート上の関数、
Sumif関数を横取りして処理できそうです。
Sub test()
    With ActiveSheet.UsedRange
        MsgBox WorksheetFunction.SumIf(.Columns("U"), 8, .Columns("P"))
    End With
End Sub
 
※動作確認はしてませんので、バグがあったらごめんなさいです。

投稿日時: 21/07/07 19:49:16
投稿者: メロス

[quote="simple"]
SearchRngsなどという謎な変数名にしているから誤解が生じるのでは?
変数の名前はとても重要ですよ。
  
total = SearchRng.Offset(0, -5).Value + SearchRng.Offset(0, -5).Value
total = SearchRng.Offset(0, -5).Value
としてそれぞれ意味が説明できますか?
  
なぜ二回足すのですか?
また、
total = SearchRng.Offset(0, -5).Value
はtotal変数に2回目以降に見つかった所のP列の値を「上書き」していますよね。
全然加算していっていないですよね。
いかがですか?
 

simple さんの引用:
先走ってしまいますが、こういうことでしょうか。
(1)
最初 に見つかった時点では、単にP列の値を、合計のための変数totalに代入する
だけでよいはずです。
total = SearchRng.Offset(0, -5).Value

(2)
二回目以降に見つかったら、その都度、合計に加算していけばよいと思います。
total = total + SearchRng.Offset(0, -5).Value

このように書くと、両辺にtotalがでてくるので、
普通の数式と違って混乱するのかもしれません。
 
これは、右辺から読みます。
・現在の合計値変数(total)に、新たに見つかったマッチ行のP列の数値を加算し、
・この加算結果を、改めて合計値変数(total)に代入します、
と読みます。
 
以上を踏まえて、修正してみてはいかがですか?

 
 
 
ご回答とアドバイス誠にありがとうございます。
加算されなかった理由は変数が上書きされていたためだったのですね。
たいへん勉強になりました。
また、変数も意図が分からない名前の付け方をしてしまっていますね。
「total」に修正します。
 
また、指摘いただいたように修正すると、求めている結果を得ることができました。
 
この度はご回答いただきありがとうございました。