プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になってます。
またわからないのでご教授下さい。

添付画像のようにBに№1から№6までの番号を振っています。
例えば、№1であれば8行目から15行目が№1の行範囲です。構成は、№と記入したセルの上に空白行があり、その下に№と記入したセルがありその下の行に品名があり、その下が結合セルになっており、この結合セルの行数は挿入したり削除したりと変動します。結合セルも下にもう1行あります。これで一つの№の行の塊になります。行数は変数jで取得しています。

問題は、№の行の塊が丸ごと非表示になっている場合があることです。複数非表示の可能性もあります。
添付画像では№2が非表示になっています。

やりたいことは、インプットボックスに№の数字を入れると、その№の行が表示されていればその№の行の塊で非表示にして、非表示ならば、再表示したいと思っています。
Findで検索して検索できた場合は、№の行は表示されているはずなので普通に非表示にできました。
問題は、非表示の場合どこに表示したい№が書いてあるか見つけられないことです。
画像では、№2の位置が見つからないので下のコードの Else の部分に非表示だった場合の処理を記述する必要がありますが、いい方法が思いつきませんでした。
何か、良い方法があるでしょうか?
よろしくお願いいたします。


Sub sample()
Dim buf As Long
Dim p As Long
Dim j As Long
Dim Titles As Variant
Dim v As Variant
Dim bufRng As Range
Dim TargetCell As Range

buf = InputBox("№の数字を入力してください")

For p = 1 To 6
Titles = Array("№" & p)

For Each v In Titles 'vに№1、№2、№3・・・と入れていく
Set bufRng = Columns(2).Find(What:=v, LookIn:=xlValues) '2(B)列目から№を検索
If Not bufRng Is Nothing Then
   Set TargetCell = bufRng
If TargetCell = "№" & buf Then
 'jに結合の行数を数えて(№の上と№と名前の行と下1行分の合計4行)の結合していない行もプラス
j = TargetCell.Offset(2, 0).MergeArea.Rows.Count + 4
'№*の範囲全体を非表示してやる
TargetCell.Offset(-1, 0).Resize(j, 1).EntireRow.Hidden = True
End If

Else
'検索できなかった№は非表示になっていると考えられるのでその場所を特定してその範囲を再表示する
?????.Offset(-1, 0).Resize(j, 1).EntireRow.Hidden = False
  End If

 Next v
Next p

End Sub

「Excel2013VBAでFindで検索」の質問画像

質問者からの補足コメント

  • そうですね。多分xlFormulasで検索すれば見つかるであろうことは知っていたので、№を固定されたところから数式でひっぱってくれば簡単に行けるのであろうとは思いましたが、増やしたり減らしたりする場合もあるので、自分で追加する場合はその辺の事情が分かるからいいんですが、他の人が使う事を想定すると№を数式でよそから引っ張ってくるという方法は避けたいというのがあったので、何らでみつけられないかな?と思って質問しました。
    最初の№と最後の№は非表示であっても見つけることができるのですが、真ん中の方はちょい難しいです。
    あきらめて、数式入れて検索かけるしかないんですかね?

    No.1の回答に寄せられた補足コメントです。 補足日時:2016/11/20 19:06
  • 分かりにくくてすみません。
    実際は、最後の番号は6という指定ではなく変数で指定しており増減します。
    このシートの作りが分からない人が、増減の操作を行う可能性があります。(数式で№を入れてください、と伝えておけば問題ないと思いますが、それも何だかすっきりしなかったのでいい方法を思いつく方がいればお知恵を拝借したいと思いまして)

    ループさせている意味は、まず第一段階として、ループで拾えなかった番号は非表示になっているために検索できなかった番号だと認識できるかな?と、拾えない番号をまとめて格納できるならそれを利用して何とかできないだろうか?という所から始めたのでとりあえずループさせていました。

    No.3の回答に寄せられた補足コメントです。 補足日時:2016/11/20 20:36

A 回答 (4件)

こんにちは。



これでうまくいくかは分かりませんが、要するに、最初にRangeの範囲を非表示・表示に関わりなく、その構造をCollection変数に登録しておいて、そこから導き出す方法を、最初、配列にしようかと思いましたが、なんとくなくそちらのほうがよいかなと考えました。非常にたくさん数があるのでしたら、その範囲の登録は別にすると良いと思います。あまり格好が良くありませんが、試してみてください。ダメなら、また別な方法を考えます。表示・非表示はトグルにしています。

