1

An Access pass-through query works when using the default parameters. When used in an Access report, the prompts that are used returns records based on the default parameters in the ptq and not the answered prompts. Default data is being returned.

I have a SQL Server based stored procedure that works, uspWorkCentreReport, that uses @TheDate DATE, @WC VARCHAR(15), @Shift INT for parameters and returns, through a SELECT statement, these columns:

[JOB NUMBER], [REL #], [JOB NAME], QTY.  

Here's the ALTER line of the stored procedure code:

ALTER PROCEDURE [dbo].[uspWorkCentreReport]
     @TheDate DATE,
     @WC VARCHAR(15),
     @Shift INT

The Access pass-through query, ptq_uspWorkCentreReport, passes these default parameters '2019-05-30','PCOT',1 and uses a DSN-less ODBC connection that works to return default data. I forgot to try but I think it will return correct data with whatever default parameters I use to replace '2019-05-30','PCOT',1. EDIT - I tried it this morning and indeed any appropriate replacement parameters return the appropriate associated records. Here's the ptq's one line:

exec uspWorkCentreReport '2019-05-30','PCOT',1

I provide the ptq with default parameters based on Albert D. Kallal's SO reply.

I use an Access select query, qry_ptq_uspWorkCentreReport, to receive [JOB NUMBER],[REL #],[JOB NAME],QTY and pass the parameters TheDate, set to Date With Time, WC, set to Short Text, and Shift, set to Integer.

qry_ptq_uspWorkCentreReport uses the pass-through query. The parameters are set using Access' Parameters applet and not within the query fields. Running this select query prompts for the 3 parameters but only returns data based on the default parameters set in the ptq's one line. I did not think to look at the Access SQL statement but will do so when I get to work tomorrow morning. EDIT - Here's the SQL statement for qry_ptq_uspWorkCentreReport:

PARAMETERS TheDate DateTime, WC Text ( 255 ), Shift Short;
SELECT ptq_uspWorkCentreReport.[JOB NUMBER], ptq_uspWorkCentreReport.[REL #], ptq_uspWorkCentreReport.[JOB NAME], ptq_uspWorkCentreReport.QTY
FROM ptq_uspWorkCentreReport;

Of course the above three functions culminate in an Access report, rpt_qry_ptq_WorkCentreReport to make the records human readable.

I have used the same scenario for another report the takes From and To dates as parameters. When that report runs, the prompts take the dates and return records based on those dates and not the dates in the ptq. Here's that ptq:

exec uspMergeAandPJobs '2018-01-01','2019-01-01'

Indeed, I tried using

exec uspMergeAandPJobs '',''

And the report returns 0 records!

Not sure what I am missing and would appreciate any feedback. TIA.

I tried the following with the help of a tutor:

Sub Report_Load()

    Dim strFromDate     As String
    Dim strToDate       As String
    Dim strWC           As String
    Dim intShift        As Integer
    Dim strSQL          As String

    strFromDate = InputBox("From Date and Time: ")
    strToDate = InputBox("Enter To Date and Time: ")
    strWC = InputBox("Enter Work Center: ")
    intShift = InputBox("Enter Shift: ")

    Dim qdf As DAO.QueryDef, rst As DAO.Recordset
    Set qdf = CurrentDb.CreateQueryDef("")
    qdf.SQL = "exec dbo.uspWorkCentreReport " & "'" & strFromDate & "', " & "'" & strToDate & "', " & "'" & strWC & "', " & intShift & ";"

    qdf.Connect = "ODBC;DRIVER=ODBC Driver 13 for SQL Server;SERVER=OURS\NTSQL;Trusted_Connection=Yes;DATABASE=TablesCoE;ApplicationIntent=READONLY;"

    qdf.ReturnsRecords = True
    Set rst = qdf.OpenRecordset

    rst.Close
    Set rst = Nothing
    Set qdf = Nothing

End Sub

After the prompts VBA spits up a Run-Time error 3129 - Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'. Neither of us were able to determine what was causing the error. In VBA the "qdf.SQL..." line is highlighted in yellow.

EDIT - Adding stored proc's SQL code:

ALTER PROCEDURE [dbo].[uspWorkCentreReport_TEST] @FromDate DATETIME,@ToDate DATETIME,@WC VARCHAR(15),@Shift INT

AS

BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

--  Build table variable SumTable structure
DECLARE @SumTable TABLE(matl_nbr VARCHAR(60),QTY DECIMAL(4,0),matl_dsc VARCHAR(50))

--  P jobs and their summed WorkCentre traversals using crosstab - each traversal is added up
INSERT INTO @SumTable(matl_nbr,matl_dsc,QTY)
SELECT     SRC1.matl_nbr,SRC1.matl_dsc,
    SUM(CASE WHEN SRC1.locn_to = @WC THEN 1 ELSE 0 END) AS QTY
FROM 
(
SELECT matl_nbr,matl_dsc,locn_to
FROM mtrk_CompanyE.dbo.trxn_hstd th
WHERE (last_upd >= @FromDate AND last_upd <= @ToDate) AND
    locn_to = @WC
)SRC1
GROUP BY matl_nbr,matl_dsc

--  These updates take all the summed WorkCentre (locn_to) columns and turn each into "1" for later summing
UPDATE @SumTable
SET QTY = 1 
WHERE QTY >1

--  Shortening the material number from 123456_00_00_R1_00 to 1234560
UPDATE @SumTable 
SET matl_nbr = LEFT(matl_nbr,6) + right(LEFT(matl_nbr,9),1)

SELECT LEFT(A.matl_nbr,6)[JOB NUMBER],SUBSTRING(A.matl_nbr,7,1)[REL #],matl_dsc AS [JOB NAME],QTY
FROM (SELECT matl_nbr,matl_dsc,
        SUM(CASE WHEN QTY = 1 THEN 1 ELSE NULL END) AS QTY
FROM @SumTable
GROUP BY matl_nbr,matl_dsc)A
ORDER BY QTY DESC;

END

EDIT - Finished sub:

Private Sub Report_Open(Cancel As Integer)

    Dim strFromDate     As String
    Dim strToDate       As String
    Dim strWC           As String
    Dim intShift        As Integer
    Dim strSQL          As String

    strFromDate = InputBox("Enter From Date and Time: ")
    strToDate = InputBox("Enter To Date and Time: ")
    strWC = InputBox("Enter Work Center: ")
    intShift = InputBox("Enter Shift: ")

    strSQL = "exec dbo.uspWorkCentreReport_TEST " & "'" & strFromDate & "', " & "'" & strToDate & "', " & "'" & strWC & "', " & intShift & ";"

    CurrentDb.QueryDefs("ptq_uspWorkCentreReport").SQL = strSQL

    DoCmd.OpenReport "rpt_qry_ptq_uspWorkCentreReport", acViewReport

    Me.lblFromDate.Caption = strFromDate
    Me.lblToDate.Caption = strToDate
    Me.lblWC.Caption = strWC
    Me.lblShift.Caption = intShift

End Sub
Tim
  • 71
  • 9
  • I don't understand your setup. A pass-through query is basically a constant SQL string and a connection string. It doesn't have parameters. Is there an Access query too? How do they work together? – Andre May 31 '19 at 07:01
  • @Andre - The Access report calls the Access SELECT query which prompts for parameters. The Access SELECT query passes the parameters to the Access pass-through query. The Access pass-through query passes the same parameters to the SQL stored procedure. The SQL stored procedure takes the parameters and returns records back down the line. SOP for Access, it's just not working for me in this instance. – Tim May 31 '19 at 13:23
  • *The Access SELECT query passes the parameters to the Access pass-through query.* - this is not possible, since a PT query **has no parameters**. What exactly happens here is missing from your question. – Andre May 31 '19 at 13:46
  • *I provide the ptq with default parameters based on Albert D. Kallal's SO reply.* -- I'm pretty sure you have a misconception there, but unless you provide your whole function, we cannot help you. – Andre May 31 '19 at 15:08
  • @Andre - I provided the WHOLE function for the ptq above, not sure what you are missing. I provided two as a matter of fact! Except for the contents within the quotes and the sp name the second ptq I mention is exaclty the same as Albert D. Kallal's. AND, it even works in a separate report/query/ptq/sp process! But sorry for the misconception just the same. While a ptq may **have no parameters** it sure does pass them. That is the gist of the issue. Can you help? – Tim May 31 '19 at 16:43
  • @Andre - Also, did you not see the SQL view for the Access SELECT query? That very code was created by Access! Not me! See the parameters there? see how it is only dealing with the ptq? – Tim May 31 '19 at 16:52

1 Answers1

1

Your Access query has parameters:

PARAMETERS TheDate DateTime, WC Text ( 255 ), Shift Short;

and since they are defined in the query definition, Access asks for them when opening/running the query.

But these parameters are never used!

There is no way for Access to pass these parameters into the pass-through query that is the basis of the Access query. Again, a PT query is nothing more than a Connect string and a constant SQL string.

So when you run the Access query, it will always run the saved contents of the PT query, i.e.
exec uspWorkCentreReport '2019-05-30','PCOT',1
The parameters you entered are ignored.

What you need to do (as outlined in the answer you refer to):

  • create a form to collect the parameter values
  • dynamically create the SQL string for the PT query with VBA
  • assign that SQL to the PT query:
    CurrentDb.QueryDefs("ptq_uspWorkCentreReport").SQL = strSql
    (it is automatically saved)
  • and then you can run the report based on the Access query - or better: directly use the PT query as record source for the report.

Remove the parameters from the Access query, they are of no use for your situation. Or remove the query entirely, unless you need it to join the PT query with something else.


Edit for above edit:

If you get a runtime error, there is probably a syntax error in your .Sql. Build the SQL string in a variable, do Debug.Print strSql, and run that string in SSMS. You may need to change date formatting (depending on your locale settings).

Also: See my 3rd bullet. Defining a temporary querydef and opening a recordset doesn't work for a report. You must assign the .Sql of the existing query that is the record source of the report.

Addendum: if you need to create a new query, first set .Connect, and then .Sql, so Access knows it's a Pass-Through query.
Access SQL doesn't know exec.

Edit 2

You have an existing, working PT query ptq_uspWorkCentreReport, which returns records for one set of parameters, e.g.

exec uspWorkCentreReport '2019-05-30','PCOT',1

Use this query as record source for your report.

To run the report with different parameters, you must modify the query's SQL. You can do this manually in query design view, or with VBA.

I think Report_Load() is too late for modifying its record source (the PT query). Run the following sub, then open the Report.

Sub SetUspParameters()

    Dim strFromDate     As String
    Dim strToDate       As String
    Dim strWC           As String
    Dim intShift        As Integer
    Dim strSQL          As String

    strFromDate = InputBox("From Date and Time: ")
    strToDate = InputBox("Enter To Date and Time: ")
    strWC = InputBox("Enter Work Center: ")
    intShift = InputBox("Enter Shift: ")

    strSQL = "exec dbo.uspWorkCentreReport " & "'" & strFromDate & "', " & "'" & strToDate & "', " & "'" & strWC & "', " & intShift & ";"

    Debug.Print strSQL

    ' This line is all that's needed to modify the PT query
    CurrentDb.QueryDefs("ptq_uspWorkCentreReport").SQL = strSQL

End Sub

In practice, you don't want to use 4 x InputBox, but a form.

Andre
  • 26,751
  • 7
  • 36
  • 80
  • I tried using your last bullet. I set the form's four fields to "=FromDate" et al to match the stored proc. But when I run the report I get records based on the answers provided in the PTQ and not the actual answers to the prompts. I also worked through several VBA options with a tutor and he was unable to get the VBA to return records, the VBA based on links in my initial question. I list that above in an edit to my question. – Tim Jun 03 '19 at 03:15
  • I've added the extra step to build strSQL first and during debug this is the string: `"exec dbo.uspWorkCentreReport_TEST '2019-05-24 00:00:00', '2019-05-24 23:59:59', 'INSP', 1;"` Taking that without the leading and trailing quotes into SSMS executes and returns expected data. The VBA debug session still errors with the same error listed above "...3129..." – Tim Jun 03 '19 at 11:49
  • See "Addendum": if you assign the SQL to a **PT** query (as you need to do), the error shouldn't arise. @TimGibney – Andre Jun 03 '19 at 11:56
  • One difference of note between this Access report issue and the one that is working is this: none of the returned fields are parameter fields; the four fields I pass to SQL are different from the four fields returned from SQL. In the current scenario I cannot return the dates or other parameter fields as there are grouping and aggregates that preclude me from including the dates in the SQL code, to maintain aggregated records. In the report that is working a date field is passed and returned. I'll edit in the Stored proc's SQL to my original post. – Tim Jun 03 '19 at 12:01
  • This should not matter at all. As long as your PT query returns records, you can use it as record source. Access does neither know nor care about the specifics of your proc. – Andre Jun 03 '19 at 12:18
  • Sorry... A$$hat moment! simply change the order. Gotcha. – Tim Jun 03 '19 at 12:42
  • Sorry, can't help you there. Check that the PT query works on its own, double-check control sources. @TimGibney – Andre Jun 03 '19 at 13:49
  • Another mistake! I din't run your sub exactly. Now I am. How do I run the sub first then use DoCmd.OpenReport to run the report? When I try you code in-line in On Open I get the prompts then "Run-time error '3265': Item not found in this collection." at the CurrentDb.QueryDefs... line. – Tim Jun 03 '19 at 14:05
  • Check that the PT query name is correct `"ptq_uspWorkCentreReport"`. – Andre Jun 03 '19 at 14:29
  • Success! @Andre, thank you very much for being patient. Finished sub edited in to original post. – Tim Jun 03 '19 at 16:15
  • Done! And appreciated. Also, I am currently working on a date/time picker as a response to your statement about using a form rather than prompting. That was always the plan but the report had to come first. @Andre – Tim Jun 04 '19 at 12:51