Define table in select query from the value of a text box - ms-access

I have a very basic select query in MS Access. The only variable is that I want the user to select the region from a drop down list (combo box). There is a different table for each region, so I want the FROM field to pull from the combo box.
My query looks like this:
SELECT
STOCK_CODE, STOCK DESCRIPTION
FROM
Forms![frm_MAIN_MENU]![txt_MAIN_MENU_REGION]
When I run this I get the following error:
"Syntax error in FROM field"
I think I have read somewhere that this is not possible? If someone can perhaps clarify?
Thank you

This is one example of why the database structure that you have setup is not a very good idea. Using this sort of design will mean that you have to work much harder to get the database to work properly.
A far better design would be to replace all of your individual tables with one table, and add a field in their that identifies the region. You will then be very easily able to filter this single table on this region identifier.
Having said that, if you really want to do it this way, it can be done in VBA. Assuming that [txt_MAIN_MENU_REGION] is your combo box, and is populated with your regions:
Private Sub txt_MAIN_MENU_REGION_AfterUpdate()
On Error GoTo E_Handle
Dim strSQL As String
If Not IsNull(Me!txt_MAIN_MENU_REGION) Then
strSQL = "SELECT STOCK_CODE, [STOCK DESCRIPTION] FROM " & Me!txt_MAIN_MENU_REGION
End If
Me!lstRegion.RowSource = strSQL
sExit:
On Error Resume Next
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "frmRegion!txt_MAIN_MENU_REGION_AfterUpdate", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Regards,

Related

MS Access 2013 copy a specific number of fields and paste into a new record

