I have been using MS Access to aid in generating pdf reports based on a table. I have created a form that contains a text box for entering a client's name (this value is in the main table) and a button that when clicked runs the code:
Private Sub cmdPrintRecord_Click()
Dim strReportName As String
Dim strCriteria As String
strReportName = "Current SP Report"
strCriteria = "[Owner]='" & Me![Owner] & "'"
DoCmd.OpenReport strReportName, acViewPreview, , strCriteria
End Sub
The idea here is to generate an individual PDF report based on the clients name.
The above procedure has been able to do that successfully however, I have encountered that as I run it, the data in my table is affected, specifically the client name field.
For example: I'll run a report for client "Anthony" and it shows 10 products which is correct, but then if I go back and run that same report again it will show 11 products. It is as if the procedure here is altering the data table.
How can I troubleshoot this issue and or are there any alternatives recommended?
Thanks.
Attached is the MS link where I obtained the source code:
https://support.microsoft.com/en-us/kb/209560
If the Control Source of a form control (textbox, combo box) is linked to a table then it will modify that table. In your case, you want to receive user input based on selections from a table and not to modify the table itself. You want to use the "Row Source" property to limit the selection to table items and clear the Control Source. This pulls potential options from the table without changing existing table entries.
Like this:
Notice that the source of options for the combobox is a query that defines what items should appear in the dropdown but no Control Source is specified.
Related
Is there some sort of work-around that could make this possible? Or could anyone offer just some general advice on my situation below? I tried to set the record source through VBA but had no luck.
My situation:
I have a main form with a subform contained within, and I want the subform to be purely for data entry (Data Entry = Yes). Upon clicking a button, the user is sent from the main form to a report (print preview only). I want the source for this report to be the subform the users are entering data into, but I don't have this option from the report's property sheet itself (no forms), and I also was unable to set it through VBA. Here's my code, it's one line so I highly doubt it's the problem.
Private Sub Report_Load()
Reports![P18003 SDR Report].RecordSource = "P18003 SDR Subform"
End Sub
Previously, to work-around this I had a parameter query that waited for the user to enter data into an unbound textbox from the main form, and an after update trigger on that textbox would load any data relevant to that parameter (my employer and I miscommunicated the requirements).
It turns out though that I don't need to load any older data, and I run into problems with my current parameter query in the event that the user does input a parameter which loads old data - that old data is transferred to the report in addition to the new data they've just entered. This is the main problem with the method I am currently using, and it trashes almost all functionality with this form and report. The events that a user would need to enter a parameter which queries older data are few and far between, but it's not a functional product unless I can get the subform to be connected to the report directly. There's likely something obvious I'm missing here (or at least, I hope there is).
Thanks in advance for taking the time to read this and for any help you may offer.
you can either send the recordsource to the report itself in the OpenArgs by the open report event, after the click event in the subform
Private Sub btnSubform_Click()
Dim strSQL as String
strSQL = "SELECT * FROM SubformQuery WHERE ID = " & CurrentSubfromRecordID
Docmd.OpenReport, acViewReport, , , , strSQL
End Sub
and then in the Report.
Private Sub Report_Open(Cancel As Integer)
Me.recordsource = Me.OpenArgs
End Sub
Or you can make a paramter Query and set this Query criteria as record source for the report. So the parameter in the query is pointing to the current selected row in the subform. Like this:
--- At the Criteria in the Query designer:
--- RecordSource for the Report:
Forms![FormMain]![YourSubform]![ID]
Now every time the reports obens he gets the ID from the current selected record of your subform.
Looked everywhere for help on this; I can't believe that there's no way it can be solved:
Scenario: I have an unbound subform that displays data in a datasheet. The user selects a report to display from a combo box and a query is generated on the fly then displayed in the subform. The user may then export the report (from the querydef) to an xlsx format file for distribution to colleagues. All works well.
However, the user also refines the data in the datasheet, selecting and sorting using the column controls. The question is: how do I export the refined data?
I'd be very grateful for any help. Thanks
All the selecting and sorting of the datasheet is stored in the me.filter property of the subform.
So you take the filter and hand it over to the report. You can use the filter just like a normal WHERE-clause of a SQL query.
[the name of the SubForm container control in the host form].Form.Filter = the where clause
EDIT: Here is some code that you use in the main form preferrably in the procedure that kicks off the creation of the report:
dim strWHERE As String
strWHERE = Me.subform.Form.Filter
docmd.OpenReport "YourReport", , , strWHERE
Pls give us feedback if it works.
I am creating a small Access DB for our Data Entry guys. Our main DB is mysql but due to ease of use we are creating an Access DB to make it easier for them to enter the Data. I have done most of it but am stuck with this problem (which I know how to solve in mysql+php) Please pardon my ignorance, but I have just started using MS Access.
I have two tables - ClientPhones and sales. The ClientPhones table has phone, clientid fields. sales table has salesid, clientid, date, etc fields.
I also have a Form which has all relevant fields for the sales table. I want to add a new field, phone_no in that form. When a user inputs the number and on focus lose event, I was access to run a query on the clients table to see if the phone number exists in any of the 3 phone number fields. If it finds a client with that phone number, the client ID should be populated, else a new form to input the client details should be shown.
Is this possible with MS access or am I doing this incorrectly?
Use the text box's After Update event to retrieve the clientid which matches the phone number the user entered.
If a clientid is found, store it in the text box which is bound to clientid.
If no match is found, ask whether the user wants to add a new client, and open that form if they respond yes.
This code outline assumes txtSearchPhone is the name of the text box where the user enters the target phone number, and txtClientId is the name of the text box where you want to store clientid.
Private Sub txtSearchPhone_AfterUpdate()
Dim varClientId As Variant
Dim strCriteria As String
strCriteria = "[phone]='" & Me.txtSearchPhone.Value & "'"
Debug.Print strCriteria '<-- inspect this in Immediate window; Ctrl+g will take you there
varClientId = DLookup("clientid", "ClientPhones", strCriteria)
If IsNull(varClientId) Then
If MsgBox("Add new user?", vbYesNo) = vbYes Then
'DoCmd.OpenForm ... (see Access help topic)
End If
Else
Me.txtClientId.Value = varClientId
End If
End Sub
Make sure the text in txtSearchPhone does not include a single quote character (') because the DLookup will break if it does. You can use the text box's Validation Rule and/or Before Update event to make sure a single quote is not present.
I have a particularly difficult problem to deal with.
I am working on a Form for access. This form contains a large amount of cascade data connections.
It serves as a filtering, selection, review, and editing interface for the database.
Below I have included a basic description of the design;
-ComboBox1 populates its data from a reference table, and cascade updates to ComboBox2.
-ComboBox2 populates based on selection of ComboBox1 and then cascades information to ListBox1 which runs a query to generate a list of records.
-Selecting a record in Listbox1 populates the various hidden columns of the list into matching text and comboBox fields for display/Editing. It also on click cascade Populates Listbox2 using a query to pull records from a different table that are related to the selected record from ListBox1.
-I have a number of buttons to handle adding, deleting, and editing the records of the table where ListBox1 Queries its information from.
Everything up to this point works correctly (thanks in part to aid from people answering my other questions)
Where I am stuck now is in trying to create similar buttons that serve the same function with the Table where ListBox2 drawns its records(Add/Edit/Delete)
I have added the Add button successfully already but have become stuck on the edit function.
I have a button that I am trying to build an "OnClick" event for. It needs to pull the selected record from a listbox and have the form it is opening be set to that specific record.
I know I can pull the selected value from the list box with listbox.selected.value but How does that translate into the DoCmd.OpenForm syntax?
The DoCmd.OpenForm parameters you want to adjust are the optional WhereCondition and DataMode. WhereCondition accepts a SQL Where clause without the word where. This restriction is applied to the form's rowsource before the form opens.
DataMode can override the form's saved settings for AllowEdits and DataEntry. It sounds like you want to use acFormEdit in this case.
Private Sub CommandFoo_OnClick()
Dim strWhere As String
'Do yourself a favor and build the WhereCondition in a string variable so that you can see what you've built.
'Surround text values in double quotes.
'Surround dates with # and specify in m/d/yyyy or yyyy-mm-dd
'Make sure you build in spaces in as necessary.
strWhere = "NumberField1=" & ListBox1.Columns(0) & " AND TextField2=" & Chr(34) & ListBox1.Columns(1) & Chr(34)
Debug.Print strWhere
DoCmd.OpenForm FormName:="YourFormName", WhereCondition:=strWhere, DataMode=acFormEdit
End Sub
I have a report (ReportX) that I wish to open from two different forms (FormA and FormB) in my database. I wish to do this because FormA and FormB address different aspects of my data, even if they ultimately get to the same output. ReportX is based on data from QueryX.
The problem I have is that QueryX would ideally filter the data based on the current RecordID in the current form. But I don't know how to accomplish this. I'd like to design QueryX so that the criteria for RecordID is essentially CurrentForm!RecordID, but research suggests that I cannot do this. Must I make separate but otherwise identical queries and reports for each form? Or is there a way to use VBA to define the query criteria when I click on the OpenReportX command button?
I already tried using the WHERE condition in the OpenReport command:
DoCmd.OpenReport "ReportX", acViewPreview, ,"RecordID = " & RecordID
but that did not display the results I wished. I need the report header to display/print for each RecordID and the page count in the page footer to reflect only the current/total pages of the RecordID in question. (In other words, if record 1 is one page, record 2 is two pages and record 3 is three pages, then ReportX, when displaying the first page of record 2, should say "Page 1 of 2" and not "Page 2 of 6.") So being able to display and print a single record properly using record filters would also solve my problem.
Which is the least cumbersome/most possible solution?
You should be able to accomplish this using the WHERE condition argument when you open a report:
DoCmd.OpenReport "rptName", acViewPreview, ,"RecordID = " & Me!RecordID
In the case where a I need more control over a Report's recordsource than what the Where condition argument can do for me, I will set the Reports RecordSource to be blank (after designing the report). Next I write code create the correct SQL statement in the Open Report button's Click event, followed by code to open the report and pass in the SQL as an opening argument for the report.
Private Sub cmdOpenReport_Click()
Dim sSQL as string
sSQL = "SELECT * FROM tblWhatever WHERE RecordID = " & Me!RecordID
DoCmd.OpenReport "rptReportName", acViewPreview, , , ,sSQL
End Sub
Then in the report's Open event I write code to set the recordsource:
Private Sub Report_Open(Cancel As Integer)
If IsNull(Me.OpenArgs) = False Then
Me.RecordSource = Me.OpenArgs
End If
End Sub
If neither of those accomplish what you want then you have an issue of a different sort. It's a little difficult for me to understand why you need All Records to show up in the header but only one record in the detail area. And how you expect to accomplish this. You might be best off trying to write a query first that gives you the exact results that your looking for so you know that it can be done.
As a side note, I actually use very few saved queries in my designs. It's not that there's anything wrong with using them, as the option is there for your convenience. I frequently use raw SQL on both forms and reports and set the RecordSource to the SQL on the Form or Reports Open or Load events.
Yes you can point to form data items in a query, and subsequently use that query in a report. The forms need to be open before the report runs. As far as having a header for each record, that is controlled in the settings of the report and how it displays the data.
In the Field, or Critera you can use the format:
[Forms]![frm_Process_Candidates]![QuestionTemplate]
Where frm_Process_Candidates would be the name assigned to your form, and QuestionTemplate is either the name of a control on your form, or a field from the data source of your form.
If you have a sub-form, there will be another [Form] call in the middle there.
[Forms]![frm_Dropdown_Admin]![frm_Dropdown_Admin_Detail].[Form]![text22]
Access should figure it out from there.