Access VBA Loop through Query help - ms-access

I have a form (Cobind_frmMain) that allows the user to create a pool of titles that are attached to it. So there is a top level Pool Name (TopLvlPoolName) and on a subform, the titles are added to it. What I need is to issue a Report for each of the titles. I have the report and queries all set up. Right now, the report will show all the titles in one file. The titles are in a field called "CatCode".
What I need is the following:
1. Save each title as a PDF and save it to our server.
2. Open email and attach the PDF.
3. Repeat until all titles are done.
EDIT: This is what I have so far for code and the error message I still get is: "Too Few Parameters" on the Set Recordset line. I'm trying to set the parameter in the strSQL line. I want the PartPoolName (in Cobind_qryReport, a query) to equal the TopLvlPoolName on the open form. The SQL for Cobind_qryReport is listed below:
Private Sub btn_Run_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "Select * FROM Cobind_qryReport WHERE PartPoolName = " & Me.TopLvlPoolName
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 Recordset.EOF = False
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF, "K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" & [CatCode] & "_" & [PartPoolName] & "Cobind Invite_" & Format(Now(), "mmddyy") & ".pdf"
DoCmd.SendObject acSendReport, "Cobind_rptMain", acFormatPDF, , , , [CatCode] & "_" & [PartPoolName] & " Cobind Invite", "Please find the cobind invite attached. Response is needed by " & [RSVP] & ". Thank you.", True
Recordset.MoveNext
Loop
End If
Exit_PO_Click:
MsgBox ("It didn't work")
Exit Sub
Err_PO_Click:
MsgBox Err.Description
Resume Exit_PO_Click
End Sub
Cobind_qryReport SQL:
SELECT tblEvents.EventTitle, Cobind_tblPartic.CatCode, Cobind_tblPartic.CodeQty, Cobind_tblPartic.PartPoolName, Cobind_tblTopLvl.RSVP, Cobind_tblPartic.ID
FROM Cobind_tblTopLvl, Cobind_tblPartic INNER JOIN tblEvents ON Cobind_tblPartic.CatCode = tblEvents.EventCode
GROUP BY tblEvents.EventTitle, Cobind_tblPartic.CatCode, Cobind_tblPartic.CodeQty, Cobind_tblPartic.PartPoolName, Cobind_tblTopLvl.RSVP, Cobind_tblPartic.ID
ORDER BY Cobind_tblPartic.ID;
Thank you again for all your help!

You're query Cobind_qryReport has a parameter that you need to set. if you want to know the parameter name try the following code
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("Cobind_qryReport")
If qdf.Parameters.Count > 0 Then
MsgBox (qdf.Parameters(0).Name)
End If
Update
Since you know you've got a parameter doing select * from Cobind_qryReport it might just be easier to set the parameter and then use the qdf to open the recordset e.g.
Dim rs as DAO.Recordset
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("Cobind_qryReport")
qdf.Parameters(0).Value = 7832
Set foo = qdf.OpenRecordset()
Note: you can use the parameter name in the place of the ordinal when setting the parametervalue
e.g. qdf.Parameters("Foo").value = 7832

Related

Creating Event Procedure in MS Access

I have tried to create the event procedure, but It returns zero irrespective of my selection.
I have two tables, which are correctly joined, and below is the code that has an issue.
First, "MsgBox Me.Technology" is returning my selection value eg. Python, Java, but "MsgBox rs!ProjEmployeeID" is returning 0 all times. Help me troubleshoot the code. Thank you. I want it to return Project Employee ID like 1, 2, 3
Option Compare Database
Private Sub Technology_AfterUpdate()
MsgBox Me.Technology
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT ProjEmployeeID FROM Project WHERE Technologies = Trim('" & Forms!Form_employee_by_technologies!Technology & "')")
rs.AddNew
MsgBox rs!ProjEmployeeID
Dim strDocName As String
Dim strWhere As String
strDocName = "Technology"
strWhere = "[EmployeeID] =" & rs!ProjEmployeeID
DoCmd.OpenReport strDocName, acViewReport, , strWhere, acWindowNormal
End Sub

