Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Only half of form instances close (Access 2002 SP-2)

    I have an Access form (hereafter the Sidekick form) that can be instantiated multiple times, and can be called by several different main forms (hereafter the Calling Forms). Whenever a Calling Form is closed, I want any Sidekick forms that were opened by that Calling Form to close automatically. So the Sidekick form has an event sink for the Close event of the Calling Form.

    Now let's say I close a Calling Form that has 6 open Sidekicks. I've verified (with Debug.Print) that the mfrmCaller_Close event sink runs in all 6 Sidekicks. But the fly in the ointment comes when I add the following lines to the event sink:
    <pre> Me.SetFocus
    DoCmd.Close</pre>

    With those lines in the event sink, the event sink only fires for Sidekicks 1, 3 and 5, which accordingly get closed. Sidekicks 2, 4 and 6 remain open. (Adding DoEvents doesn't help.) It looks like somehow the closing of Sidekick 1 prevents the event sink in Sidekick 2 from running, and likewise with Sidekick 3 (interfering with 4) and Sidekick 5 (interfering with 6). To emphasize: It's not just that the DoCmd.Close method fails for 2, 4 and 6. The event sink doesn't run at all (e.g., a Debug.Print line ahead of the SetFocus and Close lines doesn't happen either).

    I can work around the problem by having the Form_Close event procedure of each Calling Form call a close-the-related-forms method of the Sidekicks collection class, but that's a less encapsulated approach. Anybody know why I'm getting the every-other-form behavior and if there's a way to avoid it and still use the event sink in the Sidekick form module to close the Sidekicks?

  2. #2
    Gold Lounger
    Join Date
    Feb 2001
    Location
    Sint Niklaas, Belgium
    Posts
    2,778
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    It looks like you when you close sidekick 1, sidekick 2 becomes sidekick 1, then you close sidekick 2 that was sidekick 3, ...
    Try to close your sidekicks in reverse order, first 6, then 5 then 4,...
    Francois

  3. #3
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Since the DoCmd.Close line is in a separate event sink in each of the 6 instances (each of which is responding to the same event -- the closing of the Calling Form), I don't have any control over the order in which they fire. (It just happens, in this case, that they fire in ascending order -- that is, in the same order in which the instances were created.) Note that the DoCmd.Close line makes no reference to the FormNum property (that's the form class property that gets assigned the ID nos. 1-6) of the particular instance.

  4. #4
    Gold Lounger
    Join Date
    Feb 2001
    Location
    Sint Niklaas, Belgium
    Posts
    2,778
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    I had never worked with multiple instances of a form.
    If just run some simple test and found that if you use :
    DoCmd.Close acForm, "Sidekick Form Name"
    in the on close event of the Calling Form, this should close all instances of the Sidecick form.
    Do this work for your situation ?
    Francois

  5. #5
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Thanks for the input. The reason that won't work here is that Sidekick instances can be called up by more than one Calling Form, and if Calling Form A closes while Calling Form B has 2 instances open, I don't want the instances called by Calling Form B to close. Using the Sidekick event sink fits this nicely since the Close event that each sink is tied to is the Close event of the form that called that Sidekick.

    As I mentioned in my initial post, if I resign myself to putting code in the Close event of each Calling Form, I can get the result I want by having the Sidekicks collection class loop through the instances in its collection and close each instance whose .CallingForm property is set to the form that's closing (using the same SetFocus and DoCmd.Close lines as my failed approach, which in this context don't exhibit the skip-every-other-form misbehavior).

    But it somewhat undercuts the much-ballyhooed "encapsulation" potential of class modules (and particularly their event-sink feature) when hooking into the class necessitates putting code in multiple event procedures in the "client" objects. To me, the Encapsulation Holy Grail involves hooking into the server class in a single place in the client (in my case, the Click event of the Calling Form button that loads a Sidekick instance) where you instantiate the class and pass it the necessary objects and other arguments, and then having the rest of the required hooks into the client be located in event sinks in the class.

    Mainly, though, I was just curious as to whether anyone else had encountered the strange every-other-instance behavior with event sinks and/or knew of a direct fix (rather than a workaround) -- i.e., a way to ensure that all instances of the event sink run.

  6. #6
    Gold Lounger
    Join Date
    Feb 2001
    Location
    Sint Niklaas, Belgium
    Posts
    2,778
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Just another idea.
    Put an invisible textbox on your Sidekick form.
    When opening an instance of the Sidekick form, put the name of the Calling Form in that invisible control.
    In the On Close Event of the Calling Form, enter the following code :

    Dim x As Integer
    For x = Forms.Count - 1 To 0 Step -1
    If Forms(x).Name = "Sidekick Form" Then
    If Forms(x).Controls("Invisible Control Name") = "Calling Form Name" Then
    Forms(x).SetFocus
    DoCmd.Close
    End If
    End If
    Next x
    Francois

  7. #7
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Only half of form instances close (Access 2002 SP-2)

    I'm not sure why you're using those lines at all. What's wrong with a simple <code>DoCmd.Close acForm, Me.Name</code>? There is no need to use SetFocus, and the event will only fire for the close event of the specific calling form, so there should be no confusion.
    Charlotte

  8. #8
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    The form I'm trying to close with the .SetFocus and DoCmd.Close lines isn't the Calling Form (it's the close event of the Calling Form that's triggering the event sinks in question), but instead the Sidekick instances that were opened by that Calling Form. There might be several Sidekick instances open when the Calling Form closes, and there might also be several other Sidekick instances that were opened by a different Calling Form (and that I don't want to close).

    Your suggestion doesn't target the specific instances of the Sidekick form that were called by the Calling Form that's closing. (In my attempted method, they're tied to that Calling Form because they have event sinks tied to the Close event of that Calling Form, and they close themselves because of the Me.SetFocus line.)

    In the interests of science, however, I tried putting your code in the event sink and got a half-successful result similar to the strange result I get from my code. With 6 Sidekick instances open (each called by Calling Form A), and with your code in an event sink in each instance tied to the Close event of Calling Form A, the result of closing Calling Form A is that instances 1, 2 and 3 close while instances 4, 5 and 6 remain open. As with my code, this is because only 3 of the 6 event sinks run. Also as with my code, it's actually the event sinks for instances 1, 3 and 5 that run, but your code causes those event sinks to close instances 1, 2 and 3 rather than instances 1, 3 and 5 (which are the ones that my code closes) because your code doesn't close the particular instance in which the running event sink is located -- it just closes the earliest-opened instance among the instances that remain open at that time.

    The mystery remains as to how and why the closing of the form instances prevents half of the event sinks from running. (I put a Debug.Print line at the start of the event sink, so I know that the event sinks for the "missing instances" aren't firing at all, rather than firing but somehow failing to close anything.) <img src=/S/shrug.gif border=0 alt=shrug width=39 height=15>

  9. #9
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Only half of form instances close (Access 2002 SP-2)

    I'm not sure I understand what you're trying to do. Can you post a stripped down version of your database? I don't know if you are raising an event on the Calling Form and sinking that on the sidekick forms with a WithEvents declaration or if you are actually binding the calling form to the sidekick forms, which eliminates confusion. However, if you are calling multiple instances of the *same* sidekick form from a single calling form without using a collection, how are you telling the sidekick form what calling form to listen to? The problem you're having is the result of the way Access loads multiple instances of an object. The only way I know of to get around that is to assign the objects to a collection when you open them. You could create the collection in the calling form and then in the close event of the calling form, call a routine to clear the collection and close all the sidekicks that were opened by that form. Because you have a pointer to each object instance and that pointer has a key, you can handle each one individually and close it individually. Otherwise, you're trying to do it the hard way.
    Charlotte

  10. #10
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Thanks for hanging in there. As I mentioned in my initial post, the Sidekick form has an event sink for the Close event of the Calling form -- i.e., the Sidekick form class module has a module-level WithEvents pointer to the Calling Form (mfrmCallingForm) and an mfrmCallingForm_Close event sink. And I have a separate Sidekicks collection class that keeps track of the multiple open Sidekicks.

    If the only code in the aforementioned event sink is Debug.Print mlngFormNum & " responded." and I close the Calling Form, there is, as expected, a corresponding line in the Immediate Window for each open Sidekick instance that was called by that Calling Form. But if I then add Me.SetFocus and DoCmd.Close to the event sink, only half the event sinks run (every other one, in the order they were opened, starting with the first -- i.e., 1, 3 and 5 if there are 6 open instances), and so only half the form instances get closed.

    As I also noted in my initial post, I can definitely work around the problem (e.g., by having the Form_Close event procedure of each Calling Form call a close-the-related-forms method of the Sidekicks collection class -- a workaround I somewhat dislike for its lack of encapsulation), but my preference was to find out if there was a way to salvage the functionality of the event sinks in the context of closing instances.

  11. #11
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    As a follow-up, it looks to me like this is a (I assume replicable) bug. I just created a new database and freshly created the minimum forms and code necessary to check out the behavior, and the same misbehavior happens there as well.

    In case anyone's interested, I've attached a text file with the minimal code and instructions necessary to demonstrate the problem. (The database ended up 120KB whether I compressed it or not, so I can't attach it.) To keep things simple, I dispensed with the collection class.

  12. #12
    Platinum Lounger
    Join Date
    Dec 2001
    Location
    Melbourne, Australia
    Posts
    4,594
    Thanks
    0
    Thanked 27 Times in 27 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Why don't you convert the DB into 97 format, this will save quite a deal of space.

  13. #13
    WS Lounge VIP rory's Avatar
    Join Date
    Dec 2000
    Location
    Burwash, East Sussex, United Kingdom
    Posts
    6,280
    Thanks
    3
    Thanked 191 Times in 177 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Steve,
    This is indeed replicable. It would appear that as soon as you anything more than a Dim statement or a debug, the event does not fire for all instances! I've just tried using PostMessage and SendMessage API calls to close the forms directly using their window handles rather than setting focus and that doesn't work either.
    However, as you mentioned that you have a Sidekicks collection class, why don't you simply use the terminate event of that class to remove each instance from the collection?
    Regards,
    Rory

    Microsoft MVP - Excel

  14. #14
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Only half of form instances close (Access 2002 SP-2)

    I don't know whether Microsoft considers it a bug or just says it is by design. I do know that it's been around since at least Access 97 where I first ran into it and it isn't limited to this scenario. Whether you like it or not, the only way to handle this is through the collection.
    Charlotte

  15. #15
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Only half of form instances close (Access 2002 SP-2)

    Thanks for the input. My collection class keeps track of all the open instances, some of which may have been called up by Calling Form A, some by Calling Form B, and so on. When Calling Form A closes, I want to close the instances that were called up by Calling Form A (and only those instances).

    The way I have it set up now, the Close event of Calling Form A calls a CloseWindows method of the collection class (passing it a pointer to Calling Form A as an argument) and that method loops through the collection and closes the instances whose .CallingForm properties are a pointer to Calling Form A. It works fine. The main think I dislike about it is that it means implementing the form instances requires putting the right code in two different events of each client object (i.e., each Calling Form). I'd thought one of the main advantages of event sinks was that they meant that classes didn't need to have accompanying "how to" instructions along the lines of "To implement this class, put this code in Event A, this code in Event B, this code in Event C...".

    I could avoid the need to do that if I added event sinks to the collection class that were tied to the Close event of each Calling Form. The reason that's more cumbersome than I'd like is that, as I understand it, you can't declare an array or any other kind of multiple-item structure WithEvents, so I'd have to have a separate object variable for as many different Calling Forms as there might be (Private WithEvents mfrmCallingForm1 as Form, Private WithEvents mfrmCallingForm2 As Form, etc.) and a separate event sink for each. Or is there a better solution I don't know about?

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •