I ran the following code On Lost Focus event in Access 2010 with no problems.
Dim strSpell
strSpell = txtMyField
If IsNull(Len(strSpell)) Or Len(strSpell) = 0 Then
Exit Sub
End If
With txtMyField
.SetFocus
.SelStart = 0
.SelLength = Len(strSpell)
End With
DoCmd.SetWarnings False
DoCmd.RunCommand acCmdSpelling
DoCmd.SetWarnings True
After upgrading to O365 (Access 2016), the spell check works with no problems unless there's multiple spelling corrections. If the user choose to Change All or change more than 1 word Access crash and the user need to restart the program. I tried to change the code to run On Exit event but it didn't help. I also decompile the database and found no erros.
The only way I can run spell check is using the spell check on the ribbon. I hide the ribbon to prevent the users from messing around so this option is not going to work. Also, I would like to limit spell check to one field and force it after the user exit the field.
I'm guessing that Access is crashing because more than one correction trigger the event again and since spell Check is already running the program crash. Any idea how to fix it ?
UPDATED NOTES FROM COMMENTS
In my testing I found that when you hit Enter several time when you
type in the field, it cause the program to crash.
Text field is LONG TEXT
Form field is bound to text field
I was able to repeat the hanging process "Not Responding" message with a Long Text field and 3500 characters and LOTS of items with 'spelling errors`.
Using your code it would crash with LostFocus code or even if I put it in a command button.
I started wondering if it was the whole text selection that was causing an error with how the spell checker tried to do its job - and whether that was even needed.
When I moved your code out of the LostFocus event and replaced it with this code in the Exit event it worked reliably
EDIT: Moved code to Exit event and specified specific textfield
Private Sub txtMyField_Exit(Cancel As Integer)
With txtMyField
'If the textbox has data run the Spell Checker
If Len(.Value & "") > 0 Then
.SetFocus
.SelStart = 0
.SelLength = Len(.Value)
DoCmd.SetWarnings False
DoCmd.RunCommand acCmdSpelling
DoCmd.SetWarnings True
.SelLength = 0
End If
End With
End Sub
Related
I've been using Application.forms.Count to measure the number of forms that are open, and most of the time, this function works correctly. However, every once in a while, the count is wrong.
When I view the amount in a MsgBox, Access thinks that there are 2 forms open when it is obvious that only 1 is open. I have this running on my Form_Unload method, as the form should only close if it is the last form still open. I have made sure that there are no other instances of Access running when this is performed and no pop-ups or modals are open.
Dim Form As Double
Form = Application.forms.Count
MsgBox Form
If Form = 1 Then
'Nothing, form closes
DoCmd.ShowToolbar "Ribbon", acToolbarYes
Else
MsgBox "You cannot close this form right now."
cancel = True
End If
End Sub
As mentioned, this code does work most of the time, but it is a major hindrance when the wrong count occurs, and I'd like to find out what is causing it.
Using (Debug.Print Forms(0).Name and Debug.Print Forms(1).Name), I was able to figure out that the form I had open had somehow duplicated itself (though only one version of the form is open on the screen). While I have no idea how this happened, a simple restart of MS Access will get rid of the duplication. I'll add this supplemental if statement to prevent this in the future:
If formCount = 1 Then
...
Else
If Forms(0).Name = Forms(1).Name Then
'The duplication error is happening again
DoCmd.Close "FormNameHere"
End If
End If
After all this time, I believe I've found the root of this error. I did not previously know that forms could be opened in the background without actually appearing, and this happens when you read or write a project-level variable. I had checked on a variable and then tried to check the number of forms up, and there was two open despite only one being visible. I think a simple DoCmd.Close "formNameHere" after checking on the variable would be the best way to go about this problem.
Extremely puzzling:
Upon opening a simple form from another form by vba, the cursor moves to a particular field.
However, when this field is Null there is each second time Error 2110. The syntax to be used changes every time as shown below.
Even more puzzling:
Upon clicking "Debug", the error proves to be imaginary: on the corresponding code line, one can simply continue with F5 or F8 and the procedure ends correctly with the focus where desired.
I found a provisory workaround which does not generate the error message but would like if possible to avoid such limping coding:
'…
Debug.Print Me![MyTextField].Enabled ' always True
Debug.Print Me.Name ' always correct form
Me.Repaint
On Error Resume Next
[MyTextField].SetFocus ' without Me!
Me![MyTextField].SetFocus
' Forms![MyForm]![MytextField] : same result as with Me!]
' one time error with Me! but not without Me!,
' next time vice versa, and so forth…
On Error GoTo 0
'…
When [MyTextField] is not Null, both syntaxes work fine without generating an error.
What is wrong with this .SetFocus command ? "Repairing" the database didn't help.
You can't set focus to the control that has focus. It would give you a very easy way to set up a infinite loop.
You would have to set focus to another control first.
Minty's right. An easy workaround is doing it in an if statement or create a bool to see if IsNull(fieldhere) = true then exit sub or your action here. Or more simply maybe try:
if MyTextField.gotfocus = true then
do something
else
MyTextField.setfocus
I recently ran into this issue in something similar and had to create a public bool function and test it on load events. Please note that I'm a beginner in access so there's probably many better ways to complete this :)
In a data validation form, I have a subroutine checking previously-entered data on a LostFocus event by ensuring that the release time (TimeReleased in table; Me.txtTimeReleased on form) is after the capture time (ObservationTime in table; Me.txtObservationTime on form). I'm using LostFocus rather than BeforeUpdate because the data were bulk-imported into the db and are now being error-checked.
My users keep getting a compile error (Compile Error: method or data member not found) upon tabbing out of the field this sub is attached to but I cannot reproduce the problem locally. The error occurs on this line:
If (Me.txtTimeReleased) <= (Me.ObservationTime) Then
and the part highlighted is '.txtTimeReleased'
Full code block:
Private Sub txtTimeReleased_LostFocus()
Dim badData As Variant
Dim resp As Variant
'Also check that time released is after time captured
If Not IsNull(Me.txtObservationTime) And Not IsNull(Me.txtTimeReleased) Then
If (Me.txtTimeReleased) <= (Me.ObservationTime) Then
resp = MsgBox("Release time must be after capture time." & vbCrLf & "Please double check this field's value: is it correct?", _
vbYesNo + vbExclamation + vbDefaultButton2, "Release Time Before Capture Time")
If resp <> vbYes Then badData = True
End If
End If
If badData = True Then
Me.cmbTaxonId.SetFocus 'set focus away so can set focus back
With Me.txtTimeReleased
.SetFocus
.SelStart = 0
.SelLength = 10
End With
End If
End Sub
Other things to note:
Both the table field and form control are formatted as 'Short Time' (24-hour time)
There is an input mask on that form control for 24-hour time; I use input masks very rarely and thus aren't familiar with them--perhaps the input mask could be causing the problem?
There are similar LostFocus subs on most of the other controls which do not produce this (or any other) error
Things I've tried:
Checking spelling
Fully decompling and recompiling the code: starting with shift, compact and repair with shift, open with /decompile flag while holding shift, compact and repair with shift, re-open with shift, and finally compile (without error)
Replacing the form in their database with one that works fine for me on the same data
Google
Things that seem odd to me:
I can't reproduce the error locally.
The error is triggering on the second instance of
Me.txtTimeReleased rather than the first: it has already passed a Not
IsNull(Me.txtTimeReleased) check.
The fact that it's a compile error: could that be masking something else?
Thanks for your time, and please let me know if there's any additional information that would be useful. Any thoughts are most welcome!
You checked for Null txtObservationTime and txtTimeReleased, but compare then txtTimeReleased and ObservationTime. Maybe solution is:
If Not IsNull(Me.txtObservationTime) And Not IsNull(Me.txtTimeReleased) Then
If (Me.txtTimeReleased) <= (Me.txtObservationTime) Then
Opening the .mdb with the /decompile flag is one of the first things I would have suggested, but you said you already tried that.
Here's another undocumented trick to deal with "hidden" compile problems that get baked in by VBA behind the scenes:
First, make a backup copy of your .mdb just to be safe (this is, after all, an undocumented technique).
Then, save your form to a text file using SaveAsText:
SaveAsText acForm, "MyFormName", "C:\MyFormName.txt"
Finally, re-load your form using the equally undocumented LoadFromText:
LoadFromText acForm, "MyFormName", "C:\MyFormName.txt"
Compile.
Compact.
Repair.
Hope for the best.
Good luck.
I suggest you use variables:
intThat = Me.txtTimeReleased
If intThis <= intThat Then
Try using ! instead of a dot:
intThat = Me!txtTimeReleased
If intThis <= intThat Then
And now, the answer that worked for me last week:
Comment out the offending line.
Run a compile that is successful.
Restore the offending line.
The compile may work now. Don't ask me why.
I've been working in Access on a project and the longer I work on it the more disdain I have for it. I've been googling and attempting workarounds all day but I can't quite find what I am trying to do.
I have a form that is linked to a table. I have one button that will set the record of the form to a new record. If you start typing into any one of the text boxes the record starts updating, it's not really doing an insert at this point. However if I navigate off the record the update is called. there isn't anything I can do to stop the update from happening if the user does not want to add a new record that I can find. I'm using
DoCmd.GoToRecord , , acNewRec
To get the form to have all the text boxes go to a new record. At this point as soon as you start typing into any of the text boxes you can't go back. The autonumber will incriment and I have sku builder that concatenates the autoNumber to a prefix to act as a serial number.
What I need to do, is figure out a way to get the update to cancel if the user clicks close. I've tried to disable close, but you can always right click the bar and select close from there. This, along with anything that prompts the form to close commits that in process record and subsequently fires the "afterUpdate" event. I read some Microsoft documentation and "form_unload" is called first in the workflow but insert always goes before that. I've also tried to use the "beforeUpdate" but that fires as soon as you attempt to write into one of the boxes and not right before "afterUpdate"
It seems there is a pretty huge hole in the space between beforeUpdate and afterUpdate. I don't think this is a terribly complicated operation I'm trying to attempt here but perhaps I've been working on it for so long I have missed a simpler solution. I just need to cancel the insert operation or prompt the user that they are closing the form with an open record. If they hit no insert will fire, and yes it will.
Also, I have no appetite to rewrite for ADO because of my timeline. I just need to quickly throw some forms together and get it done. There are also a ton of fields that I don't want to setup for an ADO insert. They are all built but I have this one issue that is giving me grief and I need to apply this solution to all the forms.
TLDR - Stopping a databound form from inserting if the user has entered text and tries to exit the form.
Solution Edit:
Change the form to modal/popup and disable close.
Add a button to handle close.
Add boolean flag
Private Sub Form_BeforeInsert(Cancel As Integer)
NR = True
End Sub
Then add the code for the close button.
Private Sub cmdClose_Click()
Dim msgRes As VbMsgBoxResult
If NR Then
msgRes = MsgBox("Do you want to save the current new record?", vbYesNoCancel, "Closing form...")
If msgRes = vbYes Then
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Close
ElseIf msgRes = vbNo Then
Me.Undo
DoCmd.Close
End If
End If
DoCmd.Close
End Sub
You can always do either a Me.Undo or DoCmd.RunCommand acCmdUndo on FormClose
OR if you still can't get it to work (I've spent a lot of time in Access and I know it can be finicky) you can do a DoCmd.RunSql ("Delete * from TableName where Id=NewID")
You can also try this:
DoCmd.DoMenuItem acFormBar, acEditMenu, 8, , acMenuVer70
DoCmd.Close , , acSaveNo
You may also want to disable the close button and create a button to cancel the record so you can put all the code in there. If you set the form mode to a dialog you shouldn't be able to right click close it.
I am trying to make a small form in MS Access 2003 SP3, I use some function that some other people made and these function has msgbox in it. I would like to disable msgbox while I am running the form. Is it possible in Access to disable msgbox?
I created my finction called msgbox. Seems like its working. Thanks everyone for your help.
Public Function MsgBox(Prompt, Optional Buttons As VbMsgBoxStyle = vbOKOnly, Optional Title, Optional HelpFile, Optional Context) As VbMsgBoxResult
If myProcedureisRunning then
VBA.MsgBox Prompt
else
debug.print prompt
endif
End Function
If in fact these message boxes are produced from VBA code, then comment them out. However, if they are Access generated, such as the message box when inserting or updating records, you need to use the command DoCmd.SetWarnings False in order to suppress them. Just make sure to turn warnings off only when needed, then turn them back on. Otherwise, ALL message boxes from Access will be off, even in "design mode".
Do a CTRL-F and find for MSGBOX and comment it. I guess that's the only way you can do it.
Press Alt+F11 to open the Visual Basic IDE, then press CTRL+F to search. Type msgbox into the find, select "Replace" and type'msgbox into the "replace with" box (note the apostrophe). This will comment out all msgbox statements in the project.