ib11
ib11

Reputation: 2558

C# converting Word VBA macro BuiltInDocumentProperties("Number of Pages") is null

I have a Word VBA macro that I am converting to C# using the Office.Interop.

The code works nicely and I was able to convert everything, but I got stuck with trying to read to number of pages from the BuiltInDocumentProperties.

No matter what cast I use, it still does not work and returns null.

Here is the converted code:

using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office;
using Microsoft.Office.Interop;
using System.Diagnostics;
using System.Reflection;

Word.Application oWord = new Word.Application();
Word.Document oTgtDoc = new Word.Document();

var PgNum = oTgtDoc.BuiltInDocumentProperties["Number of Pages"];

float intWidthCount = engColWidth;

while (true)
{
    oTgtDoc.Tables[1].Columns[1].SetWidth(intWidthCount, Word.WdRulerStyle.wdAdjustProportional);      

    intWidthCount += 5;
    oTgtDoc.Repaginate();
    oWord.Application.ScreenRefresh();

    if (oTgtDoc.BuiltInDocumentProperties["Number of Pages"] > PgNum && intWidthCount > engColWidth)
    {
        while (oTgtDoc.BuiltInDocumentProperties["Number of Pages"] > PgNum)
        {
            intWidthCount--;
            oTgtDoc.Tables[1].Columns[1].SetWidth(intWidthCount, Word.WdRulerStyle.wdAdjustProportional); 

            oTgtDoc.Repaginate();
            oWord.Application.ScreenRefresh();
        }
        break;
    } 
    else
    {
      PgNum = oTgtDoc.BuiltInDocumentProperties["Number of Pages"];
    }

I have looked at several other post and msdn and did not get to the right solution yet. For example this one: Accessing document properties - Excel Workbook/CSV in VB

Or this one with the Dictionary, which would not work as I need to access it several times in the while loop: Read BuiltInDocumentProperties/CustomDocumentProperties alway null with Word 2010?

Any suggestions how to access this BuiltInDocumentProperties["Number of Pages"] from my C# code?

Upvotes: 1

Views: 795

Answers (2)

user3598756
user3598756

Reputation: 29421

edited: added example of using var PgNum = oTgtDoc.BuiltInDocumentProperties(Word.WdBuiltInProperty.wdPropertyPages).Value.ToString(); before "Reflection" example

edited 2: to take account for OP's need to use PgNum as an int

you must use

 var PgNum = oTgtDoc.BuiltInDocumentProperties(Word.WdBuiltInProperty.wdPropertyPages).Value;

or

 int PgNum = oTgtDoc.BuiltInDocumentProperties(Word.WdBuiltInProperty.wdPropertyPages).Value;

and BTW

Word.Document oTgtDoc = new Word.Document();

won't return any new Word document (i.e. a 'real' new document in Word UI) but just a new word document object in your class

should you actually want to have a new blank UI Word document than you'd use:

    object oMissing = Missing.Value;
    Word.Document oTgtDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);

here's how I tested var PgNum = oTgtDoc.BuiltInDocumentProperties(Word.WdBuiltInProperty.wdPropertyPages).Value.ToString(); with a console application

using System;
using System.Reflection;
using Word = Microsoft.Office.Interop.Word;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {    
            RunWordExample();
        } 


        static void RunWordExample()
        {
            Word.Application oWord = new Word.Application(); //Create an instance of Microsoft Word

            //Create a new Document
            object oMissing = Missing.Value;
            Word.Document oTgtDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);

            //make Word visible
            oWord.Visible = true;

            // get number of pages #1
            var PgNum = oTgtDoc.BuiltInDocumentProperties(Word.WdBuiltInProperty.wdPropertyPages).Value.ToString();
            Console.WriteLine("doc {0} has {1} page(s)", oTgtDoc.Name, PgNum);
            Console.ReadLine();

        }

    }
}

Finally, by drilling down the links you provided I think it could be useful to build a helper class and learn a bit about how Reflection works by exploiting BuiltInDocumentProperties object

using System;
using Word = Microsoft.Office.Interop.Word;
using System.Reflection;

namespace WordHelpers
{
    class MyWordHelpers
    {   
        public static string GetBuiltInDocumentProperty(Word.Document oDoc, string propertyName)
        {
            object oDocBuiltInProps;

            oDocBuiltInProps = oDoc.BuiltInDocumentProperties;
            Type typeDocBuiltInProps = oDocBuiltInProps.GetType();

            //get the property
            object oDocAuthorProp = typeDocBuiltInProps.InvokeMember("Item",
                                       BindingFlags.Default |
                                       BindingFlags.GetProperty,
                                       null, oDocBuiltInProps,
                                       new object[] { propertyName }); // <-- here you exploit the passed property 

            //get the property type
            Type typeDocAuthorProp = oDocAuthorProp.GetType();

            // return the property value
            return typeDocAuthorProp.InvokeMember("Value",
                                       BindingFlags.Default |
                                       BindingFlags.GetProperty,
                                       null, oDocAuthorProp,
                                       new object[] { }).ToString(); ;
        }
    }

}

to be used as follows (from a console application)

static void RunWordExample()
{
    Word.Application oWord = new Word.Application(); //Create an instance of Microsoft Word

    //Create a new Document
    object oMissing = Missing.Value;
    Word.Document oTgtDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);

    //make Word visible
    oWord.Visible = true;

    // get number of pages
    Console.WriteLine("doc {0} has {1} page(s)", oTgtDoc.Name, MyWordHelpers.GetBuiltInDocumentProperty(oTgtDoc,"Number of Pages"));
    Console.ReadLine();

}

Upvotes: 1

Arina
Arina

Reputation: 91

Does it have to be from BuiltInDocumentProperties?

You could try this:

// get number of pages
Microsoft.Office.Interop.Word.WdStatistic stat = Microsoft.Office.Interop.Word.WdStatistic.wdStatisticPages;
int pages = doc.ComputeStatistics(stat, Type.Missing);

Copied from this answer: How to get page number?

More info on Word statistics from MSDN

Upvotes: 1

Related Questions