John W. Colby
jwcolby at colbyconsulting.com
Tue Jan 13 08:43:42 CST 2004
Chris, I credit Shamil with teaching me everything I know about Withevents. I would never have discovered them, and would not be where I am today in Access without his examples and his prodding to look at WithEvents. If you looked at Shamil's stuff you will see where he places the [Event Procedure] in the control's event procedure using code inside the Init event of the class itself as the class instantiates. That is where I learned to do this and one reason I so dislike developers putting function calls in those properties. I used to use the tag property a lot using ADH code to set and read them. Once I started using classes I moved away from that to either setting properties directly in the class init or (in the case of my scanner, where it's more generic) using class properties to set these values later. There are pluses and minuses to using the tag - the control carries it's initialization properties with it, but if any other developer uses the tag yours can get trashed. I finally just stopped using it although there is still ONE place I do, and that is in my Just In Time form loading, where I place the form name in the tag. If it's there it will do JIT, otherwise it just loads normally. I would like to thank you though for the hint about input masks. My users have been pushing me to "standardize" the date inputmasks and using my framework I can do just that quite easily. John W. Colby www.ColbyConsulting.com -----Original Message----- From: accessd-bounces at databaseadvisors.com [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of chris at thecube.net Sent: Tuesday, January 13, 2004 8:00 AM To: accessd at databaseadvisors.com Subject: RE: [AccessD] =function() in .onclick John, Very similar to my method, but with a few slight differences, i may have missed out on new methods of using withevents, but i instantiate a class for the form, and instantiate classes for each of the controls (unless i exclude them) i control the behaviour of the controls using a list of parameters in the tag property so an entire data form could look like this behind the scenes. Dim DEEP As New clsFormControls Private Sub Form_Load() DEEP.Init Me End Sub Private Sub Form_Close() DEEP.Terminate End Sub and then i have a range of parameters for each of the controls: Text Boxes: DateControl=True applies a common input mask and formatting, as well as adding double-click functionality that pops up a calendar FilterForm=True;FilterField=<MyField> Dynamically filters the Form Data QuickSearch=True;SearchCtl=ControlName for doing a quick search (suprisingly) I have made various of other additions but i must mention that my code is largely based on Shamil Salakhetdinov's external events programming but i feel quite pleased with my modifications ----- Original Message ----- From: John W. Colby To: "Access Developers discussion and problem solving"<accessd at databaseadvisors.com> Sent: Tue, 13 Jan 2004 06:32:48 -0500 Subject: RE: [AccessD] =function() in .onclick Chris, >do you have a lot of variants for say textboxes or do you prefer to add parameters at runtime to sink different events / control behavior? I actually have an entire framework that does all of this stuff. I have a form class that sinks all of the form's events. That class has a collection which holds a class instance for each control found on the form. I then have classes for each control type which implement standard behaviors which I find useful - dblclick for a combo can open a list form for entering or correcting data contained in the combo, NotInList can add data to the table behind the combo and requery the combo when done etc. The form class has a scanner that cycles through all the controls in its form's control collection, instantiating a class for each control found (that I have a class for anyway). IOW, as the form loads, it scans for all controls, loads a class for each control found and saves a pointer to that control in the control class collection in the form's header. I then use what I call SysVars or System Variables to enable / disable specific form / control functionality. It turns out I have to "set up" things like the double click and NotInList for a combo anyway, i.e. I have to tell the combo the name of the form or the name of the table and the field in the table to place data in NotInList. My form open ends up looking something like: Option Compare Database Option Explicit Public WithEvents fclsFrm As dclsFrm Private Sub Form_Open(Cancel As Integer) On Error GoTo Err_Form_Open Set fclsFrm = New dclsFrm fclsFrm.Init Nothing, Me, Cancel If Cancel Then Exit Sub 'init the combo dbl-click and NotInList On Error Resume Next With fclsFrm.Children .Item("cboCountry").NotInListData "", "", "lfrmCountry" .Item("cboState").NotInListData "", "", "lfrmState" End With 'look for the lfrm used by these combos. 'fclsFrm.Children("cboCountry").LFrm = "lfrmCountry" 'fclsFrm.Children("cboState").LFrm = "lfrmState" Exit_Form_Open: Exit Sub Err_Form_Open: Select Case Err Case 0 '.insert Errors you wish to ignore here Resume Next Case Else '.All other errors will trap Beep MsgBox Err.Description, , "Error in Sub tfrmClients.Form_Open" Resume Exit_Form_Open End Select Resume 0 '.FOR TROUBLESHOOTING End Sub As you can see, I dim a class for the form (fclsFrm), then in OnOpen I instantiate it. By the time the form class init returns all the control classes have been loaded and are sitting in the children collection keyed on control name. I then "set up" things like NotInList by calling a function in the combo's class passing in the name of the form (and also table / field for single field list tables). Sometimes I want the NotInList to open a form (it is complex data with many fields), sometimes I want it to just enter the data into a specific field in the table (it is a simple list like titles or colors). So, the answer to your question is, I have the generic functionality I need for the controls already in the class for that control type. I can use it or not depending on whether I tell the class to do so. Very form / application specific behaviors I will generally program out in a separate class. John W. Colby www.ColbyConsulting.com -----Original Message----- From: accessd-bounces at databaseadvisors.com [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of chris at thecube.net Sent: Tuesday, January 13, 2004 6:08 AM To: accessd at databaseadvisors.com Subject: RE: [AccessD] =function() in .onclick John, Thanks for the 'warm' response <g>. I think i will get on and write the checkbox class to handle all of the checkboxes, on the subject of WithEvents/DEEP, do you have a lot of variants for say textboxes or do you prefer to add parameters at runtime to sink different events / control behaiviour? Cheers John Chris ----- Original Message ----- From: John W. Colby To: "Access Developers discussion and problem solving"<accessd at databaseadvisors.com> Sent: Tue, 13 Jan 2004 05:39:56 -0500 Subject: RE: [AccessD] =function() in .onclick I can't help you as to why it sometimes works and others it doesn't. However I'd like to say I HATE it when developers do this (and I have to maintain it). I routinely use the find dialog to find instances of code. Doing it like that means that I have to use a find and replace utility instead which is much more intrusive to my development effort. Another thing is that if you ever intend to use Withevents, they don't fire unless the words [Event Procedure] are in the property. If you have an event stub, you can use withevents (sink the event in a class) and the event handler in the form at the same time - the event handler in the class simply gets control first. Doing it with the function call in the property prevents sinking that control's events anywhere else. Now... If you ever handed that application off to someone like myself (who uses withevents), I build a class that directly pokes the words [Event Procedure] into the control's event property (to make sure the event fires) and now MY class works but your functionality abruptly ceases to work. Just thought I'd throw that out there. If I were you I'd probably write a class that handles those checkboxes, either individually or en mass. John W. Colby www.ColbyConsulting.com -----Original Message----- From: accessd-bounces at databaseadvisors.com [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of chris at thecube.net Sent: Tuesday, January 13, 2004 5:24 AM To: accessd at databaseadvisors.com Subject: [AccessD] =function() in .onclick Hi All, Instead of writing 54 event procedures, i simply iterate through a collection of checkboxes and set their AfterUpdate property to a function like so: for index = 1 to 54 me("chkTemplate" & index).Afterupdate = "=toggleTemplate(" & index & ")" next now, on some Access 2000 installs this works fine, yet on others it baulks at trying to put a function straight into the event like above. Am I doing anything wrong? Cheers Chris