Updating a record by using a selection box control - sql

I would like to know what the preferred function to put in a code string immediately after a user selects a selection box control of a record so that his selection is acknowleged and included as "true". In short, I have a form where the user uses a selection box to indicate which records to select and then executes a command where I have code that should copy and paste the records he selected. Unfortunately, the last record selected, upon running executing the copy/paste command is not recognised. I understand that I probably need to add a function such as ' go-to the next record' however I am not sure if this is the best way or if there is a more standard way that programmers use to not lose the last record selected. Below is the code I am currently using which currently does not pick up the last record selected by the user.
Private Sub Comando99_Click()
If CurrentRecord = Recordset.RecordCount And CurrentRecord <> 1 Then
DoCmd.GoToRecord , "", acFirst
Else
DoCmd.GoToRecord , "", acNext
End If
Dim intAnswer As Integer
On Error GoTo HandleError
intAnswer = _
MsgBox("Are you sure you want to add these dependencies to your dependency project tracker?", _
vbQuestion + vbYesNo, "Add Dependencies")
If intAnswer = vbYes Then
st_sql = "INSERT INTO [tblDependencies] ( [Description] )SELECT [tblDependencyTypeListing].[Dependency (General)] FROM [tblDependencyTypeListing] WHERE ((([tblDependencyTypeListing].[ToIncludeInProject])=True))"
Application.DoCmd.RunSQL (st_sql)
st_sql = "UPDATE[tblDependencies],[tblHoldingProjectid]SET[tblDependencies].[ID Project]=[tblholdingprojectid].[ID_Project]where([tbldependencies].[ID Project])=0 and ([tblholdingprojectid].[ID_Project])is not null"
Application.DoCmd.RunSQL (st_sql)
st_sql = "UPDATE[tblDependencies]SET[tblDependencies].[Automatic date of entry]=now() where([tblDependencies].[Automatic date of entry])is null"
Application.DoCmd.RunSQL (st_sql)
st_sql = "UPDATE[tblContacts],[tblDependencies]SET[tblDependencies].[Automatic user entry]=[tblContacts].[Complete name]where([tblContacts].[In use])is not null and([tblDependencies].[Automatic user entry])is null"
Application.DoCmd.RunSQL (st_sql)
st_sql = "UPDATE[tblDependencytypelisting]SET[tblDependencytypelisting].[toincludeinproject]=null"
Application.DoCmd.RunSQL (st_sql)
Me.Refresh
End If
ExitHere:
Exit Sub
HandleError:
MsgBox "Error is " & Err.Description
Resume ExitHere
End Sub

Problem is resolved by entering the following IF statement at the beginning of the routine to ensure that prior to running the code, ACCESS moves to the next record to ensure that it acknowledges the last modification made
If CurrentRecord = Recordset.RecordCount And CurrentRecord <> 1 Then
DoCmd.GoToRecord , "", acFirst
Else
DoCmd.GoToRecord , "", acNext
End If

Related

MS Access: Why is my code not being reached?

