<br />
<b>Notice</b>:  Function _load_textdomain_just_in_time was called <strong>incorrectly</strong>. Translation loading for the <code>jonradio-multiple-themes</code> domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the <code>init</code> action or later. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 6.7.0.) in <b>/var/www/vhosts/ronmaliepaard.nl/httpdocs/blog/wp-includes/functions.php</b> on line <b>6131</b><br />
{"id":146,"date":"2014-05-09T14:36:58","date_gmt":"2014-05-09T13:36:58","guid":{"rendered":"http:\/\/www.ronmaliepaard.nl\/blog\/?p=146"},"modified":"2014-05-09T14:43:31","modified_gmt":"2014-05-09T13:43:31","slug":"146","status":"publish","type":"post","link":"https:\/\/www.ronmaliepaard.nl\/blog\/146\/","title":{"rendered":"The sequence of events in workbooks"},"content":{"rendered":"<h1>The sequence of events in workbooks<\/h1>\n<div>2013\/01\/31\u00a0by\u00a0<a title=\"Frans\" href=\"http:\/\/pixcels.nl\/author\/frans\/\" rel=\"author\">frans<\/a><\/div>\n<div>\n<p>When you open a workbook Excel not only raises the Workbook_Open event but also a few other events. The same applies to switching worksheets, or closing the workbook. In this post I examine the sequence of activation\/deactivation events in an Excel multiple window application, and with a ribbon custom tab. However, most of the findings also apply to normal single window applications without a custom tab, and also to Excel 2013.<\/p>\n<p>In a multiple window application (or Multiple Document Interface, MDI) we can distinguish five levels:<\/p>\n<div>\n<div id=\"highlighter_304220\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<\/td>\n<td style=\"text-align: left;\">\n<div>\n<div><code>Application - the top level;<\/code><\/div>\n<div><code>Workbook\u00a0\u00a0\u00a0 - within the active excel instance the user can switch to another workbook;<\/code><\/div>\n<div><code>Window\u00a0\u00a0\u00a0\u00a0\u00a0 - within the active workbook the user can switch to another window;<\/code><\/div>\n<div><code>Sheet\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - within the active window the user can switch to another sheet;<\/code><\/div>\n<div><code>Range\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - within the active sheet the user can switch to another cell.<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Note that this is not a true hierarchical relationship, since the parent of a sheet is the workbook, not the window.<\/p>\n<p><a title=\"The sequence of events in workbooks\" href=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/MDImodel.png\" rel=\"lightbox[248]\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/MDImodel-300x225.png\" alt=\"MDImodel\" width=\"382\" height=\"287\" \/><\/a><\/p>\n<div><\/div>\n<p>The conceptual model in the figure above presents an overview of the five levels and their Activate\/Deactivate events. You may keep this in mind when reading on.<br \/>\nNote that on every level two events are raised when switching to another object. However, on Range level only an \u201cActivate\u201d event is fired (SelectionChange).<\/p>\n<h3>Opening the workbook<\/h3>\n<p><a href=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/ExcelEvents1.xlsm\">ExcelEvents1.xlsm<\/a>\u00a0is a workbook with two worksheets and two windows, and a custom tab with two cloned controls. In the workbook and worksheet modules all relevant events are defined. Most events have only two lines of code, to create a trace list in the VBE Immediate Window. Consider this trace list as an extension of the VBE Call Stack.<br \/>\nAfter opening the workbook the trace list is:<\/p>\n<div>\n<div id=\"highlighter_929090\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_Open<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Activate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_WindowActivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Ribbon.customUIonLoad<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>At startup Excel not only fires a Workbook_Open but also a Workbook_Activate and a Workbook_WindowActivate event. Always in this sequence. Note that the Workbook_WindowActivate is\u00a0<em>always<\/em>\u00a0fired, even when your application has only one window. Since most Excel applications have a single window interface we usually don\u2019t need this event.<\/p>\n<h5>Ribbon custom tab<\/h5>\n<p>The trace list above makes clear that the custom tab is loaded\u00a0<em>after<\/em>\u00a0the three workbook events. This gives you the opportunity to initialize any data structures that are used by the controls in the custom tab before these controls are loaded. For example, perhaps some controls must be hidden or disabled on startup. Or in Workbook_Open you determine the language to be used in the custom control labels.<\/p>\n<h5>CustomUIonload not always raised<\/h5>\n<p><a title=\"The sequence of events in workbooks\" href=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/CantExecuteInBreakMode.png\" rel=\"lightbox[248]\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/CantExecuteInBreakMode.png\" alt=\"CantExecuteInBreakMode\" width=\"298\" height=\"169\" \/><\/a><\/p>\n<p>If you add a msgbox statement in the Workbook_Open handler, code execution will pause until the user closes the messagebox. Obvious. But now replace the msgbox by a Stop statement. Then something else happens: after re-opening the file you receive one or more messages saying that VBA can\u2019t execute code in debug mode. After closing these messagebox(es) and continue running your code (F5) the Ribbon.customUIonLoad is missing in the trace list and indeed was not executed. However, the custom tab is installed.<\/p>\n<h5>More debugging trouble<\/h5>\n<p>Keep the Stop in the Workbook_Open handler and again re-open the app. Now use F8 to step through your code, and watch the trace list when you press F8 on \u201cEnd Sub\u201d. Conclusion: if you want to debug and step through your startup code then you have to set breakpoints in each fired events. Be aware of this potential debugging pitfall.<\/p>\n<h5>Disabled events or deferred events?<\/h5>\n<p>Now set EventEnabling to false in the Workbook_Open. Save and re-open, and see this trace list:<\/p>\n<div>\n<div id=\"highlighter_111556\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_Open<\/code><\/div>\n<div style=\"text-align: left;\"><code>Ribbon.customUIonLoad<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Again we see that the ribbon does things its own way, ignoring the events setting. (See\u00a0<a title=\"Disable Shift key on open\" href=\"http:\/\/pixcels.nl\/disable-shift-key-on-open\/\">Disable Shift key on open<\/a>.) Indeed, the ribbon is not part of the Excel Object Model, just like activex controls and userforms. The two Activate events were not fired, as we could expect. However\u2026 are they really not fired? Do some switching between sheets and windows, and you will see that no new events occur. Obvious, we disabled them. But then go to the VBE Immediate Window and set eventenabling to true. Immediately the two \u201cmissing\u201d events are fired! Or perhaps we should say: processed. They were fired at startup before events were disabled. Disabling events does not kill any events that were fired already. Processing was deferred until events were enabled again.<\/p>\n<h5>The startup window<\/h5>\n<p>At startup Excel always activates the last window. If your app has 5 windows then the window with WindowNumber = 5 will be activated, even when you saved it with window 3 active. This is important to note. If you want your user to start on the first window you might be tempted to activate window 1 at the end of Workbook_Open. It will do so, but remember: after the Workbook_Open a Window_Activate is fired that will activate window 5! Indeed, this can be very confusing. A simple workaround is to create your windows in reverse order. Or activate your preferred window later, in the Workbook_WindowActivate handler.<\/p>\n<h5>The missing Sheet activation<\/h5>\n<p>Note that in Open events series a Worksheet_Activate is missing. Unfortunately, I would argue. And perhaps a bit inconsistent. Excel sends us a message that the workbook is activated; Excel sends us a message that the window is activated. Why not send us a message that the sheet is activated too? Anyway, if you want your user to always start on Sheet1, and you need to do some initialization on Sheet1 you can use code like this on startup:<\/p>\n<div>\n<div id=\"highlighter_461416\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>If Activesheet.Name = Sheet1.Name Then Sheet1.Initialize Else Sheet1.Activate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>And in Worksheet_Activate of Sheet1 you call Me.Initialize. Note that only Sheet1.Activate is not sufficient: if Sheet1 is already the activesheet this event won\u2019t fire.<\/p>\n<h3>Switching<\/h3>\n<h5>Switching between Workbooks<\/h5>\n<p>Switching to another workbook (eg by creating a new workbook) gives this events list:<\/p>\n<div>\n<div id=\"highlighter_385579\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_WindowDeactivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Deactivate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>And if the user switches back from another workbook (eg closes the new workbook):<\/p>\n<div>\n<div id=\"highlighter_728588\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div>1<\/div>\n<div>2<\/div>\n<\/td>\n<td>\n<div>\n<div><code>Workbook_Activate<\/code><\/div>\n<div><code>Workbook_WindowActivate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Again, note that there\u2019s no SheetDeactivate or SheetActivate event fired. If you want for example a userform visible when SheetOne is active then you must trigger the show\/hide of the userform from another event. The obvious event is the WindowDe\/Activate, where you can Init\/Exit the active sheet.<\/p>\n<h5>Switching between Windows<\/h5>\n<div>\n<div id=\"highlighter_388810\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_WindowDeactivate 2<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_WindowActivate 1<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Still no SheetDe\/activate events fired, even if the two windows show different sheets. See the previous paragraph for a solution if you need to do some inits\/exits for a sheet.<\/p>\n<h5>Switching between Sheets<\/h5>\n<div>\n<div id=\"highlighter_913735\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Worksheet_Deactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Worksheet_Activate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetActivate SheetTwo<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Finally, a SheetDe\/activate! Note that first the lowest event level is fired. More on this later.<\/p>\n<h3>Closing the Workbook<\/h3>\n<p>When the user closes the workbook the trace list is:<\/p>\n<div>\n<div id=\"highlighter_638345\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_BeforeClose<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_WindowDeactivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Deactivate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Keep in mind that the Before_Close event is not the last event being handled.<br \/>\nIf the user has made changes and then closes the workbook, Excel will ask to save the changes. This is the trace list:<\/p>\n<div>\n<div id=\"highlighter_571818\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_BeforeClose<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_BeforeSave<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_AfterSave<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_WindowDeactivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Deactivate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>Application level events<\/h3>\n<p>In\u00a0<a href=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/ExcelEvents2.xlsm\">ExcelEvents2.xlsm<\/a>\u00a0I added class CApplicationEvents. This class traps all relevant application level events and adds them to the trace list. The object is created in Workbook_Open and destroyed in Workbook_BeforeClose. (That\u2019s how to do it, right? Think about it a minute. Still sure? Let\u2019s see\u2026)<br \/>\nThis is the trace list after opening the file:<\/p>\n<div>\n<div id=\"highlighter_823036\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<div style=\"text-align: left;\">6<\/div>\n<div style=\"text-align: left;\">7<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_Open<\/code><\/div>\n<div style=\"text-align: left;\"><code>Application_WorkbookOpen<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Activate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Application_WorkbookActivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_WindowActivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Application_WindowActivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Ribbon.customUIonLoad<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>No surprises. Let\u2019s move on.<br \/>\nAfter switching from SheetOne to SheetTwo in the active window we see:<\/p>\n<div>\n<div id=\"highlighter_360391\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<div style=\"text-align: left;\">6<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Worksheet_Deactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Application_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Worksheet_Activate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetActivate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>Application_SheetActivate SheetTwo<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Handling the events starts on the lowest level, then moving up in the hierarchy.<br \/>\nFinally, this is the trace list after closing the file:<\/p>\n<div>\n<div id=\"highlighter_491231\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_BeforeClose<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_WindowDeactivate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Deactivate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>But wait! Don\u2019t we miss something here?! This is one of the pitfalls that can be hard to debug if you\u2019re not aware of the sequence of events. Got the answer already? Spoiler follows. In the Workbook_BeforeClose handler we destroyed the clsApplicationEvents object. So it can\u2019t listen anymore to the events that are fired\u00a0<em>after<\/em>\u00a0the BeforeClose! If you comment out the set-to-nothing line in the Workbook_BeforeClose handler then the trace list becomes:<\/p>\n<div>\n<div id=\"highlighter_276773\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<div style=\"text-align: left;\">6<\/div>\n<\/td>\n<td style=\"text-align: left;\">\n<div>\n<div><code>Workbook_BeforeClose<\/code><\/div>\n<div><code>Application_WorkbookBeforeClose<\/code><\/div>\n<div><code>Workbook_WindowDeactivate<\/code><\/div>\n<div><code>Application_WindowDeactivate<\/code><\/div>\n<div><code>Workbook_Deactivate<\/code><\/div>\n<div><code>Application_WorkbookDeactivate<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Looks much better now! So it\u00a0<em>seemed<\/em>\u00a0to be the right place to kill the object in Before_Close but in fact this is too early. What to do? A simple workaround is: in the Workbook_BeforeClose set a switch Closing to true. In Workbook_Deactivate you add a line like:<\/p>\n<div>\n<div id=\"highlighter_444013\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>If Closing Then Set clsApplicationEvents = Nothing<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>This solution is implemented in ExcelEvents3.xlsm, see next item.<\/p>\n<h3>Trapped workbook and worksheet events<\/h3>\n<p>Beside Application events we can also trap most of the Workbook and Worksheet events. In\u00a0<a href=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/ExcelEvents3.xlsm\">ExcelEvents3.xlsm<\/a>\u00a0we added two classes, one to trap Workbook events and one to trap Worksheet events. In the Workbook_Open handler now four objects are created to trap the events of the Application, of the Workbook and of the two Worksheets. Now, when we switch from SheetOne to SheetTwo in the active window, we get up to five sheet-deactivate and five sheet-activate events:<\/p>\n<div>\n<div id=\"highlighter_293632\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<div style=\"text-align: left;\">6<\/div>\n<div style=\"text-align: left;\">7<\/div>\n<div style=\"text-align: left;\">8<\/div>\n<div style=\"text-align: left;\">9<\/div>\n<div style=\"text-align: left;\">10<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>MyWorksheet_Deactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Worksheet_Deactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyWorkbook_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyApplication_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyWorksheet_Activate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>Worksheet_Activate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyWorkbook_SheetActivate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetActivate SheetTwo<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyApplication_SheetActivate SheetTwo<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Note that the trapped event is always processed first. However, there is one exception to this rule. After opening the workbook we see:<\/p>\n<div>\n<div id=\"highlighter_531202\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>Workbook_Open<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyApplication_WorkbookOpen<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyWorkbook_Activate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_Activate<\/code><\/div>\n<div style=\"text-align: left;\"><code>Etc<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>There is no MyWorkbook_Open event in the list. Since event trapping is set in the Workbook_Open handler it is not possible to trap this event before it is processed. Seems obvious, so actually there was no need to expose this event to the class.<br \/>\nYou can use Events3.xlsm to do some more research on trapped events. If you want you can add other events to the classes, or add classes to trap embedded chart events, or querytable events. Whatever.<\/p>\n<h3>Talking about Charts<\/h3>\n<p>A chart can be either an embedded chart (contained in a ChartObject object) or a separate chart sheet (quote Microsoft MSDN). If the chart is embedded it behaves just like any other object that can live on a worksheet. For example, on a worksheet you can switch the selection between cells, charts, controls, images etc. You can create a class to trap embedded chart events, much like you create a class to trap querytable events. No big deal.<br \/>\nOn the other hand, if the chart is a \u201cchart sheet\u201d it behaves just like a normal worksheet. Indeed, a chart sheet and a worksheet are both sheets, members of the sheets collection. In the module of a chart sheet you can define events, like you did in the worksheet module. Also you can define a class to trap these chart sheet events. Then, switching from SheetOne to a Chart sheet results in a trace list like this:<\/p>\n<div>\n<div id=\"highlighter_497822\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"10\">\n<div style=\"text-align: left;\">1<\/div>\n<div style=\"text-align: left;\">2<\/div>\n<div style=\"text-align: left;\">3<\/div>\n<div style=\"text-align: left;\">4<\/div>\n<div style=\"text-align: left;\">5<\/div>\n<div style=\"text-align: left;\">6<\/div>\n<div style=\"text-align: left;\">7<\/div>\n<div style=\"text-align: left;\">8<\/div>\n<div style=\"text-align: left;\">9<\/div>\n<div style=\"text-align: left;\">10<\/div>\n<\/td>\n<td>\n<div>\n<div style=\"text-align: left;\"><code>MyWorksheet_Deactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Worksheet_Deactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyWorkbook_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyApplication_SheetDeactivate SheetOne<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyChart_Activate Chart<\/code><\/div>\n<div style=\"text-align: left;\"><code>Chart_Activate Chart<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyWorkbook_SheetActivate Chart<\/code><\/div>\n<div style=\"text-align: left;\"><code>Workbook_SheetActivate Chart<\/code><\/div>\n<div style=\"text-align: left;\"><code>MyApplication_SheetActivate Chart<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>No big deal either.<\/p>\n<h3>And what about Excel 2013?<\/h3>\n<p><a title=\"The sequence of events in workbooks\" href=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/MDI20102013.png\" rel=\"lightbox[248]\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/pixcels.nl\/wp\/wp-content\/uploads\/2013\/02\/MDI20102013-150x150.png\" alt=\"MDI20102013\" width=\"265\" height=\"265\" \/><\/a><\/p>\n<p>Microsoft decided to move Excel 2013 from MDI to SDI. Does this change the event model as we described above? Quote from MSDN: \u201cSDI means that each workbook will have its own top-level app window and will have its own corresponding ribbon. All existing application-level window methods, events, and properties are unaffected by this change. All existing workbook-level window methods, events, and properties now operate on the top-level window for that workbook.\u201d So the answer is: no, not at all. The only \u2013 big \u2013 difference is the way the windows are presented to the user, see screenshots. In 2013 every window has it\u2019s own ribbon and statusbar, which makes a multi window arrangement in 2013 much less attractive. Nevertheless, even in 2013 Excel will raise all events and event series as described above.<\/p>\n<h3>Conclusion<\/h3>\n<p>In this post I examined the sequence of events in a MDI Excel app with two windows. Most apps are SDI and are perhaps a bit less complicated. In any case, MDI or SDI, it is important to be aware of the events and event series that are fired by Excel and when and how they are processed. As we have seen this is not always obvious. An event driven multi window application requires good planning and good design. In upcoming posts I want to share some more on these issues. For now: I hope this pixcel helps. Excel!<\/p>\n<p>&nbsp;<\/p>\n<p>Source:\u00a0\u00a0\u00a0<a title=\"Events in Excel Workbooks\" href=\"http:\/\/pixcels.nl\/events-in-workbooks\/\" target=\"_blank\">Events in Excel Workbooks<\/a><\/p>\n<p>Related :\u00a0<a title=\"Events And Event Procedures In VBA\" href=\"http:\/\/www.cpearson.com\/excel\/Events.aspx\" target=\"_blank\">Events And Event Procedures In VBA<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The sequence of events in workbooks 2013\/01\/31\u00a0by\u00a0frans When you open a workbook Excel not only raises the Workbook_Open event but also a few other events. The same applies to switching worksheets, or closing the workbook. In this post I examine the sequence of activation\/deactivation events in an Excel multiple window application, and with a ribbon custom tab. However, most of the findings also apply to normal single window applications without a custom tab, and also to Excel 2013. In a&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.ronmaliepaard.nl\/blog\/146\/\"> Lees Meer<span class=\"screen-reader-text\">  Lees Meer<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","_uag_custom_page_level_css":"","footnotes":""},"categories":[8],"tags":[],"post_folder":[128],"class_list":["post-146","post","type-post","status-publish","format-standard","hentry","category-excel"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false,"nisarg-full-width":false,"wpsso-schema-1x1":false,"wpsso-schema-4x3":false,"wpsso-schema-16x9":false,"wpsso-thumbnail":false,"wpsso-opengraph":false,"wpsso-tc-summary":false,"wpsso-tc-lrgimg":false},"uagb_author_info":{"display_name":"maliepro","author_link":"https:\/\/www.ronmaliepaard.nl\/blog\/author\/maliepro\/"},"uagb_comment_info":0,"uagb_excerpt":"The sequence of events in workbooks 2013\/01\/31\u00a0by\u00a0frans When you open a workbook Excel not only raises the Workbook_Open event but also a few other events. The same applies to switching worksheets, or closing the workbook. In this post I examine the sequence of activation\/deactivation events in an Excel multiple window application, and with a ribbon&hellip;","_links":{"self":[{"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/posts\/146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/comments?post=146"}],"version-history":[{"count":0,"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/posts\/146\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/media?parent=146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/categories?post=146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/tags?post=146"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/www.ronmaliepaard.nl\/blog\/wp-json\/wp\/v2\/post_folder?post=146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}