Wordドキュメント上で指定した段落以外の段落を折り畳む
段落を折り畳むことができる
知らなかった。
Wordの標準機能にあった。
百聞は一見に如かず。次をご覧いただきたい。

「百聞は一見に如かず」と偉そうに言った割にはわかりにくい画像ですまないw
見出しスタイルを当てた段落は、左側に「・」(ポツ)が付く。
んで、このポツにカーソルを近づけると、小さな三角形が表示される。
そいつをクリックしてやると、その見出しに属する本文が折り畳まれたり、展開されたりするのだ。
こいつをVBAで操ってみる。
[Paragraph].CollapsedStateプロパティ
[Paragraph].CollapsedStateというプロパティがある。
こいつがTrueだとその見出しに属する本文が折り畳まれ、Falseだと展開される(表示される)という仕組みらしい。
ちなみに、おなじみコチラの解説によると、
Returns or sets whether the specified paragraph is currently in a collapsed state. Read/write Boolean.
とのこと。
指定した見出しスタイルに指定したキーワードが含まれている段落のみ表示するメソッド
長ったらしくて意味が取りづらくてすまぬ。
たとえば、

このようなドキュメント(笑)があったとして、たとえば、「【安倍晋三内閣総理大臣】」という見出しの段落だけを表示して、他の見出しの段落本文は折り畳んでしまおう、ということ。要するに、

こんな状態にしたい、ということ。
リスト1
Public Sub showOnlySpecifiedParagraph(ByVal tgtDocument As Document, _
ByVal styleNameKey As String, _
Optional ByVal headerKey As String)
'///指定したスタイル名の見出しの段落のみ表示し、他は折り畳む。'
'///headerKeyを指定すれば、そのキーワードを含む見出しの段落のみを表示。'
'///styleNameKey:表示する段落の見出しスタイルの名前(のキーワード)'
'///headerKey: 表示したい見出しのキーワード。'
Dim para As Paragraph
For Each para In tgtDocument.Paragraphs
With para
'段落名にstyleNameKeyが含まれていなければContinue'
If InStr(1, .Style, styleNameKey) = 0 Then GoTo Continue
'headerKeysが指定されていなければ折り畳む'
If headerKey = "" Then _
.CollapsedState = True: GoTo Continue
'段落のテキストにheaderKeyが含まれていなければ折り畳む'
If InStr(1, .Range.Text, headerKey) = 0 Then
.CollapsedState = True
Else
.CollapsedState = False
End If
End With
Continue:
Next
End Sub
処理の手順は細かくコメントを入れたので、それを見ればだいたいわかると思う。
For Each ~ Nextで全ての段落を巡回し、
段落のスタイル名にstyleNameKeyで指定したキーワードが含まれていて、なおかつその見出し段落の文字列にheaderKeyで指定したキーワードが含まれていたら、CollapsedStateプロパティをFalseにし(つまり、折り畳まない。)、それ以外のときはTrueにする(つまり、折り畳む。)
というだけのもの。
このメソッドを、先ほどの

のドキュメント(笑)に対して、次のコードで使ってみる。
リスト2
Private Sub test00()
Call showOnlySpecifiedParagraph(ActiveDocument, _
"見出し 2", _
"安倍晋三")
End Sub
スタイル名に「見出し 2」という文字列を含み、なおかつ見出しに「安倍晋三」という文字列を含む段落の本文だけを残し、他の段落の本文は折り畳む、というマクロ。
コイツを実行すると、

