MS Access - run report from a form that has 2 buttons that use the same report but have different results - vba

We would like to run a form that will have 2 buttons that use the same report but have different results:
Button 1 - open report for current record (which we have working) using
Private Sub Command25_Click()
DoCmd.OpenReport "Bale Spike Certificate", acViewPreview, , "[no] = " & Me.[no]
End Sub
Button 2 - open (Bale Spike Certificate) report (same report that button 1 points to) but when it opens it requests the user to enter the serial number [no] which will show the report of the entered serial number.
Can get the report to work off a query by using a criteria on the [no] field, but when I change the report to use the query as the record source, button 1 (current record print) stops working and the other way round, if I use DoCmd for the current record.
Is there a way of achieving this? Or do I create 2 reports for each button?

You could use an InputBox:
Private Sub Button2_Click()
Dim SerialNo As Long
SerialNo = Val(InputBox("Enter Serial No.:", "Bale Spike Certificate"))
If SerialNo > 0 Then
DoCmd.OpenReport "Bale Spike Certificate", acViewPreview, , "[no] = " & SerialNo & ""
End If
End Sub

Related

How to make textbox inputs numbers with 2 decimal places and then check their sum?

struggling with something in VBA and can't find a clear answer online. Quite new to this. Basically, for the user form below (linked image due to my level), I would like to make all the textbox inputs be numbers (2 decimal places) and then when you click "Next" it checks that all the values sum to 100. If not, error message appears. I've tried lots of different ways of doing this and can't get it to work. I would like for all textbox inputs to be numbers (2dp), and then all the numbers to just add and then check this sum. For each textbox, I've done the following Sub Routine (variable name changes each time for name of textbox):
Private Sub BinQnt_AfterUpdate()
On Error Resume Next
Dim BinQnt As Single
BinQnt = Format(BinQnt, "percent")
End Sub
For the Next button I have done the following:
Private Sub MaterialsData_Next_Click()
'Check mix design = 100%.
'If = 100%, input data to database.
tot = BinQnt + FillQnt + FineQnt + CoarQnt + RAPQnt + CRQnt 'Names of each text box.
If tot = 100 Then
'Code here for inserting values into database. Omitted to save space and confusion.
'Go to next page.
BaseUserForm.MultiPage1.Value = 2
'If doesn't = 100%, then show error MsgBox
Else
MsgBox "Error, please check mixture design sums to 100%. Currently at " & tot & "."
End If
Screenshot of userform.

How to limit a drop down list in a combo box to only show the values that include the letters that the user typed?

I am using Access 2010 database. I have a combo box that gives me a full list of equipment numbers (they have letters and numbers i.e.: sdp1234).
To try to speed up the database I was told to limit the drop down lists in combo boxes.
Currently, users can start typing the equipment # and an item from the list will be highlighted matching with their typed characters.
I want the users to be able to type "12" and the list show should have only the values between "sdp1200" and "sdp1299". Or even just all the items that have "12" inside.
I am not sure if this is done in VBA or in the properties tab for the combo box.
Well a solution would be :
Put this on the top of your VBA..just under Option ...
Dim comboboxOriginal As String
Put this code in the Change Event
Private Sub cboFilterAsType_Change()
If Len(Nz(comboboxOriginal, "")) = 0 Then
comboboxOriginal = Me.cboFilterAsType.RowSource
End If
If Len(Me.cboFilterAsType.Text) > 1 Then
Me.cboFilterAsType.SelStart = Len(Me.cboFilterAsType.Text)
Me.cboFilterAsType.RowSource = Replace(comboboxOriginal, ";", "") & " WHERE SOMEFIELD like ""*" & Me.cboFilterAsType.Text & "*"""
DoCmd.RunCommand acCmdSaveRecord
Me.cboFilterAsType.Requery
Me.cboFilterAsType.Dropdown
End If
End Sub
TO clear the filtering
Private Sub cboFilterAsType_DblClick(Cancel As Integer)
If Len(Nz(comboboxOriginal, "")) > 0 Then
Me.cboFilterAsType.RowSource = comboboxOriginal
End If
End Sub
Take a note that the RowSource should be something simple like SELECT SomeID From ATable

Count row in ms access report that have same data in 2 column

