I have a form Main with a subform Issue on it. To implement search functionality on Main so that users can search for records in Issue that have a given substring, Main has a text box keyword and a submit button SubmitBtn. Here is the VBA code I am using to try to make this work:
Private Sub SubmitBtn_Click()
Dim keyword As String
Dim recordSourceSql As String
keyword = Nz(Me.keyword.value)
recordSourceSql = "select * from [Issue] where [Details] like " & quoteWrap(keyword)
Me.Issue.Form.RecordSource = recordSourceSql
Me.Issue.Form.Requery
End Sub
Private Function quoteWrap(value As String) As String
quoteWrap = "'*" & value & "*' "
End Function
The problem is that after this line:
Me.Issue.Form.RecordSource = recordSourceSql
there is only one record showing in Issue--it's the first record in the original recordset, when there should be at least 20 records showing with the value of keyword that I tested. Once this occurs, the Me.Issue.Form.Requery call does not change the contents of Issue.
I know that the correct recordSourceSQL is being created, because when I put in, e.g., "data" for keyword, I get this string for recordSourceSQL:
select * from [Issue] where [Details] like '*data*'
and when I create a query in Access and set this as the SQL, I get all the correct results returned.
What's wrong with this code to search the subform according to the given criteria?
UPDATE: I was able to get this to work by setting Me.Issue.Form.Filter to the WHERE clause in recordSourceSql. I don't understand why .Filter works but changing .RecordSource doesn't.
UPDATE 2: The .Filter solution is not working either. I've described this issue in this SO question.
I created a sample, copied your code and was able to replicate your problem and solve it.
If your subform was unbound (i.e., recordsource was empty) and the primary key of your main table and Issue table had the same field name (e.g., both were named "ID", etc.) and you did not link any parent or child fields, then it will only work if you specifically name each field like this:
recordSourceSql = "SELECT Issue.IssueID, Issue.Details FROM Issue WHERE Issue.Details Like '*Data*'"
You are correct! Wildcards in the select don't work in this scenario, including Select Issue.* From Issue.
Alternatively, if you rename the primary key in your Issue table so it is not the same as your main form main table, then the wildcards work as you would expect. When I made this change your exact code worked:
recordSourceSql = "SELECT * FROM Issue WHERE Details Like " & quoteWrap(Keyword)
Note the Me.Issue.Form.Requery is not necessary. Just setting or changing the RecordSource automatically requeries.
It does not seem to matter if the two primary key fields are dragged to the main or subform. It also doesn't help to make the subform databound but empty with an initial recordsource in the property sheet of "Select * from Issue Where 1=2" (one way to create an empty recordset, but keep the form bound).
I don't know if this is an MS-Access quirk or something intentional. It seems to me that I must have come across this scenario many times (primary key was "ID", subform unbound, no child fields linked) but I don't recall coming across this limitation. Maybe I didn't use a wildcard. When I googled, I didn't find this reported by others but no doubt some MS-Access expert out there will know the reason.
Hope this helps.
Related
I have a sub form in Access that allows a user to select records using check boxes. In addition to this sub form there is a combo box with a list of names.
Is it possible to select a few records using the check boxes and assign a name to them with a press of a button?
The button is called [assignButton] , the sub form is called [list subform] and the combo box is called [personCombo] .
This seems like a simple task, but I am unfamiliar with how the VBA for the button triggering this kind of action would be written?
All records are bound to an existing table called "tbl_jobs" this table has the same amount of rows and columns as the subform in the screenshot
Disclaimer: The following code is only intended to illustrate how to update the subform rows, so it includes no error handling or other common process code. Also notice that the SQL statement has no additional criteria in the WHERE clause, primarily because the question lacks the subform's actual RecordSource query and/or information about how the subform table is prepared and/or filtered for each time the form is loaded.
Private Sub AssignPerson_Click()
Dim qry as QueryDef
Set qry = CurrentDb.CreateQueryDef("", _
"UPDATE tbl_jobs SET Person_Name = [ParamName]" & _
" WHERE [Select] = True")
qry.Parameters("ParamName") = PersonCombo.Value
qry.Execute
Me.list_subform.Requery 'Ensure subform displays updated rows
End Sub
Really this question is borderline "Too broad" for Stackoverflow. There are multiple ways to accomplish what you want, and your problem is one of design, coding and understanding. But in the end, this model code is rather simple and satisfies the basic requirements so I feel it not worth nitpicking.
I am relatively new to Access and any SQL and VBA I have picked up is self-taught, so I would really appreciate answers that are not too heavily laden with technical terms...that said, I am having an issue with allowing comboboxes to be left blank on a form if the user chooses not to input data. Also, I am using Access 2016.
Initially the problem I ran into was that if a combobox was entirely skipped and left blank, or if the user selects the combobox and then tries to move on without making a selection from the list, they got the error "You tried to assign the Null value to a variable that is not a Variant data type," and were unable to move on to any other fields on the form or to save the record being entered.
I found this article that details a possible solution, but I can't seem to get it to work. I made an unbound combobox, set the Row Source to:
SELECT EmailID, PersonalEmail FROM EmailT UNION SELECT "<N/A>","<N/A>" FROM EmailT
ORDER BY PersonalEmail;
where PersonalEmail is a field of type short text and the EmailID is an autonumber. I also followed the article's steps for formatting the combobox (column width, etc.) and set it to Limit to List = Yes.
Here is my exact code:
Private Sub Combo62_AfterUpdate()
If Combo62 = "<N/A>" Then
EmailID = Null
Else
EmailID = Combo62
End If
End Sub
Private Sub Form_Current()
If IsNull(EmailID) Then
Combo62 = "<N/A>"
Else
Combo62 = EmailID
End If
End Sub
< N/A> now shows up on my list, but if it is selected I get the error: "The value you entered isn't valid for this field. For example, you may have entered text in a numeric field or a number that is larger than the FieldSize setting permits."
Access's debugger highlights the line:
EmailID = Null
but I am not sure what steps I should take now to try and fix this.
I am completely open to other methods of allowing the combobox to be left blank if someone knows of a better way to do this also. For all I know, I am missing something really obvious! Thanks in advance for any insight!
EDIT: Thanks for your help guys, I never did figure out what exactly the problem was, but I got some advice from another forum to rethink my database design so this ended up being a null issue--it's all totally different now!
If the recordsource for your form contains a query with one-to-many relationships this error may come up. Try to use only the base table as the recordsource for the form. Use subforms if you need to display related data. The rest of the code may then be unnecessary.
I have a subform which could be different depending on a user choice (as they are make table queries). Consequently I have had to store the actual table name in a variable caled MyResultSO. This works fine and returns the correct table name. I am then trying to get the value of a field from the subform. I am then trying to combine the variable with the field name.text to get the value of the field from the subform but can't get the syntax correct.
I have tried variations but, for example here is one:
MyResultSO = Me.RESULTS.SourceObject
'this works fine and returns "Table.POWER PRICES Query Table 3"
MyProductCode = MyResultSO & !PRODUCT_CODE.Text
'which is where I am trying to combine the value of variable MyResultSO and the field which is PRODUCT_CODE.Text.
Combined this should return the value of the current record from the following:
Table.POWER PRICES Query Table 3!PRODUCT_CODE.Text.
As you will probably tell from the above, I am not very experienced with VB.
Somewhere in the private module of the main form, here Me:
MyResultSO = Me.RESULTS.SourceObject
MyProductCode = Me.RESULTS.Form.Controls("PRODUCT_CODE").Value
Not to use .Text, that requires .Focus: so is bad, it does not always work!
MyProductCode = Me.RESULTS.Form.Controls("PRODUCT_CODE").Text ' <= it's bad.
Here PRODUCT_CODE is the name of a control on the subform named "Table.POWER PRICES Query Table 3".
Looking for a second set of eyes to figure out my problem with an Access form filter. I created a search form, when filled in, appends search criteria to a string variable (strQuery) that is put in place to the [WhereCondition] for opening a form. However, when the script is ran, nothing comes up except for a filtered form with no records.
Here is the line that opens the form:
DoCmd.OpenForm "ADD_NEW_NCMR", , , strQuery
Before the line is ran, strQuery equals:
1=1 AND [NCMR].[NCMR_NUM] = '12-129'
The form name, and table.column combination are all correct. In fact, using the DCount function returns the result of 1, which is correct for this query, and returns the correct number for other queries as well. This makes me think that there is nothing wrong with the where condition.
DCount("[NCMR_NUM]", "NCMR", strQuery)
Check your form's Data Entry property. You can find it on the Data tab of the form's property sheet.
If Data Entry = Yes, the form will not display existing records.
Sounds like you want Data Entry = No, so that existing records which match your OpenForm WhereCondition will be displayed.
So I have an input form that I want to use to update a table with certain fields of information. I have the ID of the record automatically coming up in a text box. I have three text boxes that I need to add to the table (excluding the ID) on a button click.
Name
Date
Method
are the field names.
As_Name
As_Date
As_Method
are the text box names
The table name is POC, and the ID is POC_ID (its an autonumber).
So I do not want these objects (text boxes) to be bound to the table because this is a little separate "pop-up" form that comes from a form that the table, and I only want the input to be relative to the POC_ID that is already selected via the original form.
So how do I write the vba for this to 1)check to make sure that records do not already exist....2)update the fields (listed above) with data input from the text boxes(listed above). I want to be able to use this with a button click....
EDIT:
actually it is one table not two; i have two forms that I want to be able to send information to the same table (different information though). this db was already built by someone else and know I have been deamed to take it over.
I need to add a second little pop up form for additional information to be added based on new requirements (there is literally no where for me to place this on the other one). I have already done that, and used a suggested object approach to reference the first forms (from which this second "pop-up" form springs from) to add the relative id fields. Now I have this second little pop up form that just asked three values to be inputted (which are the ones listed above).
I just simply do not know how to link the text box, with a field so that once a user enters in the information, clicks "save" it saves the information to the table relative to the TripID that is there (one mentioned above). the only way I know how to get the text boxes to save data to the table is to use the builder/wizard when I create a new one.
I would like to learn how to link an object (text box, cmb, list) etc on a form, to a table with an "On Click" method so that I can use a save button. Basically that is it!
The OpenForm method of DoCmd allows for several arguments, including Where and Openargs. You can take advantage of these.
However, something seems to be quite wrong with your table design in that you appear to be holding the same information in two tables and for no stated reason. Have you read http://www.r937.com/relational.html?
I would suggest that the design you need probably only includes a numeric field POC_ID that is a foreign key to the main table.
Still not sure I understand your situation, but let me offer the outline of an answer. If my outline is not close enough, please explain where I went astray.
Your parent form, frmParent, has a command button (cmdMoreFields) which opens the child form (frmChild) where you will enter values for 3 additional fields in the record currently displayed in frmParent. After the user enters those values in frmChild (in text box controls named As_Name, As_Date, and As_Method), she will click a command button (cmdSave) to store those values to fields (Name, Date, and Method) in table POC, and close frmChild. Also, frmParent includes a text box (txtPk_field) which holds the value for the primary key (field pk_field in table POC) of the current record.
However, I'm not sure which field/control you're using for txtPk_field, and doubt that value is available if the the current record has not yet been saved. So, I'll suggest this code for the cmdMoreFields "on click" event:
If Me.Dirty Then Me.Dirty = False
DoCmd.OpenForm "frmChild"
In the "on click" event of cmdSave (on frmChild), try code similar to:
Dim strSql As String
strSQL = "UPDATE POC SET [Name] = """ & Me.As_Name & """, [Date] =#" _
& Me.As_Date & "#, Method = """ & Me.As_Method & """ WHERE pk_field = " _
& Forms!frmParent.txtPk_field & ";"
Debug.Print strSql
CurrentDb.Execute strSql, dbFailOnError
DoCmd.Close
If that approach works, consider passing the pk_field value to frmChild with Openargs, as Remou suggested.
Note: I assumed the data type for Name is text, Date is date/time, and Method is text. You will have to change the UPDATE statement delimiters for any fields whose data types differ from my guesses.