Help | Site Map
Connecting Tech Pros Worldwide
Reply
 
LinkBack Thread Tools
  #1  
Old March 27th, 2008, 04:57 PM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default Unexplained Exit of Access

I have form which handles Shift-Esc by calling a close of the form (See line #6 below).
Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  2.     If (Shift And acShiftMask) <> acShiftMask Then Exit Sub
  3.     On Error Resume Next
  4.     Select Case KeyCode
  5.     Case vbKeyEscape
  6.         Call DoCmd.Close
  7.     Case vbKeyUp
  8.         Call DoCmd.GoToRecord(Record:=acPrevious)
  9.     Case vbKeyDown
  10.         Call DoCmd.GoToRecord(Record:=acNext)
  11.     End Select
  12. End Sub
Although identical code works fine from my cmdExit button, whenever this executes (from within the KeyDown event procedure) it causes the application (Access) to exit completely.

I'd be interested to hear of anything that can throw any light on the matter.

Running Access 2000 on Windows 2000 Server.
Reply
  #2  
Old March 27th, 2008, 05:21 PM
missinglinq's Avatar
Moderator
 
Join Date: Nov 2006
Location: Richmond, Virginia USA
Posts: 2,633
Default

Don't know what to tell you, Ade, it works as advertised for me! I can only duplicate the behavior by putting DoCmd.Quit in the form's Form_Close event.

Sorry!

Linq ;0)>
Reply
  #3  
Old March 27th, 2008, 10:08 PM
FishVal's Avatar
Expert
 
Join Date: Jun 2007
Location: Israel
Age: 32
Posts: 2,034
Default

Hi, Adrian.

It is really weird. I have only a couple of guesses.
  • did you try to explicitely pass form name as argument to DoCmd.Close method?
  • is there any code in OnClose event handler?
  • in step mode, does Access crash immediately after executing DoCmd.Close?
  • what will happen if you disable error trapping?

Regards,
Fish
Reply
  #4  
Old March 28th, 2008, 01:00 AM
ADezii's Avatar
Expert
 
Join Date: Apr 2006
Location: Philadelphia
Age: 59
Posts: 4,253
Default

