MS Access Database form not updating after SQL requery - sql

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.

Related

How can I make a form instance open a specific record on creation?

I'm trying to optimize the performance of my access frontend. One of the problems I'm stumbling on is how to set a multi-window form to open immediately to a specific record, because at the moment it queries everything twice.
Essentially, I allow my users to open multiple instances of a form. That way, a user can compare multiple records by placing the windows of those forms side by side.
At the moment, my code looks like this:
Set frm = New Form_Name
frm.RecordSource = "select * from Table where id = " & ID 'ID is a variable passed to the method
I'm pretty sure back then this question was one of the building blocks I relied on.
The problem is that on the first line, access already entirely opens the form and does everything the form does when opening, such as Form_Open, Form_Current, and loading subforms. Then, when I set the recordsource, it does all (or most) of that again, which significantly slows down the process of opening the form.
Here are some of the things I've tried:
Changing the Form_Current to recognize that it's being "used" twice and only actually run the code once. The problem is that the code is already very optimized and doesn't seem to be the bottleneck, so this doesn't seem to do much. Actually opening the form seems to be the bottleneck.
Trying to change the properties of the original form so that it opens the specific record I need, but I can't seem to change the properties without it opening the form.
Looking for a way to supply arguments to the form. That doesn't seem to be supported in VBA.
One other idea that popped into my mind was creating a variable in vba with the ID of the record, setting recordsource in the form properties to fetch that variable, but then, when I would open another form and change that ID, the form
I realize that I can do this with DoCmd.OpenForm, but that doesn't give me the option to open multiple instances of the same form.
How can I achieve this? This would mean a significant performance improvement.
OK, so I actually wanted to ask this question. But just before I hit the submit button, I had an idea...
Here's the idea: you set a global variable in VBA, which you then access in the form filter command. In my case I just added Public OpeningID As Long at the top of my VBA module. Then I create a function to get that value:
Public Function getFormID() As Long
getFormID = OpeningID
End Function
Then, in the form, you can set the filter criteria as ID = getFormID(). And then when you open the form instance, you do it like this:
OpeningID = ID
Set frm = New Form_Name
OpenindID = 0 'reset this to make sure that if it's being accessed when it shouldn't, it generates a clear error
The only problem is what happens when you refresh the form, as that will call the method again. When you refresh the form via VBA, you can set the OpeningID beforehand, and to avoid users refreshing the form, you can add this to your form (don't forget to turn on Key Previews in the form settings):
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyF5 Then KeyCode = 0
End Sub
Bang. Forms open almost twice as fast. Awesome.

MSAccess VBA: Pass values from a subform to a seperate form

I have a form frmDetail that contains several locked fields I want populated only when another form has been filled out, in the name of having some kind of standardization in my data. This other form frmSignOut is used to enter in a date and location that will populate the fields on frmDetail. frmSignOut also contains a subform subULookup that looks up users from a different table using an identifier number. The resulting last name, first name and phone # should also be passed to frmDetail. I also hope to combine first and last name somehow into a Last,First format.
My approach so far has been to open frmSignOut modally with acDialog and I inserted Visible=False into the On_Click event on frmSignOut. Then I try to reference my subform fields and set them to the desired fields on frmDetail. I finish by refreshing and then closing the dialog form.
Private Sub CmdSignOut_Click()
DoCmd.OpenForm("frmSignOut"),,,,,acDialog
If CurrentProject.AllForms("frmSignOut").isLoaded=True Then
Set Forms!frmSignOut!SubULookup.PhoneNbrTxt=Me.ContactNbrTxt
DoCmd.Close (acForm), ("frmSignOut")
Me.Refresh
End If
End Sub
I have only been able to get this far, trying to pull the first field PhoneNbrTxt. I can get frmSignOut to open, I put in data and when I click my 'close' command button I get run-time error 438: Object doesn't support this property or method.
The line highlighted is where I try to reference my subform field. I also have a 'Cancel' button added to frmSignOut that just closes the form, I have no errors there.
Again I'm completely new to Access without much prior experience in anything related, I'd appreciate any knowledge you guys can throw at me.
EDIT: I've been able to successfully pull the value to Me.ContactNbrTxt by adjusting my code to the below.
Me.ContactNbrTxt = Forms!FrmSignOut!SubULookup.Form!PhoneNbrTxt
It looks like the missing part was the Form! right before the control name, along with formatting this correctly and dropping Set.
Im still trying to work out how to combine first and last name before also pulling those to frmDetail, if anyone can help there.

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

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?

Creating a form where user inputs start and end dates of a report

I am working on MS Access 2007.
I am trying to create a form where the user will input 2 dates - a start date and an end date. I want these dates to become the boundaries of a report.
For example if the user inputs 01/03/14 and 10/03/14, I want Access to create a report of the data (eg Selling Price) between these two dates.
How can I do this?
There are a few ways to perform this.
The easiest, and most straight forward, in my personal opinion, involve creating a form where the user(s) will be entering Start/End dates, using a query that captures all of the information necessary for your report (including your date parameters), and the report with your query as the recordsource.
Form
Create a form with 2 text box controls: Name them whatever you like (StartDateTxt, EndDateTxt, for example), and a button control.
Query
Now, create a query, that retrieves all of the correct information you need for this report. I know you said selling price, for starters.
For the date fields you want to narrow down your search by, you need to put them in the WHERE clause or the Criteria field in QBE. It might look something like:
[Forms]![YourFormName]![StartDateTxt] and [Forms]![YourFormName]![EndDateTxt]
Note: Referencing fields can sometimes be tricky.
Report
Next, you need to create a report. If you're new to this, you can use the Report Wizard located at: Create - Reports section - Report Wizard.
You can select your query from the dropdown list on the first prompt, and add the fields you desire/need. Click next: Here you can sort your order of appearance on the report. Click next: Then you can justify your layout - if you aren't familiar with the differences, you can play around with them. Click next: Select a 'theme' to be applied to your report (font/colors, etc). Click next: Then you can either preview the report or Modify the report's design. (Really, you can do either, by clicking either button and clicking print preview or design view.)
If you click on Preview the report - Access should ask you for any parameters your underlying query requires.
Back to the form.
Right click on your button control. -> Properties -> Event -> OnClick -> click the [...] icon to the very right of the row. Select code builder.
VBA
In-between Private Sub and End Sub, you're going to write
DoCmd.OpenReport "YourReportName"
You can also check to make sure your report isn't already open.
Dim ReportName As String
ReportName = "YourReportName"
If CurrentProject.AllReports(ReportName).IsLoaded Then
DoCmd.Close acReport, ReportName
End If
DoCmd.OpenReport ReportName, acViewPreview
I hope this helps you/answers your question.
Edit: If anyone wants to edit/add on to this either by means of clarification or another alternative approach, please feel free. Just let me know.

Microsoft Access 2013 Form Objects

I have a database that was create in Access 2010. We recently updated our systems to Access 2013. In Access 2010 I have no errors accessing a form object with
Form_frmName.txtFieldName.Value
However, when using Access 2013 I get a runtime 2424 error stating that "The expression you entered has a field, control, or property name that Microsoft Access can't find. I am accessing from a module.
The module sets these fields visible using
With Form_frmName
.txtFieldName.Visible = True
End With
before attempting to access them.
Has there been any changes in the way form objects are accessed between 2010 and 2013? Is this an issue others have faced?
In Response to #WayneGDunn's questions below
QUOTE:
I need to know exactly what and how you are using this.
1. You have a bound textbox named 'txtFieldName' on a form. As #brad asked, is there a subform, and if so, is this field on the subform?
2. You said the code is in a module, but is the code in the form where the field is defined?
3. Please explain where/what form 'frmQAtab' is (you said your form name was 'frmName', so what is the other, how related?)
4. Is the code in an event? Can you share the entire subroutine?
5. Have you tried creating a dummy query and using the builder to reference the field?
RESPONSE:
1. I have a form (frmMain) with multiple tabbed pages. frmName is one of those tabs, containing the bound field txtFieldName.
2. The module is run from the form the field is in.
3. My apologies frmQAtab is frmName, I just neglected to make that generic in my copy-paste.
4. The event is a button click. The button click runs a sub from a module. That sub makes visible the fields, runs a query based on user input (two date fields), populates the bound fields with the returned record set, then attempts to access them for processing (another query is run to process a complete other set of fields). To post the entire subroutine would be a bit more than I would ask you to chew on. This is legacy code I'm trying to fix, and it's rather large.
5. I have not tried a dummy query. Access is not my field (I'm mainly a C#, scripting, guy.) Is there some suggestions in this area you could give?
One of the following references to your fields should work. I created a form (named 'frmMain'), then created a Tab Control with two tabs. On the first tab, I inserted another form (named 'frm3197'). I also created a text box on the tab control named 'txtFieldName' AND in form 'frm3197'. From a button click on 'frmMain', the following will reference each of those fields.
Private Sub cmdButton1_Click()
Forms![frmMain]![txtFieldName] = Now()
Forms![frmMain]![frm3197].Form![txtFieldName] = Now()
End Sub