Microsoft Access - Creating a form which looks up data between 2 dates - forms

For my College assignment, I have to create a database in Access, I have done 99% of my database, apart from this section which I'm stuck on.
In my DB, I have a tickets table, which contains records on order information and a field containing a date. For my assignment, I have to create a Form which reads from a Query.
For example, in my Form i have already created i have 2 Combo boxes with the dates already pulled from the Query. I need to be able to drop down one of the boxes and input 1 date, and then drop down the other box and select a different date, press a button and it generate me a Report.
The part I am asking for help on is the expression which is used to look up the data inside the Query. I tried using this expression, which Access said was too complicated.
[Forms]![frmOrdersBetweenTwoDates]![Combo33] And [Forms]![frmOrdersBetweenTwoDates]![Combo36]
My full SQL query is:
SELECT tblTickets.CustomerID, tblCustomers.FullName, tblCustomers.AddressLine1, tblTickets.OrderNumber, tblTickets.OrderDate
FROM tblCustomers INNER JOIN tblTickets ON tblCustomers.[CustomerID] = tblTickets.[CustomerID]
WHERE ((("WHERE [OrderDate]") Between [Forms]![frmOrdersBetweenTwoDates]![Combo52] And [Forms]![frmOrdersBetweenTwoDates]![Combo54]));
My expression/query now returns the report, but there is no data inside the report. How could i fix this?
Cheers.

Should post the complete query statement. Expect the filter clause should be like:
WHERE [date fieldname] BETWEEN [Forms]![frmOrdersBetweenTwoDates]![Combo33] AND [Forms]![frmOrdersBetweenTwoDates]![Combo36]
However, I don't use dynamic parameterized queries. I prefer to use the WHERE argument of OpenReport (same for OpenForm), in VBA:
DoCmd.OpenReport "report name", , , "[date fieldname] BETWEEN #" & Me.Combo33 & "# AND #" & Me.Combo36 & "#"

Related

How do I search forms in Access using values from another table that is being referenced?

The management staff in my department has been asked to record any and all errors committed by our team. I created a database to store them and a simple form for the management team to use to record each error. Several fields are referencing other tables such as Staff, issue category, root cause, etc...
We need to be able to search the forms for specific records to either update or review, and I have found the best way for us to search is by filtering the forms based on the individual who committed the error. Here is the code that I am using for the search button:
Private Sub SearchRecord_Click()
Dim Search As String
Search = InputBox("Please enter who committed the error", "Name", ErrorMadeBy)
If Search = "" Then Exit Sub
Me.Filter = "ErrorMadeBy = """" & Search & """
Me.FilterOn = True
End Sub
The filter works great, but instead of filling out the name, you have to use the ID number in the Staff table when filling out the Input Box. I'd like to be able to input the name (or part of the name) instead of having to have everyone memorize the ID numbers from the staff table.
What I do in these cases?
Fire up the query builder - left join in those extra tables (with the text parts in place of the id).
So be it a part number, quote number for a project etc? Just left join in those tables in the query builder and save that query.
Now, your search box and code can be somthing like:
dim rst as DAO.RecordSet
strSQL = "Select * from MyCoolQuery where PartName like '" & txtPartName & "*'"
set rst = currentdb.OpenRecordSet(strSQL)
if rst.EOF = false then
me.RecordSet.FindFirst "PartID = " & rst!PartID
end if
In fact, you can even often left join in those extra tables right into the current form, and even use ctrl-f to search if the said text boxes are place on the given form. However, I tend to separate out the search process from the actual form. So I might build a search form, say like this:
So in above, they can search say by a Hotel name, or project name or whatever. Becuase the one query has the text parts, then they can be searched. But I put the query results into a grid and each row of course has the PK ID, and thus a search could result in 10 matches, they are now free to click on any row - and i jump to the form to display the one records.
eg: the row click button does this:
docmd.OpenForm "frmTourBooking",,,"ID = " & me!ID
So, this makes for a great work flow. Users search, see, pick and then jump to the form with the one record, and then close and return back to search form - and often it has the several "hits" from that search that you want to work on anyway.

Do ampersands work for user input in reports?

I have a working query that goes something like this:
Base table ACCT, link to others (listagg/subqueries) and ensure matching year("rollyear") field. Then the final step is to say which year ACCT table is in.
SELECT
FROM table ACCT
FULL OUTER JOIN table TABLE2 on ACCT.id = TABLE2.id and ACCT.rollyear= TABLE2.rollyear
...
FULL JOIN table TABLE7 on ACCT.id = TABLE7.id and ACCT.rollyear= TABLE7.rollyear
where ACCT.rollyear = extract (year from sysdate) +1
I typically use the calendar year plus one. I've been playing with using ACCT.rollyear = &rollyear to get user input... The limitation/issue I have is getting that running using the "User Defined Reports" feature.
Am I using this feature correctly? Does that only work for SQL Queries and not reports? Ive seen videos/comments about Stored Procedures and using "Accept...." but my attempts to mimic give errors and I'm not sure I'm on the right track. Thanks for any advice.
Change your query to use a bind variable:
where ACCT.rollyear = :rollyear
Then in the 'Binds' section you will see a variable with that name:
When you run your query you'll then be prompted to supply the value:

