Есть ли способ установить временные флаги для объектов книги Excel? - PullRequest
0 голосов
/ 07 марта 2011

У меня есть вспомогательный класс C # (ExcelMacroHelper), который помогает вводить код макроса VBA в открытые книги Excel и запускать полученные макросы.Я только что понял, что следующие шаги сломают мой код:

  1. Приложение C # внедряет код макроса в активную книгу, что заставляет ExcelMacroHelper пометить свое состояние как готовое к запуску макросов

  2. Пользователь переключается на другую книгу в Excel.

  3. Приложение C # пытается запустить макрос.ExcelMacroHelper будет считать, что он готов к запуску макросов, но код VBA был внедрен в другую книгу, поэтому вызов не будет выполнен.

Чтобы это исправить, я думаю, что мне нужно немногоспособ установки временного свойства для объекта Workbook, указывающий, что мой макрос-код был введен в него, или, по крайней мере, способ сохранения списка Workbook s, которые были обработаны.Есть идеи?

Ответы [ 3 ]

1 голос
/ 08 марта 2011

Вы можете использовать Имена для хранения значений (а также ссылок на диапазоны и т. Д.)

В псевдокоде

if not (name already exists) then
    Set nm = workbook.Names.add("Injected")
    nm.Value = False
    nm.Visable = False
end if

if nm.value = False
    //Inject Code
    nm.value = true
endif

Примечание: самый простой способ проверить, существует ли имя, это попытаться получить доступи обработайте ошибку, если она не

0 голосов
/ 11 марта 2011

Я использовал пользовательские свойства документа. Примерно так:

private bool needToInjectMacroCode() {
    // Get custom document property with name tagPropertyName

    object properties, property, propertyValue;

    properties = excel.ActiveWorkbook.GetType().InvokeMember(
        "CustomDocumentProperties",
        BindingFlags.Default | BindingFlags.GetProperty,
        null, excel.ActiveWorkbook, null);

    try {
        property = properties.GetType().InvokeMember(
            "Item",
            BindingFlags.Default | BindingFlags.GetProperty,
            null, properties, new object[] { tagPropertyName });
    } catch (TargetInvocationException) {
        return true;
    }

    propertyValue = property.GetType().InvokeMember(
        "Value",
        BindingFlags.Default | BindingFlags.GetProperty,
        null, property, null);

    return (tagString != (propertyValue as string));
}

// ...

private void setMacroCodeInjected() {
    // Set custom property with name tagPropertyName to value tagString

    object properties = excel.ActiveWorkbook.GetType().InvokeMember(
        "CustomDocumentProperties",
        BindingFlags.Default | BindingFlags.GetProperty,
        null, excel.ActiveWorkbook, null);

    try {
        properties.GetType().InvokeMember(
            "Add",
            BindingFlags.Default | BindingFlags.InvokeMethod,
            null, properties, new object[] {
                tagPropertyName, false,
                Office.MsoDocProperties.msoPropertyTypeString,
                tagString
            });
    } catch (TargetInvocationException) {
        object property = properties.GetType().InvokeMember(
            "Item",
            BindingFlags.Default | BindingFlags.GetProperty,
            null, properties, new object[] { tagPropertyName });

        property.GetType().InvokeMember(
            "Value",
            BindingFlags.Default | BindingFlags.SetProperty,
            null, property, new object[] { tagString });
    }
}
0 голосов
/ 07 марта 2011

Вы можете использовать свойство Tag Workbook .

Когда вы вводите код, вы можете сделать что-то вроде этого:

public class ExcelMacroHelper
{
   public static void Inject(Workbook workbook)
   {
       if ((workbook.Tag as String != "Injected"))
       {
          //Inject the code

           workbook.Tag = "Injected";
       }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...