Автоматизация Excel: Близкие пропавшие без вести события

Другой привет все,

Я делаю автоматизацию Excel через Interop в C#, и я хочу быть информированным, когда рабочая книга закрывается. Однако нет никакого события Close на рабочей книге, ни события Quit на приложении.

Кто-либо сделал это прежде? Как я могу записать часть кода, который реагирует на закрываемую рабочую книгу (который только выполняется, если рабочая книга действительно закрывается)? Идеально это должно произойти после закрытия рабочей книги, таким образом, я могу полагаться на файл для отражения всех изменений.

Детали о том, что я нашел до сих пор:

Существует событие BeforeClose(), но если там не сохраняются, изменяется, это событие генерируется перед пользователем, которого спрашивают, сохранить ли их, поэтому в данный момент, я могу обработать событие, у меня нет заключительного файла, и я не могу выпустить COM-объекты, обе вещи, что я должен/. Я даже не знаю, будет ли рабочая книга на самом деле закрыта, так как пользователь мог бы принять решение прервать закрытие.

Затем существует событие BeforeSave(). Так, если пользователь выбирает "Yes" для сохранения несохраненных изменений, то BeforeSave () выполняется после BeforeClose (). Однако, если пользователь принимает решение "Прерваться", то хиты "файл-> сохраняют", тот же самый заказ событий выполнен. Далее, если пользователь выбирает "No", BeforeSave () не выполняется вообще. То же содержит, пока пользователь не нажимает ни одной из этих опций.

5
задан chiccodoro 5 May 2010 в 08:30
поделиться

2 ответа

Я создал хак, используя подход, похожий на опрос, и он работает:

Учитывая рабочую книгу, которую нужно наблюдать, я создаю поток, который периодически пытается найти эту книгу в сборнике трудовых книжек.

(Класс DisposableCom - мое текущее решение для правильной очистки COM-объектов .)

Excel.Application app = wbWorkbook.Application;
string sWorkbookName = wbWorkbook.Name;

Thread overseeWorkbooksThread = new Thread(new ThreadStart(
    delegate()
    {
        bool bOpened = false;

        Excel.Workbooks wbsWorkbooks = app.Workbooks;
        using (new DisposableCom<Excel.Workbooks>(wbsWorkbooks))
        {
            while (true)
            {
                Thread.Sleep(1000);

                if (wbsWorkbooks.ContainsWorkbookProperly(sWorkbookName))
                    bOpened = true;
                else
                    if (bOpened)
                        // Workbook was open, so it has been closed.
                        break;
                    else
                    {
                        // Workbook simply not finished opening, do nothing
                    }
            }

            // Workbook closed
            RunTheCodeToBeRunAfterWorkbookIsClosed();
        }
    }));

overseeWorkbooksThread.Start();

Методы расширения «ContainsWorkbookProperly» выглядят следующим образом:

public static bool ContainsWorkbookProperly(this Excel.Workbooks excelWbs,
    string sWorkbookName)
{
    Excel.Workbook wbTemp = null;
    try
        wbTemp = excelWbs.Item(sWorkbookName);
    catch (Exception)
    {
        // ignore
    }

    if (wbTemp != null)
    {
        new DisposableCom<Excel.Workbook>(wbTemp).Dispose();
        return true;
    }

    return false;
}

Тем не менее, мне было бы интересно, есть ли более простой или лучшее решение.

4
ответ дан 14 December 2019 в 13:29
поделиться

Можете ли вы использовать оба события? На BeforeClose() установите флаг, затем BeforeSave() посмотрите, установлен ли флаг. Однако вам понадобится способ сбросить его, если срабатывает BeforeClose(), а BeforeSave() нет. Не уверен, есть ли что-то еще, что могло бы помочь в этом.

Edit: Похоже, вы уже прикрыли это «выполняется точно такой же порядок событий». Но если вы сможете найти способ сбросить его (еще одно событие «Отмена»?), это может сработать.

-1
ответ дан 14 December 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: