Can't Go To Specific Record on Continuous Form in MS Access - vba

Searched and searched and cannot find a solution to this. I have a form with many continuous form subforms. When I change a value in, lets say FIELD_A on one of the subforms, I run calculations on several other subforms, then the focus returns to FIELD_A. However, during the calculations an update to the PARENT form happens, and needs to happen. So, when I return focus to the original subform, the first record on my subform has the focus. I need to then go to the record I was working on.
I've tried several options, but nothing works. However, if I set a DEBUG breakpoint at the line in the code where it moves to the specified record, then physically RUN the code from that line, it works! I've tried setting a wait period in there to no avail.
Here's a snippet of the code:
Call common.CalculateAllLoadTotals _
(Me, Me.AffiliateID, Me.ClientID, Me.FacilityID, Me.ProposalRevision)
Me.Recordset.FindFirst "[AffiliateID] = '" & Me.AffiliateID & "'" & _
" AND [ClientID] = " & Me.ClientID & _
" AND [FacilityID] = " & Me.FacilityID & _
" AND [ProposalRevision] = " & Me.ProposalRevision & _
" AND [EquipmentID] = " & currItemID
I also tried this:
dim currRecord as Long
currRecord = Me.CurrentRecord
' >>> REST OF CODE HERE <<<
Call common.CalculateAllLoadTotals _
(Me, Me.AffiliateID, Me.ClientID, Me.FacilityID, Me.ProposalRevision)
Me.Form.Recordset.Move = currRecord
As I said, the code works (either one) IF I pause it with a debug then continue executing. Strange.

Sorry that's will not be a complete answer but it is quite lot for a comment.
Regarding your first solution - I'd advise you to try Me.Recordset.Requery
to refresh current record in the main form without moving position.
Regarding you 2nd option - I'd advise to have a look at bookmarks - before update remember bookmark, make some calculations and then move position to the saved bookmark. Something like this -
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[MyPK]=" & Me!cmbFindByPK
If Not rs.NoMatch Then
If Me.Dirty Then
Me.Dirty = False
End If
Me.Bookmark = rs.Bookmark
End If
Set rs = Nothing
taken from here Why clone an MS-Access recordset?

I suspect you are updating the recordset underlying the parent form. This causes the parent form to automatically requery, hence the subform position returning to the first record.
The solution is to update the controls on the parent form instead:
Me.Parent!Controlname = XXXX

Related

Setting Form Field to autopopulate with previous record entry for text, date, and combo box

I am still very new to most vba coding. I'm trying to do pretty much the exact same thing as with this post:
Microsoft Access Form Setting Default Value to Previous Entry for Both Text Boxes and Drop Down Lists
but nothing from it seems to be working for me. I want to populate each field in the form with the previous record's data via a button Autofill_Click()
Private Sub Autofill_Click()
Me!DateTimeID.DefaultValue = Me![DateTimeID].Value
Me.frmDate.DefaultValue = "#" & Me.frmDate & "#"
Me.Location.DefaultValue = "'" & Me.Location & "'"
End Sub
I'm receiving the error code "type mismatch" for the first line with DateTimeID, as well as an error code "There is an invalid use of the . or ! operator or invalid parentheses." for the second line with frmDate. The third line isn't even throwing an error code, but it isn't populating the desired field (or any field, for that matter) with what I want.
Any help would be much appreciated.
For text:
Me.[DateTimeID].DefaultValue = "'" & Me.[DateTimeID] & "'"
For date/time:
Me.frmDate.DefaultValue = "#" & Me.frmDate & "#"
For number:
Me.Quantity.DefaultValue = Me.Quantity
Code is usually put in control's AfterUpdate event so user doesn't have to do anything other than normal data entry/edit.

update table through form

