4
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python(pywin32)でWordを操作する[7] - 既存文書を開く/閉じる(Documents.Open(), Document.Close())

Last updated at Posted at 2018-06-10

#概要

Documents.Open(), Document.Close()を利用して既存文書を開いて閉じます。
そのほかのテーマは以下です。

#利用する文書について

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

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

charp.png

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

word_obj__.png

オブジェクト名 プロパティ/メソッド 説明 リンク
Documents - Documentのコレクション msdn
Open() 文書を開く msdn
Document - Documents内の1つの文書 msdn
Close() 指定した文書を閉じる msdn

#コード

qtconsoleの確認結果を示していきますが、前回同様テンプレ的な処理は省略します。
↓の「★なんらかの処理★」部分に記述しているイメージで読んでください。

import win32com.client

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

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


なんらかの処理


#Wordを終了する : Quitメソッドを呼ぶ
Application.Quit()

##文書を開く

Documents.Open()を利用して、C:\tmp\CSharp Language Specification.docxにあるファイルを開きます。ファイル名を絶対パスで指定して開いてみます。

In [54]: doc=Application.Documents.Open(r"C:\tmp\CSharp Language Specification.docx")

pathlibを利用して相対パス的に開いてみます。

In [57]: import pathlib

In [58]: cd c:\tmp
c:\tmp

In [59]: p=pathlib.Path(".").joinpath("CSharp Language Specification.docx")

In [60]: p.resolve()
Out[60]: WindowsPath('C:/tmp/CSharp Language Specification.docx')

In [61]: doc=Application.Documents.Open(str(p.resolve()))

##文書を読み取り専用で開く

Documents.Open()を読み取り専用で開いてみます。引数のReadOnlyを利用します。
名前付き引数に気を付けるも参照ください。

Documents.Open() - msdn

