MS Access will occasionally remove checkboxes from my Yes/No fields and replace them with 0 and -1 - vba

My new database is built using a variety of queries and tables. These tables and queries have two checkbox fields that are set for "Test" and "Approved". The way that these come into play is that I have buttons on one form called "ApprovalForm" that open up another form called "ViewForm". The goal was that "ViewForm would change its subform's source object every time one of these buttons is clicked. ApprovalForm closes itself first, then ViewForm opens, then Subform.SourceObject is updated to the query specified by whatever button was clicked.
Private Sub View_NonSize_APL_Click()
On Error GoTo View_NonSize_APL_Click_Err
DoCmd.Close acForm, ("ApprovalForm")
DoCmd.OpenForm ("ViewForm")
Forms!ViewForm!View_Subform.SourceObject = "Query.NonSize - APL View"
Forms!ViewForm!View_Subform.Form.Requery
Forms!ViewForm.Form.Requery
Forms.ViewForm.Caption = "NonSize - APL View"
View_NonSize_APL_Click_Exit:
Exit Sub
View_NonSize_APL_Click_Err:
MsgBox Error$
Resume View_NonSize_APL_Click_Exit
End Sub
With the process finished, the final result should be that the fields are populated by the query, which is looking at a table off on the side. The user has no access to the table itself, just that specific select query. However, in rare occasions, the checkboxes will not load correctly, instead displaying as 0s and -1s. What is peculiar about this is that when you click the button on "ViewForm" that leads back to "ApprovalForm" and click the same exact button AGAIN, the checkboxes load correctly.
My guess is that it has something to do with how "ViewForm" loads in, and due to it being a business project, the computer that it is working on is less than optimal. I tried to remedy the situation by using "Requery" and "Refresh" in the code to hopefully reload the process. I have also tried the cumbersome route of having the form close after being loaded and immediately reloading again. (Open the form, load its query, close the form, then open the form again.) That actually proved to ruin the entire process.
Is there anything I can do to counter this problem?

Related

Button to check for missing values in a MainForm and Subforms in MS Access

New to Access (still), have only basic VBA skills.
I've got 3 subforms (subfrm_PackingSteps1 , subfrm_MetalDetection and subfrm_Weights - the first 2 are continuous and the other one is single form) within a main form (frm_daily_packing_record) that users go through and input data. The user should be able to input data in no particular order, and only at the end there would be a button to confirm that the user is ready to save this form.
I'd like to have this button on the main form that checks each control (in main form and subforms) for empty values. I found and adjusted a code to check the recordset of one of the continuous forms (see below), but I can't figure out:
how to include a code that checks each control instead of manually adding all of them (I've used a function before that utilises the Tag property, but can't add it to this)
how to keep the button in the main form while checking the controls/recordsets in the other subforms.
Thanks in advance.
Private Sub ConfirmBtn_Click()
Dim blnSuccess As Boolean
blnSuccess = True
Me.Recordset.MoveFirst
Do While Not Me.Recordset.EOF
If IsNull(Me.pc) Or IsNull(Me.InnerP) Then
blnSuccess = False
Exit Do
End If
Me.Recordset.MoveNext
Loop
If blnSuccess = True Then
MsgBox "You may proceed to save this record"
Else
MsgBox "You still have some empty fields to fill in!", vbCritical + vbOKOnly, "Empty Fields!"
End If
End Sub
I personally don't like this because it is too code-heavy and can easily break when the form is modified.
Instead may I suggest doing it slightly different, for each field have vba code .ondirty or .onupdate and do the validation checking right as the user is actually on that field.
This has 2 benefits, it is creating the validation when you are creating each form field and it STOPS the user right when their first mistake or bad data is entered. The last thing I want is to enter 50 fields, scroll to the bottom, submit fails then scroll back and try to find where the mistake was. If validation is done while the user it doing the actual data entry, when you get to the bottom you should have valid data and the submit should succeed without further testing.
Less code to debug and timely messages to the user if an error is caught!

Why does MsAccess Record entry only Update (and show in table) after form close and reopen?

