Home |
Search |
Today's Posts |
#1
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
A couple of things I've learned while developing an Excel Spreadsheet with
VBA Objects and Events: 1. It is possible to add and delete control toolbox objects to the worksheet using code in the ThisWorkbook, the Active Worksheet, Module, and Class Module and handle events for both the events added to the worksheet at design time and added/deleted during run time. For example: -------- Module1 -------- Option Explicit Public mcolEvents As Collection Dim clsevents As CEvents Sub InitializeEvents() Dim objcontrol As OLEObject If mcolEvents Is Nothing Then Set mcolEvents = New Collection End If 'Loop through all the controls For Each objcontrol In ActiveSheet.OLEObjects If TypeName(objcontrol.Object) = "Frame" Then Set clsevents = New CEvents Set clsevents.FRControl = objcontrol.Object Set clsevents.TBControl = objcontrol.Object.Controls(0) Set clsevents.SBControl = objcontrol.Object.Controls(1) mcolEvents.Add clsevents GoSub Next_Control End If If TypeName(objcontrol.Object) = "CommandButton" Then Set clsevents = New CEvents Set clsevents.CBControl = objcontrol.Object mcolEvents.Add clsevents GoSub Next_Control End If If TypeName(objcontrol.Object) = "CheckBox" Then Set clsevents = New CEvents Set clsevents.CHControl = objcontrol.Object mcolEvents.Add clsevents GoSub Next_Control End If Next_Control: Next End Sub Sub TerminateEvents() ' Destroy class collections to free up memory Set mcolEvents = Nothing End Sub -------- Class CEvents -------- Option Explicit Private WithEvents TB As MSForms.TextBox Private WithEvents SB As MSForms.SpinButton Private WithEvents CB As MSForms.CommandButton Private WithEvents CH As MSForms.CheckBox Private WithEvents FR As MSForms.Frame Public Property Set TBControl(objNewTB As MSForms.TextBox) Set TB = objNewTB End Property Public Property Set SBControl(objNewSB As MSForms.SpinButton) Set SB = objNewSB End Property Public Property Set CBControl(objNewCB As MSForms.CommandButton) Set CB = objNewCB End Property Public Property Set CHControl(objNewCH As MSForms.CheckBox) Set CH = objNewCH End Property Public Property Set FRControl(objNewFr As MSForms.Frame) Set FR = objNewFr End Property Private Sub Class_Terminate() Set TB = Nothing Set SB = Nothing Set CB = Nothing Set CH = Nothing Set FR = Nothing End Sub --------------------- will setup the events for frame objects containing textbox and spinbuttons, command buttons and checkboxes. If you need to add/delete the object from a workbook event, worksheet event, and during code, you just need to rerun the InitializeEvents procedure in the module using the following code whenever you add/delete an object to recognize the events/clean-up the events: Set mcolEvents = Nothing Application.OnTime Now, "InitializeEvents" This will reset the events for the objects that are still on the worksheet after an object is either added or deleted from the screen. When you add an object, make sure you activate or setfocus to the object to make it work. For example, to active the frame object - use: objFR.Activate You can also call the InitializeEvents procedure from the ThisWorkbook.Workbook_Activate event and the ThisWorkbook.Workbook_SheetActivate event when you display the first worksheet or change worksheets that will use the same code. 2. When adding/deleting objects, public variables that will be used from the ThisWorkbook, Worksheet, Module, and Class Module get blown away for no reason. For example, I was setting variables to handle highlighting of a textbox within a specific frame whenever the worksheet was initially displayed, redisplayed, or the a new frame/textbox/spinbutton object was added. But the object that I was highlighting would lose cursor control and highlighting when the object was added or another object was deleted. You can get around this by using namedfields. For example: objFR.Object.Controls(0).SelStart = 3 objFR.Object.Controls(0).SelLength = 2 objFR.Object.Controls(0).HideSelection = False ThisWorkbook.Names.Add Name:="strtimechange", RefersTo:="MN", Visible:=False ThisWorkbook.Names.Add Name:="iCur", RefersTo:=3, Visible:=False This will ensure the values of the variables are always retained. Just make sure you recall the values when you need them using code like: Dim strtimechange As string Dim icur As Integer strtimechange = Mid(ThisWorkbook.Names("strtimechange").RefersTo, 3, Len(ThisWorkbook.Names("strtimechange").RefersTo) - 3) iCur = Mid(ThisWorkbook.Names("icur").RefersTo, 2) 3. Use Application.EnableEvents, Application.ScreenUpdating, and Application.Cursor around the code in your procedures to control events from being repeated, screen from being repainted, and the cursor to show a temporary "busy" cursor instead of the default. Anyway - hope this helps - Alot of people helped me to get to this point and I wanted to thank them by sharing what I learned to others in return. Steve P.S. Sorry if I left anything out when I editing the code to include in this post. I can provide additional info to anyone that needs it. |
Thread Tools | Search this Thread |
Display Modes | |
|
|
![]() |
||||
Thread | Forum | |||
Lessons from optimizing a slow spreadsheet | Excel Discussion (Misc queries) | |||
I learned how to rename workbook without saving it | Excel Programming | |||
in three lesson i learned more about the ribbon and its new use | Excel Discussion (Misc queries) | |||
Microsoft lessons should be listed from basic to advanced | New Users to Excel | |||
Excel Function lessons Needed! | Excel Worksheet Functions |