form before that user need to select and when search button is clicked, it will show a report based on user selection
this is the report after the search button is click
Hi expert. I have a problem in looking for rows in ms access report that have duplicate data across columns family and name. So if in the first row column family = a and name = b, and in another row family = a and name = b, then we have a duplicate row regardless of other columns. I want it to count from the report not from the table or query. This is because the report will show based on user selection on combo box and list box from other form. and when the search button was clicked, then it will generate the report.
Therefore, I would like to have a button "Summary" in report where its can show result like below (based on report form):
the result
and so on ....
I hope i can get a positive feedback from you guys. Thanks
Below are the code that i used to generate the report :
Code for button report
one way to do this without passing more than 1 parameter is to place the summary in a sub report and reveal that sub report with the push of a button. Unfortunately sub reports in footers are buggy in access so you have to filter the sub report manually.
we start with a similar simple normalized database:
Then I added a simple form with a multi-select listbox of families and a button to open a filtered report.
Private Sub cmdSearch_Click()
'Build Filter for report
Dim strFilter As String
Dim firstselectedfamily As Boolean
firstselectedfamily = True
For i = 0 To lstFamilys.ListCount - 1
If lstFamilys.Selected(i) = True Then
If firstselectedfamily = True Then
strFilter = "FamilyFK = " & lstFamilys.Column(0, i)
firstselectedfamily = False
Else
strFilter = strFilter & " OR FamilyFK = " & lstFamilys.Column(0, i)
End If
End If
Next i
'open report with filter
DoCmd.OpenReport "ExampleReport", acViewReport, "", strFilter, acNormal
End Sub
here is the ExampleReport with a button to show a summary of duplicates:
The button reveals the hidden sub report based on a query that finds the duplicates:
The duplicates query is made by grouping based on family and test where both the count of familyID and TestID is at least 1:
Normally the summary report would be linked to the main report by a master child relationship, but the summary looks natural in the main reports footer where sub reports happen to be bugged and do not filter correctly. To get around the bug we provide code to filter the summary report:
Private Sub cmdSummary_Click()
'filter summary form by using the main reports filter
Me.subfrmSummary.Report.Filter = Me.Filter
Me.subfrmSummary.Report.FilterOn = True
Me.subfrmSummary.Requery
'show/hide summary form
If Me.subfrmSummary.Report.Visible = False Then
Me.subfrmSummary.Report.Visible = True
Else
Me.subfrmSummary.Report.Visible = False
End If
End Sub
Again, to get around the bug do not link the sub report to the main report with a master/child relationship. Instead set the filter with code.
You can build an aggregate query based on your report query, and build a report based on this query.
SELECT Family, whichTest, Count(*) as ProductCount FROM Report_Query_Name GROUP BY Family, whichTest
This takes in to consideration that you have the report query saved as a separate query outside of your report.

Access Report with multiple column groups