Some Background:
I have a database that acts as a ledger (keeps tabs on current payments).
1:Payments for each customer are stored in one table (PaymentTbl),
2:I have another table (TermAgreementTbl) that holds information on the agreed terms of the service
3: My last table (PdUpToTbl) takes the payment information as well as term agreements information from the two other tables and calculates/displays the information in a clearer manner. One of the ways it will do this, is by deleting the last record in PdUpToTbl, and replacing it, or by just adding a new record (case dependent).
Now MY Issue:
I have a form for my TermAgreementTbl that has a subform showing the relevant PdUpToTbl.
A button opens a pop-up form to enter a new payment and update the related PdUpTotbl.
Everything in the back end is functional, however after I enter a new payment (and save and close the pop-up payment form), NO new record is shown in my PdUpToTbl Subform. Instead it shows something like (some irrelevant info redacted):
For the new record to display properly, I have to close the entire form, and reopen it. There has got to be a way to get around this through vba with some code, right?
Thank you for taking the time.
Edit 1:
By the way, after I perform A LOT of vba code, I use this to enter my record:
With pdUpToRS
.AddNew
![DatePaid] = NewRecordSet.Fields("DatePaid").Value
![Amount] = Amount
![AppliedAmount] = AppliedAmount
![OnAcct] = OnAcct
![AllPdUpTo] = AllPdUpTo
![RemainBalDue] = RemainBalDue
![PdUpToString] = PdUpToString
![PaymentType] = NewRecordSet.Fields("PaymentType").Value
![PaymentNumber] = PaymentNumber
![ID] = NewRecordSet.Fields("ID").Value
![PmntTblID] = PmntTblID
![BdCk] = BdCk
![Late] = Lte
![ApplyDiscount] = ApplyDiscount
![ForgetUnderage] = ForgetUnder
![ForgetOverage] = ForgetOver
![Note] = Note
.Update
End With
Update using requery
I have tried to Requery using:
Forms![MainForm]![Subform].Requery
But it gives me the error:
2118 - - - You must save the current field before you run the Requery action.
And if I add the save line:
DoCmd.RunCommand acCmdSaveRecord
Forms![MainForm]![Subform].Requery
I get the resulting error:
2046 - - - The command or action 'SaveRecord' isn't available now.
Ok, the docmd "menu" options to save a record?
They OFTEN run on the form that has the current focus - so often, then the form you want to save is not the one you expected.
I suggest you replace this:
DoCmd.RunCommand acCmdSaveRecord
with
if me.Dirty then me.Dirty = false
Now, above above "me" is is the current form WHERE that code is running, not some form that might happen to have the focus.
Now, as for a form "requery" (to refresh without close then re-open)?
Again, assuming the above just did the save of the data, then to force a re-load of the current form (again, the form in which the code is running), then:
me.Requery
In fact, if you did not have multiple sub-forms, then a me.refresh would probably work (and a me.Refresh will also save the current record).
So, while the if me.dirty = true then me.dirty = false is about the best way to save the current reocrd in the current form where the code is running?
It is a question of where your code is running, and often when the code is running.
In place of the me.dirty = false, you can also do this, but it often will cause a lot more flicker and refreshing then you want.
But, the shortest code to ensure a save of the forms data, and then requery (same as form close then open), would thus be this:
Me.Refresh
me.Requery
However, often issues can arise if you have some dialog form open - so perhaps a closer look at how your code is updating is often imporant.
But, a me.Requery will re-load everything, but you of course want to ensure you force record saves of the data first.
I think the Requery function will serve you well.
https://learn.microsoft.com/en-us/office/vba/api/access.subform.requery

Macro in form stops working after opened with vba