こうなる。
改良
しかし、上掲のshowOnlySpecifiedParagraphメソッド。困ったことに見出しのキーワードが一つしか指定できない。
つまり、たとえば先のドキュメント(笑)の場合、「議長と銭田掏次郎委員の発言だけを表示させたい」という場合には対応できないのだ。
これはイマイチ。
そこで、先の第3引数headerKeyに複数のキーワードが指定できるように改良する。
リスト3
Public Sub showOnlySpecifiedParagraph( _
ByVal tgtDocument As Document, _
ByVal styleNameKey As String, _
Optional ByRef headerKeys As Variant) '……(1)'
'///指定したスタイル名の見出しの段落のみ表示し、他は折り畳む。'
'///headerKeysを指定すれば、そのキーワードを含む見出しの段落のみを表示。'
'///styleNameKey:表示する段落の見出しスタイルの名前(のキーワード)'
'///headerKeys: 表示したい見出しのキーワード。配列か値で渡す'
'headerKeysが省略されていれば、""にする。'
If IsEmpty(headerKeys) Then headerKeys = "" '……(2)'
'headerKeysが配列でなければ、文字列にして要素数1の配列化'
If Not IsArray(headerKeys) Then '……(3)'
headerKeys = Array(CStr(headerKeys))
End If
Dim para As Paragraph
For Each para In tgtDocument.Paragraphs
With para
'段落名にstyleNameKeyが含まれていなければContinue'
If InStr(1, .Style, styleNameKey) = 0 Then GoTo Continue
'headerKeysが指定されていなければ折り畳む'
If headerKeys(0) = "" Then _
.CollapsedState = True: GoTo Continue
'段落のテキストにheaderKeyが含まれていれば折り畳まない'
If isToCollapse(.Range.Text, headerKeys) Then '……(4)'
.CollapsedState = True
Else
.CollapsedState = False
End If
End With
Continue:
Next
End Sub
Private Function isToCollapse( _
ByVal tgtHeaderText As String, _
ByRef tgtArray As Variant) As Boolean '……(5)'
isToCollapse = False
Dim i As Long
For i = LBound(tgtArray) To UBound(tgtArray)
If InStr(1, tgtHeaderText, tgtArray(i)) > 0 Then
Exit Function
End If
Next
isToCollapse = True
End Function
変更したのは(1)~(5)の5箇所。
まず(1)の
Public Sub showOnlySpecifiedParagraph( _
ByVal tgtDocument As Document, _
ByVal styleNameKey As String, _
Optional ByRef headerKeys As Variant)
で第3引数を変更。
Variantにして、文字列でも配列でも受け取れるようにした。
(2)の
If IsEmpty(headerKeys) Then headerKeys = ""
は引数チェックその1。
第3引数が省略されていたら、headerKeysを""にする。
(3)の
If Not IsArray(headerKeys) Then headerKeys = Array(CStr(headerKeys)) End If
は引数チェックその2。
配列でなかったら、値を文字列型にキャストしてheaderKeysに格納。
(4)の
If isToCollapse(.Range.Text, headerKeys) Then .CollapsedState = True Else .CollapsedState = False End If
では、折り畳むかどうかの判定にisToCollapseメソッドを用いている。Trueなら、その段落の本文は折り畳むべし、ということだ。
isToCollapseメソッドは、(5)の
rivate Function isToCollapse( _
ByVal tgtHeaderText As String, _
ByRef tgtArray As Variant) As Boolean
isToCollapse = False
Dim i As Long
For i = LBound(tgtArray) To UBound(tgtArray)
If InStr(1, tgtHeaderText, tgtArray(i)) > 0 Then Exit Function
Next
isToCollapse = True
End Function
このとおり。
引数tgtArrayの要素のうち、どれか一つでも見出し段落の文字列に含まれていたらFalse(つまり、折り畳まんでいい)を返す。
使ってみる
次のコードで実験。
リスト4
Private Sub test01()
Dim var As Variant
var = Array("銭田", "議長")
Call showOnlySpecifiedParagraph(ActiveDocument, _
"見出し 2", _
var)
End Sub
第3引数に「銭田」、「議長」という二つのキーワードを格納した配列を渡す。
コイツを実行すると、

こうなる。無事に「銭田掏次郎委員」と「議長」の発言だけを表示させ、「安倍晋三内閣総理大臣」の発言を折り畳むことができた。
おわりに
議事録なんかで、特定の出席者の発言だけを抽出したいときに便利だと思います。