Как эффективно использовать событие WorkbookBeforeClose правильно?

Ежедневно, человек должен проверить, что определенные рабочие книги были правильно обновлены с данными рынка Bloomberg и Агентства Рейтер; т.е. все данные выжили и что 'числа выглядят корректными'. В прошлом люди не проверяли 'числа', которые привели к неточным загрузкам на другие системы.

Идея состоит в том, что 'что-то' должно быть разработано, чтобы препятствовать тому, чтобы использование закрылось/сохранило рабочую книгу, если он не проверил, что обновления корректны/точны. numbers look correct действие является просто интуитивным осуществлением, таким образом не будет кодирован всегда.

Простое решение состояло в том, чтобы предложить пользователям до закрытия определенной рабочей книги проверять, что данные были проверены.

Using VSTO SE для Excel 2007, Дополнение было создано, который сцепляется в WorkbookBeforeClose событие, которое инициализируется в дополнении ThisAddIn_Startup

private void wb_BeforeClose(Xl.Workbook wb, ref bool cancel)
{
    //.... snip ...

    if (list.Contains(wb.Name))
    {
        DailogResult result = MessageBox.Show("some message", "sometitle", MessageBoxButtons.YesNo);

        if (result != DialogResult.Yes)
        {
            cancel = true; // i think this prevents the whole application from closing
        } 
    } 
}

Я нашел следующее ThisApplication.WorkbookBeforeSave по сравнению с ThisWorkbook.Application.WorkbookBeforeSave который рекомендует, чтобы использовал ThisApplication.WorkbookBeforeClose событие, которое я думаю, - то, что я делаю, с тех пор охватит все открытые файлы.

Проблема, которую я имею с подходом, - то, что предположение, что у меня есть несколько открытых файлов, некоторые из которых находятся в моем list, событие препятствует тому, чтобы Excel закрыл все файлы последовательно. Это теперь требует, чтобы каждый файл был закрыт индивидуально.Править: это происходит, когда Exit Excel используется из меню File.

Вопросы

  1. Я использую WorkbookBeforeClose событие правильно и является этим эффективным и эффективным использованием события?
  2. Я должен использовать Событие уровня приложения или событие уровня документа?
  3. Поведение описано выше нормального?
  4. Любые другие предложения одобрены при использовании событий рабочей книги в дополнении

Обновление [30 марта 2010]:

Чиня вокруг, я также попробовал следующее, которое попыталось связать BeforeClose обработчик событий к каждой рабочей книге, которая была открыта, как предложено из ссылки выше.

private void ThisAddIn_Startup(...)
{
    // snip
    Globals.ThisAddin.Application.WorkbookOpen += Application_Open; 
}

private void Application_Open(XL.Workbook wb)
{
    wb.BeforeClose += Document_WorkbookBeforeClose; // method does the same as above
}

Проблема, которую я нашел с этим подходом, это, я пытаюсь близко ко всему Excel Files (использующий опцию Exit Excel), обработчик событий не выполняется. От моего наблюдения это происходит, когда документ, который будет проверен, не является активным документом.

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

Обновление [07 апреля 2010]:

Предложенный ответ долины реки полезен, но не занимается непосредственными вопросами под рукой, я таким образом разъяснил последний вопрос немного далее.

Я также нашел этот блог, Как Получить Excel VSTO Workbook Closed Event, который несколько относится к моей проблеме, поскольку это могло использоваться в рамках альтернативного подхода к моему решению с помощью подхода типа монитора к обработке рабочих книг (и возможно также использовать недавно представленный OnWorkbookClosed событие).

Обновление [08 апреля 2010]:

Кажется, существует некоторый беспорядок, я не обеспокоен никакой проверкой на самих рабочих книгах, а скорее использую ли метод я (т.е. использую Прикладной уровень WorkbookBeforeClose событие), корректно. комментарий @Mathias' ниже показывает корректное понимание части проблемы относительно вопроса 3, я думаю, что это - поведение Excel по умолчанию все же. Решение преодолеть это состояло в том, чтобы создать близкую функцию, которая закрывает только мои определенные файлы.

  1. Поведение описано выше нормального? Да, но почему? Поскольку дополнительные рычаги в событие уровня приложения, проверки и отмену события блокируют приложение от закрытия дальнейших рабочих книг. Ключ здесь ref bool cancel аргумент (cancel=false позволяет нормальное закрытие рабочей книги (значение по умолчанию), cancel=true препятствует тому, чтобы рабочая книга закрылась),

