Python(pywin32)でWordを操作する[8] - 段落単位の文字列取得, 統計(ページ数, 段落数,etc)取得

#概要

Paragraphsコレクション、Paragpraphsオブジェクトを利用して段落単位で文字列を取得します。
そのほかのテーマは以下です。

- Paragraphs(i).Range.Text連続アクセス性能
    - シーケンシャルアクセスはイテレートするのが圧倒的に早い
- Wordの段落とは何か？
- 行頭の黒い点(・)は何？
- Range.Textをprintすると表示がおかしくなる？
- 校閲タブ→文字カウントで取得できる統計と一致しない？


#利用する文書について

Word文書が安全かどうか保証できないので適宜用意してください。

そこそこ量があり、章・節を使った構造的文書(例えば、設計書・仕様書)がほしかったので、ここではローカルにあった(Visual Studioインストールで入った)「C# Language Specification Version 5.0」(CSharp Language Specification.docx)のコピーを利用しています

![charp.png](https://qiita-image-store.s3.amazonaws.com/0/34777/1e659368-f25f-2fe7-d6aa-ed2492d3e2dd.png)

#今回利用するWordオブジェクト

![word_obj8.png](https://qiita-image-store.s3.amazonaws.com/0/34777/fd8c6b4c-23e5-b339-36a8-c06ab68efcdb.png)



|オブジェクト名|プロパティ/メソッド|説明|リンク|
|:---|:---|:---|:---|
|Document |-      |Documents内の1つの文書|[msdn][doc_msdn]|
|         |ComputeStatistics()|統計情報(ページ数、段落数など)を取得する|[msdn][doc_stat_msdn]|
|Paragraphs|-    |Paragraphのコレクション|[msdn][paras_msdn]|
|          |Count|Paragraphの数|[msdn][paras_count_msdn]|
|Paragraph |-    |1つの段落を表すオブジェクト|[msdn][para_range_msdn]|
|          |Range|この段落を表すRangeオブジェクトを取得|[msdn][para_range_msdn]|
|Range    |-    |隣接する領域を表すオブジェクト|[msdn][rng_msdn]|
|         |Text|Rangeのテキストを設定もしくは取得|[msdn][rng_text_msdn]|



#コード
qtconsoleの確認結果を示していきます。

「★なんらかの処理★」部分に記述しているイメージで読んでください。

```python
import win32com.client

#Wordを起動する : Applicationオブジェクトを生成する・・・[2]
Application=win32com.client.Dispatch("Word.Application")

#Wordを画面表示する : VisibleプロパティをTrueにする・・・[2]
Application.Visible=True

#Word文書を読み取り専用で開く : Documents.Open(ReadOnly=True)メソッドを呼ぶ・・・[7]
doc=Application.Documents.Open(
       FileName=r"C:\tmp\CSharp Language Specification.docx",
       ConfirmConversions=None,
       ReadOnly=True)


★なんらかの処理★


#Word文書を保存せずに閉じる : Document.Close(SaveChanges=0)メソッドを呼ぶ・・・[7]
doc.Close(SaveChanges=0)

#Wordを終了する : Quitメソッドを呼ぶ・・・[2]
Application.Quit()
```

コメントの「・・・[n]」は記事の番号です。


##段落の単位で文字列を取得する

Paragraph.Range.Textで段落のテキストを見てみます。

```python
In [27]: for i in range(1,10):
    ...:     print(f"{i}:" + doc.Paragraphs(i).Range.Text)
1:
2:
3:
4:
5:
6:
7:C#
8:Language Specification
9:Version 5.0
```

段落の単位で文字列を取得できました。

[Paragraphs(i).Range.Textに連続アクセスするとだんだん重くなっていく](https://qiita.com/int_main_void/items/7c5bc0aab52d8bfadd6e#paragraphsirangetext%E9%80%A3%E7%B6%9A%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%80%A7%E8%83%BD)ので、テキスト取得であれば新たにRangeを作るのがいいです。

```python
In [95]: start=doc.Paragraphs(1).Range.Start
    ...: end=doc.Paragraphs(10).Range.End
    ...: doc.Range(start,end).Text
    ...: 
Out[95]: '\r\r\r\r\r\rC#\rLanguage Specification\rVersion 5.0\r\x0cNotice\r'
```

また、[制御文字が入っている](https://qiita.com/int_main_void/items/7c5bc0aab52d8bfadd6e#%E8%A1%8C%E9%A0%AD%E3%81%AE%E9%BB%92%E3%81%84%E7%82%B9%E3%81%AF%E4%BD%95)ためprint時は置き換えが必要です。

```python:制御文字を\nに置き換えてprint
In [96]: import re

In [97]: ctrlch = re.compile(r"[\x00-\x1F\x7F]")

In [98]: def p_range_txt(range_txt, repl=""):
    ...:     global ctrlch
    ...:     print(ctrlch.sub(repl, range_txt))

In [99]: 
    ...: start=doc.Paragraphs(1).Range.Start
    ...: end=doc.Paragraphs(10).Range.End
    ...: p_range_txt(doc.Range(start,end).Text,"\n")






C#
Language Specification
Version 5.0

Notice

```

#Paragraphs(i).Range.Text連続アクセス性能

Paragraphs(i).Range.Textにfor i in range(1,1000)でアクセスしたらあまりにも遅かったので時間を計ってみました。(遅すぎるので1000では計測してません。)

```python:遅い・・・5分まっても終わらない
for i in range(1,1000):
    d.Paragraphs(i).Range.Text
```

下記のtest_speed()関数を%timeitで時間計測してみます。

```python:時間計測
In [70]: def test_speed(d,n=1):
    ...:     for i in range(1,n+1):
    ...:         d.Paragraphs(i).Range.Text

In [74]: %timeit -n1 -r1 test_speed(doc,100)
12 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
```

n=100個のときt=12secでした。

n=100,200,300,400,500と変えていったときのtをプロットしてみます。

![plot.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/e65cc47e-edf2-6f9b-934b-bcac4df07a64.png)

※黒い点線はn=100個のときt=12secからの期待値。


残念なことにn=500個のときt= **337sec**。


近似曲線は
y = 0.0017x^2 - 0.0907x + 1.0217
になりました。
x=1000とすると、1604secで26.7minになってしまいますね。


100個ごと(dvsr個ごと)にParagrahをまとめたあとループする関数を作ってみました。
※test_speed3～4は省略

```python:100個ごとにParagrahをまとめたあとループ
def test_speed5(doc,n=100,dvsr=100):
    q, m = divmod(n, dvsr)
    start_end  = [(1+dvsr*i, dvsr+dvsr*i) for i in range(0,q+1)]
    start_end += [] if m==0 else [(1+dvsr*(q+1), m+dvsr*(q+1))]
    for start,end in start_end:
        r_start = doc.Paragraphs(start).Range.Start
        r_end   = doc.Paragraphs(end).Range.End
        r       = doc.Range(r_start,r_end)
        for i in range(1,r.Paragraphs.Count+1):
            r.Paragraphs(i).Range.Text
```


![performance2.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/c602ce6c-7c7b-fabc-0cb3-42f09d25b91a.png)

近似曲線は、
y = 5E-06x^2 + 0.2721x - 4.08
になりました。
二次の項が抑えられたのでほぼ線形に近くなりました。
x=1000で273sec(約4.5分)でそこそこ現実的な値になってきましたので実測してみます。

```python
In [126]: %timeit -n1 -r1 test_speed5(doc,n=1000,dvsr=100)
2min 55s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
```

近似曲線からの予測より40sec程度早くなりました。

複数Paragraphのテキストを取得するなら[Document.Range()メソッド](https://qiita.com/int_main_void/items/f135d321262d9de05efc)で,Paragraphをまとめて新たなRangeを作り、そのRangeでループするのがいいと思います。なお、まとめる数は25個がよさそうです。
(25個あたりに最適な値がありそうです)

```python:まとめる数は25あたりに最適な値がありそう？
# 25個がベストスコア
In [128]: %timeit -n1 -r1 test_speed5(doc,n=500,dvsr=25)
58.9 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

In [127]: %timeit -n1 -r1 test_speed5(doc,n=500,dvsr=10)
1min 26s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

In [129]: %timeit -n1 -r1 test_speed5(doc,n=500,dvsr=20)
1min ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

In [125]: %timeit -n1 -r1 test_speed5(doc,n=500,dvsr=50)
1min 15s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
In [130]: %timeit -n1 -r1 test_speed5(doc,n=500,dvsr=100)
2min 4s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
```

##シーケンシャルアクセスはイテレートするのが圧倒的に早い

for ～ in でWordのコレクションから値が取り出せることに今更気が付きました。
グラフ化するまでもなく、シーケンシャルアクセスはイテレートするのが圧倒的に早いです。

```python
In [201]: def test_speed6(d,n=1):
     ...:     for i,p in enumerate(d.Paragraphs):
     ...:         p.Range.Text
     ...:         if i>=n:
     ...:             break

In [202]: %timeit -n1 -r1 test_speed6(doc,1000)
15 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
```


#Wordの段落とは何か？

Paragraphs(1)～(6)の何も出てないところをもう少し調べてみます。

```python
In [28]: doc.Paragraphs(1).Range.Text
Out[28]: '\r'

In [29]: for i in range(1,7):
    ...:     s = doc.Paragraphs(i).Range.Text.encode("utf-8").hex()
    ...:     print(f"{i}:" + s)
1:0d
2:0d
3:0d
4:0d
5:0d
6:0d
```

'\r'(0x0d,[キャリッジリターン][cr_weblio])でした。

Paragraphsと画面は以下のイメージで対応してます。

![parag.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/19b3640b-5fa3-ae02-2f8f-d9bcb305c141.png)

WordでEnterキー押したときに出てくる![cr.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/985457a6-1b2b-b926-34bd-9e6ad4aa5698.png)マークは'\r'だったんですね。

Wordの段落(Paragprahオブジェクト)は「Enterキーを押した箇所で区切られる領域」といえそうです。


#行頭の黒い点(・)は何？

よく見てみるとParagprah(9)の下の行頭に黒い点(・)があります。

![paras10.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/0324d39f-2a74-fa70-57b3-396de59fb911.png)

これ何でしょうか？

Paragprah(10)にあると思うので出力してみます。

```python
In [42]: doc.Paragraphs(10).Range.Text
Out[42]: '\x0cNotice\r'
```

'\x0c **Notice** \r'と読めます。

次ページの最初に「Notice」があります。

![next_page.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/e2764d23-bb5d-b882-0d7b-4d015acafe55.png)

'\x0c'はASCIIコードの[Form Feed(改ページ)][wiki_ascii]です。

'\x0c'が黒い点そのものでしょうか？

この黒い点についてもう少し調べてみると、

[画面に表示される「・」は何？-インストラクターのネタ帳][word_black_dot]

> この「・」は、［改ページ位置の自動修正］が設定されている段落の先頭に表示されます。
・・・略・・・
［次の段落と分離しない］チェック
［段落を分割しない］チェック
［段落前で改ページする］チェック
のいずれかがOnになっている段落で「・」が表示されます

ということがわかります。

「Notice」の［改ページ位置の自動修正］は・・・

![page_break_setting.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/0df295fe-44f4-7c79-cce7-71e85251478b.png)

「段落を分割しない」にチェックが入ってました。※チェックを外すと黒い点が消えます。


行頭の黒い点(・)は、［改ページ位置の自動修正］の設定によってページ区切りが段落内にあることを示していたようです。また、ページ区切りは'\x0c'だとわかりました。

![ページ区切り.png](https://qiita-image-store.s3.amazonaws.com/0/34777/7ae31890-ecc6-31a1-b90e-6fa3df4d2b34.png)


#Range.Textをprintすると表示がおかしくなる？

```python
In [47]: doc.Paragraphs(10).Range.Text
Out[47]: '\x0cNotice\r'
```

print(doc.Paragraphs(10).Range.Text)をしてみると・・・

[print_para10.gif](https://qiita-image-store.s3.amazonaws.com/0/34777/95916290-4e96-eaf7-eb2f-8417bae587a0.gif)

のように'\x0c'(改ページ)をプリントした時点で画面がクリアされてしまいます。

そこで制御文字を置き換えてprintする関数p_range_txt()を作ります。

```python
In [52]: import re
    ...: ctrlch = re.compile(r"[\x00-\x1F\x7F]")
    ...: def p_range_txt(range_txt, repl=""):
    ...:     global ctrlch
    ...:     print(ctrlch.sub(repl, range_txt))

In [53]: p_range_txt(doc.Paragraphs(10).Range.Text)
Notice

In [54]: p_range_txt(doc.Paragraphs(10).Range.Text, "??")
??Notice??
```
'\r'
制御文字全体を"\n"で置き換えておけばとりあえずは問題ないかと。

```python
In [102]: p_range_txt(doc.Paragraphs(10).Range.Text,"\n")

Notice


In [103]: 
```



#校閲タブ→文字カウントで取得できる統計と一致しない？

Paragraphs.Countを使って、Paragprahオブジェクトの数を調べてみます。

```python
In [19]: doc.Paragraphs.Count
Out[19]: 10449
```

よく見ると、「さっきの統計の段落数と違う」と気がつきます。
![統計.PNG](https://qiita-image-store.s3.amazonaws.com/0/34777/51505a88-e865-89ba-f46e-12e5910f46fe.png)

なぜでしょうか？

[Hey, Scripting Guy! Word 文書の文と段落の数を数える方法はありますか][scriptingguy_how_to_count_word_pages]

> たとえば、次の抜粋 (アンダースコアはそれぞれ Enter キーを押した箇所を示しています) には、段落がいくつあると思いますか。

> 段落 1。_
_
段落 2。_
_
段落 3。_
> 
> **ご想像のとおり、答えは "場合による" です。**
> 
> ComputeStatistics メソッドを使用して段落数を計算した場合(略)、Word では、ここに 3 つの段落があると認識します。
> しかし、Paragraphs コレクションを使用する場合 (略)、Word では、この文書に 5 つの段落があると認識されます。
> というのも、この場合、Word では Enter キーを押した回数を数えているだけだからです。(略)
> 実際、Enter キーを 5 回押したことが、Paragraphs コレクションに 5 つの項目が含まれている理由です。


統計側の段落数は空行を無視しているようです。

統計と同じ値を取得する場合は, Document.ComputeStatistics()を利用します

[Document.ComputeStatistics Method - msdn][doc_stat_msdn]

> Syntax
expression . **ComputeStatistics( Statistic , IncludeFootnotesAndEndnotes )**



|名前|必須 / 省略可能|説明|
|:---|:---|:---|:---|
|Statistic|必須|計算する統計量。WdStatistic列挙のいずれか|
|IncludeFootnotesAndEndnotes|省略可能|True:テキストボックス, 脚注, 文末脚注を含める(デフォルト=False|

[WdStatistic列挙-msdn][wdstatistic-enumeration-word]

|名前|値|説明[msdn_ja-jp](https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/wdstatistic-enumeration-word)|説明[msdn_en-us](https://msdn.microsoft.com/en-us/vba/word-vba/articles/wdstatistic-enumeration-word)|
|:---|:---|:---|:---|
|wdStatisticCharacters|3|文字数|Count of characters.|
|wdStatisticCharactersWithSpaces|5|スペースを含めた文字数|Count of characters including spaces.|
|wdStatisticFarEastCharacters|6|アジア言語の文字数|Count of characters for Asian languages.|
|wdStatisticLines|1|行数|Count of lines.|
|wdStatisticPages|2|ページ数|Count of pages.|
|wdStatisticParagraphs|4|段落数|Count of paragraphs.|
|wdStatisticWords|0|単語数|Count of words.|



実際に取得してみます。

```python
#ページ数 wdStatisticPages
In [90]: doc.ComputeStatistics(Statistic=2)
Out[90]: 527

#単語数 wdStatisticWords
In [91]: doc.ComputeStatistics(Statistic=0)
Out[91]: 179959

#文字数(スペースを含めない) wdStatisticCharacters
In [92]: doc.ComputeStatistics(Statistic=3)
Out[92]: 966014

#文字数(スペースを含める) wdStatisticCharactersWithSpaces
In [93]: doc.ComputeStatistics(Statistic=5)
Out[87]: 1151262

#段落数 wdStatisticParagraphs
In [93]: doc.ComputeStatistics(Statistic=4)
Out[93]: 9964

#段落数 wdStatisticParagraphs
In [94]: doc.ComputeStatistics(Statistic=1)
Out[94]: 23284

#全角文字・半角カタカナの数 wdStatisticFarEastCharacters
In [95]: doc.ComputeStatistics(Statistic=6)
Out[95]: 3
```

統計と同じ値が取得できました。

半角英数の単語数はWdStatistic列挙に対応する値がないので、

半角英数の単語数 = 単語数 - 全角文字・半角カタカナの数

で計算しているようです。



#関連
[Python(pywin32)でWordを操作する[1] - Wordオブジェクトモデル](https://qiita.com/int_main_void/items/16cede139bd64514b810)
[Python(pywin32)でWordを操作する[2] - Wordを起動／終了する](https://qiita.com/int_main_void/items/8776cc4b9b05478273b3)
[Python(pywin32)でWordを操作する[3] - 新規ドキュメント作成](https://qiita.com/int_main_void/items/a36cf348d6eedb31246f)
[Python(pywin32)でWordを操作する[4] - 文字列を入力/取得/削除する](https://qiita.com/int_main_void/items/f135d321262d9de05efc)
[Python(pywin32)でWordを操作する[5] - ドキュメントをファイルに保存する、Wordのオプション変更](https://qiita.com/int_main_void/items/b8549c92b33ea0f7d63b)
[Python(pywin32)でWordを操作する[6] - 特定のタイトルが付いているウィンドウの操作](https://qiita.com/int_main_void/items/6c3569dc242f843ca946)
[Python(pywin32)でWordを操作する[7] - 既存文書を開く/閉じる(Documents.Open(), Document.Close())](https://qiita.com/int_main_void/items/af46e7fe40f528b0b5cd)
[Python(pywin32)でWordを操作する[8] - 段落単位の文字列取得, 統計(ページ数, 段落数,etc)取得](https://qiita.com/int_main_void/items/7c5bc0aab52d8bfadd6e)

#参考

- [オブジェクト モデル - MSDN][object_model]
- [PyWin32 Documentation - Tim Golden's Stuff][tim_pywin32_docs]
- [Hey, Scripting Guy! Word 文書の文と段落の数を数える方法はありますか][scriptingguy_how_to_count_word_pages]
- [Office Space : Microsoft Word ドキュメントの統計情報を取得][Office_Space_how_to_get_stat]
- [ASCII - Wikipedia][wiki_ascii]
- [画面に表示される「・」は何？-インストラクターのネタ帳][word_black_dot]
- [Form Feedとは - IT用語辞典 Weblio辞書][ff_weblio]
- [キャリッジリターンとは - IT用語辞典 Weblio辞書][cr_weblio]


[wdstatistic-enumeration-word]:https://msdn.microsoft.com/en-us/vba/word-vba/articles/wdstatistic-enumeration-word
[OfficeOpenReadOnly.vbs]:https://gist.github.com/motoraku/c9aef3c43843331b554f

[cr_weblio]:https://www.weblio.jp/content/%E3%82%AD%E3%83%A3%E3%83%AA%E3%83%83%E3%82%B8%E3%83%AA%E3%82%BF%E3%83%BC%E3%83%B3
[ff_weblio]:https://www.weblio.jp/content/Form+Feed
[word_black_dot]:https://www.relief.jp/docs/000160.html
[wiki_ascii]:https://ja.wikipedia.org/wiki/ASCII#ASCII%E5%88%B6%E5%BE%A1%E6%96%87%E5%AD%97
[scriptingguy_how_to_count_word_pages]:https://gallery.technet.microsoft.com/office/60bf3e62-d647-4146-8b0c-63a6ac8aac84
[Office_Space_how_to_get_stat]:https://technet.microsoft.com/ja-jp/library/ee692861.aspx
[com_python_ruby]:https://magazine.rubyist.net/articles/0009/0009-Win32OLE.html#python-%E3%81%AE%E5%A0%B4%E5%90%88
[makepy_hunya]:http://d.hatena.ne.jp/Wacky/20091011/1255240572
[named-objects_msdn]:https://msdn.microsoft.com/en-us/vba/word-vba/articles/returning-an-object-from-a-collection-word#named-objects

[word_defalut_file]:http://ciao.aoten.jp/ciao/2016/03/post-d958.html
[word_default_file2]:https://tonari-it.com/word-vba-document-open-close/

[set_default_filepath]:https://stackoverflow.com/questions/45252880/set-parameterized-com-property
[app_options_msdn]:https://msdn.microsoft.com/en-us/vba/word-vba/articles/options-defaultfilepath-property-word
[enum_WdDefaultFilePath_msdn]:https://msdn.microsoft.com/en-us/vba/word-vba/articles/wddefaultfilepath-enumeration-word

[doc_saveas2_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/document-saveas2-method-word
[doc_save_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/document-save-method-word
[docs_save_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/documents-save-method-word
[app_vbe_msdn]:https://msdn.microsoft.com/en-us/vba/word-vba/articles/application-vbe-property-word

[quit_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/application-quit-method-word
[visible_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/application-visible-property-word
[object_model]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/object-model-word-vba-reference
[qiita_com]:https://qiita.com/mintcandy/items/979a4a2669c8fc1f4f2f
[tim_pywin32_docs]:http://timgolden.me.uk/pywin32-docs/index.html
[vov]:http://www.dastec.org/vov/index.htm
[macro]:https://www.wordvbalab.com/
[macro_list]:https://www.wordvbalab.com/page-2266/
[vbscript_word_page]:http://www.segmentation-fault.xyz/entry/2017/11/25/222859
[vbscript_word_search]:https://technet.microsoft.com/ja-jp/library/ee692875.aspx

[rng_delete_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/document-content-property-word
[rng_text_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-text-property-word
[doc_rng_msdn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-range-method-word

[rng_start_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-start-property-word

[rng_end_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-end-property-word
[doc_content_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/document-content-property-word

[rng_insaft_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-insertafter-method-word

[rng_insbfr_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-insertbefore-method-word

[inserting-text-in-a-document]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/inserting-text-in-a-document
[app_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/application-object-word
[docs_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/documents-object-word
[doc_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/document-object-word
[paras_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/paragraphs-object-word
[para_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/paragraph-object-word
[sens_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/sentences-object-word
[wrds_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/words-object-word
[chrs_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/characters-object-word
[rng_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-object-word
[rng_txt_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/range-text-property-word
[para_rng_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/paragraph-range-property-word
[docs_count_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/documents-count-property-word
[docs_open_mdsn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/documents-open-method-word
[doc_close_mdsn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-close-method-word
[doc_fullname_msdn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-fullname-property-word
[doc_name_msdn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-name-property-word
[doc_activate_msdn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-activate-method-word
[doc_path_msdn_ja-jp]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-path-property-word
[doc_path_msdn_en-us]:https://msdn.microsoft.com/en-us/VBA/Word-VBA/articles/document-path-property-word
[docs_add_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/documents-add-method-word
[app_activedoc_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/application-activedocument-property-word
[doc_saveas2_mdsn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-saveas2-method-word
[doc_activate_msdn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-activate-method-word

[app_tasks_mdsn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/tasks-object-word
[tasks_count_mdsn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/tasks-count-property-word
[tasks_exists_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/tasks-exists-method-word
[tasks_exitwindows_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/tasks-exitwindows-method-word
[app_task_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-object-word
[task_name_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-name-property-word
[task_visible_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-visible-property-word

[task_winstate_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-windowstate-property-word
[task_top_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-top-property-word
[task_left_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-left-property-word
[task_width_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-width-property-word
[task_height_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-height-property-word

[task_activate_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-activate-method-word
[task_close_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-close-method-word
[task_move_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-move-method-word
[task_resize_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-resize-method-word
[task_sendwindowmessage_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/task-sendwindowmessage-method-word

[WdWindowState]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/wdwindowstate-enumeration-word
[docs_open_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/documents-open-method-word

[doc_close_msdn]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/document-close-method-word
[wdsaveoptions-enumeration-word]:https://msdn.microsoft.com/ja-jp/VBA/Word-VBA/articles/wdsaveoptions-enumeration-word
[doc_stat_msdn]:https://msdn.microsoft.com/en-us/vba/word-vba/articles/document-computestatistics-method-word
[para_range_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/paragraph-range-property-word
[paras_count_msdn]:https://msdn.microsoft.com/ja-jp/vba/word-vba/articles/paragraphs-count-property-word