Create PDF button for current record - vba

Private Sub CreatePDF_Click()
Dim FileName As String
Dim FilePatch As String
FileName = "Geleidelijst" & Me.OrderNrCopy
Filepath = "C:\Users\A\Desktop\Test\" & FileName & ".pdf"
Forms("GeleidelijstForm").Filter = "[InvoerOrderNr]='" & Me![OrderNrCopy] & "'"
Forms("GeleidelijstForm").FilterOn = True
DoCmd.OutputTo acOutputForm, "GeleidelijstForm", acFormatPDF, Filepath
End Sub
It seems to create a PDF of all records, I only want it for the current record but it won't work.
And if possible, if the file already exist to create it with a different name by adding a number behind it or something but that's not necessary.
Thanks for any help.

For anyone that needs the code to create a PDF file from the current record.
Had to change the entire code, it will save the current Form so the Report displays the accurate information and will refresh after, and ask you where you would like to safe the PDF file. Afterwards it will close the print preview.
Replace the FormName, NameOfColumnInTable, NameOfMatchingTextboxOnForum, ReportName and File to your own.
Private Sub CreatePDF_Click()
DoCmd.Save acForm, "FormName"
Me.Refresh
DoCmd.OpenReport "FormName", acViewPreview, , "NameOfColumnInTable = '" & Me.NameOfMatchingTextboxOnForum & "'"
DoCmd.OutputTo acOutputReport, "ReportName", acFormatPDF, File, False, , , _
acExportQualityPrint
DoCmd.Close
End Sub

Related

Passing a variable from one form to another