VS 2005 с VSTO SE

7
задан Todd Main 22 July 2010 в 20:15
поделиться

3 ответа

Рекомендуется использовать WorkbookBeforeClose уровня приложения . Проблема в том, что нестабильное поведение возникает из-за того, что файлы не сохраняются при вызове WorkbookBeforeClose . В противном случае произойдет событие Save, и вы фактически потеряете событие WorkbookBeforeClose , поскольку оно уже произошло. Вот код VBA, который помогает справиться с этим.

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If Not Me.Saved Then
        NotSavedPrompt = Me.Name & " has not been saved. Would you like to save now?"
        SaveYesNo = MsgBox(NotSavedPrompt, vbQuestion + vbYesNoCancel)
        Select Case SaveYesNo
            Case vbYes
                Me.Save
            Case vbNo
                Me.Saved = True
            Case vbCancel
                Cancel = True
                Exit Sub
          End Select
    End If
    Call MyRoutine() //'this should be your sub that does what you want
End Sub
7
ответ дан 6 December 2019 в 23:04
поделиться
  1. Правильно ли я использую событие WorkbookBeforeClose и эффективно ли это использование события?

    Я не могу найти более подходящего события. Однако я думаю, что другим подходом было бы использование функции Save & Close , которая использует событие WorkbookBeforeSave

  2. Должен ли я использовать событие уровня приложения или событие уровня документа ?

    на момент написания этого, я бы сказал, что да. Поскольку я не могу создать надстройку на уровне документа с помощью имеющихся у меня инструментов, это лучшее решение. Если бы инструменты были доступны, я бы изменил свойства документов _AssemblyName и _AssemblyLocation соответствующих файлов. Однако я бы изменил стратегию решения, используя шаблоны и затем сохранив файлы по мере необходимости. Кроме того, перед сохранением, не изучив это полностью, необходимо добавить / удалить правильные свойства документа. Событие на уровне документа хорошо подошло бы с использованием подхода, описанного выше.

  3. Является ли описанное выше поведение нормальным?

    Да, но почему? Поскольку надстройка перехватывает событие уровня приложения, проверка и отмена события блокируют приложение от закрытия любых последующих книг.Ключевым моментом здесь является аргумент ref bool cancel (cancel = false разрешает нормальное закрытие книги (по умолчанию), cancel = true предотвращает закрытие книги). Если я ошибаюсь, дайте мне знать.

  4. Любые другие предложения приветствуются при использовании событий книги в надстройке.

    См. Ответы выше об альтернативных подходах и использовании различных событий.

1
ответ дан 6 December 2019 в 23:04
поделиться

Поскольку при таком подходе у вас возникают проблемы, а Excel может не позволять вам делать то, что вам нужно, возможно, вы могли бы рассмотреть другой подход для решения общей проблемы.

Не могли бы вы встроить что-нибудь в книгу, которая пометила бы ее как «Проверено / Непроверено» на основании того, проверял ли кто-то числа? В зависимости от того, как на самом деле используется книга (не ясно из вопроса), способ отображения ее как непроверенной может варьироваться ... (визуально) установить цвет фона на светлый оттенок красного или (программно) изменить используемый именованный диапазон, чтобы указать на пустую область, чтобы другие надстройки / макросы не могли найти данные.

Пользователь, который должен проверить книгу, должен будет щелкнуть кнопку (в книге или на панели инструментов), чтобы указать, что он ее проверил. Затем ваш код отменит указанные выше изменения и установит флаг, указывающий, что книга была проверена. Это может быть скрытая ячейка где-нибудь в книге или в свойствах модуля VBA.

Напомним ... при открытии проверьте флаг. Если не установлен, измените книгу, чтобы она выглядела непроверенной. Если он установлен, то никаких изменений не требуется. Когда пользователь проверяет книгу, установите флаг и сохраните ее навсегда.

Надеюсь, это поможет!

3
ответ дан 6 December 2019 в 23:04
поделиться
Другие вопросы по тегам:

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