I have two related table, i want this error/message to appear when appending to my second table. "You cannot add or change a record because records is required in table ".
I already set the relationship to Enforce Referential Integrity, Cascade update Related Fields and Cascade Delete Related Records
Here is my code
Private Sub cmdImport_Click()
On Error GoTo ErrHandler
Dim ImportExcelFile As String
ImportExcelFile = SelectFile
If ImportExcelFile = "" Then Exit Sub
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, "Temp-Member", ImportExcelFile, True
DoCmd.OpenQuery "AppendtoMember"
MsgBox "Import complete", vbInformation, "Import"
DoCmd.OpenQuery "DeleteTemp-Member"
ExitSubError:
Exit Sub
ErrHandler:
MsgBox Err.Description & Err.Number, vbCritical, "Error"
End Sub
To customize message when append action fails, use Execute method and error handler. If any record fails, none will insert.
CurrentDb.Execute "AppendtoMember", dbFailOnError
I solved it, i put a look up value field to "MemberID" which is my second table(my primary key to first table and foreign key to second table)and set "Limit to List" to Yes
I also put your suggestion to my code to use-CurrentDb.Execute "AppendtoMember", dbFailOnError.
Thank you
Related
I'm trying to setup reminders based on tasks added from a Table called "Tasks" Here is the code I'm using but something isn't right as it keeps giving me issues with the following line:
intStore = DCount("[TaskName]", "[Status]", "[DueDate] <=Now() AND [Complete] =0")
When the code runs I get the error:
Microsoft Access database engine cannot find the input table or query
for 'Status' Make sure it exists and is spelled correctly.
In my table I have fields for Task Name, Status, and Due Date so I'm not exactly sure why this is coming up.
Below is the entire line of code:
Private Sub Form_Load()
'On Load of the switchboard check Jobs table for any uncompleted jobs
Dim intStore As Integer
intStore = DCount("[Priority]", "[Tasks]", "[DueDate] <=Now() AND [PercentComplete] <=0")
If intStore = 0 Then
Exit Sub
Else
If MsgBox("There are " & intStore & " uncompleted jobs" & _
vbCrLf & vbCrLf & "Would you like to see these now?", _
vbYesNo, "You Have Uncomplete Jobs...") = vbYes Then
DoCmd.Minimize
DoCmd.OpenForm "Tasks", acNormal
Else
Exit Sub
End If
End If
End Sub
You can only perform a DCount on one field (primary key is best if you are just doing a general count on the table). You have entered "[Status]" where Access is expecting a table or query name to be used as the source of the [TaskName] field.
See here for more information.
Judging by your other code example I expect that your code needs to be:
intStore = DCount("[TaskName]", "[Tasks]", "[DueDate] <=Now() AND [Complete] =0")
I have a button on a Continuous subform with the below VBA attached -
Private Sub del_Click()
On Error GoTo del_Click_Err
Dim LResponse As Integer
On Error Resume Next
DoCmd.GoToControl Screen.PreviousControl.Name
Err.Clear
If (Not Form.NewRecord) Then
LResponse = Eval("MsgBox('You are about to delete a record.'" & _
"'#If you click yes, you won't be able to undo this delete operation.' & Chr(13) & Chr(10) & " & _
"'Are you sure you want to delete this record?##', 276, 'Are you sure?')")
If LResponse = vbYes Then
DoCmd.SetWarnings False
DoCmd.OpenQuery "qry_DeleteSpecific"
DoCmd.RunCommand acCmdDeleteRecord
DoCmd.SetWarnings True
Else
End If
End If
If (Form.NewRecord And Not Form.Dirty) Then
Beep
End If
If (Form.NewRecord And Form.Dirty) Then
DoCmd.RunCommand acCmdUndo
End If
If (MacroError <> 0) Then
Beep
MsgBox MacroError.Description, vbOKOnly, ""
End If
del_Click_Exit:
DoCmd.SetWarnings True
Exit Sub
del_Click_Err:
MsgBox Error$
Resume del_Click_Exit
End Sub
The button was originally the auto-generated 'Delete Record' button and I have since modified it to include the query activation as well as my own msgBox.
The 'delete' button obviously worked fine before modification. The query also works as intended and I tested a button on a seperate form that just included the MsgBox code, which also worked.
But bringing it all together has failed somehow. When I click the button I don't get the MsgBox and it doesn't delete a record or run the query.
DoCmd.GoToControl Screen.PreviousControl.Name
This line appears to have fired correctly though.
Could anybody explain what may be going wrong with this?
---Edit---
Replaced
Error Clear
With
On Error GoTo del_Click_Err
I now get the error message -
The expression you entered contains invalid syntax
So it turns out it was all in the Quotes. The quotation issue is still a bit of a mystery to me, but I managed to get my code working.
Here's the change -
LResponse = Eval("MsgBox(""You are about to delete a record."" & " & _
"""#If you click yes, you won't be able to undo this delete operation."" & Chr(13) & Chr(10) & " & _
"""Are you sure you want to delete this record?##"", 276, ""Are you sure?"")")
Single quotes seemed to work when it was just the msgBox code by itself but not in the extended code. Anyway, I'll know to look out for this again.
#Andre your comment helped me debug this. I initially left 'Error Clear' as that was what the wizard put in for the delete button.
Recently started learning Access and I'm a bit stuck on deleting records within a form. I have a list with the following code:
Private Sub lstPickList_AfterUpdate()
Dim rst As DAO.Recordset
Set rst = Me.RecordsetClone
rst.FindFirst "OrderID=" & lstPickList.Column(0) & ""
If rst.NoMatch Then
MsgBox "The selected record can not be displayed." _
& "To display this record, you must first turn off record filtering.", _
vbInformation
Else
Me.Bookmark = rst.Bookmark
End If
Set rst = Nothing
End Sub
And a button that I would like to use to delete whatever Order is currently selected on the list. The "DeleteRecord" macro just gives me a "The command or action 'DeleteRecord' isn't available now." error. Searching has given me a bunch of code that hasn't worked for me at all.
You can delete directly from the clone:
If rst.NoMatch Then
MsgBox "The selected record can not be displayed." _
& "To display this record, you must first turn off record filtering.", _
vbInformation
Else
rst.Delete
End If
I'm getting the following error when trying to delete a table:
Run-time error '3211'
The database engine could not lock table 'RuleViolations1516' because
it is already in use by another person or process.
Here is the offending procedure, with a comment showing the line throwing the error:
Public Sub ImportRuleViolations()
DoCmd.Close acForm, "frmImportRuleViolations"
If _
TableExists("RuleViolations1516") = True _
Then
Debug.Print "Table RuleViolations1516 already exists"
DoCmd.DeleteObject acTable, "RuleViolations1516" ' <-- EXECUTION STOPS HERE
Debug.Print "...old table deleted..."
DoCmd.TransferSpreadsheet acTable, _
10, _
"RuleViolations1516", _
Forms!frmImportRuleViolations.txtRuleViolationsPath & Forms!frmImportRuleViolations.txtRuleViolationFile, _
-1
Debug.Print "...new data imported."
ElseIf _
TableExists("RuleViolations1516") = False _
Then
Debug.Print "Table RuleViolations1516 does not already exist"
DoCmd.TransferSpreadsheet acTable, _
10, _
"RuleViolations1516", _
Forms!frmImportRuleViolations.txtRuleViolationsPath & Forms!frmImportRuleViolations.txtRuleViolationFile, _
-1
Debug.Print "...new data imported."
End If
Dim db As DAO.Database
Dim tDef As TableDef, fld As DAO.Field
Set db = CurrentDb
db.TableDefs.Refresh
' LRN
Set tDef = db.TableDefs("RuleViolations1516")
Set fld = tDef.CreateField("newLRN", dbText, 20)
fld.OrdinalPosition = 2
tDef.Fields.Append fld
db.Execute _
"UPDATE RuleViolations1516 Set newLRN=[Learner Ref]", dbFailOnError
' delete old field
tDef.Fields.Delete "Learner Ref"
tDef.Fields.Refresh
' rename new field
tDef.Fields("newLRN").name = "LRN"
tDef.Fields.Refresh
Set fld = Nothing
Set tDef = Nothing
' AimRef
Set tDef = db.TableDefs("RuleViolations1516")
Set fld = tDef.CreateField("newAimRef", dbText, 20)
fld.OrdinalPosition = 7
tDef.Fields.Append fld
db.Execute _
"UPDATE RuleViolations1516 Set newAimRef=[Aim Reference Number]", dbFailOnError
' delete old field
tDef.Fields.Delete "Aim Reference Number"
tDef.Fields.Refresh
' rename new field
tDef.Fields("newAimRef").name = "AimRef"
tDef.Fields.Refresh
Set fld = Nothing
Set tDef = Nothing
Set db = Nothing
DoCmd.OpenForm "frmImportRuleViolations"
End Sub
The offending sub also makes reference to another function:
Public Function TableExists(name As String) As Boolean
TableExists = DCount("*", "MSysObjects", "Name = '" & name & "' AND Type = 1")
End Function
The above sub and function run on their own separate module (not tied to a form module).
The table RuleViolations1516 is not open when I run the sub. The form frmImportRuleViolations uses the RuleViolations1516 table in some queries behind some subforms, but as you can see from the sub, I've closed this form on the first line.
Any pointers would be appreciated.
Update:
frmImportRuleViolations has 2 subforms on it... removing them (temporarily) stops the issue. I need the subforms on the form though.. how can I get around this?
As I understand your updated question, you have a form called frmImportRuleViolations and that has a subform I'll call frmImportRuleViolationsSubform1.
frmImportRuleViolationsSubform1 references the RuleViolations1516 table somewhere on it.
I'm assuming you are also triggering this reload from a button or other control on frmImportRuleViolations. If so, then that makes sense as the cause of your error. Access may not have given up every reference to RuleViolations1516 by the time it gets to the close event.
That and a form closing and reopening itself can get kind of hairy.
One fairly easy thing to do would be to drop and load the table before the frmImportRuleViolationsSubform1 is opened. As a user (and a developer) that's what I would expect - I open the form and it's right up to date. And worst case situation closing the form and re-opening it gives me a refresh.
Failing that (it absolutely has to be reloaded after the form is closed); then I would make whatever is closing it open frmImportRuleViolations as a modal window, and then put reload of the table code after the call to frmImportRuleViolations since it will wait until control is returned to the calling window.
You could also instead load the data into a temporary staging table, and then delete the contents of RuleViolations1516 and repopulate it from the staging table. This would probably be the route I would take as it would eliminate the closing and opening of the frmImportRuleViolations form. You'd just have to tell the table on the sub-form to refresh (which I'll leave an an exercise for the reader).
Aside from that, a couple style notes:
'' this
If _
TableExists("RuleViolations1516") = True _
Then
'' could be equally written as
If TableExists("RuleViolations1516") Then
'' the "= True" is implied and not required
And
'' this
ElseIf _
TableExists("RuleViolations1516") = False _
Then
'' is redundant to the previous if. A simple else would do, since we
'' know if the last time it ran, it wasn't true, it must be false
And the DoCmd block looks like it does the same thing in both the if and else, so I'd be inclined to extract it like this:
If TableExists("RuleViolations1516") then
Debug.Print "Table RuleViolations1516 already exists"
DoCmd.DeleteObject acTable, "RuleViolations1516"
Debug.Print "...old table deleted..."
else
Debug.Print "Table RuleViolations1516 does not already exist"
end if
DoCmd.TransferSpreadsheet acTable, _
10, _
"RuleViolations1516", _
Forms!frmImportRuleViolations.txtRuleViolationsPath & _
Forms!frmImportRuleViolations.txtRuleViolationFile, _
-1
Debug.Print "...new data imported."
That way when you come back to change the name of the file (or whatever) you are only changing it in one place, etc. and goes along with the DRY principle - "DRY - don't repeat your self".
I like the use of underscores so that what you have coded does not run off the edge of the screen like some extract from war and peace. It makes it much more readable.
What you've done is not wrong. It's just not what most developers would do. And as much as we write code for the computer to function the way we want, we also want the next developer to touch your code 5 years down the line to easily understand what you are doing. And code always lasts longer than you think it will :^)
Good luck!
I was recently given the task of creating a form that will autofill with the information from a table. The information the form autofills is selected using a primary key called ModID. I have a combo box that has a List of the ModIDs that are listed as Active.
SELECT ModID
FROM P_Review
WHERE Status = "Active"
Simple enough. I then have VBA code running on the event After Update. So after the value for the combo box is select or changed it will run this VBA code.
Option Compare Database
Option Explicit
Private Sub selectModID_AfterUpdate()
'Find the record that matches the control.
On Error GoTo ProcError
Dim rs As Object
Set rs = Me.RecordsetClone
With rs
.FindFirst "ModID=" & Me.selectModID
If Not .NoMatch Then
Me.Bookmark = .Bookmark
Else
DoCmd.RunCommand acCmdRecordsGoToNew
Me!localModID = Me.selectModID.Column(0)
End If
End With
ExitProc:
Exit Sub
ProcError:
MsgBox "Error: " & Err.Number & ". " & Err.Description
Resume ExitProc
End Sub
The code runs fine (I get no errors when I debug or run).
Now for the access text box. I would like to populate certain fields based off the variable localModID. I have a dlookup in a text box to find the information in the table P_Review.
=DLookUp("Threshold","P_Review","ModID =" & [localModID])
So the DlookUp should find the value for the column threshold, in the table P_Review, where the ModID in P_Review equals the localModID set in the VBA code. But when I go to form view and select a ModID I get the Error 3070: The Microsoft Access database engine does not recognize as a valid field name or expression. I did copy this code from another database we are already using but it fails in this new instance.
Private Sub ModID_AfterUpdate()
Dim rs As Object
Set rs = Me.RecordsetClone
With rs
.FindFirst "ModID='" & Me.ModID & "'"
If Not .NoMatch Then
Me.Bookmark = .Bookmark
Else
DoCmd.GoToRecord , , acNewRec
Me!ModID = Me.ModID
End If
End With
End Sub
This is the answer to question. I used this code to auto update.
Try
Forms!<whatever_this_form_name_is>![localModID]
in your DLOOKUP