Crystal Reports: If/Else formula giving wrong results

I am writing a Crystal report with 2 separate queries - one using DB2 database and one using a SQL database. I linked the queries together using a field, though I did have to convert the data type on one so it could be linked (not sure if this is relevant).
The DB2 query is giving me all of my customer data displayed on the report, including a customer ID. The only thing I'm pulling from the SQL DB is the same customer ID, just from another table. If the customer ID from the DB2 query is found in the customer ID list from SQL, I do not want to display that customer record.
First, I created a formula called "CustID" like this:
if {Command.Customer_ID} = {Command1.Customer_ID} then "True" else "False"
I then wrote a Record for Select Expert like this:
{#CustID} = "False"
This is giving me no records returned at all. I feel like I have a lapse in my logic somewhere but I can figure out where. Thanks in advance.

Apply a Report filter in code

My particular, specific issue is probably too localized, but the general question I'm about to ask is something I'm sure others will ask and have wondered:
General question: In Sql Server Reporting Services, is it possible to apply a filter to a report in code? If not, is it possible to use branching in the report filter based on the value of a variable, and can you point me to documentation or explain how to do it.
My specific example follows, to expand on what I mean by the above, in case I worded it badly:
I'm learning SSRS and the docs and Google are coming up short.
The desired effect is that we have a report based on an incident tracking system. In this system, we have various teams that can track incidents: IT Ops, Development, Security, etc. Each of these teams have team members assigned.
We have a base report that displays ALL incidents.
We have added a boolean parameter named "LimitByTeam", which produces a CheckBox on the report as you'd expect.
We have added a String parameter that accepts multiple values. The allowed values come from a data set that lists the teams. This has added the expected drop-down list to the report, allowing users to select one or more teams.
We added a dataset that contains team and team member.
If the CheckBox is NOT selected, we want to display all incidents. (The default)
If it IS selected, we want to have the report to filter based on the login ID of the person who created the incident ticket.
Were I to do this in SQL, I'd do it as
Select
(ticket fields)
From
Table
WHERE TicketCreator IN (
Select LoginId FROM TeamMembersTable
WHERE TeamName in ('IT Ops', 'Developers'))
In SQL, or in VB, etc, this would be simple.
In SSRS I'm not figuring out quite how to do this. I've gotten as far as figuring out that I can use Custom Code to do more complex logic using VB (and it appears to be VB.NET. HOORAY! Familiar territory)
So I've added custom code and verified that I can read the value of the report parameter, but I can't figure out for the life of me how to apply a filter if the parameter value is True. Here's what I've got.
Public Sub ApplyTeamFilter()
' Report.Parameters("LimitByTeam") is a
' boolean report parameter that I'm able to access
' so I've got the IF statement worked out
If Report.Parameters("LimitByTeam").Value = True Then
' Pseudo-code - I'm looking for something like Report.Filters.Add(filterstatement)
' Alternatively a way to change this to a function to return a list of items from
' the Team MembersTable table and use it in a custom expression.
End If
End Sub
The problem is that I can't seem to find a Filters property on the Report object, or any method that lets me find it. Since I couldn't find it there, I expanded my search to everything in this section of the MSDN library and can't find it, or anything even remotely resembling a way to do what I'm attempting.
I'm also trying to do something like this because I think I see a way to use this function:
Public Function IsLoginIdInTeam(ByVal LoginId as String, byVal Team As String) As Boolean
' Report.Parameters("LimitByTeam") is a
' boolean report parameter that I'm able to access
' so I've got the IF statement worked out
If Report.Parameters("LimitByTeam").Value = False Then
Return True ' Default
Else
' Access the TeamMembers table and look for a match
' Something like
' Convert.ToBoolean(Report.DataSets!TeamMembers.Compute(Count, "TeamName = '" & Team & "' AND LoginId = '" & LoginId & "'")
End If
End Function
But I can't figure out how to access the Data Sets in the report, either, much less the syntax for interacting with them. The pseudocode works with a System.Data.DataTable, but I suspect SSRS DataSets are a different beast.
Am I missing something blindingly obvious? Should I be giving up on filtering this way in the report, and try another track, like changing the original query in the DataSet?
I'm not a huge fan of boolean parameters in SSRS (or BIT in SQL for that matter.) You can't write things like
WHERE #MyBool OR #MyOtherBool
It needs to be
WHERE #MyBool = 1 or #MyOtherBool = 1
So if I have an SSRS report with a boolean called MyBoolParam and a multivalue text parameter called MyMultiSelectTextParam , a SQL query like this will work:
SELECT
MyField,
MyOtherField
FROM
MyTable t
WHERE
#MyBoolParam = 1
OR
t.MyField IN ( #MyMultiSelectTextParam)
(My preferred alternative to boolean parameters is actually a string with possible values, but it would be handled in the query in the same way.)
If you can't easily change your SQL query (such as using a third party SP) then you can also accomplish the same thing by adding a filter to the SSRS DataSet. Right click on the DataSet in the Report Data pane and look at the Dataset Properties. The Filters pane will let you add criteria that are evaluated for each row. I haven't used these as much with multivalue parameters, but the IN Operator should work for that.

Reporting Services and Dynamic Fields

I'm new to reporting services so this question might be insane. I am looking for a way to create an empty 'template' report (that is basically a form letter) rather than having to create one for every client in our system. Part of this form letter is a section that has any number of 25 specific fields. The section is arranged as such:
Name: Jesse James
Date of Birth: 1/1/1800
Address: 123 Blah Blah Street
Anywhere, USA 12345
Another Field: Data
Another Field2: More Data
Those (and any of the other fields the client specifies) could be arranged in any order and the label on the left could be whatever the client decides (example: 'DOB' instead of 'Date of Birth'). IDEALLY, I'd like to be able to have a web interface where you can click on the fields you want, specify the order in which they'll appear, and specify what the custom label is. I figured out a way to specify the labels and order them (and load them 'dynamically' in the report) but I wanted to take it one step further if I could and allow dynamic field (right side) selection and ordering. The catch is, I want to do this without using dynamic SQL. I went down the path of having a configuration table that contained an ordinal, custom label text, and the actual column name and attempting to join that table with the table that actually contains the data via information_schema.columns. Maybe querying ALL of the potential fields and having an INNER JOIN do my filtering (if there's a match from the 'configuration' table, etc). That doesn't work like I thought it would :) I guess I was thinking I could simulate the functionality of a dataset (it having the value and field name baked in to the object). I realize that this isn't the optimal tool to be attempting such a feat, it's just what I'm forced to work with.
The configuration table would hold the configuration for many customers/reports and I would be filtering by a customer ID. The config table would look somthing like this:
CustID LabelText ColumnName Ordinal
1 First Name FName 1
1 Last Name LName 2
1 Date of Birth DOBirth 3
2 Client ID ClientID 1
2 Last Name LName 2
2 Address 1 Address1 3
2 Address 2 Address2 4
All that to say:
Is there a way to pull off the above mentioned query?
Am I being too picky about not using dynamic SQL as the section in question will only be pulling back one row? However, there are hundreds of clients running this report (letter) two or three times a day.
Also, keep in mind I am not trying to dynamically create text boxes on the report. I will either just concatenate the fields into a single string and dump that into a text box or I'll have multiple reports each with a set number of text boxes expecting a generic field name ("field1",etc). The more I type, the crazier this sounds...
If there isn't a way to do this I'll likely finagle something in custom code; but my OCD side wants to believe there is SQL beyond my current powers that can do this in a slicker way.
Not sure why you need this all returned in one row: it seems like SSRS would want this normalized further: return a row for every row in the configuration table for the current report. If you really need to concatenate then do that in Embedded code in the report, or consider just putting a table in the form letter. The query below makes some assumptions about your configuration table. Does it only hold the cofiguration for the current report, or does it hold the config for many customers/reports at once? Also you didn't give much info about how you'll filter to the appropriate record, so I just used a customer ID.
SELECT
config.ordinal,
config.LabelText,
CASE config.ColumnName
WHEN 'FName' THEN DataRecord.FirstName
WHEN 'LName' THEN DataRecord.LastName
WHEN 'ClientID' THEN DataRecord.ClientID
WHEN 'DOBirth' THEN DataRecord.DOB
WHEN 'Address' THEN DataRecord.Address
WHEN 'Field' THEN DataRecord.Field
WHEN 'Field2' THEN DataRecord.Field2
ELSE
NULL
END AS response
FROM
ConfigurationTable AS config
LEFT OUTER JOIN
DataTable AS DataRecord
ON config.CustID = DataRecord.CustomerID
WHERE DataRecord.CustomerID = #CustID
ORDER BY
config.Ordinal
There are other ways to do this, in SSRS or in SQL, depends on more details of your requirements.