My database has a unique field for the name of the child receiving gifts from our Christmas project and notifies us of the duplication as we leave the record. However that is many keystrokes later. Is there a way to activate the message upon leaving the field rather than the record.?
Yes, use the BeforeUpdate event of the field. In this, look up the value entered and, if found, set:
Cancel = True
and pop a messagebox.
Related
I have a strange issue with one of my data entry forms. I have a main form from which I open said data entry form using a button. Once the form is open, I can enter a new record (the DE-form is set to allow additions and data entry is set to YES). The first time AFTER opening the main form, and only the very first time (subsequent tries work as intended), when opening the DE-form from the button and attempting to enter new data into the field "Bezeichnung", I get the following error message:
You can't assign a value to this object.
The weird thing comes now. After clicking OK in the dialogue box, in spite of what the message just indicated, the field contains the character I had just entered and allows me to continue adding data without issue.
After adding the new record and confirming, it shows up on my main form, as well as the related table, as intended. I have tried making a new DE-form from scratch but encountered the same thing. The message only pops up the very first time I attempt to enter new data via the DE-form after opening the main form. Opening the DE-form a second or third time while the main form is still up does not result in the same message. Also, it's the same with any of the fields on the DE-form, not just the first one. After the message pops once, it never shows up again until I close the main form. This is the only DE-form in my project that has this issue, I can#t seem to figure out why. Any help is appreciated.
Database Structure:
Details of my data entry form:
*The DE-form consists of a form with a subform on it (white box in the middle). I have other forms where this is neccesary and in order to keep the design consitent I opted to do the same with this one. Both forms have an invisible textbox bound to stoff_id. The DE-subform has Link Master Field and Link Child Field set to stoff_id
Recordsource DE-form main
SELECT chemikalien_tabelle.stoff_id
FROM chemikalien_tabelle;
Recordsource DE-form sub
SELECT chemikalien_tabelle.stoff_id, chemikalien_tabelle.bezeichnung, chemikalien_tabelle.einsatzgebiet, chemikalien_tabelle.kategorie_id
FROM kategorie_tabelle INNER JOIN chemikalien_tabelle ON kategorie_tabelle.kategorie_id = chemikalien_tabelle.kategorie_id;
I found a solution on another site. Apparently, what is causing the message is an invisible textfield bound to the primary key stoff_id (which is AutoValue) of chemikalien_tabelle on the DE-subform. I usually add the primary key somewhere to my forms since it is likely I will need it. I still don't know why this issue popped up though. The original answer I am refering to did not either Foreign Solution. The post is in German, so check it out at your discretion. Removing the textbox fixes the issue but without it I cannot assign a completely new record. I have a number of other data-entry forms that have the same setup, so I am not sure why this only caused issues in this particular case. Maybe someone else has a an idea?
I use a form to update/insert a database in Access 2016.
I found Access has an option to record version of a field value change if data type of this field is long text and append only property is set to yes. I decided to concat all the values of a single record and save to this long text (history) field.
Now I have added an invisible textbox control to that form. The value of this field i.e. "history" will be populated when an event occurs (on unload from form current record) and that invisible textbox control value is set running a function.
So now I need to know which event should I address to populate history field?
I tried several events but all say conflict!
This seems like a last changed date kind of problem. I have has success with using the form's before update event for this. E.g.:
Private Sub Form_BeforeUpdate(Cancel As Integer)
With Me
.LastChangedDate = Now()
End With
End Sub
If you are having trouble accessing the history from the control you could set a vba variable to it using the Current event of the form. Be careful, the Current Event fires for many reasons and the code has to defend itself from running except when you want.
I frequently test many conditions and switch settings so the Current event does not crash or worse. Trial and error needed.
For example, you could record the key of the record whose history you have saved for later and test to see if it has changed before saving it again. Also, I make sure that initialization of the OPEN and LOAD events are complete along with any other initialization necessary before I allow the Current event to do anything significant.
Good luck.
MS Office 365 ProPlus, Access 2007 - 2016
I'm trying/failing to change the value of a field in a table after it is inserted using the "after insert" trigger. Something like this...
EditRecord
SetField
Name orig_id
Value = [mytable].[id]
End EditRecord
This doesn't seem to work.
USysApplicationLog gives...
SourceObject = mytable.AfterInsert
DataMacro InstanceID = {489D5697-5247-44A8-AE3C-3773A25F72E5}
Error Number = -20335
Category = Execution
Object Type = Macro
Description = EditRecord failed because the default alias represents a record which is read only.
The field is not read only. After the fact I can edit it just fine. I don't know what the "default alias" is nor what that even means.
If the trigger can't do this, can you think of another way to accomplish the same thing ?
You don't want to use the AfterInsert, since then the record is already saved, and tucked away nicely, and everything you need to change in that record is assumed to have been done. In fact, the default context will cause the record in question to be read only. You CAN get around this by pulling the record again, (looking up a record), but if you modify it again then all of the triggers for that record will fire again.
So I ONLY suggest you use this event to sum() or add/edit OTHER tables, but not the record that was just edited and saved.
If you need/want to update this current record, then move your "edit" or "modify" code to the "BeforeChange". This event not only lets you edit/modify right before the save (and thus preventing endless loops in which the update triggers fire again and again), but the CURRENT record is in full context, and you don't even need any "edit record" command, since you have the fresh un-saved record right in context. You thus can use SetField without the need for EditRecord.
So, the AfterInsert is really too late here, and if you could modify the record in that event, you will cause the AfteUpdate event to fire again if you do use a workaround.
Now, if you use BeforeChange, it will fire for both insert and edits (change). So, if your code really only needs to run when inserting, you can check this status by using
If [isinsert] = True then
Edit
Also, it looks like your code is attempting to save (capture) the previous value, and if it is, then you can use:
[old].[id]
Of course this does not make too much sense for "id", since that is usually an autonumber PK column, but for grabbing other values during an update in the BeforeChange event, you can certainly test + inspect the previous (old) values.
Creating a simple UI using MS Access, hoping to do minimal actual coding (actually helping a friend who is not a coder).
Simplified requirement: Single table, primary key is phone number, lots of other non-mandatory fields. Display a form allowing just the phone number to be entered, if a record with that key exists display the full record, if a record with that key does not exist bring up an form allowing the other fields to be entered for this phone number and hence create a new record.
Q1: Any simple way to achieve this kind of function? Example?
We've got some of this going with a standard form, can execute code if insertion fails, but a standard dialogue box is displayed warning about the duplciate key violation.
Q2: How can we trap that attempted insertion, avoid having the dialogue come up?
You will have to get your hands dirty and write some code to get this outcome. A starting point would be something like this presto code. Post back if you get stuck on any of the parts.
If fCheckIfRecordExists(lYourKey)=True then
Docmd.OpenForm “frmEditExistingRecord”
Else
Docmd.OpenForm “frmEnterNewRecord”
End if
Public function fCheckIfRecordExists (lYourKey as Long) as Boolean
‘Code to check if a record exists, simple method is to use dLookup or a count SQL statement with the criteria as the key you are trying to find
End function
EDIT:
First things first make a form with 1 text box called txtPhone_number and a command button called cmdSearch.
Next put this bit of code in the module behind the form
Public Function fDoes_record_exist(strPhone_number As String) As Boolean
If DCount("Phone_number", "tblYour_table", "Phone_number=" & strPhone_number) > 0 Then
fDoes_record_exist = True
Else
fDoes_record_exist = False
End If
End Function
Next you need to put some code behind the click event of the command button. This code can be expanded on to check for a valid phone number later if you want
If fDoes_record_exist(Me.txtPhone_number) = True Then
DoCmd.OpenForm "frmShow_existing_record"
Else
DoCmd.OpenForm "frmEnter_new_record"
End If
That should set you on your way nicely but post back if you run into problems
Here is an overview of the process with Access logic:
You need an unboud control labelled Phone in the form header, where user will be able to enter the phone number to search. You need to use the After_Update event of that control to trigger your search. There will be a second Phone control, bound this time, in the Detail section of the form for effective data entry/update.
Use the Form_Error event to intercept the error message when user tries to save a duplicate key, in order to display a nice message, and eventually Cancel his changes.
The advice from Kevin Ross to use VB Code is clearly one approach, and I think is appropropriate if we anticipate less trivial requirements in future. However I'm in a situation where I'm helping someone with zero coding background and hence if possible I'd prefer to let them use simple Macros rather than full-scale VB.
As it happens the functionality I require can be implemented with just Macros, and it depends on the suggestion from iDevelop.
The outline of the solution I used:
Create an InitialEntry form with no association to any particular table, it has:
a data entry field for the telephone number
a read-only text box where I can display a message
a button labelled Add
a button labelled Show
I write three macros:
A macro AlreadyExists that displays a message saying "We already that one"
A macro NewEntry that opens a data entry form for my table, in Add mode, and which copies the phone number from InitialEntry!TelephoneNumber
A macro TestForExisting this uses a condition
DCount("*","MyTable","[PhoneNumber] = [FormPhoneNumber] " ) > 0
to control whether to execute AlreadyExists, and a similar test to control whether to call NewEntry.
While this is not as efficient as VB, it does seem to be understandable by a non-coder, so at least we can implement our application.
I have a form in which we are showing customer records in a grid.User clicks a row, and in a new form record is shown.After editing some values, user may click cancel. if so, in grid we need to return to original values.
How can I restore the original state of the entity.We are using linq-to-sql, and grid is bounded to List.One way I see is,using getoriginalentitystate method.
If a user cancels a process, no change is made at the Database and the control reverts back to the pre-action state. This is a normal and built-in behaviour.
In case, if this is not happening, try rebinding List to it's DataSource, like
myList.Databind()
As the user is entering data in the form, the values should be stored in your UI layer (not written to your "database"). The data in the form is held there temporarily until the user clicks 'OK'/commit. If the user clicks 'cancel' the form is simply discarded and not written to the database.
Until the user hits 'OK', the original data is still in the database. You can get the original values there.