This has taken me nearly 2 weeks and I don't know what else to do. I have a main form (UserSearch) that has a subform (TestUserSub). The associated table for both forms is tblusers.
very simple; on the main form (UserSearch) I have a ComboBox associated with the fields in the tblusers eg cmbid, cmbname, cmbdept and so on. All I want, is for a user to make a selection from any of these comboboxes and for the associated fields to display in the subform (TestUserSub). I have tried several different versions of code in the after update event in a couple of the ComboBoxes and nothing is happening in the subform or in other instances I get error message.
One example i have tried is filtering running an SQL command
Private Sub cmbid_AfterUpdate()
Dim strSQL As String
If IsNull(Me.cmbaccess) Then
Me.RecordSource = "tblusers"
Else
strSQL = "SELECT tblUsers.[Team Member_ID] FROM tblUsers " & _
"WHERE (((tblUsers.[Team Member_ID])= " & [form_testusersub].[txtid2]))& ";"
Me.RecordSource = strSQL
End If
End Sub
The above didn't work... Can someone please help me with this. I have a sample database that I have been working off of and by some very strange way, they have managed to do this same thing without calling any code. Is this possible?
I was able to figure out the code using the sample below
Private Sub yourcombobox_AfterUpdate()
Dim LSQL As String
If IsNull(Me.yourcombobox.Value) Then
Form_yoursubform.RecordSource = "tablename"
Me.yoursubform.Requery
requerysubform 'macro to requery the whole form
Else
LSQL = "select * from tablename"
LSQL = LSQL & " where field= '" & yourcombobox & "'"
Form_yoursubform.RecordSource = LSQL
requerysubform 'macro to requery the whole form
End If
End Sub
hope this helps.
Related
I want to populate a List Box on a Word User Form based on the data entered in a Text Box on the same form. Ideally this would happen in real time (using the change event I think) with each character entered in the Text Box filtering the items that appear in the List Box.
The data source is an Excel "data base" accessed using DAO. The code below works but it enters the entire data base into List Box (based on this - Link).
Private Sub UserForm_Initialize()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim NoOfRecords As Long
'Open the database (Excel File)
Set db = OpenDatabase("C:\Users\T400\Documents\UserFormListTest.xlsx" _
, False, False, "Excel 8.0")
'Retrieve the recordset > Excel Range = "ListBoxData"
Set rs = db.OpenRecordset("SELECT * FROM ListBoxData")
' Determine the number of retrieved records
With rs
.MoveLast
NoOfRecords = .RecordCount
.MoveFirst
End With
' Set the number of Columns = number of Fields in recordset
ListBox1.ColumnCount = rs.Fields.Count
ListBox1.Column = rs.GetRows(NoOfRecords)
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Sub
How can I filter the data so the List Box is only populated per the Text Box? I was hoping for a simple solution like maybe modifying the SELECT * query portion of the code.
Is this possible? Or is there a better way?
As i mentioned in the comment to the question, MS Excel uses Jet database engine. So, you have to use wildcards which correspond to that database engine.
So, if you want to develop custom "search/find" functionality, you may add Combobox control on the form with these options: All, StartsWith, Contains and EndsWith. A sample code should look like (replace the name of controls to yours):
Dim sName As String
Dim sSearchType As String
Dim sQry As String
sName = TextBox1.Text
sSearchType = ComboBox1.Value
sQry = "SELECT * FROM ListBoxData "
Select Case sSearchType
Case "All"
'do nothing; return all records
Case "StartsWith"
sQry = sQry & "WHERE Name Like '" & sName & "*'"
Case "Contains"
sQry = sQry & "WHERE Name Like '*" & sName & "*'"
Case "EndWith"
sQry = sQry & "WHERE Name Like '*" & sName & "'"
End Select
Set rs = db.OpenRecordset(sQry)
'other stuff
More about wildcards, you'll find here:
Access wildcard character reference
Office: Wildcard Characters used in String Comparisons
On my form I have a button which the user can click. It will then prompt the user with 3 input boxes, where the user can enter in the information that he wants to run a query on. I want the query to run based on the values that he enters into the 3 inputboxes, but I cannot seem to figure this out. The query is based on another table in my database. Here is the code I've written. It won't compile because I have too many arguments. This is probably because I don't know how to pass variables with the DoCmd.OpenQuery command.
Private Sub VariableQuery_Click()
Dim strProdCode As String
Dim strCampCode As String
Dim strMailDate As String
strProdCode = InputBox("Enter Product Code", "Product Code")
strCampCode = InputBox("Enter Campaign Code", "Campaign Code")
strMailDate = InputBox("Enter Mail Date", "Mail Date")
DoCmd.OpenQuery "contribution", , , "[PRODUCT_CODE]=" & strProdCode & _
"[CAMPAIGN_CODE]=" & strCampCode & "[MAIL_DATE]=" & strMailDate
End Sub
Any help is appreciated. The name of the query I am trying to run is "contribution". PRODUCT_CODE, CAMPAIGN_CODE, and MAIL_DATE are the names of the fields in the database and PRODUCT_CODE and CAMPAIGN_CODE are both text fields, and MAIL_DATE is a Date/Time field.
I don't know if there is a different way to do this but how I would approach the problem is by creating the SQL string
Dim strSQL As String
strSQL = "SELECT ... INTO ... " _
& "FROM ... " _
& "WHERE [PRODUCT_CODE]='" & strProdCode &"' AND [CAMPAIGN_CODE]='" & strCampCode & "' AND [MAIL_DATE]=#" & strMailDate & "#"
DoCmd.RunSQL strSQL
Things to note
When you have WHERE kind of clauses you have to qualify the values of the fields appropriately e.g. '' around strings, ## around dates and nothing around numbers
DoCmd.RunSQL I believe only runs actions queries e.g. UPDATE, DELETE etc. Plain SELECT are not action queries.
If you want to hide the warnings that popup there are two ways to do it, one is to use CurrentDB.Execute(strSQL) instead or to use DoCmd.SetWarnings(False) and DoCmd.SetWarnings(True)
Edit (Possible helpful links)
http://allenbrowne.com/tips.html
Building SQL strings in Access/VBA
You can Google "building sql strings in ms access" or some variation of that for more sources
I have a form with an unbound combobox that has all the column headings for the table dbo_orderheader. What I want to do is use the combobox field to act as the table column header instead of hard coding it to a specific table column header, that way a user can search dynamically from the form on the column they choose instead of having a huge list of search boxes for each table column.
Please can anyone help on a way to do this in an access query? I am using Access 2007.
Thanks.
See Picture Attached
I'm pretty sure that there's no way to imbed a form reference as a column heading in a static query design, but you could use code behind your form to dynamically update the query design and then open the query, something like this
Private Sub btnOpenQuery_Click()
Dim cdb As DAO.Database, qdf As DAO.QueryDef
Const queryName = "flexQuery"
Set cdb = CurrentDb
DoCmd.Close acQuery, queryName, acSaveNo
On Error Resume Next
DoCmd.DeleteObject acQuery, queryName
On Error GoTo 0
Set qdf = cdb.CreateQueryDef(queryName, _
"SELECT URN, StyleNo, [" & Me.Combo3.Value & "] " & _
"FROM dbo_OrderHeader " & _
"WHERE [" & Me.Combo3.Value & "]=""" & Me.Text5.Value & """" _
)
Set qdf = Nothing
Set cdb = Nothing
DoCmd.OpenQuery queryName, acViewNormal
End Sub
Note: This sample code assumes that the "dynamic" column is a Text column, so it puts " characters around the Text5.Value when constructing the SQL statement. This code would have to be enhanced to handle other column types (e.g., no quotes for numeric columns, and perhaps # delimiters for dates).
I am doing some maintenance work on a linked-table application in Microsoft Access 2010 and experiencing this little gem of a problem. The application is linked to a SQL Server 2008 database. The application has a main form that allows a user to choose a combination of park code and resource and pops up an edit form for the details of that particular combination. If that combo doesn't exist in the database, the application inserts a new record in, but the issue is that 2 records get inserted.
Here's the seat of the problem code, it gets called when I need to insert a new record in a details popup form:
Private Sub New_Rec(unit_code As String, resource As String, sql As String)
DoCmd.RunSQL ("INSERT INTO PARK_RESOURCES (unit_code, resource, sensitivity) VALUES " _
& "('" & unit_code & "','" & resource & "','public')")
'Force an explicit save
'http://www.pcreview.co.uk/forums/update-cancelupdate-without-addnew-edit-t1150554.html
If Me.Dirty Then
Me.Dirty = False
End If
Me.RecordSource = sql
End Sub
Creating a "new" record results in 2 records getting inserted into the Recordset. It doesn't seem to matter if I move the explicit save code before or after setting the RecordSource. In either order (and stopping after either) produces 2 new records inserted in the database (verified by querying in SSMS).
When I set the RecordSource property and step through the code, the event chain looks like: Me.RecordSource = sql --> Form_BeforeUpdate() --> Form_AfterUpdate() --> Form_After_Insert() --> Form_Current(). The duplicate is not present at the close of BeforeUpdate, but by the time I get to AfterUpdate, the duplicate has already been inserted. What happens between BeforeUpdate and AfterUpdate that causes this to happen?
According to MSDN, the order is: BeforeInsert → BeforeUpdate → AfterUpdate → AfterInsert. They also state that setting the value of a control through Visual Basic doesn't trigger these events. But when I update the RecordSource in code, the last 3 events certainly fire; BeforeInsert is the only one that a step-through doesn't stop on.
As per Daniel Cook's request, here is the calling code.
Private Sub Form_Load()
On Error GoTo Err_Form_Load
Me.KeyPreview = True
If Not IsNull(Me.OpenArgs) Then
ProcessOpenArgs (Me.OpenArgs)
Me.lblHeader.Caption = Me.unit_code & ": Resource - " & Me.resource
Else
Me.lblHeader.Caption = "Information Needs"
End If
... (error trapping)
End Sub
And the ProcessOpenArgs sub (OpenArgs get set as "park;resource"):
Private Sub ProcessOpenArgs(open_args As String)
On Error GoTo Err_ProcessOpenArgs
Dim Args() As String
Args = Split(open_args, ";")
Me.unit_code = Args(0)
Me.resource = Args(1)
'Check to see if there are records in the database for current unit/resource combo'
Dim rs As DAO.Recordset
Dim sql As String
sql = "SELECT * FROM PARK_RESOURCES " & _
"WHERE resource='" & Me.resource & "' AND unit_code='" & Me.unit_code & "'"
Set rs = CurrentDb.OpenRecordset(sql, dbOpenDynaset, dbSeeChanges)
'if there aren''t, create a new record'
If (rs.RecordCount = 0) Then
New_Rec Me.unit_code, Me.resource, sql
Else 'go to the current listing'
Me.RecordSource = sql
End If
Exit_ProcessOpenArgs:
Exit Sub
Err_ProcessOpenArgs:
MsgBox Err.Number & Err.description
Resume Exit_ProcessOpenArgs
End Sub
I will continue to comb through the event documentation and as a last resort I may go totally nuts and just stick every possible event in my VBA code and step through them, but does anyone know what could be happening to cause the duplicates?
In your ProcessOpenArgs, the If (rs.RecordCount = 0) Then line could be a problem unless you first use rs.MoveLast - see here
When I'm setting Me.unit_code and Me.unit here:
Private Sub ProcessOpenArgs(open_args As String)
On Error GoTo Err_ProcessOpenArgs
Dim Args() As String
Args = Split(open_args, ";")
Me.unit_code = Args(0)
Me.resource = Args(1)
the code is creating 1 record and then New_Rec inserts a second record in the DB. When the Form automatically Requeries after Me.RecordSource = sql, it sticks the first record (created by the Me.xxx = yyyy statements in ProcessOpenArgs into the DB too and then pulls both back out to the Form Recordset. That's where the double insert is coming from.
In order to correct it, I changed Me.unit_code and Me.resource to local subroutine variables l_unit_code and l_resource and used those instead in ProcessOpenArgs. That took care of this problem as well as a second problem that I had with records form one resource type bleeding into other resource types.
Thanks all for the assist!
I am using SQL 2005 as backend and MS Access as frontend.
Now, I get all my filtering of the data with views and no problems so far but I came accross some issues.
In access I had a form and on that form I had a field1 which I used to filter the data I wanted in that form with query. Example: Last, First Name or DOB. In Access I used the Expression builder to point the query to that field and I got my filter.
Now how do I do it in this new environment since when I create view (In Access) I can not filter on that field.
I was thinking on sp but I am not sure how do i go about it.
Any ideas?
I was thinking on sp but I am not sure how do i go about it.
If you still wanted to keep this form a normal “bound” access form then you could do something like this.
Setup a pass through query that fires your SP. The basic format for that is along the lines of this
EXEC [dbo].[spAgents_with_more_than_X_days_sick_by_Team] #Date_from = N'2009-09-14', #Date_to = N'2010-09-14', #Team_ID = N'TEM1', #Days_sick =5
You would then modify this when opening the form like this
Set qDef = DBEngine(0)(0).QueryDefs("RqryAgents_more_than_X_sicks_detail_2")
With qDef
.Connect = strSQL_con_string
.SQL = "EXEC [dbo].[spAgents_with_more_than_X_days_sick_by_Team]"
.SQL = .SQL & " #Date_from = N'" & Format(Me.txtDate_from, "yyyy-mm-dd") & "', "
.SQL = .SQL & "#Date_to = N'" & Format(Me.txtDate_to, "yyyy-mm-dd") & "', "
.SQL = .SQL & "#Team_ID = N'" & Me.txtTeam_ID & "', "
.SQL = .SQL & "#Days_sick =" & Me.txtDays_sick
End With
This should work just fine however if it was me (and I know it’s not everyone’s preference) but I would make this an unbound form and populate it by firing your SP using ADO to fill a recordset and go from there.
If you want details of how to do that then just ask and I will post an example
EDIT: Code sample added
Dim cmd as new ADODB.Command
Dim dbCon as new ADODB.Connection
Dim rst as new ADODB.Recordset
dbCon.ConnectionString=”Your_Connection_string”
dbCon.open
With cmd
.ActiveConnection = dbCon
.CommandText = "spYour SP"
.CommandType = adCmdStoredProc
.NamedParameters = True
.Parameters.Append .CreateParameter("#Your_pram1", adVarChar, adParamInput, 20, Format(Me.txtDate, "yyyy-mm-dd"))
.Parameters.Append .CreateParameter("#Your_pram2", adSmallInt, adParamInput, 0, Me.cboPhone_skill)
End With
Set rst = cmd.Execute()
With rst
If .EOF=False then
Me.txtYour_text_box_1=!Your_SP_field_1
Me.txtYour_text_box_2=!Your_SP_field_3
Me.txtYour_text_box_3=!Your_SP_field_2
End if
End with
Rst.close
Dbcon.close
Set rst=nothing
Set cmd=nothing
Set dbcon=nothing
You don't mention if these text boxes are in fact in the same form with the data and you don't mention if each text box was optional, and if they were not optional, then did you fill out 1, 2 or 3 boxes and then hit a button?
If you just looking to find people with a given lastName, then in the after update event of the un bound lastname box, just go:
Me.RecordSource = "select * from tblCustomers where LastName = '" & me.txtLastName "'"
The above is one line of code. I just don't see the need for so much code as others posted here.
You can expand on your question if you looking to make all 3 boxes optional, or if you looking to have a search based on more then one box, but I can rather tell you that you don't need the amounts of code posted here, but the one line of code as per above will suffice.