

初心者です。
エクセルVBAでWordのプロパティ値を取得するためBuiltinDocumentProperties("Number of Pages")を使っているのですが、なぜかページ数が正しく表示されません。
例えば6ページある文書の総ページ数が2というふうに全然関係ない数字が返ってきます。念のためマクロ後にプロパティ値を再確認すると、表示された2に変わってしまっているんです。もちろん実際の文書に存在するページ枚数は変わっていません。
文書自体を開いて上書きしてやると、ページ数の数字は戻るのですが、マクロを実行すると同じ結果になります。どうしてでしょうか?
EXCEL2000です。詳しい方お願いします。
No.10ベストアンサー
- 回答日時:
> なぜかウチのEXCELはページ数ではなくて、総文字数を返します。
それは、恐らく参照設定の問題ですね。実行時バインド(CreateObject)
方式では ComputeStatistics に渡す引数のインデックス番号が正しく
渡らないのだと思います。参照設定を行えば問題なく動作します。
ちなみに私は昔から BuiltinDocumentProperties は当てにならない、、
と思いこんでましたから、ComputeStatistics を使ってました。
今回、Wendy02 さんが良い情報を提供して下さいましたので、私も今後は
BuiltinDocumentProperties 派でいこうと思います。
ただ、今回このスレッドで紹介された方法はいずれもファイル全体を一度
は読み込む方法ですから、処理速度は遅いですね。機会があれば、
バイナリー解析でページ数を取得する関数を作ってみたいと思います。
それから、蛇足で恐縮ですが、#8 発言の手前、一応アップしておきます。
ユーザー定義関数を作ってみました。が、、関数にする必要性はあまり
無かったです(;-ω-) =3
Word ファイルのパスを渡すと、各種情報が一次元配列で返されます。
使いかたは、サンプルコードを見てください。
Variant型の変数で関数の戻り値を一次元配列で受けます。その変数の
添え字に取得したい BuiltinDocumentProperties のインデックス番号
を指定します。
まぁ。。ファイル処理周りの例外処理をメインルーチン側で省けるので
意義は在ると言えば在るのですが。
Sub 使い方サンプルコード()
Dim Fname As String
Dim aryInfo As Variant
Dim sMes(8) As String
Dim Sp As String
Fname = Application.GetOpenFilename("MsWordファイル(*.doc),*.doc")
If UCase$(Fname) = "FALSE" Then
Exit Sub
End If
'関数の戻り値は一次元配列なので Variant型 の変数で受ける
aryInfo = GetMsWordBuiltinProperties(Fname)
'結果表示
If IsArray(aryInfo) = False Then Exit Sub
Sp = vbTab & ": "
sMes(0) = "ファイル名" & Sp & Dir(Fname)
sMes(1) = "バイト数" & Sp & Format(aryInfo(22) / 1024, "#,##0") & " KB"
sMes(2) = "タイトル" & Sp & aryInfo(1)
sMes(3) = "文字数" & Sp & aryInfo(16)
sMes(4) = "(SP含む)" & Sp & aryInfo(30)
sMes(5) = "行数" & Sp & aryInfo(23)
sMes(6) = "ページ数" & Sp & aryInfo(14)
sMes(7) = "段落数" & Sp & aryInfo(24)
sMes(8) = "単語数" & Sp & aryInfo(15)
MsgBox Join$(sMes, vbCr)
End Sub
'MsWord ドキュメントの各種統計情報を取得
Function GetMsWordBuiltinProperties(strFilePath As String) As Variant
'要参照設定:Microsoft Word x.x Object Library
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim aryRet(1 To 30) As Variant
On Error GoTo ErrorHandler
'初期化
GetMsWordBuiltinProperties = False
'ファイルが無いまたは拡張子が異なる場合は False を返す
If Dir(strFilePath) = "" _
Or UCase$(Right$(strFilePath, 4)) <> ".DOC" Then
Exit Function
End If
'MsWord ファイルオープン
Set wdApp = New Word.Application
Set wdDoc = wdApp.Documents.Open(strFilePath, ReadOnly:=True)
'ドキュメントの統計情報を取得
With wdDoc
.Repaginate 'Thanks Wendy02 san!
For i = 1 To 30
aryRet(i) = .BuiltinDocumentProperties(i)
'Index 24-29 は Word では使わないと思います
If i = 24 Then i = 29
Next i
End With
'戻り値をセット
GetMsWordBuiltinProperties = aryRet
Terminate:
On Error Resume Next
wdDoc.Close False
wdApp.Application.Quit
Set wdDoc = Nothing
Set wdApp = Nothing
Exit Function
ErrorHandler:
'想定外のエラー発生の場合には False を返す
GetMsWordBuiltinProperties = False
On Error GoTo 0
GoTo Terminate
End Function
こんにちはidbr2です。
お礼が大変遅くなり恐縮しております。こちらが質問しておきながら済みませんでした。
ちょっと忙しくなってしまったので、ゆっくりブックを開くこともままなりません。
せっかくですので、教えていただいたコードが意味する内容も含めて、独学していく上での糧にするため色々確認したいのですが、そこはやはり初心者ということでそういった作業にさえある程度時間を要してしまいます。
よって、まだ示していただいたマクロに手を付けられずにいるのですが、用事の方がもう少しかかわりそうなので、とりあえずお礼のほうを先にいたします。
いろいろありがとうございました。今回、大変勉強になりました。
No.11
- 回答日時:
KenKen_SPさん、idbr2さん。
こんにちは、Wend02です。
>バイナリー解析でページ数を取得する関数を作ってみたいと思います。
それは、どのようにして行われるのか、C++でも使うでしょうか?今回、私は、プロパティを取得するタイプライブラリは、すでに、存在しているはずだと思っています。理由は、
Application.GetOpenFilename("MsWordファイル(*.doc),*.doc")
で、プロパティの内容は見てとれますですね。それは、そういう機能のあるプログラムが存在していることに他なりません。ファイルの表層部分にでも記録があるものだと思っています。私の場合は、未だ、いろんな資料が少ないもので、なかなか分らない部分も多いです。
今回、それを調べる過程で、MSの資料が出てきただけで、本来の目的とは違いました。もう少し、私も本格的な勉強をしないと、こういうところがクリアできないのです。
こんにちはidbr2です。
お礼が大変遅くなり恐縮しております。こちらが質問しておきながら済みませんでした。
ちょっと忙しくなってしまったので、ゆっくりブックを開くこともままなりません。
せっかくですので、教えていただいたコードが意味する内容も含めて、独学していく上での糧にするため色々確認したいのですが、そこはやはり初心者ということでそういった作業にさえある程度時間を要してしまいます。
よって、まだ示していただいたマクロに手を付けられずにいるのですが、用事の方がもう少しかかわりそうなので、とりあえずお礼のほうを先にいたします。
いろいろありがとうございました。今回、大変勉強になりました。
No.9
- 回答日時:
Wendy02です。
以下は、修正版です。Sub MsWordタイトル取得2()
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim Fname As String
Dim FileSize As Long, myWait As Long
Dim wdCnt As Long, wdtitle As String
Set wdApp = New Word.Application
Fname = Application.GetOpenFilename("MsWordファイル(*.doc),*.doc")
If Fname = "False" Then
Exit Sub
End If
Set wdDoc = wdApp.Documents.Open(Fname, , True)
With wdDoc
.Repaginate '書き換えた部分
wdtitle = .BuiltinDocumentProperties(wdPropertyTitle)
wdCnt = .BuiltinDocumentProperties(wdPropertyPages)
.Close False
End With
wdApp.Quit
Set wdDoc = Nothing
Set wdApp = Nothing
MsgBox wdtitle & vbCrLf & " 総ページ数" & wdCnt
End Sub
以下を参考にしました。
http://support.microsoft.com/default.aspx?scid=k …
(http://support.microsoft.com/kb/212653/ja)
英語からの拙訳:
WD2000: BuiltInDocumentPropertiesで誤ったページ・カウント表示を返す場合。
記事ID:212653
本記事は、Q212653の元で以前に発表された。
ドキュメントにページ改行を挿入し、マクロを使ってBuiltInDocumentProperties のプロパティを用いてページ・カウントを返した時に、返されるページが誤っている場合。
そのドキュメントはページ数を返す前に、"repaginate"で再ページカウントする必要がある。
Sub GetNumberOfPages()
ActiveDocument.Repaginate
MsgBox ActiveDocument.BuiltInDocumentProperties(wdPropertyPages)
End Sub
No.8
- 回答日時:
こんにちは、idbr2 さん、Wendy02 さん。
こちらも色々検証してみましたが、どうも CreateObject
では無理みたいですね、、原因は不明ですが。
参照設定必須みたいです、、、
関数化したものをアップしますので、よろしければ、
暫しお待ちを。
No.7
- 回答日時:
Wendy02です。
ごめんなさい。
>基本的なミスとしては、WordのApplicationが終了していません。
その元のwdApp.Quit を入れずに書いたのは私でした。
m(__)m なんと言ってよいのか、引っ込みつきません。すぐに気が付いてよかったです。重ねてすみません。
No.6
- 回答日時:
こんにちは。
Wendy02です。>おそらく完全に文書を読み込み切れていないのが原因なのかなと、自分では推測しております。
確認しました。おっしゃる通りです。ただし、そのコードは、とても危険な内容です。あやうく、フリーズをするところでした。とりあえず以下のようにしてみてください。基本的なミスとしては、WordのApplicationが終了していません。もしも、Applicationをオープンしたままでしたら、GetObjectを使いながら、取得すればもっと速く取れるはずです。Visible を入れてみて気が付きました。
今回、API関数を入れ、Waitを付けてみました。その値(FileSize/50000)自体は、PCのスペックに依存するものですから、最適値は、変わります。もちろん、KenKen_SPさんのComputeStatisticsの方法でも、切り替えれば、取得可能なはずです。
それから、CreateObjectでも取れるはずですが、安定を考えて、参照設定を使いました。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub MsWordタイトル取得()
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim Fname As String
Dim FileSize As Long, myWait As Long
Dim wdCnt As Long, wdtitle As String
Set wdApp = New Word.Application
Fname = Application.GetOpenFilename("MsWordファイル(*.doc),*.doc")
If Fname = "False" Then
Exit Sub
End If
FileSize = FileLen(Fname)
Set wdDoc = wdApp.Documents.Open(Fname, , True)
'wdApp.Visible = True
myWait = Int(FileSize / 50000) * 1000
Sleep myWait
With wdDoc
wdtitle = .BuiltinDocumentProperties("Title")
wdCnt = .BuiltinDocumentProperties("Number of Pages")
.Close False
End With
wdApp.Quit
Set wdDoc = Nothing
Set wdApp = Nothing
MsgBox wdtitle & vbCrLf & " 総ページ数" & wdCnt
End Sub
No.5
- 回答日時:
#2のWendy02ですが、
自分の発言を撤回します。
#Wordを開いていませんか?そうすると、コードが違ってきてしまいます。
ではなくて、開け方が問題ではないでしょうか?オートメーションで開ける分には、ドキュメントが開いていようがいまいが、関係がありません。それで、私は、この問題は、環境の違いによって途中で書き換わっていると考えています。Officeのプロパティは、元々、外部ツールなどで閲覧できるように作られているので、開いて書き換えなければ、変わらないはずです。
Sub WhatTPages_inWDDoc()
Dim WdApp As Object
Dim WdDoc As Object
Dim myRange As Object
Dim myFile As String
Dim Pagecount As Integer
myFile = "C:\MyFavorite.Doc"
On Error GoTo ErrHandler
Set WdApp = CreateObject("Word.Application")
With WdApp.Documents.Open(myFile, , True)
Set myRange = .Content
myRange.Collapse Direction:=0
Pagecount = .BuiltinDocumentProperties(14)
.Close 0
End With
MsgBox Pagecount & " ページ"
ErrHandler:
Set WdApp = Nothing
End Sub
お礼が遅くなって済みませんでした。
さっそく教えていただいたマクロを試しましたが、やはりページ数は2と表示されます。おそらく完全に文書を読み込み切れていないのが原因なのかなと、自分では推測しております。
それと、ご質問があったマクロの最終目的なのですが、ワード文書がひとつ出来上がるごとに、作成日時と文書タイトル、総ページ数などをエクセルの一覧表に記入していくという作業をしたかったので、ダイアログから選択した文書のプロパティ値をマクロで取得して、エクセルの表に書き込んでくためのものです。
最初の状況報告があいまいで申し訳ありませんでした。
下記に途中まで作ってみたマクロを載せます。
Sub MsWordタイトル取得()
Dim wdApp As Object, Fname As String, wdDoc As Object
Dim wdCnt As Long
Dim wdtitle As String
Set wdApp = CreateObject("Word.Application")
Fname = Application.GetOpenFilename("MsWordファイル(*.doc),*.doc")
If Fname = "False" Then
Exit Sub
End If
Set wdDoc = wdApp.Documents.Open(Fname)
wdtitle = wdDoc.BuiltinDocumentProperties("Title")
wdCnt = wdDoc.BuiltinDocumentProperties("Number of Pages")
wdDoc.Close False
MsgBox wdtitle & vbCrLf & " 総ページ数" & wdCnt
Set wdApp = Nothing
End Sub
No.4
- 回答日時:
#1 です。
重ねて失礼しました。#3 は変数の宣言が漏れたり、WORD のインスタンスが残ったり、お粗末なコード
でした。差し替えさせて頂きます。適当ですみません。
Sub Sample()
Dim wdApp As Object
Dim wdDoc As Object
Dim lngPageCount As Long
Set wdApp = CreateObject("Word.Application")
'ファイルオープン
Set wdDoc = wdApp.Documents.Open("C:\test.doc")
'ページ数取得
lngPageCount = wdDoc.ComputeStatistics( _
Statistic:=wdStatisticPages, _
IncludeFootnotesAndEndnotes:=True)
'WORDを閉じる
wdDoc.Close
wdApp.Application.Quit
'ページ数表示
MsgBox lngPageCount
'オブジェクト変数を解放
Set wdDoc = Nothing
Set wdApp = Nothing
End Sub
お礼が遅くなって済みませんでした。
さっそく教えていただいたマクロを実行してみたのですが、なぜかウチのEXCELはページ数ではなくて、総文字数を返します。
これはコードの問題ではなくて、ブック自体がおかしくなっているのかも知れないと考え、ブックを新たに作って再挑戦をしましたがこれも駄目。アプリの自動修復を試みたのですが、悪いことは続くもので、ただいまCDRのハードの方が故障していてOfficeのCDを読み込めません。
結局、現時点で打つ手なしかなと諦めモードです。
BuiltinDocumentProperties("Number of Pages")を使うと処理が不完全のまま進行する例が確かにあるということは、何とか自分でも調べられました。
教えていただいたComputeStatistics( Statistic:=wdStatisticPages)の動作確認が取れないのが残念です。
No.3
- 回答日時:
#1 です。
失礼。Excel VBA でしたね。ページが重たいと BuiltinDocumentProperties("Number of Pages") は不安定
みたいですね。ページを開く途中で、コードが実行されている感じがします。
コーディんグにもよると思いますが。
以下は Excel VBA で書き直しました。ご参考までに。
Sub Sample()
Dim wdApp As Object
Set wdApp = CreateObject("Word.Application")
'ファイルオープン
Set wdDoc = wdApp.Documents.Open("C:\test.doc")
'ページ数取得
lngPageCount = wdDoc.ComputeStatistics( _
Statistic:=wdStatisticPages, _
IncludeFootnotesAndEndnotes:=True)
'WORDを閉じる
wdDoc.Close
'ページ数表示
MsgBox lngPageCount
'オブジェクト変数を解放
Set wdDoc = Nothing
Set wdApp = Nothing
End Sub
No.2
- 回答日時:
こんにちは。
私も、コードを書く時は、BuiltinDocumentProperties("Number of Pages")で、ページ数は取っていますので、その取るまでのコードを見せていただけませんか?
もしかしたら、Wordを開いていませんか?そうすると、コードが違ってきてしまいます。アクセスする間に、そのWordが書き換わっている可能性がありますね。実体のある「ファイルのプロパティ」でないと、うまくいきませんからね。
それと、大事なことなのですが、そのコードの最終目的を教えてください。それがないと、見当違いな話になることがありますから。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- ノートパソコン ページ番号の入れ方について 3 2023/02/16 17:11
- C言語・C++・C# プログラミングの問題です。至急教えてください。 /***から***/の部分をプログラミングにしてほし 1 2022/10/13 11:48
- PHP PHP MySql ページング 2 2022/09/20 06:38
- Word(ワード) ワード2023でテキストボックス内の数字が勝手に変わってしまう 1 2023/02/09 14:47
- Visual Basic(VBA) VBAでPDFのアクティブページ番号取得 1 2023/05/25 12:41
- その他(ブラウザ) IE・edgeで日増しに観られるサイトが減ってくる。 1 2022/10/04 22:40
- TOEFL・TOEIC・英語検定 この本の訳まちがいではありませんか? 1 2022/11/15 11:52
- Word(ワード) Office 365のWordでオブジェクト挿入であるWord文書にほかのWord文書やPDFを貼り 2 2022/05/09 15:57
- Word(ワード) 最高裁判所から通達がある Wordの書式設定。所謂 裁判所に提出するすべての書類のことです。 A4縦 2 2022/12/23 15:00
- Excel(エクセル) Excelから複数のWordファイルを操作する方法について教えて頂きたい。 やりたいことは、複数のW 2 2022/07/26 20:11
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
-
大麻の使用罪がなかった理由や法改正での変更点、他国との違いを弁護士が解説
ドイツで2024年4月に大麻が合法化され、その2ヶ月後にサッカーEURO2024が行われた。その際、ドイツ警察は大会運営における治安維持の一つの方針として「アルコールを飲んでいるグループと、大麻を吸っているグループ...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
動かなくなってしまった古いVBA...
-
VBAでフォルダ内のhtmlファイル...
-
webブラウザからローカルファイ...
-
AccessからOLEオブジェクト型の...
-
【ACCESS VBA】アクセスからデ...
-
VBAで次のような処理をできるか...
-
FileDialog オブジェクトでファ...
-
コモンダイアログでフォルダを...
-
excel マクロ PDF化の際のエラ...
-
VB.net XMLの作成方法 Iniの代替
-
vbs ブック共有を解除
-
タイムスタンプの更新の方法2
-
コモンダイアログで拡張子の無...
-
VB.Netソリューションでフォー...
-
vbaサブフォルダーをワイルドカ...
-
「エクセルファイルが開いてい...
-
エクセルのプロパティーでセキ...
-
ExcelブックをGoogleスプレッド...
-
(C#)フォルダを指定するダイ...
-
Excel 相対パス
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
動かなくなってしまった古いVBA...
-
「エクセルファイルが開いてい...
-
FileDialog オブジェクトでファ...
-
VBAでフォルダ内のhtmlファイル...
-
VB6でUTF-8ファイルの読取りを
-
vbaサブフォルダーをワイルドカ...
-
webブラウザからローカルファイ...
-
ffftpでファイル取得が0バイト...
-
サブフォルダ含むフォルダ内の...
-
ファイルを複数選択した時のフ...
-
VBAでCSVファイルを読み込もう...
-
複数のワークブックのVBAを変更...
-
excel マクロ PDF化の際のエラ...
-
Wordのプロパティ・総ページ数...
-
フォルダ階層・ファイル名・ペ...
-
フォルダ内のファイル存在監視...
-
AccessからOLEオブジェクト型の...
-
VB.net XMLの作成方法 Iniの代替
-
【ACCESS VBA】アクセスからデ...
-
vbs ブック共有を解除
おすすめ情報