VBA SQL Sum Operation in Form

In my form i want to use a sum on row SWS from tblKurse used in the query for the form. On a Button Click event i want to sum the values in that row whenever the criterion in my where is met. Problem is i get an invalid argument error whenever i run it. I just cant find my mistake. Maybe someone can help.
Heres the function that i call after the button click event:
Public Function chkSWS() As Integer
Dim db As Database
Dim rst As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT SUM(tblKurse.SWS) As Stunden " _
& "FROM tblKurse " _
& "WHERE tblKurse.Dozent_ID = " & Me.cmbKursDOzent
Debug.Print strSQL
Debug.Print Me.Dozent_ID
Set rst = db.OpenRecordset(strSQL, dbForwardOnly)
chkSWS = rst![Stunden]
Set rst = Nothing
Set db = Nothing
End Function
Error points on the "Set rst" line, so it might been a bad Select statement?
printed SQL Statement:
SELECT SUM(tblKurse.SWS) As Stunden FROM tblKurse WHERE tblKurse.Dozent_ID = 1
Change this line
Set rst = db.OpenRecordset(strSQL, dbForwardOnly)
to this
Set rst = db.OpenRecordset(strSQL, dbOpenSnapshot)

MS ACCESS how to change a query criteria to look up a record and then create a report

enter image description herei have a program that create field tickets, when the ticket is finished i can see it in a list box name FinishedJobs, when i double click on a ticket inside the listbox it ask me if i want to reopen it or send it to print. The first one (reopen) is done but the second one i can't get it to work.
The problem is i have the ticket number in a variable named strCriteria and i want to use that value and put it in the criteria inside the query name JobsTicketGeneralReport, so i can open a report using that query.
PLEASE HELP ME TO CHANGE THE CRITERIA IN THE QUERY TO SEARCH MY TICKET NUMBER. I'M WILLING TO CHANGE THE CODES IF YOU SUGGEST THAT.
NOTE: My query is a combine query it has 6 tables and has the ticket number in common, when i call the ticket number it bring the information of all tables.
This what i am doing:
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As Recordset
Dim varItem As Variant
Dim strCriteria As String
Dim qdfOld As String
Dim strSQL As String
' Get the database and stored query
Set db = CurrentDb()
Set qdf = db.QueryDefs("JobsticketGeneralReport")
' Loop through the selected items in the list box and build a text string
For Each varItem In Me!List0.ItemsSelected
strCriteria = strCriteria & ",'" & Me.List0.Column(0) & "'"
Next varItem
' Check that user selected something
If Len(strCriteria) = 0 Then
MsgBox "You did not select anything from the list" _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
'Debug.Print strCriteria
' Remove the leading comma from the string
strCriteria = Right(strCriteria, Len(strCriteria) - 1)
Debug.Print strCriteria
' change criteria in query
qdf.Parameters(0).Value = Trim(strCriteria)
Set rst = qdf.OpenRecordset
DoCmd.OpenQuery "JobsticketgeneralReport"
DoCmd.OpenReport "JobsticketgeneralReport", acpreview
rst.Close
qdf.Close
Set rst = Nothing
Set qdf = Nothing
HERE IS MY SQL:
SELECT JobsOrder.StartDigDate, JobsOrder.Ticket, JobsOrder.DigNumber, JobsOrder.JobType,
JobsOrder.JobAddressNumber, JobsOrder.JobAddressName, JobsOrder.JobAddressTown,
JobsOrder.JobDescription, JobsOrder.AssetID, JobsOrder.Notes, JobsOrder.FINISH,
JobsOrder.updateGIS, JobsOrder.Priority, GENERAL.STARTJOBDATE, GENERAL.ENDJOBDATE,
GENERAL.DAY1, GENERAL.DAY2, GENERAL.EMPLOYEE0, GENERAL.EMPLOYEE1, GENERAL.EMPLOYEE2,
GENERAL.EMPLOYEE3, GENERAL.EMPLOYEE4, GENERAL.EMPLOYEE5, GENERAL.EMPLOYEE6,
GENERAL.EMPLOYEE7, GENERAL.VEHICLE0, GENERAL.VEHICLE1, GENERAL.VEHICLE2,
GENERAL.VEHICLE3, GENERAL.VEHICLE4, GENERAL.VEHICLE5, GENERAL.EMPLOYEE0TIME,
GENERAL.EMPLOYEE1TIME, GENERAL.EMPLOYEE2TIME, GENERAL.EMPLOYEE3TIME,
GENERAL.EMPLOYEE4TIME, GENERAL.EMPLOYEE5TIME, GENERAL.EMPLOYEE6TIME,
GENERAL.EMPLOYEE7TIME, GENERAL.DRAWINGATT, GENERAL.FINISH, GENERAL.ASPHALT,
GENERAL.ROW, GENERAL.CONCRETE, GENERAL.DIRT, GENERAL.TRENCH, MAINS.[JOBTYPE-MAIN],
MAINS.MATERIAL, MAINS.SIZE, MAINS.DEPTH, MAINS.INTERNALCONDITION, MAINS.COMMENTS,
MAINS.REPAIRLOCATION, MAINS.LOCATION1, MAINS.LOCATION2, MAINS.MATERIAL1,
MAINS.MATERIAL2, MAINS.MATERIAL3, MAINS.MATERIAL4, MAINS.MATERIAL5,
MAINS.MATERIAL6, MAINS.MATERIAL7, MAINS.MATERIAL8, MAINS.MATERIAL9,
MAINS.MATERIAL10, MAINS.MATERIAL11, MAINS.MATERIAL12, MAINS.QTY1, MAINS.QTY2,
MAINS.QTY3, MAINS.QTY4, MAINS.QTY5, MAINS.QTY6, MAINS.QTY7, MAINS.QTY8,
MAINS.QTY9, MAINS.QTY10, MAINS.QTY11, MAINS.QTY12, MAINS.ENABLE, SERVICES.JOBPERFORMBY,
SERVICES.SERVICEASSET, SERVICES.OFFON, SERVICES.[MATERIAL-MC], SERVICES.[SIZE-MC],
SERVICES.[DEPTH-MC], SERVICES.[MATERIAL-CB], SERVICES.[SIZE-CB], SERVICES.[DEPTH-CB],
SERVICES.CURBBOXLOCATION, SERVICES.LOCATION1, SERVICES.LOCATION2, SERVICES.LOCATION3,
SERVICES.[SERVICE-COMMENT], SERVICES.[MATERIAL1-MC], SERVICES.[MATERIAL2-MC],
SERVICES.[MATERIAL3-MC], SERVICES.[MATERIAL4-MC], SERVICES.[MATERIAL5-MC],
SERVICES.[MATERIAL6-MC], SERVICES.[MATERIAL7-MC], SERVICES.[MATERIAL8-MC],
SERVICES.[QTY1-MC], SERVICES.[QTY2-MC], SERVICES.[QTY3-MC], SERVICES.[QTY4-MC],
SERVICES.[QTY5-MC], SERVICES.[QTY6-MC], SERVICES.[QTY7-MC], SERVICES.[QTY8-MC],
SERVICES.[MATERIAL1-CB], SERVICES.[MATERIAL2-CB], SERVICES.[MATERIAL3-CB],
SERVICES.[MATERIAL4-CB], SERVICES.[MATERIAL5-CB], SERVICES.[MATERIAL6-CB],
SERVICES.[MATERIAL7-CB], SERVICES.[MATERIAL8-CB], SERVICES.[QTY1-CB],
SERVICES.[QTY2-CB], SERVICES.[QTY3-CB], SERVICES.[QTY4-CB], SERVICES.[QTY5-CB],
SERVICES.[QTY6-CB], SERVICES.[QTY7-CB], SERVICES.[QTY8-CB], SERVICES.REPAIR,
SERVICES.Replace, SERVICES.INSTALL, SERVICES.REMOVE, SERVICES.TEMPDISCONNECT,
SERVICES.ENABLE, HYDRANT.[ENABLE-H], HYDRANT.[HYDRANT-ASSET], HYDRANT.[REPAIR-H],
HYDRANT.[REPLACE-H], HYDRANT.[INSTALL-H], HYDRANT.FLUSH, HYDRANT.FLOWTEST,
HYDRANT.PARTS1, HYDRANT.PARTS2, HYDRANT.PARTS3, HYDRANT.PARTS4, HYDRANT.PARTS5,
HYDRANT.PARTS6, HYDRANT.PARTS7, HYDRANT.PARTS8, HYDRANT.[QTY1-H], HYDRANT.[QTY2-H],
HYDRANT.[QTY3-H], HYDRANT.[QTY4-H], HYDRANT.[QTY5-H], HYDRANT.[QTY6-H],
HYDRANT.[QTY7-H], HYDRANT.[QTY8-H], HYDRANT.JOBPERFORM, HYDRANT.[MANUFACTORY OLD],
HYDRANT.MANUFACTORY, HYDRANT.SIZENEW, HYDRANT.SIZEOLD, HYDRANT.JOBNOTES,
HYDRANT.TIMEOPEND, HYDRANT.TIMECLOSED, HYDRANT.TIMETOCLEAR, HYDRANT.COLOROPEN,
HYDRANT.COLORCLOSE, HYDRANT.REMARKS, HYDRANT.[STATIC-PRESSURE], HYDRANT.[RESIDUAL-PRESSURE],
HYDRANT.[PITOT-TESTFLOWRATE], HYDRANT.CAPACITY, HYDRANT.[ASSET-ID1],
HYDRANT.[ASSET-ID2], VALVES.ENABLE, VALVES.[REPAIR-V], VALVES.[REPLACE-V],
VALVES.[INSTALL-V], VALVES.[REMOVE-V], VALVES.[MAINTENANCE-V], VALVES.VALVECOMMENT,
VALVES.[MATERIAL1-V], VALVES.[MATERIAL2-V], VALVES.[MATERIAL3-V], VALVES.[MATERIAL4-V],
VALVES.[MATERIAL5-V], VALVES.[MATERIAL6-V], VALVES.[QTY1-V], VALVES.[QTY2-V],
VALVES.[QTY3-V], VALVES.[QTY4-V], VALVES.[QTY5-V], VALVES.[QTY6-V],
VALVES.[LOCATION1-V], VALVES.[LOCATION2-V], VALVES.[LOCATION3-V], VALVES.[LOCATION4-V],
VALVES.VALVE1, VALVES.VALVE2, VALVES.VALVE3, VALVES.VALVE4, VALVES.VALVE5,
VALVES.VALVE6, VALVES.VALVE7, VALVES.VALVE8, VALVES.VALVEPOSITION1,
VALVES.VALVEPOSITION2, VALVES.VALVEPOSITION3, VALVES.VALVEPOSITION4,
VALVES.VALVEPOSITION5, VALVES.VALVEPOSITION6, VALVES.VALVEPOSITION7,
VALVES.VALVEPOSITION8, VALVES.[VALVE-TURNS1], VALVES.[VALVE-TURNS2],
VALVES.[VALVE-TURNS3], VALVES.[VALVE-TURNS4], VALVES.[VALVE-TURNS5],
VALVES.[VALVE- TURNS6], VALVES.[VALVE-TURNS7], VALVES.[VALVE-TURNS8],
VALVES.[VALVE-DEPTH1], VALVES.[VALVE-DEPTH2], VALVES.[VALVE-DEPTH3],
VALVES.[VALVE-DEPTH4], VALVES.[VALVE-DEPTH5], VALVES.[VALVE-DEPTH6],
VALVES.[VALVE-DEPTH7], VALVES.[VALVE-DEPTH8], VALVES.REASON1, VALVES.REASON2,
VALVES.REASON3, VALVES.REASON4, VALVES.REASON5, VALVES.REASON6, VALVES.REASON7,
VALVES.REASON8, INSPECT.ENABLE, INSPECT.[CURBBOX-I], INSPECT.[VALVEBOX-I],
INSPECT.[SERVICE-I], INSPECT.CURBBOXREMARKS, INSPECT.VALVEBOXREMARKS, INSPECT.SERVICEREMARKS
FROM (((((JobsOrder
INNER JOIN [GENERAL] ON JobsOrder.Ticket = GENERAL.TICKET)
INNER JOIN MAINS ON GENERAL.TICKET = MAINS.TICKET)
INNER JOIN SERVICES ON MAINS.TICKET = SERVICES.TICKET)
INNER JOIN HYDRANT ON SERVICES.TICKET = HYDRANT.TICKET)
INNER JOIN VALVES ON HYDRANT.TICKET = VALVES.TICKET)
INNER JOIN INSPECT ON VALVES.TICKET = INSPECT.TICKET
WHERE (((JobsOrder.Ticket)=[ticket])
AND ((JobsOrder.FINISH)=True))
ORDER BY JobsOrder.StartDigDate, JobsOrder.Ticket;
If you want to use a parameter in the query, you should explicitly define it. Also, it is a good idea to give the parameter a different name than the involved tables and fields.
To do this, use the "Parameters" window in query design, or add a PARAMETERS clause to the beginning of the SQL:
PARAMETERS parTicket Text ( 255 );
SELECT .....
and in the WHERE clause
WHERE (((JobsOrder.Ticket)=[parTicket])
This is mainly useful if you want to read data from the query in VBA, i.e. you need this for
Set rst = qdf.OpenRecordset
But if the query is RecordSource for a report, this won't work, because the report opens its own instance of the query. In this case, you need Parfait's solution: directly use the listbox in the query.
WHERE ((JobsOrder.Ticket) = Forms!yourForm!List0)
For Each varItem In Me!List0.ItemsSelected
strCriteria = strCriteria & ",'" & Me.List0.Column(0) & "'"
Next varItem
This cannot work - you must use varItem in the loop.
Me.List0.Column(0) will always pick the same element.
Debug.Print strCriteria
This should have told you what went wrong.

How to split a report into multiple PDF files

Let's say I have an hundred page report in Access 2010 that includes lists of names (with some other details), grouped by a variable called NOM_RITIRO.
I would like to output the report into different PDF files, one for each value of the variable used for grouping.
I was trying to figure out how to make this code work:
Sub SplitPdf()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim Source As String
Dim SQL As String
Dim MyPath As String
Dim MyFilename As String
MyPath = "D:\Folder\"
Set db = CurrentDb
SQL = "Select NOM_RITIRO From QueryNominativi Group By NOM_RITIRO"
Set rs = db.OpenRecordset(SQL)
While Not rs.EOF
MyFilename = "TK_" & rs!NOM_RITIRO & ".pdf"
' Apply quotes as NOM_RITIRO is a string.
DoCmd.OpenReport "ElenchiNominativi", acViewPreview, , "NOM_RITIRO = '" & rs!NOM_RITIRO.Value & "'"
DoCmd.OutputTo acOutputReport, , acFormatPDF, MyPath & MyFilename, False
DoCmd.Close acReport, "ElenchiNominativi"
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
I got stuck when I try to run the DoCmd.OpenReport.
I get the message box "Enter parameter Value" like if the recordset is not passing any data
Any idea of what I did wrong?
If NOM_RITIRO is not a field in the recordsource of your report called "ElenchiNominativi" (or mis-spelled) then it will prompt you to enter a parameter value.
Similarly, if the recordsource of your report is a query that contains a fieldname not referenced in any of the tables, you will also get this prompt.

Error 3218: Could not update; currently locked

I've been looking through the other questions related to mine, but most are about multi-user and this one came close but not quite.
System
MS Access 2013
with Linked Tables to Office 365 Sharepoint
tblQuote - frmQuote
tblQuoteItems - sbfrmQuoteItems
No Record Locks
I'm attempting to setup a select all/deselect all button that when clicked runs db.Execute Update on the tblQuoteItems where equal to Quote ID and Quote Version.
I have a button on the main form that calls the below process.
Public Sub SelectLineItems(strTable As String, strID As String, _
intID As Integer, bln As Boolean, Optional intVersion As Integer)
Dim db As Database
Dim strSQL As String
Dim strVersion As String
Set db = CurrentDb
strSQL = "UPDATE " & strTable & " SET [Selected] = "
If intVersion > 0 Then
strVersion = " AND [QuoteVersion] = " & intVersion
Else
strVersion = ""
End If
If bln Then
strSQL = strSQL + "False WHERE " & strID & " = " & intID & strVersion & ";"
Else
strSQL = strSQL + "True WHERE " & strID & " = " & intID & strVersion & ";"
End If
db.Execute strSQL, dbFailOnError
db.Close
Set db = Nothing
Exit Sub
It's pretty simple, nothing to crazy. The problem occurs when I try to run this after a record has been modified by the form and it still has focus. Because of the dbFailOnError I get the error message, If I remove dbFailOnError it will update every record except the one that has been modified through the form.
If I modify the record then select a different record manually by clicking with the mouse, the record is no longer locked and the Update works with no errors.
I have tried to replicate the process of clicking on a new record and have put the below code
If Me.Dirty Then Me.Dirty = False
In every Event I could think of like:
The subform_Current, subform_Dirty, subform.Control.Dirty/Lost_focus/subform_Before and After Update, The exit event of the subform control on the main form...etc
Placing the code in different areas doesn't make any difference, the first time the code is called it updates the record and I can confirm this in the table, the new value is present.
I've attempted to requery the subform
I've tried
DoCmd.GoToRecord , , acFirst
Then setting focus to the first control of the record.
I've even tried changing the update from the db.Execute to using a recordset object
Dim db As Dao.Database
Dim rs As Dao.Recordset
Dim strSQL As String
Dim strVersion As String
If intVersion > 0 Then
strVersion = " AND [QuoteVersion] = " & intVersion
Else
strVersion = ""
End If
strSQL = "SELECT * FROM " & strTable & " WHERE " & strID & "= " & intID & strVersion
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
With rs
Do Until .EOF
.Edit
!Selected = bln
.Update
.MoveNext
Loop
End With
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
But again it will cycle through every unlocked record and update, until it gets to the one modified by the form which then throws the same error.
I've tried opening the recordset then closing it then reopening it. But it doesn't seem to matter it's the form that's holding onto the locked record.
The only solution that has worked for me was to Set the subform recordsource to nothing, then run the update, then reset the recordsource to what it was.
The Selected column is within the QuoteItems table itself, and not in it's own table with reference to the QuoteItems ID
My question is how do I get the form to release the record through code that mimics the action of manually clicking on a new record without resetting the subform's recordsource.
Your approach with using Dirty=False is the right thing to do. But you have to apply it to the subform, as this is where the recordlock occurs. If your Code is in the Main form, you need to add this before your code to update the records.
Me.sbfrmQuoteItems.Form.Dirty = False
In that line sbfrmQuoteItems is supposed to be the name of the SubForm-Control in your main form!