I have set Duplicates(No) to one of my table's ID. Then I created a form with Combobox to select all records from that table and to store selected record in a field of joined table (ID foreign key). If I try to add another record with same ID, Access prompts me with a warning message "The changes you requested to the table were not succesfull...etc).
What I want is to remove this message and create a custom one. Here is what I tried:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim sWhere As String
sWhere = "[ID_Table]=" & Me.Combo5
'
If DCount("*", "Table1", sWhere) > 0 Then
Cancel = True
Me.Undo
MsgBox " Duplicate"
End If
End Sub
This code executes If I select whatever value from combobox. Here are my tables:
Table1
ID_Table(PK)
Field1
Field2 etc.
JoinTable
ID_Join(PK)
ID_Table1(FK)
ID_Table2(FK)
ID Field that has property Duplicates(No) is in Table1 (PK). How can I get this working correctly ?
I figured out, what a stupid mistake :
Instead of
If DCount("*", "Table1", sWhere) > 0 Then
I had to change to
If DCount("*", "JoinTable", sWhere) > 0 Then
Code didn't work because I was referencing to wrong Table. Problem solved, thanks for response Matt.
Related
I am not sure if there is another post like this but i think my question is a little different.
I am currently designing a database to track employee training given by employer. My current error I find is adding an employee by using a bound form (frmAddEmployee) to my employees table (tblEmployees).
What I have at the moment that works is VBA code that shows a notification when you enter a value into a textbox for the employee number and it finds a duplicate record in the table. The VBA will also show the record in the same form that corresponds with the value you have entered when you clear the notification.
Here's the code I use for the txtEmpNumber after update:
Private Sub txtEmpNumber_AfterUpdate()
Dim EmpNum As String
Dim stLinkCriteria As String
Dim EmpNr As Integer
'Assign the entered employee number to a variable
EmpNum = Me.txtEmpNumber.Value
stLinkCriteria = "[EmpNumber] = " & "'" & EmpNum & "'"
If Me.txtEmpNumber = DLookup("[EmpNumber]", "tblEmployees", stLinkCriteria) Then
MsgBox "This employee number, " & EmpNum & ", has already been entered in database." _
& vbCr & vbCr & "Please check the number.", vbExclamation, "Duplicate information"
Me.Undo
'show the record of matched employee number from the employees table
EmpNr = DLookup("[EmpID]", "tblEmployees", stLinkCriteria)
Me.DataEntry = False
DoCmd.FindRecord EmpNum, , , , , acCurrent
Me.cmdSave.Enabled = False
Me.cmdNew.Enabled = True
Else
Me.txtIDNumber.Enabled = True
End If
End Sub
The notification shows there is a duplicate value, for example 1234 and shows the record in the table for 1234 but when I try a different value like 5678 then it shows the value again for 1234 and not 5678.
Any ideas how to fix this problem?
I think the problem you are having is that this command:
DoCmd.FindRecord EmpNum, , , , , acCurrent
...searches in the current field. But if there isn't a current field (because the form doesn't have the focus), or if the current field is some other field (such as ID), the "find" won't find a match, and the record you're looking at won't change.
The simplest fix would be to change your code to this:
DoCmd.FindRecord EmpNum, , , , , acAll
That will search for the value of EmpNum in ALL the fields.
But, if there's a chance that the value for EmpNum might also appear in other fields than txtEmpNumber (for example, if someone has EmpNum = 12 and someone else is ID = 12), this will eventually start "finding" the wrong record.
So I think the best thing to do would be to make sure your current field is txtEmpNumber before you execute the FindRecord.
Me.txtEmpNumber.SetFocus
DoCmd.FindRecord EmpNum, , , , , acCurrent
That will ensure it only looks in txtEmpNumber when it's trying to find the record.
I'm a little bit lost with this one. I have a subform, which shows records based on my combobox selection. This is done like this (code is called from Combobox After_Update):
Sub ShowResults1()
With Forms![MYForm].RecordsetClone
.FindFirst "[ID] = " & Forms![MyForm]![CmbSearch]
If Not .NoMatch Then
If Forms![MyForm].Dirty Then Forms![MyForm].Dirty = False
Forms![MyForm].MySubfom.SourceObject = "MySubform"
Forms![MyForm].Bookmark = .Bookmark
End If
End With
End Sub
Main form is bound to a join table, this is It's recordsource (It is linked to 2 tables via ID's in It):
SELECT JoinTable.*, Table1.IDx AS IDx_Table1, Table1.Field1, Table1.Field2, Table1.Field3, Table2.IDy AS IDy_Table2, Table2.Field1, Table2.Field2, Table2.Field3
FROM Table2 INNER JOIN (Table1 INNER JOIN JoinTable ON Table1.IDx = JoinTable.IDx) ON Table2.IDy = JoinTable.IDy;
When upper code is executed, I get a results in subform that matches criteria, so this works fine.
Now, what I want is to have a report, that will show exactly what subform allready shows. Is this too complicated, or is there any simple solution ?
EDIT:
I have created a new query (named "SearchReport"):
SELECT Table2.IDy, Table2.Field1, Table2.Field3
FROM Table2 INNER JOIN (Table1 INNER JOIN Join_Table ON Table1.IDx = JoinTable.IDx) ON Table2.IDy = JoinTable.IDy
WHERE JoinTable.IDy=3;
This query successfully shows records that I want, but only with ID 3. Now I removed "WHERE JoinTable.IDy=3" from Query so that I can show records based on my combobox. This is how I tried opening report:
DoCmd.OpenReport "MyReport", acViewReport, "SearchReport", WhereCondition:="JoinTable.IDy =" & Forms![MyForm]![CmbSearch]
But when Report is opened, Access keeps asking about entering parameter value of IDy. Even If I enter 3, there are all records shown from that query. What Is wrong ??
Both forms and reports have a Record Source property.
In this Record Source property you can specify a table, a query, or a plain SQL statement which is your case.
In VBA, if your Subform is opened and displaying the right information, you can just say MyReport.RecordSource = MySubForm.RecordSource.
But the most proper way to achieve what you want is this :
In the code of your report, add this public sub :
Public Sub Open_This_Report(strSQL)
Me.RecordSource = strSQL
End Sub
In your form, add a button, with this ClickEvent :
Private Sub myButton_Click()
DoCmd.OpenReport "name_of_the_report", acViewNormal
Call Report_name_of_the_report.Open_This_Report(me!SubFormName.Form.RecordSource)
'or
Call Report_name_of_the_report.Open_This_Report("specific SQL query")
End Sub
Solved. I had to select records from Query that I posted in edit (full code for command button_click event - button on form):
Dim sql As String
sql = "SELECT Table2.IDy, Table2.Field1, Table2.Field3" & _
" FROM Table2 INNER JOIN (Table1 INNER JOIN Join_Table ON Table1.IDx =" & _
"JoinTable.IDx) ON Table2.IDy = JoinTable.IDy" & Forms![MyForm]![CmbSearch] DoCmd.OpenReport "APO_IIS", acViewReport
Reports![Myreport].RecordSource = sql
I am using Vb6 and Access 2007. I am adding records to the access table name "subjectcode" from vb6. The details of subjectcode table are below.
Subjectcode table : Heading(Degree,Branch,Year1,Year2,Semester,Subjectcode,Subjectname,Theory_Practical, Major_Allied_Elective) values (Bsc,computerscience,2001,2004,1,RACS1,Vb6 programming,Theory,Major)
Note :The primary key in the above table is Degree,Branch,Year1,Year2,Semester,Subjectcode
And the code i used to add entry to the access table from vb6 are given below :
If degree = "" Or branch1 = "" Or year1 = "" Or year2 = "" Or semester = "" Or subcode.Text = "" Or subname.Text = "" Or theory.Text = "" Or major.Text = "" Then
MsgBox "Fields can't be empty ! All are mandatory!"
Else
rs.Open "select * from subjectcode", con, 1, 3
rs.AddNew
rs!degree = degree
rs!branch = branch1
rs!year1 = year1
rs!year2 = year2
rs!semester = semester
rs!Subjectcode = subcode.Text
rs!Subjectname = subname.Text
rs!Theory_Practical = theory.Text
rs!Major_Allied_Elective = major.Text
rs.Update
MsgBox "Successfully Saved !", vbOKOnly + vbInformation, "info"
rs.Close
End If
And the screenshot of that Add form of vb6 is here: http://tinypic.com/r/w7c7if/6
The record is added when the same entry is not exist. And if the record is already exist it should say "Record Already exists" and i don't know how to do that. Could you guys give me idea please.
Write a save method to save your record, and a method to query the database and check for an existing record before you save the data.
Public Sub SaveSubjectCode(ByVal vDegree As String, ByVal vBranch As String, ByVal vYear1 As Integer, ByVal vYear2 As Integer, ByVal vSemester As Integer, ByVal Subjectcode...)
If (DoesRecordExist(vDegree, vBranch, vYear1, vYear2, vSemester, vSubjectcode) = True Then
' Warn the user
MessageBox("I'm sorry Dave I can't do that. The record already exists.")
Else
' Save the record
End If
End Sub
Private Function DoesRecordExist(ByVal vDegree as String, ByVal vBranch As String, ByVal vYear1 As Integer, ByVal vYear2 As Long, ByVal vSemester As Integer, ByVal vSubjectcode As String) As Boolean
RecordSet = query 'Query the database for the existing record
If RecordSet.BOF And RecordSet.EOF Then
DoesRecordExist = False
Else
DoesRecordExist = True
End If
End Function
Also, you want to avoid the the Select * query that selects every record unless you really need it because it is likely to be slow, and get slower as the number of records grow. If you want to get a recordset just to use to add a new record you can include a Where clause that does not return any records "select * from subjectcode WHERE 1 = 2, con, adOpenKeyset, adLockOptimistic
When you create a field in a table you specify whether duplicates are allowed or not. Then an offending add or update raises an exception.
The SQL DML looks like:
ALTER TABLE tblCustomers
ADD CONSTRAINT CustomerNames UNIQUE
([Last Name], [First Name])
And there are other powerful features such as check contraints as well:
ALTER TABLE tblInvoices
ADD CONSTRAINT CheckAmount
CHECK (Amount > 0)
One advantage of constraints is that your database's integrity is not held hostage by rogue applications that may fail to do chatty pre-qualification queries (or fail to implement them properly). Another is the performance improvement over chatty techniques and the fact that when there are multiple updaters the database can change between pre-qual query and update.
I have two tables which can be represented by this query (I have made this query the Recordsource of the form):
SELECT tblrcmtask.id, tblrcmtask.rcmtask,tblrcmtaskoptions.id,
tblrcmtaskoptions.rcm_id,
tblrcmtaskoptions.rcmtaskoptions
FROM tblrcmtask
INNER JOIN tblrcmtaskoptions
ON tblrcmtask.id=tblrcmtaskoptions.rcm_id
I want the user to be able to add new entries into these table via a form in access 2007.
Columns tblrcmtask.id and tblrcmtaskoptions.id are the primary keys of the tables tblrcmtask and tblrcmtaskoptions respectively.
I do not understand how do I create new ID in both the tables while the user adds new entries.The user can add only tblrcmtaskoptions.rcmtaskoptions and tblrcmtask.rcmtask in the form.Also, there are multiple rows in the table tblrcmtaskoptions for each tblrcmtask.id.
I want the user to be able to add new rows in the table tblrcmtaskoptions for an existing tblrcmtask.id
I tried using dropdowns for these two but I am facing problem while creating the new ID as Maximum of the ID + 1.
Dim MyRecords As DAO.Recordset
Dim Myfield As DAO.Fields
SQL = "SELECT Max(tblRCMTASK.ID) AS MaxOf_RCMTASKID FROM tblRCMTASK;"
Set MyRecords = dbTHIS.OpenRecordset(SQL)
Set Myfield = MyRecords.Fields
Me.txtRCMTASKID = Myfield("MaxOf_RCMTASKID") + 1
Me.txtRCMTASKID.DefaultValue = Myfield("MaxOf_RCMTASKID") + 1
MyRecords.Close
End If
Dim MyRecords1 As DAO.Recordset
Dim Myfield1 As DAO.Fields
SQL = "SELECT Max(tblRCMTASKOPTIONS.ID) AS MaxOf_RCMOPTIONSID FROM tblRCMTASK;"
Set MyRecords = dbTHIS.OpenRecordset(SQL)
Set Myfield1 = MyRecords1.Fields
Me.txtRCMOPTIONSID = Myfield1("MaxOf_RCMOPTIONSID") + 1
Me.txtRCMOPTIONSID.DefaultValue = Myfield("MaxOf_RCMOPTIONSID") + 1
MyRecords1.Close
I am getting an error which says you can't asign a value to this object and points to this line: Me.txtRCMTASKID = Myfield("MaxOf_RCMTASKID") + 1
How do I do this?
Access gives you trouble when trying to do operations on an autonumber field. If you would like to do these kinds of operations, you may be better off just using a regular number as a PK.
To get a recently inserted autonumber field to insert the same number in a related table, this is the VBA:
assuming recordset and database are declared, rs and db
dim id as integer
set db = CurrentDb
set rs = db.openrecordset("firstTable", dbOpenDynaSet)
With rs
.addNew
.Fields("field1").Value = Me.control1 'adds to column1 of your table the value of control1
.Fields("field2").Value = Me.control2
.update 'updates the record. If it is an autonumber, it will be automatically assigned. I will show you how to access this for your next insert
end with
'To get the autoID of the entry we just inserted, do this
id = db.OpenRecordSet("SELECT##IDENTITY")(0)
'Now you have the autoID of the recent insertion, so you may use it for your next one.
This is a classic form/subform set up. Create a form based solely on tblrcmtask with a subform tblrcmtaskoptions. The link child and master fields should be set to the common id. The wizards will do this for you. There is no code required. The id will be automatically added by the link fields.
You can see an example for in the 2007 version of the Northwind sample database.
I have a form that displays information on a project that has 10 check boxes. The check boxes are named "chkAudience1", "chkAudience2", etc through "chkAudience10". Any combination of boxes can be checked from none to all and anything in between.
Then I have a table that links the check boxes to the project. This table contains a field called ProjectID and a field called AudienceID (both fields are defined as number). This allows me to select all audience records for a project.
The problem is that I want to loop through the records for a project and check the boxes that match a record in the table. My current code looks like:
sqlStmt = "SELECT * FROM ProjectAudience WHERE ProjectID = " & Me.ProjectID.Value
Set rs = cn.Execute(sqlStmt)
While Not rs.EOF
'Me.chkAudience1.Value = -1
x = "Me.chkAudience" & rs(1).Value
x.Value = -1
rs.MoveNext
Wend
x will be set to "Me.checkAudience1", but the next line produces an "object required" error. How do I create a field name based on recordset data and then use that field name to set a value. (This is being done is Microsoft Access 2003)
The correct while loop is:
While Not rs.EOF
'Me.chkAudience1.Value = -1
Me.Controls("chkAudience" & (rs(1).Value)).Value = -1
rs.MoveNext
Wend
The key is the Me.Controls().