.SetFocus is not selecting the whole field

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Seth Schrock
    Recognized Expert Specialist
    • Dec 2010
    • 2965

    .SetFocus is not selecting the whole field

    I have a textbox that I use as a search field. To trigger the search, I use both an AfterUpdate event on the textbox and I have a button for those that are more mouse oriented.

    Both the button's OnClick and the textbox's AfterUpdate events call the same private sub. In that subroutine I test the results to see if there was a match and if not, I do a .SetFocus back to the search textbox so that the user can retype a new value.

    Problem: If the subroutine is called from the OnClick event of the textbox, then the cursor goes to the beginning of the field instead of selecting the whole field.

    If the subroutine is called from the button's OnClick event, then the whole field is selected like I want.

    I did check Access's setting for what to do when entering a field and it is set to select the whole field. I initially thought that it was because the control already had focus if I triggered the subroutine from the textbox's AfterUpdate event, so I tried having it set focus on the button and then going back to the textbox. There was no change for either method of triggering the subroutine so I took it back out.

    Here is my code:
    Code:
    Private Sub FindLoan()
    
    If Me.txtLoanNumberSearch & "" <> "" Then
        Me.Recordset.FindFirst "LoanNumber = " & Me.txtLoanNumberSearch
        If Me.Recordset.NoMatch Then
            Me.imgWarning.Visible = True
            Me.lblInvalidLoanNumber.Visible = True
            DoCmd.GoToRecord , , acNewRec
            Me.txtLoanNumberSearch.SetFocus
        Else
            
            Me.imgWarning.Visible = False
            Me.lblInvalidLoanNumber.Visible = False
            Me.txtLoanNumberSearch = ""
        End If
    End If
    
    End Sub
    Both events that call this subroutine, only call the subroutine and nothing else so there is no other code that is ran.

    I'm out of ideas.
    Last edited by zmbd; Dec 17 '12, 08:22 PM. Reason: [Z{Put some white-space in the post for ease on the eyes!}]
  • zmbd
    Recognized Expert Moderator Expert
    • Mar 2012
    • 5501

    #2
    That is by design.
    What you need is the following:

    Code:
    With Me.txt_controlnamehere
        .SetFocus
          z_int_length= Len(.Value)
        .SelStart = 0
        .SelLength = z_int_length
    End With

    Comment

    • Seth Schrock
      Recognized Expert Specialist
      • Dec 2010
      • 2965

      #3
      That works if I'm on an existing record, but if I'm on a new record it still puts the cursor at the beginning of the field.

      Comment

      • NeoPa
        Recognized Expert Moderator MVP
        • Oct 2006
        • 32656

        #4
        Originally posted by Seth
        Seth:
        That works if I'm on an existing record, but if I'm on a new record it still puts the cursor at the beginning of the field.
        If this is a new record then how could it be otherwise? Do you have a new record with data showing in this control?

        Z's code is almost exactly as I would have suggested (I wouldn't have used a variable to save the length of .Value), and makes perfect sense. Generally, when switching controls on a form (using Tab keys etc), each newly selected control has its value fully selected. If you select a control that is already selected, however, as in the AfterUpdate() route through the code, nothing will typically happen.

        Your choices are either to select the whole of the contents as Z's suggested, or to select another control first then come back to the one you want. Just as you would as an operator.

        Please, if you actually have a problem with this code, could you report it back more explicitly - remembering we have only the information you choose to give with which to try to determine what's going on.

        Comment

        • zmbd
          Recognized Expert Moderator Expert
          • Mar 2012
          • 5501

          #5
          Seth, You changed the problem there - nowhere in the OP do you state that you are working with a data-entry/details section of the form:
          I have a textbox that I use as a search field.
          I do a .SetFocus back to the search textbox so that the user can retype a new value.
          This code may not always work in a new record field because the value of the control field has not been established; thus, there is no length.

          This code should work for a static control as you described in the OP and has been in use in my database for 10 years both in a combo-box and in a textbox just for this purpose.

          Comment

          • Seth Schrock
            Recognized Expert Specialist
            • Dec 2010
            • 2965

            #6
            I'm not working with the detail section, if you notice in my code that if I type in a number were there is no match in the recordset then it goes to a new record. If I was previously on a record when this occurred then your code works. I am now on a new record but still working with an unbound text box that I use as a search box. If I type in the wrong number again, then it goes to the beginning of the search box and does not select the whole thing. So lets say I'm on loan number 123456 which is a good number. I then type into my search box 9999 (a nonexistent number). It then goes through my code and does select the whole field (the four 9s) and takes me to a new record. I then type in 99999 (another nonexistent number). Now it just puts the cursor at the beginning of the 9s and does not highlight them. Does that make more sense?

            Comment

            • NeoPa
              Recognized Expert Moderator MVP
              • Oct 2006
              • 32656

              #7
              Yes it does Seth.

              I'm thinking a small change in the code might be called for here. Let us know if this works :
              Code:
              With Me.txtControlName
                  Call .SetFocus
                  .SelStart = 0
                  .SelLength = Len(.Text)
              End With
              As you haven't actually left the control at this point, .Value hasn't been updated, so .Text needs to be used instead.

              Comment

              • zmbd
                Recognized Expert Moderator Expert
                • Mar 2012
                • 5501

                #8
                Seth, your code may deal with a new record, that however was not what the code was intended to deal with... it was intended to deal with a static text box is I indcated in post #5 quotes.

                The search text box should have a value in it if I understand correctly - I do not see where that would have been cleared.

                Seth, I'll have to see the code you used after my suggestion in #2 to understand why it "failed" in the new record case. It shouldn't have anything to do with the new record unless you used one of the record controls as the name for the "txt_controlnam ehere"

                As I said, I've used this particular code for a very long time without fail.
                Last edited by zmbd; Dec 18 '12, 02:53 AM. Reason: [Z{Fixed spelling}]

                Comment

                • NeoPa
                  Recognized Expert Moderator MVP
                  • Oct 2006
                  • 32656

                  #9
                  As a relevant point, but a tangent from where you are currently at, why would a Command Button need to call the procedure if an AfterUpdate() event procedure already handles that? By clicking on any other control of the form you are automatically triggering the AfterUpdate() event procedure anyway.

                  Comment

                  • Seth Schrock
                    Recognized Expert Specialist
                    • Dec 2010
                    • 2965

                    #10
                    @Z I don't have the database with me at the moment, so I can't give you an exact copy, but basically, I have just replaced my line 9 with your With statement.

                    @NeoPa I hadn't thought of the fact that I left the textbox would trigger the AfterUpdate event (not sure why I didn't), but my idea was to provide a way for people who prefer to use the mouse more than the keyboard. Personally, I would rather use the keyboard as much as possible, but many of my users prefer the mouse. Should I just take away the button's OnClick event and let the AfterUpdate of the textbox do its work?

                    Comment

                    • NeoPa
                      Recognized Expert Moderator MVP
                      • Oct 2006
                      • 32656

                      #11
                      Originally posted by Seth
                      Seth:
                      Should I just take away the button's OnClick event and let the AfterUpdate of the textbox do its work?
                      Essentially yes. I would do away with the Command Button completely, but if you must have it then it really needs no code associated.

                      Originally posted by Seth
                      Seth:
                      basically, I have just replaced my line 9 with your With statement.
                      Please try my slightly amended With code too, separately. I doubt it will make much difference, as I was not allowing for the fact that the code is only ever run when the update has completed, but it would be interesting to know anyway.

                      Comment

                      • Seth Schrock
                        Recognized Expert Specialist
                        • Dec 2010
                        • 2965

                        #12
                        I just tried the amended With code and it did the same thing.

                        You mentioned in post #4 that the other option would be to select another control and then move back to the textbox. I tried this and that doesn't work either in that it still goes to the beginning of the textbox and doesn't select the whole field. Is this the sign of a design problem on my part?

                        Also for clarification, in post #7 you said that the .Value of the textbox hadn't been changed so the .Text would need to be used. I thought that the value had already changed when the AfterUpdate event occurred. My understanding was that the BeforeUpdate event triggered, then the change happened, and then the AfterUpdate event was triggered. Is this not correct?

                        @Z Here is my code that has NeoPa's tweak.
                        Code:
                        Private Sub FindLoan()
                        Dim intLength As Integer
                        
                        If Me.txtLoanNumberSearch & "" <> "" Then
                            Me.Recordset.FindFirst "LoanNumber = " & Me.txtLoanNumberSearch
                            If Me.Recordset.NoMatch Then
                                Me.imgWarning.Visible = True
                                Me.lblInvalidLoanNumber.Visible = True
                                DoCmd.GoToRecord , , acNewRec
                                With Me.txtLoanNumberSearch
                                    .SetFocus
                                    intLength = Len(.Text)
                                    .SelStart = 0
                                    .SelLength = intLength
                                End With
                            Else
                                
                                Me.imgWarning.Visible = False
                                Me.lblInvalidLoanNumber.Visible = False
                                Me.txtLoanNumberSearch = ""
                            End If
                        End If
                        
                        End Sub

                        Comment

                        • zmbd
                          Recognized Expert Moderator Expert
                          • Mar 2012
                          • 5501

                          #13
                          Let's see what is actually in the txtLoanNumberSe arch at run time:
                          insert between lines 11 and 12
                          Code:
                          debug.print "text = " & .text
                          debug.print "value = " & .value
                          <ctrl><G> to get the debug window up and then run your form both ways; please report back what is printed in each case for both properties.

                          Comment

                          • Seth Schrock
                            Recognized Expert Specialist
                            • Dec 2010
                            • 2965

                            #14
                            Both values were the same. While the form was sitting on a new record, I typed in 987654321 and I got:
                            text = 987654321
                            Value = 987654321

                            I then typed in 123456789 and I got:
                            text = 123456789
                            Value = 123456789

                            So the value does get changed prior to the AfterUpdate.

                            Comment

                            • NeoPa
                              Recognized Expert Moderator MVP
                              • Oct 2006
                              • 32656

                              #15
                              Originally posted by Seth
                              Seth:
                              I just tried the amended With code and it did the same thing.
                              Thank you. I was starting to suspect that I had been mistaken earlier by the time we discussed not needing the code behind the Command Button. It was a thought, but clearly flawed for exactly the reason you included in your own reasoning. I would still avoid the use of the extra variable (intLength), but I'm sure that makes no practical difference.

                              What I'm going to suggest now is a variation on Z's request. Please use the following With block in place of your current one and post back the results. This will hopefully throw some light onto what the code thinks it's doing at the time :
                              Code:
                                      With Me.txtLoanNumberSearch
                                          Call .SetFocus
                              Debug.Print .SelStart, .SelLength, Len(.Text), .Text,
                                          .SelStart = 0
                                          .SelLength = Len(.Text)
                              Debug.Print .SelStart, .SelLength;
                                      End With
                              If, for any reason, what you've typed into the control is not included in the results, then please include that in your post too.

                              I expect you'll have guessed by now that the behaviour you describe is unexpected, so we're interested in helping you to determine why it is.

                              Comment

                              Working...