This is the next attempt I am making at solving this problem. In my timeline is the prior attempt.
I have three tables BOAT, BERTHAGE, LOCATION. These tables are joined in the following way in a query called Boat_Move
BOAT(boat_ID) joins to BERTHAGE(boat)
LOCATION(Loc_ID) joins to BERTHAGE(location)
This query is viewed on the form as a subform.
When the form opens up I will highlight the vessel which needs to have its location moved/updated
Once highlighted in the subform I click the edit button
Private Sub cmd_Edit_Click()
If Not (Me.Current_Week_Boat_Move.Form.Recordset.EOF And Me.Current_Week_Boat_Move.Form.Recordset.BOF) Then
With Me.Current_Week_Boat_Move.Form.Recordset
Me.txt_Boat = .Fields("BOAT_NAME")
Me.txt_Cur_Loc = .Fields("LOCATION")
Me.txt_Cur_Flo = .Fields("FLOAT")
Me.txt_Cur_Doc = .Fields("DOCK")
Me.txt_Cur_Ori = .Fields("ORIENTATION")
Me.cmd_Add.Caption = "Update"
Me.cmd_Edit.Enabled = False
End With
End If
End Sub
This puts the appropriate information into the text boxes.
I've also did up the following with the idea that this would update the location(field) in the BERTHAGE(table)
Private Sub cmd_Add_Click()
Dim strSQL As String
strSQL = "INSERT INTO BERTHAGE(BOAT, LOCATION)" & _
" VALUES(" & Me.txt_Boat & ",'" & Me.txt_Cur_Loc & "');"
CurrentDb.Execute "UPDATE BERTHAGE " & " SET LOCATION=" & Me.txt_Cur_Loc & _
" WHERE LOCATION=" & Me.txt_Cur_Loc
Current_Week_Boat_Move.Form.Requery
cmd_Clear_Click
End Sub
I'm not sure if in this instance I should be creating a new table to make the update and then overwriting the older table. The issue I see here is the older table is at around 24k records so that doesn't seem like the best way forward.
So at this point I'm facing two problems, and I am unsure if solving either one will solve the actual problem of updating the BERTHAGE(location) field.
View of the from
Any help is appreciated.

When setting user permissions to open up a particular form for a particular user I am getting a Runtime error from the DLookup statement

I am trying to restrict the availability of a form to be opened by a user. the following code picks up on the correct user access type and the correct form name, however i am getting the runtime error 2471. I would appreciate some help here as i cannot see what is wrong?
The error statement in this case is: Run-Time error '2471': The expression you entered as a query parameter produced this error: 'Stock'. When i go to debug it brings me to the DLookup and i cannot see what is wrong.
Watch expression:Watch : : "Employeeaccesstype =" & cable & " " & "AND FormName=" & thisform : "Employeeaccesstype =0 AND FormName=Stock" : String : Form_Stock.Form_Load
Private Sub Form_Load()
Dim cable As String
cable = TempVars("AccessType")
Dim thisform As String
thisform = Me.Form.Name
If DLookup("Hasaccess", "tblemployeeaccess", "Employeeaccesstype =" & cable & " " & "AND FormName=" & thisform) = False Then
DoCmd.Close
MsgBox "You Do Not Have Access"
End If
End Sub
All help will be most appreciated as i am on a deadline to finish this
If your fields Employeeaccesstype and FormName are text, then the values in the Dlookup need to be wrapped in single quotes. Additionally, you should cater for the possibility that the record doesn't exist in the table (returning a Null value from the DLookup):
If Nz(DLookup("Hasaccess", "tblemployeeaccess", "Employeeaccesstype ='" & cable & "' AND FormName='" & thisform & "'"),False) = False Then
You should also consider not actually allowing them to open the form in the first place.
Regards,
I changed tack here and went for a different approach. I created a new table to hold user login details and a query to join details on tables and referenced that on the Dlookup rather than trying to reference the login form through a variable. Witth those changes made i changed the DLookup to
If DLookup("Hasaccess", "AccessQuery", "HasAccess =false and Formname = 'Part' ") =
False Then
DoCmd.Close
MsgBox "You Do Not Have Access"
End If
This is now working correctly. Many thanks o Applecore for the assistance with this problem

vba functions malfunction after repetitive calling

