Clearing unbound data fields and running a query - ms-access

Background:
I have an access table called Tbl_Party, where the primary key is Party_ID.
I have a form (frmParty) to view the records in Tbl_Party, which displays all relevant fields and has several unbound text boxes. These unbound text boxes are used to filter records via a query I built which is activated b a button on the form. All this works fine.
Problem:
I have created a second button called Clear, which I want to clear all data from the unbound text boxes and re-run the query, which as the fields are now blank would return all records.
I created a sub routine in VBA to clear the data from the unbound text boxes which works fine when called from an event procedure:
Private Sub Clear_Click()
Me.txtBox1 = ""
Me.txtBox2 = ""
Me.txtBox3 = ""
Me.txtBox4 = ""
End Sub
The issue I'm having is combining this with re-running the query. I can only think of doing this via a Macro.
The RunCode option in a macro only lets you use functions. I have tried to build a function that calls the sub process, but functions built in the form code aren't recognised by the macro builder and I can't call the sub process from a function built in a module. I have tried building both the function and the sub (exactly as above) in a module, but it then tells me it can't find the fields.
Any ideas how to solve this issue?

Try:
Me.Requery
If the query itself is throwing an error now, probably because it contains an unvalid WHERE-clause try to modify the basic query like this:
SELCT ... FROM ... WHERE (1=1) AND (...here goes your txtBox-filtered string...)

Related

MS Access VBA: When opening a report, what event is triggered once the query that the report depends on has been completed?

I have a report that is dependent on a query. The report displays correctly but I'm trying to have a label's visibility dependent on a yes/no field in the query.
The following produces error 2424 that the field isn't found:
Private Sub Report_Open(Cancel As Integer)
lblUppersIncluded.Visible = ysnUppersIncluded
End Sub
Alternatively:
Private Sub Report_Activate()
lblUppersIncluded.Visible = ysnUppersIncluded
End Sub
Gives error 2427 expression has no value. Similarly for Report_Load.
However, a command box created on the report that executes the same line of code executes correctly.
I suspect that all of the Report events are triggered before the query has been run so those fields have not been populated. Is there an event that I can use after the query has been completed?
Sometimes the best way around problems like this is to convert your label to a text box and use conditional formatting. If your formatting needs are not met by what can be accomplished by conditional formatting then you can look into code.
Specifically for a label to be visible or not you don't even need conditional formatting. Convert to text box and use:
=IIF([My condition for visible label],"My Label text:","")
as its control source.
I've found that code dependent on the query fields will work if the Detail_Format event is used. This event is triggered in Print Preview view but not in Report View.

Can't get requery to work from form/subform

Background:
I am trying to add a new form to an old Access database that was created with Access 2003. Previous forms were based on tables, but the fields for the new form are based on a query.
I have a form called MasterList with subform MasterList_Sub. MasterList contains textboxes that I want to use to filter MasterList_Sub, along with a search and clear button. MasterList_Sub is displayed beneath.
I modified the VBA for the search button from the other forms, but it does not seem to work. Here is the code from a working form:
Private Sub SEARCH_Click()
Forms!mrtgref!Mrtgref_sub.Requery
End Sub
My code is simply
Private Sub SEARCH_Click()
Forms!MasterList!MasterList_Sub.Requery
End Sub
When I press the search button something appears to happen, but the subform does not update. I'm new to programming for Access, but based on what I've read this code looks too simple, like I'm missing something. I can't find any other VBA modules in the DB, and the fields are set up similarly to the other DBs. Any ideas on how to proceed from here?
Also, I've tried some other syntax, and when it doesn't work I get an error that starts with "Mortgagee Inquiry can't find..." Where is it getting the name Mortgagee Inquiry from?
MasterList_Sub is a subform control. .Requery is a method of the Form itself therefore you need to add .Form before .Requery.
The structure:
Forms!MainForm!SubformControl.Form.Requery
In your case:
Forms!MasterList!MasterList_Sub.Form.Requery

Cannot Get DLookup Function to work in Access 2013