Please help me explain, why this happens, after that the solution should be easy :)
I have two forms, showing different data.
Form_1: there is a combo box (with names in it), where you can choose which company you wanna see, and an after-update macro searches the record (an [ID] field), and shows the information. (To be more complicated, this [ID] field is hidden, and used for subforms, where the actual infos appear.)
Form_2: this is a continuous form, each record is in connection with the companies shown in Form_1, but several record can belong to one company. There is a button for every record to open Form_1 with the information connected to it. The vba code of the button is:
Private Sub Button_Click()
DoCmd.OpenForm "Form_1", , , "[ID] = " & Me![ID]
End Sub
In the code, the same [ID] field is used, as described above: hidden and used for subforms.
Both forms are working as needed, I am happy with them.
But after Form_1 is opened from Form_2 with the button, the combo box remains empty (actually I don't need it to be filled), and if I wanna use it to search for other items, it doesn't work, as if the macro wasn't loaded. The list of names appear, I can click on any of them, but the [ID] field is not refreshed (and of course neither the subforms). I have to close the form, and open it again from the side-list.
Why does the macro stop working?
What should I change, to make it work?
Thanks for your help!
Form1 has the filter turned on to a specific key value, so attempts to find and reposition the form's current record will fail without explicitly resetting the filter.
The Where condition of the OpenForm command does not change the form's Record Source property, nor does it perform a simple search/reposition. Rather, it applies a form filter:
DoCmd.OpenForm "Form_1", , , "[ID] = " & Me![ID]
This state is indicated in several ways
On the Home ribbon (i.e. toolbar): The Toggle Filter button is active... is highlighted by a different color.
The form's navigation bar at the bottom of the form show "Filtered" highlighted with a little funnel icon.
The Access status bar shows "Filtered" on the right near other indicators.
Of course it's possible that all of those indicators are hidden, so you just need to be aware of what each command and parameter does.
Possible solutions:
Form1's ComboBox.AfterUpdate macro should turn off the filter before searching for a new ID value.
Form2's Button_Click event opens the form without applying a filter and instead runs code that does the same thing as the ComboBox.AfterUpdate method--searches and repositions the form's record rather than filtering it.
This can be achieved in multiple ways and is largely beyond the scope of this answer, but a hint is to make a Public method in the Form1 module that performs the search. Both the ComboBox.AfterUpdate method and the other button call that same public method so they have the same behavior.

MS Access Database form not updating after SQL requery

I have a report that runs from a query. The query does use a global variable but this is not the problem but needed for the explanation. The function for the variable is:
Function Var1() As String
Var1 = strVar1
End Function
The query where statement is:
WHERE (((IIf([MinOfDueDayMin]<0,0,Int([MinOfDueDayMin]/7)+1))<Var1()+1) AND ((tblEquipment.Retired)=False))
which uses the var1 function
The criteria is on a field that is actually a calculation and that is where I think the problem starts.
The report is run for a command on another form using the following code:
strVar1 = InputBox("Enter Number of Weeks for report")
If strVar1 = "" Then Exit Sub
DoCmd.OpenReport "rptEquipPmSchedule", acViewReport
Everything works just fine
On the report I have a double click event that opens a form. This form uses part of the same query. (not the same one but two levels higher) thiS allow the user to change things so i expect to use requery for the report.
If i double click and then not even change anything and then go back to the report I have #ERROR in the fields that have the calculations
i put a me.requery in the activate event of the report. this did not work.
So I tried a work around.
When I double click the report field, i close the report and send the strVar1 value to the form that is opened. then when I close the form I reasign the strVar1 just in case it is lost be an assignment by another user (currently I am the only one using this but did it just to be sure it had the correct value.) Then I open the report again but still get the errors. I did not expect this at all. thought starting the report from scratch would certainly work. I even closed the form just after assigning strVar1.
then in final effort. When I close the form I run the exact same code:
strVar1 = InputBox("Enter Number of Weeks for report")
If strVar1 = "" Then Exit Sub
DoCmd.OpenReport "rptEquipPmSchedule", acViewReport
Which will force the user to input the value for strVal1. Even though this is not what I want but tried this for troubleshooting and I still get #ERROR.
When I run the report for a form that does not have any of the same field, no issues. When I run the report or keep it open with a requery from the form that has the same data, the report will not give the correct results. Note that if I run the query itself, the data in the query is correct.
i also tried using a number instead of Val1() in the query and got the same results.
i also tried the refresh button in the ribbon and get Unknown Function Name and all the data in the report is lost.
Anyone got any ideas??
While your textual explanation is difficult to understand the entire scope, consider re-assessing your workflow. The entire objective is to allow users to run customized criteria for reporting. And your main issue is the strVal does not persist in memory so all references to it fails.
Consider the following points:
Have users set criteria on a dedicated unbound form with button click for report where that report instance is immutable for viewing/printing only and if needed to be changed must be re-run (i.e., button re-clicked).
Access has no need for VBA's InputBox() as strVal can be an unbound textbox on this unbound form whose value remains intact for all open windows.
Have function and all its references point to form field: Form!myFormName!strValuetextbox
Because reports on pretty much any software/web app system is not used as a GUI interface to run actions, users will know if they intend to change report criteria, close current report or go back to entry point and change strVal then re-click button to re-run report.
Keep data entry/input (primary use of forms) separate from data export/output (like reports). From developer and user standpoint this compartmentalization will save you headaches down the road.

How to determine which subform has focus

I have a Form that contains several subforms. On one of the subforms, I need to run an update query if you click off to another subform (you finished with the controls, if anything changed it must update). This part works great. The trouble I am having is I don't want to bog everything down by running the update (its a loop of update queries) every time you click on any subform.
If you are on a very specific subform (PageIndex 2) then it should run the updates. Below is the code I have to determine which tab/page/subform I am on. PlanSpecs is the name of the Page.
The problem is that no matter what tab I am current on, if always says "I'm on that subform." Any idea why that might be, or any suggestions as to what I can do instead?
If (Me.PlanSpecs.PageIndex = 2) Then
MsgBox ("I'm on that subform")
Else
MsgBox ("Different Subform, move along")
End If
I don't think you can refer to them by that index, unless they're in a tab control, then you'd have the PageIndex property.
You can however do it like this,
If (Screen.ActiveControl.Parent.Name = "SubFormNameHere") Then
MsgBox ("I'm on that subform")
Else
MsgBox ("Different Subform, move along")
End If
But this code may need additional conditions, for instance if you add a tab control to that subform, then it'll return the name of the TabControl and not the parent(form).
For additional reference