Im trying to do some error handling for my code and I want my custom error message to appear if the user is trying to enter an already existing record. Access gives its own standard error message indicating a duplicate record, but I want mine displayed instead. The issue is the part of the code where I have my custom error message isn't being reached, therefore giving me the default message.
The name of the textbox is "DepartmentCode", the name of the table its being drawn from is "tDepartment" and the column name is "DepartmentCode"
My code is this...
Private Sub bAddDepartment_Click()
On Error GoTo bAddDepartment_Click_Err
Dim OKToSave As Boolean
OKToSave = True
If Not SomethingIn(Me.DepartmentCode) Then ' Null
Beep
MsgBox "A department code is required", vbOKOnly, "Missing Information"
OKToSave = False
Else
Dim myDepartmentCode As String
myDepartmentCode = "DepartmentCode = " + Chr(34) + Me.DepartmentCode + Chr(34)
If DLookup("DepartmentCode", "tDepartment", myDepartmentCode) <> Null Then
MsgBox "Department already on file", vbOKOnly, "Department already on file."
OKToSave = False
End If
End If
If OKToSave Then
' If we get this far, all data is valid and it's time to save
Me.Dirty = False
DoCmd.GoToRecord , "", acNewRec
End If
bAddDepartment_Click_Exit:
Exit Sub
bAddDepartment_Click_Err:
Resume bAddDepartment_Click_Exit
End Sub
The part not being reached is If DLookup("DepartmentCode", "tDepartment", myDepartmentCode) <> Null Then
Why is this happening?
Debugging VBA Code <-- to see which lines are actually executed.
If DLookup("DepartmentCode", "tDepartment", myDepartmentCode) <> Null Then
You can't compare to Null like that. Try this in the Immediate Window:
? ("foo" <> Null)
Null
Use IsNull()
If Not IsNull(DLookup("DepartmentCode", "tDepartment", myDepartmentCode)) Then
or if empty strings are also possible, use Nz()
If Nz(DLookup("DepartmentCode", "tDepartment", myDepartmentCode), "") <> "" Then

Close subform, remove main form filter and go back to original record

I am opening a subform from my main form to allow data to be changed. Once the changes are made, I want to pass the data back to the main form. remove the filter, and go back to the original record. I have the Primary Key in the subform so I am passing it back. I used some code from another user's but it did not work not is my code. Any thoughts?
Private Sub cmd_close_Click()
Dim result As String
Dim ID As Variant
result = MsgBox("Save Geo Location?", vbOKCancel, "Save Geo Location")
If result = vbOK Then
Forms!frm_acct_select!GeoLoc_X = Me.txt_GeoLocX
Forms!frm_acct_select!GeoLoc_Y = Me.txt_GeoLocY
Forms!frm_acct_select.FilterOn = False
'this code fails immediately
With frm_acct_select.Form
ID = Me.txt_ParentID.Value
.FilterOn = False
.Recordset.FindFirst "ParentAccountID=" & ID
End With
'this code fails type mismatch criteria at the recordset.findfirst line
' With Forms!frm_acct_select
' ID = Me.txt_ParentID.Value
' .FilterOn = False
' .Recordset.FindFirst "ParentAccountID = " & ID
' End With
DoCmd.Close acForm, "sfrm_geoloc_update", acSaveNo
Else
DoCmd.Close acForm, "sfrm_acct_select_search", acSaveNo
End If
End Sub
Apparently, I still need to work on my string formatting.
Declaring ID as String was correct however I needed to add quotes to my code.
.Recordset.FindFirst "ParentAccountID = '" & ID & "'"

Subform blocking Recordset.AddNew (Error 3027)