Range(Cells(1, 2), Cells(Rows.Count, 2).End(xlUp)

列の範囲の決め方は、全体が見えていませんので、これで良いのかは、疑問が残ります。

'//
Sub TestMacro()
 Dim rng As Range
 Dim sRng As Range
 Dim colRng As Collection
 Dim r As Variant
 Dim i As Variant
 Dim bln As Boolean
 Set colRng = New Collection  '★
 Set rng = Range(Cells(1, 2), Cells(Rows.Count, 2).End(xlUp))
 Set sRng = rng.SpecialCells(xlCellTypeConstants)
 For Each r In sRng
  If r.Value Like "№*" Or r.Value Like "その他*" Then
   colRng.Add r
  End If
 Next r
 i = InputBox("№の数字を入力してください")
 If StrPtr(i) = 0 Then Exit Sub
 i = CLng(i)
 If colRng.Count > i Then
  bln = Not (colRng(i).EntireRow.Hidden)
  Range(colRng(i).Offset(-1), colRng(i + 1).Offset(-1)).EntireRow.Hidden = bln
 ElseIf colRng.Count = i Then
  '最後尾のセル群です。サイズは、3行にしました。
  bln = Not colRng(i).EntireRow.Hidden
  colRng(i).Offset(-1).Resize(3).EntireRow.Hidden = bln
 End If
End Sub
    • good
    • 0
この回答へのお礼

解決しました

いつもいつもありがとうございます。
希望通りに動作しました。
しいていうと1箇所Offset範囲が違っていたかな、というくらいでしたが、すぐ修正できたので問題ありませんでした。
Range(colRng(i).Offset(-1), colRng(i + 1).Offset(-2)).EntireRow.Hidden = bln
列?行の範囲の決め方は実際に合わせて修正したり、最後尾のセルたちの範囲も自分で修正できたので思い通りになりました。
Collectionというのは、今回初めて見ました。1行ずつ動作をみていると、漠然とですが動作がわかりました。
Set sRng = rng.SpecialCells(xlCellTypeConstants)で、色々取得しているのはなるほど、と思いました。
非表示状態であっても、色々検索できるものですね。

お礼日時:2016/11/20 22:30

再度の補足、ありがとうございます。

ただ、やはり意味がわかりませんでした。
本当の課題は、「プログラミングの方法」ではなく、「ユーザの操作方法をどうするか」なのでしょうか?
であれば、質問のしかたを変えないと有効な回答は得られないと思いますよ。回答者側では、細かい事情が分からないですから…。
    • good
    • 0
この回答へのお礼

色々考えてください、どうもありがとうございました。
一応、全く別のやり方ですが、他の方の回答で思い通りの動作をするものがでてきました。

お礼日時:2016/11/20 22:20

すいません。

補足コメントの内容が理解できませんでした。サンプルでは、No.6までしかないが、増える可能性があるということでしょうか?
そもそも私には、No.1~No.6までループさせている意味が分かりませんでした。入力されたNo.を検索して、表示・非表示を切り替えるだけなら、次のようなコードで十分だと思うのですが…。

Sub sample()
Dim buf As Long
Dim j As Long
Dim v As Variant
Dim TargetCell As Range
buf = InputBox("№の数字を入力してください")
v = "№" & buf
Set TargetCell = Columns(2).Find(What:=v, LookIn:=xlFormulas)
If Not TargetCell Is Nothing Then
j = TargetCell.Offset(2, 0).MergeArea.Rows.Count + 4
TargetCell.Offset(-1, 0).Resize(j, 1).EntireRow.Hidden = _
TargetCell.EntireRow.Hidden Xor True
End If
End Sub
この回答への補足あり
    • good
    • 0

「見つからない」ということは「位置を特定できない」ということなので、何らかの方法で「見つける」必要があります。


一番手っ取り早いのは、FindメソッドのLookInパラメータをxlFormulasにすることにより、非表示の行でも見つけてくれます(たぶん)。
見つかった行のHiddenプロパティを判断して、表示、非表示を切り替えれば、いけるような気がします。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!