Excel VBA 質問スレッド №2136 (解決済)

入力が無いセルから指定の行までをグループ化して閉じる。

投稿者 : 素人(No.2128)     投稿日時 : 2025/07/09(Wed) 14:53:40     OS : Windows 11     EXCEL : Excel 2021
No.2128で質問させていただいた素人です。

前回の質問で、作成していただいたコードを発展させ、セル"H32,H51,H70,H89,H108,H127,H146,H165"に文字列"№1,№5,№6,№4,№3,№7,№2,№8"のいずれも入力が無い場合は、入力が無いセルの行から指定の行(182)までをグループ化して閉じたいと考えております。

ところが、H32=№1,H51=№3,H70=№5、と入力すると行70から行182までをグループ化して閉じてしまいます。

たぶんarrの順で№5の後に№3が来るため、この挙動をしているのだと思うのですが、直し方が分かりません。
(H70に№6,№4を入力しても同様の挙動となります。)

arrの順で図形番号(shapes(i+1))になっているので、arrの順は直せないと考えております。

どうしたらよいでしょうか、宜しくお願いいたします。

Sub 図形
    Dim i As Long, j As Long
    Dim arr As Variant
    arr = Array("№1", "№5", "№6", "№4", "№3", "№7", "№2", "№8")
    For i = 0 To UBound(arr)
        For j = 0 To 7
            If Cells(j * 19 + 32, "H") = arr(i) Then
                ActiveSheet.Shapes(i + 1).Visible = msoTrue
                ActiveSheet.Rows.ClearOutline
                ActiveSheet.ResetAllPageBreaks
                    If Cells(j * 19 + 51, "H") <> arr(i) Then
                        Range("A" & j * 19 + 51, "A182").Rows.Group
                        ActiveSheet.Outline.ShowLevels RowLevels:=1
                    End If
                Exit For
            End If
            ActiveSheet.Shapes(i + 1).Visible = msoFalse
        Next j
    Next i
End Sub

スポンサーリンク
[返信 1] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : さんこう     投稿日時 : 2025/07/09(Wed) 17:09:29
>たぶんarrの順で№5の後に№3が来るため、この挙動をしているのだと思うのですが

それもありますが、もっと根本的な問題があります。

どんな動作をしているかわかるようにしてみました。参考になれば。

Sub 原因調査()
    Dim i As Long, j As Long
    Dim arr As Variant
    arr = Array("№1", "№5", "№6", "№4", "№3", "№7", "№2", "№8")
    For i = 0 To UBound(arr)
        For j = 0 To 7
            If Cells(j * 19 + 32, "H") = arr(i) Then
                'ActiveSheet.Shapes(i + 1).Visible = msoTrue
                ActiveSheet.Rows.ClearOutline
                MsgBox "アウトラインをクリアしました"   '追加
                ActiveSheet.ResetAllPageBreaks
                If Cells(j * 19 + 51, "H") <> arr(i) Then
                    Cells(j * 19 + 51, "H").Select              '追加
                    Range("A" & j * 19 + 51, "A182").Rows.Group
                    ActiveSheet.Outline.ShowLevels RowLevels:=1
                    MsgBox "H" & j * 19 + 51 & "セルが「" & arr(i) & "」ではないので、アウトラインを設定しました"   '追加
                End If
                Exit For
            End If
            'ActiveSheet.Shapes(i + 1).Visible = msoFalse
        Next j
    Next i
End Sub

[返信 2] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : ピロリ     投稿日時 : 2025/07/09(Wed) 18:43:26
念のための確認ですけど・・・

■[質問] 素人(No.2128)さん(2025-07-09 14:53:40)の記事
> 入力が無いセルの行から指定の行(182)までをグループ化して閉じたい・・・
ということは、

H32=№1,H51=№3,H70=№5,H89=(未入力),H108=(未入力),H127=(未入力),H146=(未入力),H165=(未入力)
ならば、未入力の89行目~指定行の182行目までをグループ化して閉じたいってことなのでしょうけど、

H32=№1,H51=№3,H70=№5,H89=(未入力),H108=(未入力),H127=№6,H146=№8,H165=(未入力) とかでも、
未入力の89行目~指定行の182行目までをグループ化して閉じたいってことですか?
89行目~126行目までと、165行目~182行目までって話ではなくて・・・

また、指定行の182行目というのは問題無いですか? 183行目ではなくて・・・

[返信 3] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : 素人(No.2128)     投稿日時 : 2025/07/10(Thu) 09:58:06
さんこうさん ありがとうございます。
私が想定していた間違っている動きになっていました。初めは「If Cells(j * 19 + 51, "H") <> arr(i) Then」ではなく、「If Cells(j * 19 + 51, "H") = "" Then」にしてみたのですが、アウトラインを設定してくれなかったので、今の形にしました。