Having a subform displaying the same table used in recordset makes the table read only (error 3027). Getting rid of the subform fixes the problem. Similar setup works in my other form interface.
I tried to delete the subform, which fix the accessibility problem. But that would defeat the original UX purpose.
Option Explicit
Public UnitRS As DAO.Recordset
Public ModelRS As DAO.Recordset
Public NameUnitRecords As String
Public NameModelRecords As String
Public Sub Form_Load()
'Initialization
NameUnitRecords = "tblBatteriesMainRecordsUnits"
NameModelRecords = "tblBatteriesRecordsModels"
End Sub
Private Sub SetUnitRecordsets()
'Set the path to the Battery Records table
Set UnitRS = CurrentDb.OpenRecordset(NameUnitRecords, dbOpenDynaset)
End Sub
Private Sub txtBatteryID_AfterUpdate()
'Set the recordset path for unit records
Call SetUnitRecordsets
'do a findfirst search for the Battery ID, using value from textbox txtBatteryID
UnitRS.FindFirst "[Battery ID]=" & txtBatteryID
'If no matching record, leave the other fields empty
If UnitRS.NoMatch Then
'If there is a matching record, then, grab the model number
Else
'as there is an existing record with model number, run a search on the model number and grab the model info
End If
'close recordset
UnitRS.Close
'check if the button can be enabled
End Sub
Private Sub cmbModelNumber_AfterUpdate()
'Set the recordset path for model records
'do a findfirst search for the Model Number, using value from combobox cmbModelNumber
'If no matching record, leave the other fields empty
If ModelRS.NoMatch Then
'If there is a matching record, then, grab the Model Info
Else
End If
'close recordset
'check if the button can be enabled
End Sub
Private Sub btnSaveAndCLear_Click()
Dim Response, strOldModelNumber
'Set the recordset path for unit records
Call SetUnitRecordsets
'Set the recordset path for model records
'close all related tables, queries and forms
DoCmd.Close acTable, NameUnitRecords, acSaveYes
DoCmd.Close acForm, "frmSubBatteriesMainRecordsUnits", acSaveYes
'If a new model record is required
ModelRS.FindFirst "[Model Number]='" & cmbModelNumber & "'"
If ModelRS.NoMatch Then
'msg box confirm model information
'If user chooses yes
If Response = vbYes Then
'create new model record
'this block could be done with "With...End" format for less error vulerability?
'nah, unless it is repetitively called, it's too much work to inplement just the .addnew part
'requery the two combobox to reflect newest changes
'User chooses no
Else
'popup a message telling the user the battery and model record is not logged, but don't clear the field.
Exit Sub
End If
End If
'need to find the record first, otherwise it will edit the first one
UnitRS.FindFirst "[Battery ID]=" & txtBatteryID
'store the old model number value
strOldModelNumber = UnitRS("Model Number")
'New record
If UnitRS.NoMatch Then
'create a new battery record
UnitRS.AddNew
UnitRS("Battery ID") = Me.txtBatteryID
'If this is an edit on existing record
Else
'if the new value is the same as the old one
If strOldModelNumber = cmbModelNumber Then
'msgbox the same value, no change is done to the database
MsgBox "the data is the same as the old record, no change is made to the record", vbInformation, "Same data"
Exit Sub
Else
'msg box confirm edit
Response = MsgBox("Please confirm edit on existing record: " & Chr(13) & Chr(10) & "BatteryID: " & txtBatteryID & Chr(13) & Chr(10) & "Model Number: " & cmbModelNumber, vbYesNo, "New Model Record Dectected")
'If user chooses yes
If Response = vbYes Then
'goto edit mode
UnitRS.Edit
'if user chooses no
Else
'msgbox notify the user nothing is changed in the database
MsgBox "Battery and Model record not logged, you may retry logging", vbInformation, "Record not logged"
Exit Sub
End If
End If
End If
'both changes the model number and comment field anyway
UnitRS("Model Number") = Me.cmbModelNumber
UnitRS("Comment") = Me.txtComment
'commit update
UnitRS.Update
UnitRS.Close
'clear all flieds
'reset all locks
'requery the sub form to reflect the newest changes
Me.subFrmBatteryRecords.Requery
End Sub
What I would like to achieve is to have a display in the form interface to show the content of the actual record table, so that the user knows what is in the table.
There is nothing wrong with my code. There is a property option in the form object, it's called "record lock", somehow mine had "All Records" selected. By making it "No locks", the accessibility problem is gone.

Executing Append Query not doing anything