Quote:
Originally Posted by NeoPa
I have form which handles Shift-Esc by calling a close of the form (See line #6 below).
Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  2.     If (Shift And acShiftMask) <> acShiftMask Then Exit Sub
  3.     On Error Resume Next
  4.     Select Case KeyCode
  5.     Case vbKeyEscape
  6.         Call DoCmd.Close
  7.     Case vbKeyUp
  8.         Call DoCmd.GoToRecord(Record:=acPrevious)
  9.     Case vbKeyDown
  10.         Call DoCmd.GoToRecord(Record:=acNext)
  11.     End Select
  12. End Sub
Although identical code works fine from my cmdExit button, whenever this executes (from within the KeyDown event procedure) it causes the application (Access) to exit completely.

I'd be interested to hear of anything that can throw any light on the matter.

Running Access 2000 on Windows 2000 Server.
Hello NeoPa, like our esteemed colleague linq has stated - It works as advertised for me! I am leaning along the lines of our other esteemed colleague, FishVal in that although the code works as intended, the Unload(), Deactivate(), and Close() Events of the Form are obviously fired in that sequence. Anything in either one of those Events that cause cause an Exit from Access?
Reply
  #5  
Old March 28th, 2008, 01:27 AM
ADezii's Avatar
Expert
 
Join Date: Apr 2006
Location: Philadelphia
Age: 59
Posts: 4,253
Default

Quote:
Originally Posted by NeoPa
I have form which handles Shift-Esc by calling a close of the form (See line #6 below).
Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  2.     If (Shift And acShiftMask) <> acShiftMask Then Exit Sub
  3.     On Error Resume Next
  4.     Select Case KeyCode
  5.     Case vbKeyEscape
  6.         Call DoCmd.Close
  7.     Case vbKeyUp
  8.         Call DoCmd.GoToRecord(Record:=acPrevious)
  9.     Case vbKeyDown
  10.         Call DoCmd.GoToRecord(Record:=acNext)
  11.     End Select
  12. End Sub
Although identical code works fine from my cmdExit button, whenever this executes (from within the KeyDown event procedure) it causes the application (Access) to exit completely.

I'd be interested to hear of anything that can throw any light on the matter.

Running Access 2000 on Windows 2000 Server.
Back again, NeoPa. Your gonna love this one. If your SHIFT+ESC sequence is off, namely if you press these Keys almost simultaneously, and it you have the Escape Property of a Command Button with a DoCmd.Quit in its Click() Event, you will exit Access and not just the Form. I know it's far fetched, but you must admit that it is a weird problem. (LOL).
Reply
  #6  
Old March 28th, 2008, 11:29 AM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Right, I'm a bit limited for time right now (at work) so I'll just say that I will reply in more detail later. I appreciate all of your attention though.

Opening and closing of forms in my database is captured by a generic Form class module. This may well be the root of the problem, but I will explore more later (and post my findings of course).

@ADezii
I don't have that but I do have a similar button that simply closes the form. As it's in "Continuous Forms" mode though, the Escape key is unable to trigger from this. It's actually what I'm trying to reproduce. As I say though, only to close the form.

PS. I'll post the current version of my whole module simply for reference, but the code has changed in the procedure we're talking about.
Reply
  #7  
Old March 28th, 2008, 11:30 AM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Reference Post:
Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. Private strJob As String
  5. Private intOption As Integer
  6.  
  7. Private Sub Form_Open(Cancel As Integer)
  8.     With Me
  9.         strJob = ""
  10.         If .Filter > "" Then strJob = Split(.Filter, "'")(1)
  11.         .Caption = Replace(.Caption, "%J", strJob)
  12.         .lblTitle.Caption = Replace(.lblTitle.Caption, "%J", strJob)
  13.         .txtJob.DefaultValue = "'" & strJob & "'"
  14.         Call SetDefaultStep
  15.     End With
  16. End Sub
  17.  
  18. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  19.     If (Shift And acShiftMask) <> acShiftMask Then Exit Sub
  20.     'In case record navigation goes beyond start/end of .Recordset
  21.     On Error Resume Next
  22.     Select Case KeyCode
  23.     Case vbKeyEscape
  24.         Call Me.cmdExit.SetFocus
  25.     Case vbKeyUp
  26.         Call DoCmd.GoToRecord(Record:=acPrevious)
  27.     Case vbKeyDown
  28.         Call DoCmd.GoToRecord(Record:=acNext)
  29.     End Select
  30. End Sub
  31.  
  32. Private Sub Form_AfterInsert()
  33.     Call SetDefaultStep
  34. End Sub
  35.  
  36. Private Sub SetDefaultStep()
  37.     Me.txtStep.DefaultValue = Nz(DMax("[Step]", _
  38.                                       "[tblJobTask]", _
  39.                                       "[Job]='" & strJob & "'"), 0) + 1
  40. End Sub
  41.  
  42. Private Sub cmdSwitch_Click()
  43.     Dim blnOptionA As Boolean
  44.  
  45.     With Me
  46.         blnOptionA = (Not .lblJob.Visible)
  47.         .lblJob.Visible = blnOptionA
  48.         .lblStep.Visible = blnOptionA
  49.         .lblType.Visible = blnOptionA
  50.         .lblTask.Visible = blnOptionA
  51.         .lblMRFrom.Visible = Not blnOptionA
  52.         .lblMRTo.Visible = Not blnOptionA
  53.         .lblMsg.Visible = Not blnOptionA
  54.         .txtJob.Visible = blnOptionA
  55.         .txtStep.Visible = blnOptionA
  56.         .txtType.Visible = blnOptionA
  57.         .txtTask.Visible = blnOptionA
  58.         .txtMRFrom.Visible = Not blnOptionA
  59.         .txtMRTo.Visible = Not blnOptionA
  60.         .txtMsg.Visible = Not blnOptionA
  61.         If blnOptionA Then
  62.             Call .txtStep.SetFocus
  63.         Else
  64.             Call .txtMsg.SetFocus
  65.         End If
  66.     End With
  67. End Sub
  68.  
  69. Private Sub cmdDelete_Click()
  70.     With Me
  71.         If Not IsNull(.txtJob) Then
  72.             'We allow for cancellation by operator
  73.             On Error Resume Next
  74.             Call DoCmd.RunCommand(acCmdDeleteRecord)
  75.             On Error GoTo 0
  76.             Call SetDefaultStep
  77.         End If
  78.         Call .txtStep.SetFocus
  79.     End With
  80. End Sub
  81.  
  82. Private Sub cmdExit_Click()
  83.     Call DoCmd.Close
  84. End Sub
  85.  
  86. Private Sub Form_Close()
  87.     'Method must exist in order for container to handle event.
  88. End Sub
Reply
  #8  
Old March 28th, 2008, 11:40 AM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Quote:
Originally Posted by NeoPa
...
@ADezii
I don't have that but I do have a similar button that simply closes the form. As it's in "Continuous Forms" mode though, the Escape key is unable to trigger from this. It's actually what I'm trying to reproduce. As I say though, only to close the form.
...
Not quite correct - I had to set the Cancel property to False on that button as it was triggering when I simply wanted to cancel an amendment. Normally my cmdExit buttons have it set to True.
Reply
  #9  
Old March 28th, 2008, 12:16 PM
ADezii's Avatar
Expert
 
Join Date: Apr 2006
Location: Philadelphia
Age: 59
Posts: 4,253
Default

Hello NeoPa, there are a couple of conventions that you frequently use that I am a little confused on, and also curious about. I am specifically referring to the two items listed below. If you don't mind, can you please explain the logic:
  1. Case 1==> ([use of (1)] ==> Split(.Filter, "'")(1)
  2. Case 2 ==> [Replaceable Parameters]?
    Expand|Select|Wrap|Line Numbers
    1. .Caption = Replace(.Caption, "%J", strJob)
    2.         .lblTitle.Caption = Replace(.lblTitle.Caption, "%J", strJob)
  3. Thanks for bearing with me.
Reply
  #10  
Old March 28th, 2008, 12:19 PM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Update:
I tried adding the close in on the KeyUp event, but still had the same problem :(
Reply
  #11  
Old March 28th, 2008, 12:36 PM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Quote:
Originally Posted by ADezii
Hello NeoPa, there are a couple of conventions that you frequently use that I am a little confused on, and also curious about. I am specifically referring to the two items listed below. If you don't mind, can you please explain the logic:
  1. Case 1==> ([use of (1)] ==> Split(.Filter, "'")(1)
  2. Case 2 ==> [Replaceable Parameters]?
    Expand|Select|Wrap|Line Numbers
    1. .Caption = Replace(.Caption, "%J", strJob)
    2.         .lblTitle.Caption = Replace(.lblTitle.Caption, "%J", strJob)
  3. Thanks for bearing with me.
Certainly, as far as I am able.
  1. I think the line you're referring to is :
    Expand|Select|Wrap|Line Numbers
    1. If .Filter > "" Then strJob = Split(.Filter, "'")(1)
    The .Filter string would typically be something like :
    [Job]='PriceUpd'
    The Split() function returns an array (lowest element numbered 0) of string type variants where each of the characters in the string matching that supplied (') acts as a separator.
    In this case an array would be created :
    0 = "[Job]="
    1 = "PriceUpd"
    2 = ""
    As with any array (including an array returned by a function), appending an index in parentheses selects that individual element.
    So, Split(.Filter, "'")(1) == "PriceUpd"
  2. When using strings with variable items in, I prefer to build it up in exactly that way. It makes it clearer to someone reading the code that there is a string required, and a part of it is variable (the %parameter bit) but that the main string is like a template and is unchanging. The data in both the .Caption and .lblTitle.Caption properties (See lines #11 to #12) is :
    tblJobTask (%J)
    So, from the earlier code - they are both set to :
    tblJobTask (PriceUpd)
NB. The code was not provided with any expectation that anyone would try to debug from that. It is purely and simply for reference purposes. If anyone had any questions about what else was there, it may be answered simply by checking through the code.

Last edited by NeoPa; March 28th, 2008 at 12:59 PM. Reason: Retrospective edit applied
Reply
  #12  
Old March 28th, 2008, 03:42 PM
Scott Price's Avatar
Moderator
 
Join Date: Jul 2007
Location: Cajamarca, Peru
Posts: 1,303
Default

Not sure how this might be happening with your situation, but when using the .Close method, if the optional objecttype and objectname arguments are left blank, Access closes the active window.

Is it possible that the focus is being passed from the form to the database window in your setup, thus causing the active window to be the database, which then is closed?

As a simple test you could try adding the objecttype and objectname arguments to see if that changes the behavior.

Regards,
Scott
Reply
  #13  
Old March 28th, 2008, 04:46 PM
ADezii's Avatar
Expert
 
Join Date: Apr 2006
Location: Philadelphia
Age: 59
Posts: 4,253
Default

Quote:
Originally Posted by NeoPa
Certainly, as far as I am able.
  1. I think the line you're referring to is :
    Expand|Select|Wrap|Line Numbers
    1. If .Filter > "" Then strJob = Split(.Filter, "'")(1)
    The .Filter string would typically be something like :
    [Job]='PriceUpd'
    The Split() function returns an array (lowest element numbered 0) of string type variants where each of the characters in the string matching that supplied (') acts as a separator.
    In this case an array would be created :
    0 = "[Job]="
    1 = "PriceUpd"
    2 = ""
    As with any array (including an array returned by a function), appending an index in parentheses selects that individual element.
    So, Split(.Filter, "'")(1) == "PriceUpd"
  2. When using strings with variable items in, I prefer to build it up in exactly that way. It makes it clearer to someone reading the code that there is a string required, and a part of it is variable (the %parameter bit) but that the main string is like a template and is unchanging. The data in both the .Caption and .lblTitle.Caption properties (See lines #11 to #12) is :
    tblJobTask (%J)
    So, from the earlier code - they are both set to :
    tblJobTask (PriceUpd)
NB. The code was not provided with any expectation that anyone would try to debug from that. It is purely and simply for reference purposes. If anyone had any questions about what else was there, it may be answered simply by checking through the code.
Curiosity satisfied, thanks NeoPa.
Reply
  #14  
Old March 28th, 2008, 05:01 PM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

I'm afraid not Scott. This is definitely calling the close from within the form itself. The focus is in one of the bound controls when Shift-Esc is pressed.

As I only recently discovered (while working on this form) that I didn't need to include the ObjectType:=acForm and ObjectName:=Me.Name parameters if I was only interested in closing the current form, I have most of my code still with these parameters set. In this particular instance I did try both ways, for both the KeyDown event procedure and the cmdExit Click procedure.

It was worth checking, and I did. Unfortunately no joy there either.
Reply
  #15  
Old March 28th, 2008, 05:25 PM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Quote:
Originally Posted by ADezii
Curiosity satisfied, thanks NeoPa.
Anytime ADezii.

Did you find the reasoning made sense to you?
Do they sound like techniques you may want to take up?
Reply
  #16  
Old March 28th, 2008, 05:34 PM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

As an addendum to that, and only for anyone interested in such things, I actually find that I use the Replace() technique so much that I even wrote a function to handle multiple pairs of parameters for replacing.

I have to replace any posted code with multiple calls to Replace() so that it makes sense generally in the forums.
Expand|Select|Wrap|Line Numbers
  1. 'MultiReplace replaces all occurrences of varParam in strMain with varReplace.
  2. 'Using VbBinaryCompare means that case is not ignored.
  3. Public Function MultiReplace(ByRef strMain As String, _
  4.                              ByVal varParam As Variant, _
  5.                              ByVal varReplace As Variant, _
  6.                              ParamArray avarArgs())
  7.     Dim intIdx As Integer
  8.  
  9.     If (UBound(avarArgs) - LBound(avarArgs)) Mod 2 = 0 Then Stop
  10.     MultiReplace = Replace(Expression:=strMain, _
  11.                            Find:=Nz(varParam, ""), _
  12.                            Replace:=Nz(varReplace, ""), _
  13.                            Compare:=vbBinaryCompare)
  14.     For intIdx = LBound(avarArgs) To UBound(avarArgs) Step 2
  15.         MultiReplace = Replace(Expression:=MultiReplace, _
  16.                                Find:=Nz(avarArgs(intIdx), ""), _
  17.                                Replace:=Nz(avarArgs(intIdx + 1), ""), _
  18.                                Compare:=vbBinaryCompare)
  19.     Next intIdx
  20. End Function
Reply
  #17  
Old March 28th, 2008, 11:59 PM
ADezii's Avatar
Expert
 
Join Date: Apr 2006
Location: Philadelphia
Age: 59
Posts: 4,253
Default

Quote:
Originally Posted by NeoPa
Anytime ADezii.

Did you find the reasoning made sense to you?
Do they sound like techniques you may want to take up?
Quote:
Did you find the reasoning made sense to you?
The reasoning made perfect sense to me, NeoPa
Quote:
Do they sound like techniques you may want to take up?
I already made the change to single line Declarations, and eliminated all multi-line Statements, I guess anything is possible. (LOL).
Reply
  #18  
Old March 29th, 2008, 02:26 AM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

LOL - I like it ADezii :)

But I just remembered I haven't even done Fish the courtesy of replying properly to his post :(

I will get to it immediately.
Reply
  #19  
Old March 29th, 2008, 02:43 AM
NeoPa's Avatar
Administrator
 
Join Date: Oct 2006
Location: London - UK
Age: 48
Posts: 11,806
Default

Quote:
Originally Posted by FishVal
Hi, Adrian.

It is really weird. I have only a couple of guesses.
  • did you try to explicitely pass form name as argument to DoCmd.Close method?
  • is there any code in OnClose event handler?
  • in step mode, does Access crash immediately after executing DoCmd.Close?
  • what will happen if you disable error trapping?

Regards,
Fish
  1. I did try that - it behaved in exactly the same way.
  2. Good question - I do have a class that encapsulates forms and handles un-hiding the calling form when the called one is closed. In that sense code IS run on closure of the form.
  3. Although I'm unable to test this now, I do know from running this after changes have been made to the design of the form, that the .Close method is in progress already (or even completed) as the Save Changes prompt comes up before the application disappears.
  4. Error trapping has now been disabled and the problem still exists.
Reply
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles