Excel (VBA)

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

 
(Windows 8 : Excel 2016)
空白セル前後の値を抜き出したい
投稿日時: 17/12/27 17:01:02
投稿者: momo0717

現在Excelマクロにて、計測データの読み取りマクロを作成中です。
A〜F列の3行目から計測データが時間とともに表示されています。
H〜L列までに計算後の閾値を超えた値の時間を抜き出すようにしています。
ここまでは、マクロにてできたのですが、ここからができません。
やりたいことは、出力された空白セルの次&前の値(下に記す太字部分)を抜き出すマクロを作成したいです。
 
マクロ初心者で勉強中のため、有識者の皆さまにアドバイスをいただきたく。
 

											
Time	Sample1	Sample2	Sample3	Sample4	Sample5		計算結果				
0	20	20	20	20	20						
0.5	50	50	50	50	50		[b]0.5	0.5	0.5	0.5	0.5[/b]
1	80	80	80	80	80		1	1	1	1	1
1.5	50	50	50	50	50		[b]1.5	1.5	1.5	1.5	1.5
[/b]2	20	20	20	20	20						
2.5	0	0	0	0	0						
3	-20	-20	-20	-20	-20						
3.5	-50	-50	-50	-50	-50						
4	-80	-80	-80	-80	-80						
4.5	-50	-50	-50	-50	-50						
5	-20	-20	-20	-20	-20						
5.5	0	0	0	0	0						
6	20	20	20	20	20						
6.5	50	50	50	50	50		[b]6.5	6.5	6.5	6.5	6.5
[/b]7	80	80	80	80	80		7	7	7	7	7
7.5	50	50	50	50	50		[b]7.5	7.5	7.5	7.5	7.5
[/b]8	20	20	20	20	20						
8.5	0	0	0	0	0						
9	-20	-20	-20	-20	-20						

        [/code]

回答
投稿日時: 17/12/27 17:13:22
投稿者: WinArrow
投稿者のウェブサイトに移動

掲示した表の中で
>出力された空白セルの次&前の値
はよくわかりません。
どこが、空白セルなんですか?
そして、次はどこ?、前はどこ?
 
空白セルを取得するには、
 
ジャンプ機能を使うと、指定したセル範囲の全てのセルが取得できるよ!
 
マクロの記録でコードを作成してみましょう。

回答
投稿日時: 17/12/27 17:46:03
投稿者: 細雪

momo0717 さんの引用:

やりたいことは、出力された空白セルの次&前の値(下に記す太字部分)を抜き出すマクロを作成したいです。
マクロ初心者で勉強中のため、有識者の皆さまにアドバイスをいただきたく。

 
よくわからないです(笑)。
まぁ、サンプルを見る限り
「0.5を足したり引いたりしたら良いんじゃない?」
と無責任に言い放っても良いところなのかもしれませんが・・・(笑)。
 
質問者さんは「やりたいこと」を理解なさっているでしょうが、
回答者は質問文中のわずかな情報を汲み取って理解しようと頑張っているのです。
もうちょっと伝える努力をしていただけると大変助かります。
 
 
とりあえず、キーワードは「次・前」だと思うので、Offset を紹介。
  ドコのセル.Offset(行数, 列数).ヤリタイコト
で、指定した数だけ行方向・列方向に移動したセルを見に行きます。
例えば
  Range("B2").Offset(1, 2).Select
なら、B2セルから1行(下に)・2列(右に)移動したセルですから、D3セルをフォーカスします。
上(左)に移動したいなら負の数を指定してやればOKです。
 
 
現状で出せるヒントって、多分このくらいだと思いますよ。
 

回答
投稿日時: 17/12/27 21:10:03
投稿者: simple

お尋ねの件ですが、
(1)今のデータであれば、
    閾値を超えたTimeが 1 と 7 ということですね。
    0.5, 1.5, 6.5, 7.5 の行を取り出したいということですね。
     
(2) 閾値を超えたTimeは連続することはあるんですか?
    1.5 と 2 のように。
    その時は前後のTimeはどうなるんですか?
    1 と 2.5 ということですか?
    それとも、
    1, 2, 2.5 ということですか?

投稿日時: 17/12/28 11:03:07
投稿者: momo0717

回答いただき、ありがとうございます。
伝え方が悪くもうしわけありません。
補足します。
まず、B〜F列(Sample1〜5)のデータに閾値(50以上80以下)を設けております。
閾値を超えているデータのTime部分を、H〜L列までの同じ行へ抜き出しています。
サンプルで言うと0.5の前のセルが空白、1.5〜6.5の間が空白、7.5以降が空白となります。
 
欲しい値は、0.5、1.5、6.5、7.5・・・・となります。
この値を抜き出すマクロを作成したく。
 
よろしくお願いいたします。

回答
投稿日時: 17/12/28 11:42:13
投稿者: simple

1. 質問時にB〜F列に表示されている数字はデータなんですよね。
   50や80が 閾値(50以上80以下)を超えていると言われても・・・
   もう少し正確な説明をしてください。
 
2.Sample1からSample5まですべて同じ値になっていますが、
  説明の便宜上ですか?
   本当はサンプル毎に判定するのではないんですか?
 
3. 説明例では閾値を超えるのは3つが連続している例しかないですが、
   当然、1つだけというケースもあるはずですね。
   その場合は、何を書き出すのですか?
   ・ひとつのTime だけ? 
   ・それとも同じものを並べた2つのTime?
 
以上の説明があってからコードに進もうと思いますが、
列ごとに定数セルだけを取り出して、それをAreaごとに分離して、
各Areaの最初と最後をとりだす、ということになるんでしょう。

回答
投稿日時: 17/12/28 12:18:49
投稿者: もこな2

次&前の値って、行方向に見てるからTargetになってるセルの1行前と1列後のセルの値ですよね?
言われたとおりですとブランクを拾ったり、同じ数字を2回拾うような気がします。
 
単純に、Targetがブランクセル、かつ、その上のセルがブランクでなかったら値を拾うにしたらどうでしょう
未テストですがこんな感じでは?

Sub Sample()
Dim MyRange As Range
Dim buf As String

For Each MyRange In Range("H:H") 'H1がブランクだとエラーになりそうです。御留意ください。
    If MyRange.Value = "" And MyRange.Offset(-1, 0).Value <> "" Then
        buf = buf & "," & MyRange.Offset(-1, 0).Value
    End If
Next MyRange

'bufの始めの「,」が邪魔だとおもうので適当に処理
MsgBox (Right(buf, Len(buf) - 1))

End Sub

回答
投稿日時: 17/12/28 12:32:58
投稿者: もこな2

あぁそうか、これだと6.5とかが拾えないですね
  
条件式を、自身がブランクであって 1行上か下がブランクでなければ、ブランクでない方を出力に変更でどうでしょう
入れ子にしなくてもいいかもですが、とりあえずこんな感じとか・・・

Sub Sample()
Dim MyRange As Range
Dim buf As String

For Each MyRange In Range("H:H") 'H1がブランクだとエラーになりそうです。御留意ください。
    If MyRange.Value = "" Then
        If MyRange.Offset(-1, 0).Value <> "" Or MyRange.Offset(1, 0).Value <> "" Then _
            buf = buf & "," & MyRange.Offset(-1, 0).Value & MyRange.Offset(1, 0).Value
    End If
Next MyRange

'bufの始めの「,」が邪魔だとおもうので適当に処理
MsgBox (Right(buf, Len(buf) - 1))

End Sub

回答
投稿日時: 17/12/28 13:02:30
投稿者: simple

返事はないが、適当に決め打ちして参考例を書きます。
H列を対象にして、結果をN列に書く例です。
 
最初は、単純に最初と最後をN列に書き出す前提です。

Sub test()
    Dim rng As Range
    Dim area As Range
    Dim k As Long

    Set rng = Range("H2:H100").SpecialCells(xlCellTypeConstants, 23)

    For Each area In rng.Areas
        k = k + 1
        Cells(k, 14).Value = area(1)
        k = k + 1
        Cells(k, 14).Value = area(area.Count)
    Next
End Sub

レポートの下書きに使うなどということなら、
"1〜1.5" のような書式で書き出すことも可能でしょう。
その辺は、そちらでいくらでも工夫してください。
    For Each area In rng.Areas
        k = k + 1
        If area(1) <> area(area.Count) Then
            Cells(k, 14).Value = area(1) & "〜" & area(area.Count)
        Else
            Cells(k, 14).Value = area(1)
        End If
    Next

投稿日時: 17/12/28 14:02:50
投稿者: momo0717

皆さま
ご回答ありがとうございました。
無事、できました。
いろいろとご指摘いただきましたことは、肝に銘じ次回から活かしたいと思います。