Executing Append Query not doing anything
I'm having an odd problem that just reared its ugly head for some reason. I have a form that is used to add/edit/delete records in tblWorkOrder. When the record is saved, a check is made to see if the companion record in tblServiceRecord exists, and if not (like if it were the first time the record in tblWorkOrder is being saved/input) it will execute a query (qryCreateSR).
Several weeks ago it worked just fine. I had no problems with it, but then I updated tblServiceRecord to add several new columns and now it's not working at all. However, the SQL for the query doesn't delineate any of these new columns, let alone any specific information from tblWorkOrder. So I'm not entirely sure how this bug came up.
Here is the SQL:
INSERT INTO tblServiceRecord ( WorkOrderID )
SELECT Forms![frmWorkOrders].Form![txtID];
And here is the code behind the command button:
Private Sub cmdSave_Click()
If DCount("*", "[tblServiceRecord]", "[WorkOrderID] = " & [Forms]![frmWorkOrders].[Form]![txtID]) > 0 Then
Else
DoCmd.SetWarnings False
DoCmd.OpenQuery "qryCreateSR"
End If
DoCmd.RunCommand acCmdSaveRecord
DoCmd.GoToRecord , "", acNewRec
Me.lstWorkOrders.Requery
Me.lstWorkOrders.Value = ""
Me.txtComments.Value = ""
cmdSave_Click_Exit:
Exit Sub
cmdSave_Click_Err:
MsgBox Error$
Resume cmdSave_Click_Exit
End Sub
After removing the warnings suppression I get a key violation issue.
No clue what is causing the key violations. I checked my tables, and the two tables in question are tblWorkOrder and tblServiceRecord. Both have no records in them, I compacted the database, the linked fields (in tblServiceRecord, there is a reference to tblWorkOrder with the field WorkOrderID) are set to the same data type (number), and the child-tables are set to Indexed (No).
Just in case anyone wants to look at the database itself, here is a link:
https://drive.google.com/open?id=1_T-G9fyYQYjH3-YBe4PXhbBDTKNmY3ce
Try saving the current record in the form (by setting Me.Dirty = False), before inserting the record to the other table. Since you try to insert into a child table with a relation to a parent table, you must have a corresponding (saved) record in the parent table. When you create a new entry in the form, it first doesn't exist in the table until it is saved for the first time.
Private Sub cmdSave_Click()
Me.Dirty = False ' Or DoCmd.RunCommand acCmdSaveRecord <==== Save here
If DCount("*", "[tblServiceRecord]", "[WorkOrderID] = " & [Forms]![frmWorkOrders].[Form]![txtID]) = 0 Then
DoCmd.SetWarnings False
DoCmd.OpenQuery "qryCreateSR"
End If
'Removed: DoCmd.RunCommand acCmdSaveRecord <==== instead of here
DoCmd.GoToRecord , "", acNewRec
Me.lstWorkOrders.Requery
Me.lstWorkOrders.Value = ""
Me.txtComments.Value = ""
cmdSave_Click_Exit:
DoCmd.SetWarnings True
Exit Sub
cmdSave_Click_Err: // This code will never run, since a "On Error Goto cmdSave_Click_Err" is missing
MsgBox Error$
Resume cmdSave_Click_Exit
End Sub

Me.Dirty moves currently selected record

