Как я могу прочитать пользовательское свойство документа Excel, используя c# Excel Interop - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь проверить, установлено ли пользовательское свойство документа для файла Excel или нет. И если установлено, то прочитайте значение.

Вот код, который я использую, но пока не повезло. Он не попадает в foreach l oop и выходит.

var propval = ReadDocumentProperty("TestProp");

private string ReadDocumentProperty(string propertyName)
{
    Office.DocumentProperties properties;
    Excel.Workbook Wb = Globals.ThisAddIn.Application.ActiveWorkbook;
    properties = (Office.DocumentProperties)Wb.CustomDocumentProperties;

    foreach (Office.DocumentProperty prop in properties)
    {
        if (prop.Name == propertyName)
        {
            return prop.Value.ToString();
        }
    }
    return null;
}

Update1:

Я нашел этот код для установки пользовательского свойства.

Excel.Workbook workBk = Globals.ThisAddIn.Application.ActiveWorkbook;

            object oDocCustomProps = workBk.CustomDocumentProperties;
            Type typeDocCustomProps = oDocCustomProps.GetType();

            object[] oArgs = {propertyName,false,
         Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeString,
         propertyValue};

            typeDocCustomProps.InvokeMember("Add", BindingFlags.Default |
                                       BindingFlags.InvokeMethod, null,
                                       oDocCustomProps, oArgs);

Это прекрасно работает для установки пользовательского свойства. Я понятия не имею, как изменить его, чтобы прочитать значение свойства.

1 Ответ

3 голосов
/ 10 января 2020

Принцип тот же. Некоторые исследования о том, как использовать PInvoke, могут помочь, когда это необходимо для работы с «взаимодействием» Office. Чтобы использовать его, необходимо полностью понять ту часть объектной модели Office, к которой нужно обратиться: объект, свойство или метод, и какие именно аргументы требуются, поскольку нет IntelliSense, который может помочь , Первое тестирование в интерфейсе VBA может сделать это проще.

Следующий фрагмент кода, который я имею в тестовом проекте, демонстрирует, как обращаться к одному свойству документа и читать, а затем записывать его значение. Обратите внимание, что пример кода работает с BuiltInDocumentProperties. Это можно изменить на CustomDocumentProperties, если это то, что требуется.

    private void btnUpdateCustomDocProp_Click(object sender, EventArgs e)
    {
        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
        Excel.Application xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.application");
        Excel.Workbook wb = xlApp.ActiveWorkbook;
        object docProps = wb.BuiltinDocumentProperties;

        object prop = ExistsDocProp("Author", docProps);
        if (prop!=null)
        {
            object oProp = prop;
            Type oPropType = oProp.GetType();
            //read current value
            string propValue = oPropType.InvokeMember("Value",
                BindingFlags.GetProperty | BindingFlags.Default,
                null, oProp, new object[] { }).ToString();

            object oPropValue = "new test author";
            //write new value
            oPropType.InvokeMember("Value",
                BindingFlags.SetProperty | BindingFlags.Default,
                null, oProp, new object[] {oPropValue});

            MessageBox.Show(propValue + ", " + oPropValue.ToString());         
        }
    }

    private object ExistsDocProp(string propName, object props)
    {
        Office.DocumentProperty customDocProp = null;
        Type docPropsType = props.GetType();
        object nrProps;
        object itemProp = null;
        object oPropName;

        nrProps = docPropsType.InvokeMember("Count",
            BindingFlags.GetProperty | BindingFlags.Default,
            null, props, new object[] { });
        int iProps = (int)nrProps;

        for (int counter = 1; counter <= ((int)nrProps); counter++)
        {
            itemProp = docPropsType.InvokeMember("Item",
                BindingFlags.GetProperty | BindingFlags.Default,
                null, props, new object[] { counter });

            oPropName = docPropsType.InvokeMember("Name",
                BindingFlags.GetProperty | BindingFlags.Default,
                null, itemProp, new object[] { });

            if (propName == oPropName.ToString())
            {
                break;
            }
        }
        return itemProp; 
    }
...