ピロリさん ありがとうございます。
ご指摘のとおり、「未入力の89行目~指定行の182行目までをグループ化して閉じたい」と考えております。

指定のセルに順番に入力することを想定しておりますが、確かに入力が無い箇所を閉じた方が、使い勝手が良い気もします。
行32~行50、行51~行69・・・が、一つ一つの表の形になっているので、その範囲を指定して閉じてもいいかもしれません。

[返信 4] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : 素人(No.2128)     投稿日時 : 2025/07/10(Thu) 15:29:38
「If Cells(j * 19 + 51, "H") = "" Then」が反応しない理由が分かりました。
"H32,H51,H70,H89,H108,H127,H146,H165"セルに数式で関数「IFERROR(VLOOKUP)」が入力されており、VLOOKUPが"0"を返してました。
その"0"を表示形式で空欄に見せかけていました。

[返信 5] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : 素人(No.2128)     投稿日時 : 2025/07/10(Thu) 16:04:35
VLOOKUPが"0"を返してたことが判明したので、一応、想定の動きをするようになりました。
ピロリさんが、提案してくれたように、表ごとをグループ化するようにしてみました。

いかがでしょうか。

Sub 図形()
    Dim i As Long, j As Long, k As Long
    Dim arr As Variant
    arr = Array("№1", "№5", "№6", "№4", "№3", "№7", "№2", "№8")
    For i = 0 To UBound(arr)
        For j = 0 To 7
            If Cells(j * 19 + 32, "H") = arr(i) Then
                ActiveSheet.Shapes(i + 1).Visible = msoTrue
                Exit For
            End If
            ActiveSheet.Shapes(i + 1).Visible = msoFalse
        Next j
    Next i
    ActiveSheet.Rows.ClearOutline
    ActiveSheet.ResetAllPageBreaks
    For k = 0 To 7
        If Cells(k * 19 + 32, "H").Value = 0 Then
            Range("A" & k * 19 + 32, "A" & (k + 1) * 19 + 31).Rows.Group
            ActiveSheet.Outline.ShowLevels RowLevels:=1
        End If
    Next k
    
End Sub

[返信 6] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : ピロリ     投稿日時 : 2025/07/10(Thu) 18:33:06
■[返信 5] 素人(No.2128)さん(2025-07-10 16:04:35)の記事
> VLOOKUPが"0"を返してたことが判明したので、一応、想定の動きをするようになりました。
> ピロリさんが、提案してくれたように、表ごとをグループ化するようにしてみました。
> いかがでしょうか。
私に聞いているのでしょうかね? 動作確認はしてませんが、想定の動きをしているのであれば宜しいのでは。

パッと見ですが、未入力の場合ってことだったので、
  If Cells(k * 19 + 32, "H").Value = 0 Then
                   ↓
  If Cells(k * 19 + 32, "H").Value = "" Then
になるのかなぁ~ と思ってました。 未入力が空白ではなく、0 で間違いないのであれば、問題ないでしょう。

これは間違いではないですが、変数:k を使わずとも i や j は役割を終えているので、そちらを使用しても・・・
とは思いました。
後々大きなプログラムを作成するときに、使い回しも考えないと変数だらけになります。 老婆心ながら・・・

[返信 7] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : ピロリ     投稿日時 : 2025/07/10(Thu) 18:47:35
ご免なさい。 [返信 4] を見逃してました・・・
未入力は 0 のようなので、空白の件は 忘れて下さい。

[返信 8] Re : 入力が無いセルから指定の行までをグループ化して閉じる。
投稿者 : 素人(No.2128)     投稿日時 : 2025/07/11(Fri) 11:46:26
ピロリさん ありがとうございました。
今後も、機会がありましたら、よろしくお願いいたします。

当掲示板について
  • Excel VBA に関する掲示板です。Excel VBA に関する質問や疑問、それに対する解決方法など気軽に投稿してください。
  • 記事内ではHTMLのタグは使用できません。
  • 記事は一度投稿すると修正できません。内容を訂正したい場合は返信で対応してください。
  • Sub〜End Sub、Function〜End Function は自動的にプログラムコードとみなし、枠で囲って見やすくします。
  • Excel VBA とは関係ないことや、他人が不快に思うようなことなど、管理人が適当でないと判断した記事は削除する場合があります。
スポンサーリンク
返信入力フォーム
お 名 前  :
内  容   :

ステータス  :

認証コード  : キャプチャ画像 




( 処理日時 : 2025-08-27 00:27:53 )
タイトルとURLをコピーしました