I have an Access 2007 form that's giving me some headache.
I have a list of records that start as a combo box to pick a company and then a series of checkboxes to indicate the company's role.
If the user needs to add a new company, they'd pick the company name from the combo box, and then click the checkbox that indicates what role the company is playing. When the checkbox is checked, the form follows the following code to show a popup that captures additional information:
Private Sub chkOperationsAndMaintenance_AfterUpdate()
'DoCmd.RunCommand acCmdSaveRecord'
If Me.Dirty Then Me.Dirty = False
If chkOperationsAndMaintenance.Value = True Then
DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog
Me.Requery
End If
End Sub
This code will save the record on the CompanyProject table to create the row. It then pulls the CompanyProjectID (PK of the CompanyProject table) so it knows which ID to feed the popup.
The issue I'm having is that on the Me.Dirty line (and also the above commented-out acCmdSaveRecord), the entire form saves and refreshes, moving the selected row to the first record (in this case, "Gamesa") rather than the newly entered record. So the ensuing popup is fed the CompanyProjectID of the first record rather than the newly-entered record, and it also reads the "checked" state of the checkbox from the first record rather than the one upon which the user is working.
I doctored the code to look like this:
Private Sub chkOperationsAndMaintenance_AfterUpdate()
Dim CPID As Long
Dim CID As Long
Dim rs As Recordset
Set rs = Me.RecordsetClone
CID = Me.CompanyID
'DoCmd.RunCommand acCmdSaveRecord'
If Me.Dirty Then Me.Dirty = False
CPID = DLookup("MAX(CompanyProjectID)", "CompanyProject", "cpProjectID = " & Me.cpProjectID & _
" AND CompanyID = " & CID)
rs.Find "[CompanyProjectID] = " & CPID
Me.Bookmark = rs.Bookmark
If chkOperationsAndMaintenance.Value = True Then
DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog
Me.Requery
End If
End Sub
The idea with these alterations is that we'll get the FK from the parent form ("cpProjectID") and the CompanyID of the selection from the combobox, then save the record. Once the record is saved, we have the CompanyProjectID already stored, so then the rs.Find and Me.Bookmark lines will then select the record that matches that CompanyProjectID.
This sometimes works, and sometimes doesn't. Generally doesn't. In this case, I refreshed the parent form and the current form and attempted to add a new company and then click the "Owner" checkbox (which uses the same code as above, just a different checkbox ID) to see the Bookmark on the wrong row:
At this point, I'm not sure what to do. If I don't save the record (via acCmdSaveRecord or Me.Dirty=False) then I don't have a CompanyProjectID to send as the input parameter for the ensuing popup, but if I do save the record, then the form changes the record and the wrong parameter is sent and the wrong checkbox's checked state is read. I can't just use an arbitrary index to work off of (such as acNewRec), as the user might need to edit an existing row instead of adding a new one.
I tried the method in this post already: MS Access how to Update current row, move to next record, not first, but the find/bookmark isn't consistently working.
EDIT (12/15/2014)
I ended up going with the following VBA code:
Private Sub chkOperationsAndMaintenance_AfterUpdate()
Dim CPID As Long
Dim CID As Long
Dim rs As Recordset
Set rs = Me.RecordsetClone
CID = Me.CompanyID
If Me.Dirty Then Me.Dirty = False
CPID = DLookup("MAX(CompanyProjectID)", "CompanyProject", "cpProjectID = " & Me.cpProjectID & _
" AND CompanyID = " & CID)
Do While Me.CompanyProjectID <> CPID
If Me.CurrentRecord < Me.Recordset.RecordCount Then
DoCmd.GoToRecord , , acNext
Else
DoCmd.GoToRecord , , acFirst
End If
Loop
If chkOperationsAndMaintenance.Value = True Then
DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog
Me.Requery
End If
End Sub
I feel like there has to be a better answer for this, but this is appearing to work right now. I have my end user/lab rat testing it at the moment, so I'll mark this complete if this pans out. I still think there has to be a better solution for this, but at the moment, this solution is able to capture the requisite ID to pass to the popup, and it selects the appropriate row after this ID is captured.
Have you considered saving the current position - like Me.CurrentRecord, then after the save reposition to the desired record. As an example, you could add a 'Before' or 'After' Insert to save the position, then later reposition. See the following:
Option Compare Database
Option Explicit
Dim lCurRec As Long
Private Sub Form_AfterInsert()
lCurRec = Me.CurrentRecord
Debug.Print "After Insert, Current: " & Me.CurrentRecord
End Sub
<<< YOUR SUB>>>
DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, lCurRec
This code will work when adding a new record as well as when editing an existing record:
Private Sub chkOperationsAndMaintenance_AfterUpdate()
Dim c As Long
Me.Dirty = False
If chkOperationsAndMaintenance Then
DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog
c = Me.CurrentRecord
Me.Requery
DoCmd.GoToRecord , , acGoTo, c
End If
End Sub
I am guessing that your popup form does things that are specific to Operations & Maintenance, and does not change the values of any of the checkboxes on the main form. If this is the case, you don't need a Requery at all, and the code can be simplified:
Private Sub chkOperationsAndMaintenance_AfterUpdate()
Me.Dirty = False
If chkOperationsAndMaintenance Then
DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog
End If
End Sub