I am trying to get the Dlookup function to work in Access 2013, but i just cannot get it to work, heres what i have so far :-
I have a query called qry_VehicleOverview in this query there are Two fields called VehicleNumber and DateLastExam
I have a form, there are a number of fields, two of them called Vehicle1 and DateLastExamV1, in DateLastExam1 ! am trying to reference the relevant exam based on Vehicle1 from qry_VehicleOverview field, so when a Vehicle Number is added to Vehicle1 it displays the correct Exam in DateLastExam1
first of all I create a combo box in the form, called Vehicle1 and referenced it to VehicleNumber from qry_VehicleOverview
then i created a text box in the form, and called it LastExamVehicle1, in the control source of this field I added the DLookup function :-
=DLookup("[DateLastExam]","qry_VehicleOverview","[VehicleNumber]=""" & [Vehicle1].[Text] & """")
Then chose After update in Event tab and Selected code Builder in here I added :-
Private Sub LastExamVehicle1_AfterUpdate()
Me.LastExamVehicle1.Requery
End Sub
but when run the form, first of all i get an error of #Type in the field, when i change the value in Vehicle1 the eror then changes to #Error
I create a combo box in the form, called Vehicle1 and referenced it to
VehicleNumber from qry_VehicleOverview
If that is so, there is no need for DLookup as you already have the value.
Set the RowSource of Vehicle1 to qry_VehicleOverview and the count of fields for the combobox to 2 and use this ControlSource for your textbox:
=[Vehicle1].[Column](1)
It will automatically update.
Don't use [Vehicle1].[Text], use [Vehicle1].[Value] instead. Or just [Vehicle1] .
(.Value is the default property)
.Text is only valid while the focus is in the control, and in AfterUpdate it isn't anymore.
.Text is mainly useful in the Change event, but that wouldn't make sense for your case.
Edit
You probably need the "full path" to the control in DLookup. For better readability I suggest using single quotes.
=DLookup("[DateLastExam]","qry_VehicleOverview","[VehicleNumber]='" & Forms!yourForm![Vehicle1] & "'")
Also please double-check all names in your form (and then in your question). E.g. from your description, your event procedure should read:
Private Sub Vehicle1_AfterUpdate()
Me.DateLastExamV1.Requery
End Sub

MS Access run code after a row is updated

I am very new to MS Access, forgive me for this simple question but I am very confused with my current problem.
So I want to run a VBA function after a table receives an update on one of its fields. What I have done is:
Create a Macro named Macro_update under CREATE->Macro, with action RunCode, and its argument is the VBA function I wish to run. The function has no bug.
Select my table, and under Table->After Update, I wrote
IF [Old].[status]=0 And [status]=1 THEN
RunDataMacro
MacroName Macro_update
But after I update my status field in my table nothing happened... I am suspicious of the fact that in step 2 my action is RunDataMacro, but I am actually running a Macro (is there a difference?)... any help is appreciated!
You can use a Data Macro to get it working locally for now. This means that the table will need to be stored in an Access database.
If your web service is not actually using the Access Runtime to interface with the access database container, then the data macros may not fire correctly nor as intended. Your mileage may vary.
If you later migrate your database to a SQL server (MySQL, Microsoft SQL, PostgreSQL) then your data macros will need to be implemented natively on the SQL server as a Trigger.
For now, I'm writing some instructions below to demonstrate how to call a VBA function from a Data Macro locally within a single Access database:
Create the VBA Function This will be the function that you want to call from the data Macro.
Create this in a Module, not in a Form or Class Module.
This has to be a function and cannot be a sub
Code:
Public Function VBAFunction(OldValue As String, NewValue As String) As String
Debug.Print "Old: " & Chr(34) & OldValue & Chr(34);
Debug.Print vbTab;
Debug.Print "New: " & Chr(34) & NewValue & Chr(34)
VBAFunction = "Worked"
End Function
Create the Data Macro (Going to be more descriptive here since people get lost here easy)
Open the Table (i.e. TestTable) in Design View
Find the correct Ribbon
In table design view, there is a contextual ribbon called Design.
On that ribbon, there is an option called Create Data Macros
Click on Create Data Macros and select After Update
The Macro Designer window should now open
Choose SetLocalVar from the Add New Action combo box
A SetLocalVar section appears.
In this section, I see Name and Expression
Set Name to an arbitrary value, such as: MyLocalVar
Set Expression to the following
Be sure to type the = sign, which will result in two equal signs being shown
Expression Text:
=VBAFunction([Old].[FieldName],[FieldName])
Save the Data Macro and Close the Macro Designer.
Save the Table and Close the Table
Test It: Create an Update Query
Next you will need to create an Update Query that performs an update on the Table that houses the Data Macro you just created.
To test this, you can just update a string field in all records to one value.
UPDATE [TestTable] SET [TestText] = "Test"
Run the query
Press Control + G to bring up the Immediate Window. You will notice that the Data Macro fired for every updated record.

Adding records to table without using inline query in VBA/Access

I am completely new to VBA. I have been told to add records to a table by using a form and a Save button and given some very basic instructions. While I have achieved this with inline query, I have been told to follow some strict methods like usage of QueryDef/QueryDefs and .Parameters.
So far I am trying a very basic project, just to grasp the concepts, but I am unable to add any record to an empty table. In case the table is not empty(I manually enter a record), whenever I click the Save button for saving newer records, the number of records added are somehow doubling with each instance. For example, when I Save for the 1st time, 1 record is added, 2nd time 2 records of the same type is added, 3rd time 4 are added and so on.
The table(tbl_test) has 2 fields --> ID(primary key), Source(Long Text) and Reg No (Number).
The query(qry_test) is made with the Append feature and I have been told to add expressions which makes the code like this -
INSERT INTO tbl_test ( Source, [Reg No] )
SELECT [strSource] AS Expr1, [lngRegNo] AS Expr2
FROM tbl_test;
The form has 2 fields for Source(txt_Source) and Reg No(txt_RegNo) which have blank Record Sources (Unbound). The Save button has the following Event Procedure -
Private Sub btn_save_Click()
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("qry_test")
qdf.Parameters("strSource") = Me.txt_Source
qdf.Parameters("lngRegNo") = Me.txt_RegNo
qdf.Execute
End Sub
I have zero knowledge about VBA and would gladly accept ANY help. It would be great if I get any sort of source code that will explain to all the details about saving records from forms and editing them using these querydef, parameter and recordset stuff.
Welcome to StackOverflow!
If you are using a form to collect data for records that are stored in a table, running a saved append query by QueryDefs to do this is, in my opinion, not the best method.
Whilst an append query does add new records to an existing table, I would tend to use an append query where I've got multiple established records that I want to add to an existing table.
If I'm setting up a data entry form that is designed to collect new data for new records 1-at-a-time, an append query doesn't really suit this purpose.
Instead, there are a number of features built in to the design of MS-Access forms to help collect data and save it to a table. This is because forms are very much intended to be set up so that users can interact with records from a table in a controlled, user-friendly way rather than interact directly with the table object itself.
The first and most important feature of a form in this context is probably the form's record source property. When you create a new form, go in to design view for the form and open the form's property sheet (F4 key). In the "Data" tab of the form's property sheet you'll find the record source property:
The record source essentially connects your form with a set of records, whether those be records in a table object, a query object or an sql query string.
In your case it would be better, in my opinion, to bind your tbl_Test table to your form by referring to it in your form's record source:
It will seem like nothing has happened to your form, but if you now open the "Add Existing Fields" panel (alt + F8), you'll notice that the fields associated with your tbl_Test table are available to you:
Drag them to the detail section of your form...
Then put your form in to Form View:
Essentially what you and your users are seeing is the first blank record in your tbl_Test, but displayed on a form instead.
Entering data in these fields on the form...
...will put that data in to the table we specified in the form's record source...
So hopefully you can see that setting the form's record source property to that of your table, is much cleaner than trying to get an append query to collect data from your form and deliver it your table.
At this point you're probably asking a few questions:
When I have filled in the fields for a record on my form, how do I save that record?
More can be said about this, but for brevity, I'd recommend using a command button for running some vba to save the record; similar to what you've done, but utilising the form's Dirty property instead using an append query:
Here's the click event VBA for my save button example:
Private Sub cmdSave_Click()
If Me.Dirty Then
Me.Dirty = False
End If
End Sub
Me.Dirty is a Boolean (True or False) setting for the form; essentially it is automatically set to True when a user changes something on the form. To save those changes, the Me.Dirty setting will have to be set to False.
Me.Dirty is a bit like the swing gate on a sheep pen. When a shepherd puts a sheep (data) in the pen (form) they will open the gate to the pen. The open gate is like the form's Me.Dirty being set to True. To lock the sheep (data) in, the gate needs to be closed, or in the case of forms, the Me.Dirty property needs to be set to False. The VBA above essentially checks to see if the gate was opened and if it was to close it.
How do I move to a new record in the form once I have saved the current one?
Again, I'd give the user a command button to do this and run some VBA on its click event:
Here's the VBA for moving to a new record:
Private Sub cmdNew_Click()
DoCmd.GoToRecord , , acNewRec
End Sub
Summary
There is a lot more to consider than what I've outlined here, such as:
validating data before it is saved
checking other form events (such as close) to ensure data entry is not lost
navigating to an existing record
But hopefully what I've given you here is at least pointing you in a better direction. Best of luck!
Access is optimized for bound forms. Unbound forms are for special cases only.
Should you prefer unbound forms (could be for many reasons), Access isn't worth the trouble, and you should turn to Visual Studio and WinForms.
In either case, browse for a beginner's tutorial.
If you want to use an unbound for or unbound controls you can create the SQL string in the procedure:
Dim mysql as String
mysql = "INSERT INTO tbl_test ( [source], [reg_No]) VALUES (Me.txt_Source, Me.txt_RegNo)
DoCmd.RunSQL mysql