式 . Open( FileName, ConfirmConversions, ReadOnly , ・・・

|名前|必須 / 省略可能|説明|
|:---|:---|:---|:---|
|ReadOnly|省略可能|True:読み取り専用|

方法1-名前付き引数
In [71] doc=Application.Documents.Open(FileName=r"C:\tmp\CSharp Language Specification.docx", ConfirmConversions=False, ReadOnly=True)
方法2-位置引数
In [72] doc = Application.Documents.Open(r"C:\tmp\CSharp Language Specification.docx",False,True)
方法3-位置引数+Noneで省略
In [73] doc=Application.Documents.Open(r"C:\tmp\CSharp Language Specification.docx",None,True)

##文書を閉じる

docで受け取ったDocumentオブジェクト参照からClose()メソッドを呼ぶだけです。

In [74]: doc.Close()

ちなみに、Documentオブジェクトをdocで受け取るのはMustではないです。
後述しますが、Documentオブジェクトは名前付きオブジェクトなので、名前(Name, FullNameと同じ文字列)でコレクションから取りだせます。

#Open()で開いてNameを確認する
In [88]: Application.Documents.Open(r"C:\tmp\CSharp Language Specification.docx").Name
Out[88]: 'CSharp Language Specification.docx'

#Nameと同じ文字列を使って、Documentsコレクションからオブジェクトを取り出し、Close()を呼ぶ
In [89]: Application.Documents("CSharp Language Specification.docx").Close()
#Open()で開いてFullNameを確認する
In [90]: Application.Documents.Open(r"C:\tmp\CSharp Language Specification.docx").FullName
Out[90]: 'C:\\tmp\\CSharp Language Specification.docx'

#FullNameと同じ文字列を使って、Documentsコレクションからオブジェクトを取り出し、Close()を呼ぶ
In [91]: Application.Documents("C:\\tmp\\CSharp Language Specification.docx").Close()

##変更を保存せずに文書を閉じる
Document.Close()を使って、変更を保存せずに文書を閉じてみます。
引数のSaveChangesの指定に定数(wdDoNotSaveChangesなど)を利用できますが、事前準備が必要なので、今回は直値で指定します。

Document.Close() - msdn

式 . Close( SaveChanges, OriginalFormat, RouteDocument )

|名前|必須 / 省略可能|説明|
|:---|:---|:---|:---|
|SaveChanges|省略可能|文書の保存方法を指定。使用できる定数は、WdSaveOptions列挙のいずれか|

WdSaveOptions列挙-msdn

|名前|値|説明|
|:---|:---|:---|:---|
|wdDoNotSaveChanges|0|保留中の変更を保存しない|
|wdPromptToSaveChanges|-2|保留中の変更を保存するかどうかユーザーに確認|
|wdSaveChanges|-1|保留中の変更をユーザーに確認しないで自動的に保存|

引数なしのClose()と挙動の違いを見るために、文書を読み取り専用で開きます。

#文書を読み取り専用で開く : Open(ReadOnly=True)を呼ぶ
In [121]: doc=Application.Documents.Open(FileName=r"C:\tmp\CSharp Language Specification.docx", ConfirmConversions=False, ReadOnly=True)

手で適当に変更を加えます。

henkou.PNG

Close()を引数なしで呼びます。

#文書を閉じる : Close()を引数なしで呼ぶ
In [121]: doc.Close()

読み取り専用のファイルに変更を加えてしまったので、ファイル名を変更するようにダイアログができてしまいます。

dialog.PNG

キャンセルしてダイアログを抜けると以下の例外が発生します。

In [122]: doc.Close()
---------------------------------------------------------------------------
com_error                                 Traceback (most recent call last)
<ipython-input-122-f62a2a61dece> in <module>()
----> 1 doc.Close()

com_error: (-2147352567, '例外が発生しました。', (0, 'Microsoft Word', 'このファイルは読み取り専用なので上書き保存できません。\n変更内容を保持するには、文書を別の名前で保存するか、別の場所に保存する必要があります。\r (C:\\...\\CSharp Language Specification....)', 'wdmain11.chm', 24635, -2146823133), None)

変更を保存せずに文書を閉じるために、Close(SaveChanges=0)を呼び出してみます。

#変更を保存せずに文書を閉じる : Close(SaveChanges=0)を呼び出す。
In [123]: doc.Close(SaveChanges=0)

今度は、何事もなく閉じることができます。

close.PNG

念のためもう一回開きます。

In [124]: doc=Application.Documents.Open(FileName=r"C:\tmp\CSharp Language Specification.docx", ConfirmConversions=False, ReadOnly=True)

先ほど加えた変更が反映されてないことが確認できました。

open_again.PNG

#コレクションと名前付きオブジェクトについて

以前のコレクションの説明

##Wordのコレクションについて
Wordのコレクションの各要素には、Documents(1)、Documents(2)、・・・と丸括弧でアクセスします。以下に注意が必要です

  • 角括弧ではないこと
  • nは1から始まること
  • Add()、Close()などの呼び出しやGUI操作(e.g.windowのクローズ操作)でコレクションの位置が変わる

名前付きオブジェクト(Nameプロパティを持っているオブジェクト)は、数値インデックス的なアクセスに加えて、「名前」(Nameプロパティ, FullNameプロパティと同じ文字列)を使ってアクセスできます。

前回、Tasksコレクションで暗黙的に使っています。(TaskオブジェクトにNameプロパティがある)

#名前付き引数に気を付ける

pywin32だと 名前付き引数を使っても途中の引数が省略できない ようです。(msdnの仕様を読んで位置を把握しないといけない)

Documents.Open() - msdn

式 . Open( FileName, ConfirmConversions, ReadOnly , ・・・

|名前|必須 / 省略可能|説明|
|:---|:---|:---|:---|
|FileName|必須|文書の名前/パス|
|ConfirmConversions|省略可能|True:Word 形式ではない場合、ファイルの変換ダイアログを表示|
|ReadOnly|省略可能|True:読み取り専用|

ReadOlyの場合、FileNameとReadOlyの間にConfirmConversionsがあるので、ConfirmConversionsに何らかの値(True, False, None)を渡す必要があります。msdnで省略可能となっている部分は 本当に省略するのではなくNoneを渡す と既定のデフォルトで動いてくれます。

VBAだとこのあたりいい感じに処理されているので以下のようなサンプルコードがよくあります。

Documents.Open メソッドのサンプル

Sub OpenDoc()
 Documents.Open FileName:="C:\MyFiles\MyDoc.doc", ReadOnly:=True
End Sub

再実装する場合は、明示的に名前付きで設定された引数の間に隠されている引数がないか、調査する必要があります。上記の例では、ConfirmConversionsがその隠された引数です。

VBScriptは、「名前付き引数自体をサポートしてない」+「使わない引数に何も設定しなくてよい」(下記の例参照)ので、こちらも再実装する際に気を付けるポイントになります。おそらく多くのケースNoneを設定すればなんとかなると思います。

例:
Officeファイルを読み取り専用で開くスクリプト - motoraku’s gists

OfficeOpenReadOnly.vbs
'■読み取り専用で開く
Call objApp.Documents.Open(strFileName,,True)

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

#参考

4
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?