I have found similar answers to this question, even on this site, however, the syntax has not worked for my database and I'm not sure what needs to be done. This data base is used to house audits for staff performance and accuracy. I am now in the midst of creating the forms and getting them to flow properly for the user.
When conducting an audit, the user will need to enter six specific fields into the first form. Those forms are Audit, Month, Year, Username, Location, Reviewer, and Date. The user will need to complete multiple audits, however, these six fields will always be the same.
I would like to copy these fields in the first form and carry them into the second form so the user does not have to repeat the information. Here is my current code (set to run on the click of a command button on the bottom of screen 1):
Dim strSQL As String
strSQL = "INSERT INTO [tblTripMem] (Audit, Month, Year, Username, Location, Reviewer, Date)"
strSQL = strSQL & " Values (" & Me.cboFP1Audit & "," & Me.Month & "," & Me.Year & "," & Me.Username & "," & Me.Location & "," & Me.Reviewer & "," & Me.Date & ") FROM [FPScreen1]"
strSQL = strSQL & "WHERE (currentrecord = " & Me.CurrentRecord & ")"
DoCmd.RunSQL (strSQL)
Each time I run this I receive the following error: "Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'.
I am new to Access and am unsure of what this means or how to fix it. All I know is that I'm not finding a solution. Can anyone help? I'd greatly appreciate it.
Here's a mock-up Access file illustrating a way to do what you're doing without using SQL:
With Form 1 open...
...complete the various fields:
Click the Copy to Form 2 button and this will open Form 2 and populate its fields with the data from Form 1:
Here's the VBA code on the Copy to Form 2 button's OnClick event:
Private Sub cmdCopyToFrm2_Click()
Dim frm As Form
DoCmd.OpenForm "Form2"
Set frm = Forms!Form2
With frm
!AuditRef = Me.cboFP1Audit
!AuditMonth = Me.txtAuditMonth
!AuditYear = Me.txtAuditYear
!AuditUsername = Me.txtAuditUsername
!Location = Me.txtLocation
!Reviewer = Me.txtReviewer
!AuditDate = Me.txtAuditDate
End With
End Sub
Note that when Form 2 opens, the textbox that the cursor defaults to might not seem to show any data; if you move away from that textbox it should magically show (don't know why it does this, but there you go).
INSERT INTO table (...) VALUES (...) cannot have a FROM or WHERE clause. You insert a single record with fixed values, not data from another table.
But once you delete these clauses, you will have other errors, because you need to format your string and date values correctly to get the INSERT query to work.
And then you will still be prone to SQL injection errors. It is safer to use Recordset.AddNew and .Update to add records.
See e.g. here: https://stackoverflow.com/a/34969410/3820271
(but without the loop)

Wrong RecordCount on Filtered Form with SQL View DataSource

I am using an Access2010 project as frontend, referring to a MS SQL Server 2008 as backend. Within my Access project there is form frmKlientenÜbersicht. This form has a view abfKlientenÜbersicht as dataSource.
Now I am trying to get the current number of records showing up in my form by using this code:
Private Sub Form_Current()
Debug.Print "Form_Current: " & anzahlDatensätze
lblAnzahlDatensätze.Caption = anzahlDatensätze & " Klient(en)"
End Sub
Private Function anzahlDatensätze() As Integer
Dim rs As Recordset
Set rs = Me.RecordsetClone
rs.MoveLast
anzahlDatensätze = rs.RecordCount
End Function
This works fine until I am using some filters. If I am using any filter on my form, the number of records stays unchanged!
What do I have to change to get the current number of records showing up (if filtered or not)?
What is the reason why my code does not show the correct number of records?
EDIT: According to the given comments and answers I tried setting Count([pkKlient] onto a textbox (see new pic) and tried DCount("*", "abfKlientenÜbersicht", me.Filter) from within VBA Code.
Unfortunatelly it seems that the filterClause is not valid when using it as parameter value for DCount. (see pic for filterClause).
As you can see count(..) does not result in a correct number - and the filterClause (generated by access!!) seems not to be valid for use by DCount(..)
If someone wants to try it, on your own, just create an ADP, add a form, add a view, form dataSource is a view, set a filter, and try to get the number of records?!!
Looking forward for any comments/answers/hints!
with VBA, DCount will give you what you need
DCount("*", "MyTable", Me.Filter)
If you want to put this on the form, there's an easier way. use an unbound box, and set it to =count([FieldName])
This count should remain correct, regardless of if it's counted filtered records or not.
Some notes, there are a dozen things that could go wrong with this, it could hardly even be called tested. However, it was returning the correct count for me.
Apparently, the form filter just hides records, whereas this will apply a real filter. However, you need to get the format into the right shape for a valid filter. In the end, a WHERE statement would probably be easier.
Private Sub Form_ApplyFilter(Cancel As Integer, ApplyType As Integer)
With Me.Recordset
''Filter
If ApplyType = 1 Then
''Very, very roughly. Remove form name, use single quotes
''You will need a lot more code for safety
sfilter = Replace(Me.Filter, "[" & Me.Name & "].", "")
sfilter = Replace(sfilter, """", "'")
.Filter = sfilter
MsgBox "Recordset : " & Me.Recordset.RecordCount & vbCrLf _
& "Filtered : " & .RecordCount
Else
''Remove filter - ApplyType 0
.Filter = ""
End If
End With
End Sub
Additional note with similar caveats
You can also set a textbox to something on these lines:
=IIf([FilterOn]=True,DCount("id","ATable",
Replace(Replace([Filter],"[" & [Name] & "].",""),"""","'")),Count([id]))
(Remove the break in the line, it is cosmetic)

Multi-Page vs Multi-PDF Loop problems

I have a form that contains multiple partners that share a "pool". The partners are listed on a subform. After I'm done entering the information, I want a button to run a report for each of the partners with their specific information. But since it's multiple partners and I need one report for each (which I then want to email), I want to use a Loop to go through each of the partners.
EDIT1: Added entire code for review. I do have Option Explicit in and I have compiled it as well.
Private Sub btn_Run_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
strSQL = "Select * FROM Cobind_qryReport WHERE PartPoolName = """ & Me.TopLvlPoolName & """"
Debug.Print "strSQL: " & strSQL
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL)
On Error GoTo Err_PO_Click
If MsgBox("Do you wish to issue the cobind invites?", vbYesNo + vbQuestion, "Confirmation Required") = vbYes Then
rs.MoveFirst
Do While rs.EOF = False
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF,_
"K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" _
& rs!CatCode & "_" & rs!PartPoolName "Cobind Invite_" & _
Format(Now(), "mmddyy") & ".pdf"
DoCmd.SendObject acSendReport, "Cobind_rptMain", acFormatPDF, ,_
, , " Cobind Invite", "Please find the cobind invite attached._
Response is needed by " & [RSVP] & ". Thank you.", True
rs.MoveNext
Loop
End If
Exit_PO_Click:
MsgBox ("It didn't work")
rs.Close
Set rs = Nothing
Set db = Nothing
Exit Sub
Err_PO_Click:
MsgBox Err.Description
Resume Exit_PO_Click
End Sub
This should allow me to create a report for each record in my query, save it to my server, then open an email to send it out. Right now, it appears that the [PartPoolName] is hanging up the code because I'm getting a "Microsoft Office Access can't find the field "|" referred to in your expression." If I take out the [PartPoolName], it'll create a PDF with four pages (each page showing a partner), where I want to end up with four separate PDFs.
The first thing you should do is add Option Explicit to the Declarations section of your module.
Then, from the Visual Basic editor's main menu, select Debug->Compile [your project name here]
Fix all the problems the compiler complains about. I suspect one of the compiler's first complaints may be triggered by this section of your code:
rs.MoveFirst
Do While Recordset.EOF = False
Do you have two recordset objects open, or one?
After you fix everything the compiler complains about, try your revised code.
If you get runtime errors, show us the exact error message and which code line is highlighted.
If the part of your code you haven't shown us includes an error hander, you can disable that error handler like so:
'On Error GoTo Err_PO_Click
Error handlers are great for production to shield users from errors. However, during development you really need to be able to identify which code line causes the error.
Alternatively, you can leave your error handler active and select Tools->Options from the editor's main menu. In the Options dialog, select the General tab, then select the "Break on All Errors" radio button and click OK. You can switch that option back to "Break on Unhandled Errors" after you finish your testing.
Update: You wrote: Right now, it appears that the [PartPoolName] is hanging up the code because I'm getting a "Microsoft Office Access can't find the field "|" referred to in your expression."
What is [PartPoolName]? If it's a field in the recordset, you can reference its value as rs!PartPoolName If it's something else, perhaps a global variable, give us more information about it.
Update2: Whenever your current code completes without error, you will hit this:
Exit_PO_Click:
MsgBox ("It didn't work")
Can that be right?
Update3: This OutputTo statement is your issue now, right?
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF,_
"K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" & _
"Cobind Invite_" & Format(Now(), "mmddyy") & ".pdf"
Cobind_rptMain is a report. It has a RowSource for its data. You're calling OutputTo with that report 4 times (once for each of the 4 rows in the recordset). Yet you expect 4 different versions of that report ... a separate report for each PartPoolName value?
To finish off the fine work by HansUp visit a page on how to print a report for a single record and how to generate reports to attach to emails. See the Emailing reports as attachments from Microsoft Access page.

MS Access - check sub-form before entry for duplicate

I've got a subform (customersAnswersSub) inside of a main form (customersAnswers). Upon someone entering a new customerAnswersSub entry - I wanted it to check for duplicates first.
It has to check across 4 different fields to match first.
This is what I've got so far.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim rsGlobals As ADODB.Recordset
Dim sql
Set rsGlobals = New ADODB.Recordset
sql = "Select * From CustomerAnswerD where subscriptionNo=" & _
Me.subscriptionNo & " AND journal=" & Me.Journal & _
" AND volume=" & Me.volume & " AND issue=" & Me.issue
rsGlobals.Open sql, CurrentProject.Connection, adOpenDynamic, adLockOptimistic, adCmdText
If Not rsGlobals.BOF And Not rsGlobals.EOF Then
MsgBox ("Already entered")
Cancel = True
Me.Undo
End If
End Sub
it doesn't do anything - just sits there. when I close the form it'll pop up a - id already exists box.
Any idea, i'm pretty unexperienced when it comes to Access VB.
thank you
it doesn't do anything - just sits there
Just checking, since you said you're inexperienced with Access ... the form update event is not triggered until the record save is attempted. That may not happen automatically as soon as the user enters data into all the fields. However, you can trigger the update by navigating to a different record in the subform, or by a method such as choosing Records->Save Record from Access' (2003) main menu.
I don't see anything wrong with your BeforeUpdate procedure. Still I would convert it use the DCount() function instead of opening an ADO recordset. (See Access' help topic for DCount)
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim strCriteria As String
strCriteria = "subscriptionNo=" & Me.subscriptionNo & " AND journal=" & Me.Journal & _
" AND volume=" & Me.volume & " AND issue=" & Me.issue
Debug.Print strCriteria
If Dcount("subscriptionNo", "CustomerAnswerD", strCriteria) > 0 Then
MsgBox ("Already entered")
Cancel = True
Me.Undo
End If
End Sub
That assumes your table's subscriptionNo, journal, volume, and issue fields are all numeric data types. If any of them are text type, you will need to enclose the values in quotes within strCriteria.
I added Debug.Print strCriteria so you can view the completed string expression in the Immediate Window. You can also troubleshoot that completed string by copying it and pasting it into SQL View of a new query as the WHERE clause.
Also, consider adding a unique index on subscriptionNo, journal, volume, and issue to your CustomerAnswerD table design. That way you can enforce uniqueness without relying solely on your form to do it. The index will also give you faster performance with the DCount function, or your original recordset SELECT statement.
If you keep your original recordset approach, close the recordset and set the object variable = Nothing before exiting the procedure.

Alias a Caption in Access 2007

All right, I've got two tables in my Access 2007 database (well, more than that, but the question applies to these two...):
part
part_no
...
supplier_id
special_supplier_id
...
And
supplier
supplier_id
supplier_nm (NB: Caption="Supplier Name")
special_supplier_flg
Now I've built a query :
SELECT p.part_no, s.supplier_nm, ss.supplier_nm AS special_supplier_nm
FROM
part AS p INNER JOIN
supplier AS s ON p.supplier_id = s.supplier_id INNER JOIN
supplier AS ss on p.supplier_id = ss.supplier_id
All well and good, and it seems to work for the simple select (if there are any errors in the query itself, it's an artifact of retyping it for the question, and not what the question is about), and should work for code applications as well.
The problem, though, is that if I open the datasheet view of the query, both of the name fields are labeled "Supplier Name". Is there any way around this?
Try this:
SELECT p.part_no, s.supplier_nm, (ss.supplier_nm + '') AS special_supplier_nm. . .
However, if you're using the query builder you may need to be careful not to build the query with the "default" alias (from the caption) first, because that seems to stick around in some not-visible metadata.
Also, if you can edit this query in Access' query builder, if you right click on the field in question there is an option to set the caption property inside the query, and this will override whatever caption was on the original table column.
I see the same thing with Access 2003 for even a single-table query ... if the source field has a Caption assigned, that caption is used as the column header in the query datasheet view, regardless of whether or not I give the field an alias in the query definition.
Other than removing the Caption from the source table definition, the only way I could find to work around it was by manually re-assigning the field's Caption property with VBA. Query1 includes a field named id which has "Foo ID" as its Caption in the source table:
CurrentDb.QueryDefs("Query1").Fields("id").Properties("Caption") = "foo_id"
That command did cause the query datasheet view to use foo_id as the column header.
If you assign an alias to a query field, that alias is used as the name in the query's Fields collection. You can examine your query's field names and their captions with this procedure:
Public Sub InspectQueryFieldCaptions(ByVal pQuery As String)
Dim fld As DAO.Field
Dim strMsg As String
On Error GoTo ErrorHandler
For Each fld In CurrentDb.QueryDefs(pQuery).Fields
Debug.Print "Field: " & fld.Name, "Caption: " & fld.Properties("Caption")
Next fld
ExitHere:
Set fld = Nothing
On Error GoTo 0
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 3270 ' Property not found. '
Debug.Print "Field: " & fld.Name, "no caption"
Resume Next
Case Else
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure InspectQueryFieldCaptions"
MsgBox strMsg
GoTo ExitHere
End Select
End Sub
Do you have captions set in your table definition? Those definitions will show instead of what you alias. Since you are selecting a column that will have the same caption (reguardless of alias), you will see the same caption for both in the datasheet view.
Do you have the option to change the caption field? Leaving it blank will use its given name (or alias in the event of a view)
WORKAROUND THAT WORKS
OK this one has been driving me bonkers because I'm using lots of data from linked (imported) tables from our company's finance, HR and CRM systems all set up by the same developer who thought captioning every Index "ID:" was a great idea. but when you have an aggregating which brings many of these together you get a big error prone mess because the subsequent query can't work out which "ID:" is which. He's my solution:
Rather than simply passing the values through, which simply passes the caption: If the field you want to re-caption is a value field, just re-label it and multiply it by 1 like so (in this my per_id field is captioned ID:):
Perid: 1*[pe_id]
This results in a new field labelled Perid
If it is a text field just concatenate it with nothing like this:
Perid: ""&[fname]
It works.