I created a login screen for my DB which works.
I would like to pass a variable to a text box that will be on the 'Main Menu' form once you're validated.
Here's my code when you click 'Login'.
'Login button submit, validate, welcome message & main menu navigation
Private Sub cmd_login___Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
'query to check if login details are correct
strSQL = "SELECT Name FROM LoginQuery WHERE Username = """ & Me.txt_username.Value & """ AND Password = """ & Me.txt_password.Value & """"
Set db = CurrentDb
Set rst = db.OpenRecordset(strSQL)
If rst.EOF Then
MsgBox prompt:="Incorrect username/password. Try again.", buttons:=vbCritical, title:="Login Error"
Me.txt_username.SetFocus
Else
MsgBox prompt:="Hello, " & rst.Fields(0).Value & ".", buttons:=vbOKOnly, title:="Login Successful"
DoCmd.Close acForm, "frm_login", acSaveYes
DoCmd.Close
DoCmd.OpenForm "MainMenu"
End If
Set db = Nothing
Set rst = Nothing
This line displays a prompt on screen saying Login successful with the "rst.Fields(0).Value" variable which is the users full name, but I'd prefer less windows and buttons to press and instead, pass this variable to a new blank form with a textbox on it.
MsgBox prompt:="Hello, " & rst.Fields(0).Value & ".", buttons:=vbOKOnly, title:="Login Successful"
I named the textbox on the MainMenu form, txt_welcome.
I tried appending the below in the IF statement:
Dim name As String
name = "SELECT Name FROM LoginQuery WHERE Username = """ & Me.txt_username.Value & """ AND Password = """ & Me.txt_password.Value & """"
[MainMenu]![txt_welcome].Value = name
[MainMenu]![txt_welcome].Value = "dsfadsf"
MainMenu!txt_welcome.value = "justdisplaysomethingplz"
You can pass it through the OpenArgs parameter of the DoCmd.OpenForm method.
DoCmd.OpenForm "MainMenu", OpenArgs:="Something"
Then, on the MainMenu form, read its value when the form loads:
Private Sub Form_Load()
If Not IsNull(OpenArgs) Then Debug.Print OpenArgs
End Sub

How do you go to a specific record chosen from a listbox and displayed on the navigation form?

I have a navigation form which has a subform with a recordsource tblA.
Currently, the subform displays the specific record in popup window. Is it possible for it to display the record in the navigation form without having to pop up?
Private Sub Search_Change()
Dim where As String
Const SQLResults As String = "SELECT itemNumber, itemName FROM tblMain "
<whereclause> ORDER BY ItemName;"
If Me.Search.Text <> "" Then
where = "WHERE itemName LIKE '*" & Me.Search.Text & "*' "
End If
Me.SearchResults.RowSource = Replace(SQLResults, "<whereclause>", where)
End Sub
The below code displays the record in a pop-up window.
Private Sub SearchResults_Click()
Dim searchCriteria As String
searchCriteria = "[itemNumber]='" & Me![SearchResults].Value & "'"
DoCmd.OpenForm "frmDisplay", acNormal, , searchCriteria
DoCmd.Close acForm, "frmSearch"
End Sub
Since form frmNavigation is always open:
Private Sub SearchResults_Click()
DoCmd.OpenForm, "frmDisplay", acNormal, , searchCritera
DoCmd.Close acForm, "frmSearch"
End Sub
Can someone help?
I have done it! I hope this solution helps someone. The code allows the user to select the item in a listbox on a pop-up form and takes the user to that same record on the navigation form. It makes the forms operation simpler without popping up the subform. Note: You do not need to set pop-up feature on the property sheet to false. It will work regardless.
Private Sub SearchResults_Click()
Dim searchCriteria As String
Dim rs As Recordset
searchCriteria = "[itemNo]='" & Me![SearchResults].Value & "'"
Set rs = Forms!frmNavigation!NavigationSubform.Form.RecordsetClone
rs.FindFirst searchCriteria
If Not rs.NoMatch Then Forms!frmNavigation!NavigationSubform.Form.Bookmark = rs.Bookmark
Forms!frmNavigation!NavigationSubform.Form.Filter = "[itemNo]=" & Me.SearchResults.Value
Me.FilterOn = True
Set rs = Nothing
DoCmd.Close acForm, "frmSearch"
End Sub

Code returns incorrect records/fails to update form correctly

So I'm going to try my best to explain the background to clarify understanding of what I'm hoping to achieve. I have a form (Events) that has a tab control, the tab control has 3 different pages each with a different subform on.
One of the subforms (speakers) has a button control that checks the 'speakers' attendeeID and if there is a match opens the 'Onboarding' form to the record that matches.
What it is suppose to do if the record doesn't match is open form to a new record and insert the ContactID, AttendeeID and EventID.
This is the 4th iteration of the code and works to a degree/doesn't return errors
Dim myR As Boolean
Dim strSQL As String
Dim myV1 As Integer
Dim myV2 As Integer
Dim myV3 As Integer
'Define the variables to be input
myV1 = Me.AttendeeID
myV2 = Me.ContactID
myV3 = Me.EventID
'Is there a Matching Onboard Record for the current Attendee Record?
myR = DCount("*", "tbl_Onboarding", "[AttendeeID] = " & Me.AttendeeID) > 0
If myR = True Then
DoCmd.OpenForm "usf_Onboarding", acNormal, , , acFormEdit, acWindowNormal 'Edit Mode
Else 'No Matching Record, so Add one
If Me.Dirty = True Then Me.Dirty = False 'Save pending Edits
DoCmd.OpenForm "usf_Onboarding", acNormal, , , acFormAdd, acWindowNormal 'Add Mode
Forms!usf_Onboarding!txt_ForceFocus.SetFocus
strSQL = "INSERT INTO tbl_Onboarding (AttendeeID,ContactID,EventID) VALUES (" & myV1 & ", " & myV2 & ", " & myV3 & ")"
Debug.Print strSQL
CurrentDb.Execute strSQL, dbFailOnError
Me.Requery
DoCmd.Close acForm, "usf_Events", acSaveYes
End If
Using immediate I have confirmed myV1, myV2 and myV3 are all holding the correct values, and I used breakpoints to check line by line and all seemed to run okay with zero errors thrown back but I still have the following issues depending on whether myR is True/False
If the record exists (myR = TRUE) then something is now causing it
to only load the 1st record of the table (Not the one where the
attendeeID matches).
If the record does not exist (myR = FALSE) after running this the
table has the new record in with the contactID/AttendeeID/EventID
but the form doesn't update to show this (The form controls are set
to locked = False) This results in an error when closing. So
choosing not to save the data (Clicking yes on the box to discard
changes) allows the force exit but the record/data IS saved with
contactID/AttendeeID/EventID
Debug.Print strSQL also didn't do anything weirdly.
Issue 1. "If the record exists (myR = TRUE) then something is now causing it to only load the 1st record of the table (Not the one where the attendeeID matches)."
I needed to add a where clause to the openform command
DoCmd.OpenForm "usf_Onboarding", acNormal, , "AttendeeID = " & Me.AttendeeID, acFormEdit, acWindowNormal
Issue 2. "If the record does not exist (myR = FALSE) after running this the table has the new record in with the contactID/AttendeeID/EventID but the form doesn't update to show this (The form controls are set to locked = False) This results in an error when closing. So choosing not to save the data (Clicking yes on the box to discard changes) allows the force exit but the record/data IS saved with contactID/AttendeeID/EventID"
I was loading the form before creating the new records and trying to then requery another new record not the one it created. All I needed was add record first then use the open code above to load that record instead
Else 'No Matching Record, so Add one
If Me.Dirty = True Then Me.Dirty = False 'Save pending Edits
strSQL = "INSERT INTO tbl_Onboarding (AttendeeID,ContactID,EventID) VALUES (" & myV1 & ", " & myV2 & ", " & myV3 & ")"
CurrentDb.Execute strSQL, dbFailOnError
DoCmd.OpenForm "usf_Onboarding", acNormal, , "AttendeeID = " & Me.AttendeeID, acFormEdit, acWindowNormal

MS Access save record as PDF using ID

My organization uses a MS Access database to store incident reports. I have a report called "Case Details" and I want to have the option to save the report that's currently open as a PDF. I've got it working for the most part, the only issue is that when saving the PDF, it's saving all of the records, not just the record that was being viewed.
How do I fix it so that it only saves the record being viewed, using the record's ID?
Here's the code for the save button.
Private Sub Command1626_Click()
DoCmd.OutputTo acOutputReport, "Case Details", acFormatPDF, "G:\Police\Restricted\Saved Reports\ " & Me.txtPDFRef & ".pdf", True
End Sub
The "txtPDFRef" box on the report contains the following code, which is used to name the report. (Case Number - Officer - Date Saved)
="CR" & Format(Date(),"yy") & "-000" & [ID] & " - " & [ReportingOfficer] & " - " & Format(Date(),"yyyymmdd")
It seems the only way is to filter the report to the record to be printed.
So it's essential to determine the ID of the record to be printed.
It's not clear for me, if your button is located on the report itself or maybe on a form.
Button on the report itself
I tried to get it running when the button is on the report itself.
To determine the current ID it seems to be necessary that the calling button is located in the detail section of the report.
Then you can filter the report, export it to pdf and restore the maybe before applied filter.
The only backdraw is, that I found no way to view the last viewed record in the report after the code executed.
Instead you are on the first record.
This would be the code for the button:
Dim currentFilter As String
currentFilter = Me.Filter
Dim currentFilterOn As Boolean
currentFilterOn = Me.FilterOn
'If field type of ID is a number use this:
Me.Filter = "[ID] = " & Me.ID
'If field type of ID is a string use this:
'Me.Filter = "[ID] = '" & Me.ID & "'"
Me.FilterOn = True
DoCmd.OutputTo acOutputReport, Me.Name, acFormatPDF, "G:\Police\Restricted\Saved Reports\ " & Me.txtPDFRef & ".pdf", True
Me.Filter = currentFilter
Me.FilterOn = currentFilterOn
Button on a form
If the button is for example on a form and you just want to print the regarding report, then you could use this code in this button:
Const REPORT_NAME As String = "Case Details"
Dim condition As String
'If field type of ID is a number use this:
condition = "[ID] = " & Me.ID
'If field type of ID is a string use this:
'condition = "[ID] = '" Me.ID & "'"
DoCmd.OpenReport REPORT_NAME, acViewPreview, , condition, acHidden
'You would have to provide txtPDFRef in another way, because the report isn't open yet.
DoCmd.OutputTo acOutputReport, REPORT_NAME, acFormatPDF, "G:\Police\Restricted\Saved Reports\ " & Me.txtPDFRef & ".pdf", True
DoCmd.Close acReport, REPORT_NAME
It closes the report after saving to pdf. Be aware that you maybe have to provide txtPDFRef in a different way. But maybe it exists on the form too with the same name, that would make it run immediately.
Simplest solutions:
Option 1
Open the report in preview with a filter, then use outputTo without the ObjectName argument.
docmd.openReport "Case Details",,"id = " & id
docmd.outputTo objectType:=acOutputReport, outputFormat:=acFormatPDF, outputFile:= somefileName
docmd.close acOutputReport, "Case Details"
Option 2 (even simpler)
In design view, change the reports'filter property to refer to a control in the calling form.
Something like id = forms!someForm.idControl

Access report not updating after query change

I have a form, below, that allows the user to filter the database multiple ways. When they push the filter button on the form a report populates based on the filter query. The issue is if I filter the database again, even with .requery in the report code, the report doesn't update to the new Query results. I know if I manually close out of the report it works, however when I code it to DoCmd.Close it doesn't actually close the report. If I show it in
acViewPreview it updates each time I use the refilter button on the form but then I cant use buttons on the report. I am trying to make it like a kiosk so I don't want the nav tabs to show.
Filter form
Report
Form Code:
Private Sub btnFilter_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim SQL2 As String
Dim ToDate As Date
Dim FromDate As Date
SQL2 = ""
Set db = CurrentDb()
Set qdf = db.QueryDefs("Filter")
If cmbFilter.Value = "Vended Date" Then
ToDate = Format(DTPickerTo.Value, "YYYY-MM-DD")
FromDate = Format(DTPickerFrom.Value, "YYYY-MM-DD")
SQL2 = "SELECT CribMaster_Quality.Line,CribMaster_Quality.[Vended Date],CribMaster_Quality.PartNumber,CribMaster_Quality.Group,CribMaster_Quality.ItemNumber,CribMaster_Quality.Amount,CribMaster_Quality.Description,CribMaster_Quality.Cost,CribMaster_Quality.[Extended Cost],CribMaster_Quality.User " & _
" FROM CribMaster_Quality" & _
" WHERE CribMaster_Quality.[Vended Date]" & _
" BETWEEN #" & FromDate & "# AND #" & ToDate & "#" & _
" ORDER BY CribMaster_Quality.[Vended Date] DESC;"
ElseIf ckbDateConst = True Then
ToDate = Format(DTPickerTo.Value, "YYYY-MM-DD")
FromDate = Format(DTPickerFrom.Value, "YYYY-MM-DD")
SQL2 = "SELECT CribMaster_Quality.Line,CribMaster_Quality.[Vended Date],CribMaster_Quality.PartNumber,CribMaster_Quality.Group,CribMaster_Quality.ItemNumber,CribMaster_Quality.Amount,CribMaster_Quality.Description,CribMaster_Quality.Cost,CribMaster_Quality.[Extended Cost],CribMaster_Quality.User " & _
" FROM CribMaster_Quality" & _
" WHERE CribMaster_Quality." & Me!cmbFilter.Value & " = '" & Me!cmbFilterBy.Value & "' And CribMaster_Quality.[Vended Date] " & _
" BETWEEN #" & FromDate & "# AND #" & ToDate & "#" & _
" ORDER BY " & Me.cmbFilter.Value & " DESC;"
Else
SQL2 = "SELECT CribMaster_Quality.Line,CribMaster_Quality.[Vended Date],CribMaster_Quality.PartNumber,CribMaster_Quality.Group,CribMaster_Quality.ItemNumber,CribMaster_Quality.Amount,CribMaster_Quality.Description,CribMaster_Quality.Cost,CribMaster_Quality.[Extended Cost],CribMaster_Quality.User " & _
" FROM CribMaster_Quality" & _
" WHERE CribMaster_Quality." & Me!cmbFilter.Value & " = '" & Me!cmbFilterBy.Value & "'" & _
" ORDER BY " & Me.cmbFilter.Value & " DESC;"
End If
qdf.SQL = SQL2
Set db = Nothing
Set qdf = Nothing
DoCmd.OpenReport "CribMasterReport", acViewReport
End Sub
Report Code:
Private Sub btnReFilter_Click()
DoCmd.Close , acSaveNo
DoCmd.OpenForm "Filter Database Form"
End Sub
Private Sub Report_Load()
Me.Requery
With VendedDatetxt
.Requery
End With
With ItemNumbertxt
.Requery
End With
With Linetxt
.Requery
End With
With PartNumbertxt
.Requery
End With
With Usertxt
.Requery
End With
With Amounttxt
.Requery
End With
With Costtxt
.Requery
End With
With ExtendedCosttxt
.Requery
End With
End Sub
Issue 1: Requerying the Report
When a report is opened using standard techniques, such as clicking on a report in the Navigation pane or when opening a report using DoCmd.OpenReport, Access creates a default instance of the Report that is accessible via the Application.Reports collection. Before the report is first opened or if the default report instance is completely closed (i.e. removed from memory), the Application.Reports collection will not contain an instance of the report. Before accessing the default instance, ensure that the report is already open.
Like other MS Office object-model collections, Application.Reports does not have a "Contains" method or other direct way to test whether a report is already open, only by looping through numeric indexes and testing each report object. Although it seems sloppy to me, the easiest method is to use error handling to try getting the report directly, then catching the error if it's not found:
On Error Resume Next
Set frm = Application.Reports("CribMasterReport")
If err.Number <> 0 Then
'Default instance not open
End If
CAUTION: Do not refer to the report using the class name like an object, as in Report_CribMasterReport.Requery. If you do that, VBA will automatically create a new, hidden instance of the report, but it is NOT the same default instance as described above and this new instance will not be accessible via the Application.Reports collection. Likewise, using the properties and calling methods on such an object will be largely ineffective. (It is possible to create and use such independent instances, but that is an advance technique riddled with its own pitfalls and challenges.)
As the question describes, which is also confirmed by other online sources, the Report.Requery is not effective in refreshing the report after the underlying query or data have changed. However, resetting the Report.RecordSource forces a full refresh of the report when in normal Report View.
Issue 2: Report not closing
The DoCmd.Close command was missing a comma. It should be DoCmd.Close , , acSaveNo. Even better is to always use explicit names for optional parameters. Typing an extra parameter is definitely worth the saved frustration and time with typos in an ambiguous list of commas:
DoCmd.Close Save:=acSaveNo
Issue 3: Unnecessary calls
It is completely unnecessary to call Requery on the report and every single control in the Report_Load event. I get that you were trying to debug the situation, but this behavior should happen automatically. Also, the Form_Load event occurs only once when the form is first loaded, so that code would not be called again unless the report is completely closed and reopened.
Finally some alternative code
Private Sub btnFilter_Click()
'... Include previous code to reset report query
'* Call DoCmd.OpenReport every time to
'* 1) Ensure default report is open
'* 2) Automatically activate the report (even if it was already open)
DoCmd.OpenReport "CribMasterReport", acViewReport
On Error Resume Next
Dim frm As Report_CribMasterReport
Set frm = Application.Reports("CribMasterReport")
If Err.Number = 0 Then
'* Force the Report object to re-run query and recreate report
frm.RecordSource = frm.RecordSource
End If
End Sub
It is no longer be necessary to completely close the report.
Private Sub btnReFilter_Click()
''DoCmd.Close Save:=acSaveNo
DoCmd.OpenForm "Filter Database Form"
End Sub
Private Sub Report_Load()
'* Eliminated unnecessary Requery calls
End Sub