I have a database where data goes through multiple steps, and user can report and 'solve' those errors in the database.
Once an error is added in my tbl_errors, they go on and solve it. Once they have solved the error irl, the 'solve' the error in the database as well, to keep track of time and such.
This all works like a charm, when adding errors I have never encountered any problems. And at first sight, 'solving' the problems goes flawless either. The problem however, is that once I start 'solving' a lot of errors in a row, my code suddenly stops working.
It does not freeze or throw back any errors, and when I step through the code using my breakpoints and f8, all the variables seem to be correct also. Everything goes on just as always, except it just does not do anything anymore. This is only applicable to that specific error. When I add new errors, and try to 'solve' them. It works just as usual.
Important notes:
This ONLY happens when I start fast clicking on my solve button, thus calling the functions real fast behind eachother.
It only freezes for a specific errors. (Can be multiple) All other errors can be solved as usual, indicating that the code is still functioning.
I have stepped through the whole code, while checking all the keys and variables and every variable is correct.
Even though my code goes through the recordset, it does not update anything?
Below is a piece of my relationships screen to give a better understanding of the table structure, as well as the specific parts of code.
Calling the code in the OnClick event:
Private Sub solve_Click()
SolveError getorderid(gvStepDelivery), get_errorID(gvCategory, get_stepsID(gvStepNr))
Me.qry_errors_subform.Requery
Me.Refresh
End Sub
The self-written function SolveError:
Public Function SolveError(Current_order_ID As Long, Category_ID As Long)
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("tbl_errors", dbOpenDynaset)
With rs
.FindFirst "[Error_ID] = " & DLookup("Error_ID", "tbl_errors", "[Current_orders_ID] = " & Current_order_ID & " AND [Category_ID] = " & Category_ID)
.Edit
![Solved_By] = get_user
![Solved_Date] = Date
![Solved_Time] = Time
.update
End With
rs.Close
Set rs = Nothing
End Function
There are other parts of code involved (See the SolveError's parameters), but I don't think they will add some usefull info, since they are just returning the correct values. (They are correct!!)
Ok, it seems I have already found my answer. Since I was probably calling a new iteration before the previous one had completely finished, it simply stopped working. Adding the DoEvents function at the end my SolveErrors function solved it. I have yet to experience the problem again.
Public Function SolveError(Current_order_ID As Long, Category_ID As Long)
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("tbl_errors", dbOpenDynaset)
With rs
.FindFirst "[Error_ID] = " & DLookup("Error_ID", "tbl_errors", "[Current_orders_ID] = " & Current_order_ID & " AND [Category_ID] = " & Category_ID)
.Edit
![Solved_By] = get_user
![Solved_Date] = Date
![Solved_Time] = Time
.update
End With
rs.Close
Set rs = Nothing
DoEvents 'This one did the trick!!
End Function
Info on the DoEvents method can be found here: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
and here: http://office.microsoft.com/en-001/access-help/doevents-function-HA001228827.aspx

Open new instance of a form based on data in field of first form

I have a data entry form where the data clerk enters client ID among other things. Client ID's are unique to each client. I am currently trapping for duplicate ID's and allowing the clerk to go to the search form and seach for the duplicate ID to verify that it is indeed the same person and not an error inputting data. I would rather open a new instance of the data entry form based on the client ID inputted into the data entry form. I can open a new instance but am not sure how to make it display the client data based on the client ID.
There is no good way to do this except to just turn off the screen painting. Here's some code from one of my apps:
Dim frm As Form_frmInventory
Dim strRecordsource As String
Dim intType As Integer
DoCmd.Hourglass True
Application.Echo False
Set frm = New Form_frmInventory
frm!boxHeader.BackColor = 3276900 ' 5483007
frm!boxFooter.BackColor = 3276900 ' 5483007
strRecordsource = "SELECT qryInventoryForm.*, varZLStoNull(IIf([tblInventory].[InventoryClass] In ('BKS','FAC','MTH','MUS','REF','SSC'),[Creator] & [Dates] & OtherAuthors([OtherAuthors]))) AS BibCreator, CreatorDates([Birth],[Death],[OtherAuthors]) AS Dates, varZLStoNull(Trim(nz(UCase([tblBib_Authors].[LastName]) & IIf(Not IsNull([tblBib_Authors].[FirstName]),', ') & [tblBib_Authors].[FirstName],'Anon.'))) AS Creator, tblBib_Authors.CreatorCategories, Nz([CreatorSort],[LastName] & [FirstName]) AS NameSort FROM qryInventoryForm LEFT JOIN tblBib_Authors ON qryInventoryForm.CreatorID = tblBib_Authors.CreatorID WHERE ([quantity]>0 Like getSold()) AND (qryInventoryForm.InventoryID=" & lngInventoryID & ") ORDER BY Nz([CreatorSort],[LastName] & [FirstName]), InventoryClass, ShortTitle;"
frm.RecordSource = strRecordsource
' need to change the caption and disable certain things
frm.Caption = frm.Caption & " -- " & frm!InventoryClass & "-" & Nz(frm!InventoryNo, Format(frm!InventoryID, "00000"))
frm!fldShortTitle.SetFocus
frm!cmbClassFind.Enabled = False
frm!cmbCreatorFind.Enabled = False
frm!cmbInventoryNumber.Enabled = False
[etc.]
frm.Visible = True
GoTo exitRoutine
CloseForm:
Call CloseForm(Me, True)
exitRoutine:
Application.Echo True
DoCmd.Hourglass False
Exit Sub
The CloseForm() sub is pretty important, as you have to keep track of multiple instances of the form and close the right one. I got the code from the ADH97 and adapted it from there (just the basics).
It would appear from that code (I've forgotten the details) that a form instantiated with Set frm = New Form_frmInventory is not visible until you explicitly reveal it. That's a plus, as it should mean that you don't have to turn off the screen (i.e., Application.Echo False), but I'm pretty sure that I recall needing it anyway to make things appear smoothly. My memory is that the form would appear with its normal colors and then the background colors would change visibly as the code ran. This means it was visible, so I'm not sure why it's necessary to then explicitly set the form visible.
Anyway, that should get you started, I think!