So I'm working on automating a tedious process that uncle sam makes us do while deployed. I have a database where we put in a date for each day we are deployed into a table. For instance I have 4/10/2017 through 7/11/2017 listed.
Each day needs the date and location displayed and I need to put six results stacked vertically then move to the right to do the next six three more times.
I have one report named 2282report which is the master one with four subLocation[1-4]s in the appropriate spot. Originally I had it do TOP 6 then the next one would do TOP 6 but where ID > 6 but then I moved to make the date the ID as the date can't be duplicated anyway. I'm unsure of the proper way to make them linked so that the next subreport will display continue the rest.
The report looks like this when ran. I will also have over 90 days usually to list so I will need to create a second page to the main report.
What I'm thinking I'll have to do is create a new subreport for the entire location block but I don't know how to make the report_details move to a new column once it shows 6 results.
Another option I just thought of is to leave the subreports blank then make the master report set the controlsource for each one via vba. I feel this one may work because then it can check to see if there are more days then there are lines so that it can create a new page to continue. But then I need to figure out how to make it continue to the next page. There will also be a bottom section that will only have 16 days versus the 24 on the top.
You might be tempted to use VBA in the various report event handlers, but even if this might work, from my experience that would only lead to headaches trying to get everything to format properly. Instead, I recommend creating a new reporting table with a page number on each row. Source the main report from the sorted page number list and bind a multi-column subreport via the page number field. Populate the reporting table with a simple VBA procedure that correctly paginates the rows according to your scheme.
First the reporting table (add constraints as you find necessary):
CREATE TABLE SubReportTable (PageNum LONG, PageOrdinal LONG, _
Ordinal LONG, LastPage BIT, [Date of Service] DATE, [Location] TEXT)
On the SubReport:
Set RecordSoucre property: SubReportTable (alternatively specify a query that sorts on the desired fields)
Set Number of Columns to 4 along with other column settings (padding, direction, etc.).
Set CanGrow property to No on Detail section and other controls as appropriate.
Resize columns and detail section to properly fit all columns on page. (This will likely require going back and forth between print preview and design on the Main Form.)
On the main report, set the following properties:
RecordSource property: SELECT SubReportTable.PageNum FROM SubReportTable WHERE (((SubReportTable.LastPage)=False)) GROUP BY SubReportTable.PageNum ORDER BY SubReportTable.PageNum
Detail section property Force New Page to After Section.
SubReport object's Link Master Fields and Link Child Fields both to PageNum
Resize SubReport object to fit all columns properly.
Duplicate the behavior on the Main Report on a separate "Last Page" report. Set this report to select the proper subset of records based on the pagination data in the reporting table (i.e. LastPage = True). Depending on how different the last page with 16 records is formatted, it might also require creating a separate SubReport just for the 16 records, but you might get away with using the same SubReport as the main report... that'll be your problem to determine.
RecordSource property: SELECT SubReportTable.PageNum FROM SubReportTable WHERE ((SubReportTable.LastPage = True)) GROUP BY SubReportTable.PageNum ORDER BY SubReportTable.PageNum
Finally some code to populate the reporting table. You can either run this procedure directly from the VBA Immediate Window, or put it in some button's click event handler. The pagination logic can be tweaked to get the right amount of records on the last page.
Public Sub PrepareSubReporTable()
On Error GoTo Catch_PrepareSubReporTable
Dim db As Database
Dim rs As Recordset2
Dim rows As Long, pgs24 As Long, rowsLast24 As Long, rows16 As Long
Dim i As Long, p As Long, pi As Long
Set db = CurrentDb
db.Execute "DELETE * FROM [SubReportTable]", dbFailOnError
db.Execute _
"INSERT INTO SubReportTable ( PageNum, PageOrdinal, Ordinal, LastPage, [Date of Service], [Location] )" & _
" SELECT Null AS PageNum, Null AS PageOrdinal, Null AS Ordinal, False as LastPage," & _
" [Data].[Date of Service], [Data].[Location]" & _
" FROM [Data]" & _
" ORDER BY [Data].[Date of Service], [Data].[Location];", _
dbFailOnError
rows = db.OpenRecordset("SELECT Count(*) FROM SubReportTable").Fields(0)
pgs24 = rows \ 24
rows16 = rows - 24 * pgs24
If rows16 > 16 Then
rowsLast24 = rows16
pgs24 = pgs24 + 1
rows16 = 0
Else
rowsLast24 = 24
End If
Set rs = db.OpenRecordset( _
"SELECT * FROM SubReportTable" & _
" ORDER BY [Date of Service], [Location];")
i = 0
Do Until rs.EOF
p = i \ 24 + 1
rs.Edit
rs![PageNum] = p
If p > pgs24 Then
rs![lastPage] = True
pi = (i - pgs24 * 24) Mod 16 + 1
Else
pi = i Mod 24 + 1
End If
rs![PageOrdinal] = pi
i = i + 1
rs![Ordinal] = i
rs.Update
rs.MoveNext
Loop
rs.Close
Exit Sub
Catch_PrepareSubReporTable:
MsgBox Err.Number & ": " & Err.Description, _
vbOKOnly Or vbExclamation, "Error in PrepareSubReporTable"
End Sub
Now generate the main report and the last-page report, either manually or in VBA code somewhere.
Note: I used the field name PageNum instead of Page because that seemed to cause problems with a SubReport binding during print preview... probably because Page is the name of an existing variable / function for reports.

DLookup in Access not running until textBox clicked on in Form

I'm setting 12 TextBox ControlSources in my Form from VBA using the following :
...
Me.Oct.ControlSource = "=DSum('GBPValue', 'MF YTD Actual Income & Adret', 'Month=10 AND Org_Type=[Key]')"
Me.Nov.ControlSource = "=DSum('GBPValue', 'MF YTD Actual Income & Adret', 'Month=11 AND Org_Type=[Key]')"
...
[Key] is the name of a textbox in the form
When the form loads up i get some odd behavior -
all of the summary form text boxes are blank as are all the dlookup text boxes
if i then click on one of the text boxes that has a dlookup control source assigned the summary text boxes for the other columns start to populate with 0's and #Num etc. and the dlookup runs and displays the expected numbers
once i've clicked on all the dlookup fields the summary numbers calc properly.
In the final version of this the query will be re-written after user clicks from the VBA so ... is this a sensible way to get the form to re-query the DB and, if so, how can i make the DLookups run/display automatically so that everything displays immediately on form load?
You are probably looking for Recalc (Me.Recalc). However, I suggest you use a recordset, rather than DlookUp, and the Current event for the form:
Dim rs As DAO.Recordset 'Needs MS DAO 3.x library
Dim db As Database
Dim strSQL As String
Set db = CurrentDb()
'Guessing that key is a form value
'Note that Month is a reserved word
strSQL = "SELECT [Month], Sum(GBPValue) As SumVal " _
& "FROM [MF YTD Actual Income & Adret] " _
& "WHERE Org_Type= " & Me.[Key]
& " GROUP BY [Month]"
Set rs=db.OpenRecordset(strSQL)
'You can probably use a Do While Loop, consider
'naming the controls, eg, Month10
rs.FindFirst "[Month]=10"
Me.Oct = rs!SumVal
'and so on