I'll separate this post in 3 sections to be as clear as possible. The first one will be informations you need to know. Second one will be the solutions I tried so far to get this working. Third section will be the questions. I also have to precise that's the first time I'm using CrystalReports.
Informations
I'm currently working with Visual Studio 2010 with C# and I'm using SAP Crystal reports. I'm displaying the data using MySQL database.
Now, here are the tables I use to display the report:
Table : orders
Fields : id(primaryKey), date(DATE), quantity(INT), fksizes(INT), fkclients(INT)
Table : sizes
Fields : id(primaryKey), name(VARCHAR(30)), price(FLOAT)
Relationship between these 2 tables : orders.fksizes with sizes.id
Basically, I'm passing a range of dates as parameters to the Crystal Reports to display informations only between those dates. Then, I created 2 parameters : StartDate and EndDate both of type Date.
What I've tried
Here's the original query I'm using to display what I want without the date range condition :
SELECT sizes.name, SUM(orders.quantity) AS totalQty,
(SUM(sizes.price) * orders.quantity) AS totalPrice,
orders.date
FROM orders
INNER JOIN sizes ON orders.fksizes = sizes.id
GROUP BY sizes.name, orders.date
This query works correctly and display the total quantity sold and the total price for each size name. At the report's footer, I'm using a Summary field in which I got the total sum of all totalQty named sumTotalQty. I have another field for the same purpose for totalPrice named sumTotalPrice.
I have 2 rows of data test which are :
Size name Quantity sold Total Price
------------------------------------------------------------------------------
Big 2 $6.00
XBig 7 $28.00
The field sumTotalQty displays 9 and sumTotalPrice displays $34.00 which is exact results. I have to precise that the first row has 2013-10-29 as value for orders.date and the second one 2013-10-30.
Now, I want to select a range of dates for which I want to display the results. As an example, I select from 2013-10-30 to today, I should get only the second row with sumTotalQty displaying 7 and sumTotalPrice displaying $28.00. I got the single row correctly displayed, but sumTotalQty displaying 9 and sumTotalPrice displaying $34.00 which are incorrect following the date range.
I then tried to add a WHERE clause to my sql query to specify the date range like this (in Database --> Database expert...):
SELECT sizes.name, SUM(orders.quantity) AS totalQty,
(SUM(sizes.price) * orders.quantity) AS totalPrice, orders.date
FROM orders
INNER JOIN sizes ON orders.fksizes = sizes.id
WHERE orders.date BETWEEN '{?StartDate}' AND '{?EndDate}'
GROUP BY sizes.name, orders.date
I got no result displayed with it. So, I think {?StartDate} and {?EndDate} are just not set but I'm really not sure. The same goes for WHERE orders.date BETWEEN #StartDate AND #EndDate.
Questions
Why aren't {?StartDate} and {?EndDate} set even if I have entered a date range when I'm prompted to give them ?
With the original query (without the WHERE clause), how can I get the right result in my summarize fields with the date range given ? It's like it sums from the database and not from the report fields.
EDIT
After many searches, 2 other questions came in my head :
Is it possible to add DateTimePicker in the report so the user will be able to enter a starting date and an end date easily ? The report would be refreshed automatically after that.
Is there a way to create or use Crystal Reports events (OnLoad, AfterLoad,...) ?
Thank you for all help I'll get.
Question 1: You either use BETWEEN (? AND ?) or BETWEEN (#StartDate AND #EndDate)
Question 2: You would have to group your data and then use totals in your report.
Edit: After discovering that the issue is with the parameter declaration, I suggest taking a look at some of the following posts:
http://www.dotnetperls.com/sqlparameter
Why do we always prefer using parameters in SQL statements?
Do some more research and you will find lots of info on the net. What I would suggest is to add some input boxes (TextBox, DateTimePicker, etc.) to your page where the user can input the parameter values and then pass them programmatically to the report. That way you can pass the parameters to the SQL statement and get the correct data to your report. You also won't need parameters in your report.
As far as CR events go, there is the Init event, which is public
http://msdn.microsoft.com/en-us/library/aa691447(v=vs.71).aspx
and then there are some Viewer events that could be useful
http://msdn.microsoft.com/en-us/library/ms227097(v=vs.80).aspx
Related
I want to break the table as soon the data encounters June. I want only one table which should split the table keeping the table header intact. I searched the whole internet but I am not getting any reliable solution I can go with.
Right now I am getting all the month in a single column, as you can see from the image left side is what I want and right side is what I am getting
I am trying to achieve this in SSRS 2012
If I understand you correctly what you want is the same table to appear displaying information for a time period from July to the following June for each year (so July2015-Jun2016, July2016-June2017…)
If you were to use a dataset in the following format (which looks similar to that posted in your image above
CashFlowYear theDate Revenue Expense
2015 12/01/2015 1000 500
2016 01/01/2016 1100 1500
(Note that the date column where you list a bunch of month names are represented by an actual date here)
You want to create a repeating table, so create a rectangle in your report. Then create your tablix within this rectangle. It should look something like this.
Then to get the grouping behaviour that you desire, right-click the List row header, then Row Group -> Group properties and Group it on
=year(dateAdd("M", -6, Fields!theDate.Value))
This will remove 6 months from each of the dates, and group when they are in the same year (so June 2016 will become December 2015, and be grouped with the other 2015 dates)
When run the report will look like this.
You can then edit the list to insert a page break between each of the tables if you wish, or whatever additional formatting you require.
Hopefully this will assist you. Let me know if I can be of further help.
In my RDLC report I want to show my data grouped by a particular column. Here is the fields of the dataset that are returned by the method
Module name, Documentation date, Walk Date, Flushing date, Testing Date
I want to show in my report module wise how many items are Documented, Walked, Flushed, Tested. How I can do that?
I have tried to create Parent group on Module name but doing so repeats multiple lines per group ( as many lines as there are for that particular group), but I just want to show count of Documentation, Walk, FLushing etc) against each module.
Assuming that you want to count the number of non-NULL records for the Date fields in SSRS, you can use the ISNOTHING function to check each field:
=SUM(IIF(ISNOTHING(FIELDS!DocumentationDate.VALUE), 0, 1))
This just checks the field and counts the record as 1 if it's not null.
I am currently trying to report on stock quantities with a timeframe for each item in stock;
Stock at the selected minimum date within the timeframe
Stock at the selected max date within the timeframe
I have a single quantity field of an item from a transaction which I am adding to my report twice however both with differing formulas under select expert.
Stocks.Date = MINIMUM(Stocks.Date)
Stocks.Date = MAXIMUM(Stocks.Date)
I've grouped by product and have all fields in the group header. I have tried looking online for solutions but I haven't found anything that really solves the problem. If you need more information please ask, this is wrecking my brain.
Essentially what I want is(for each stock item):
Quantity field1:
SELECT Stock.Quantity WHERE Stock.Date = MINUMUM(Stock.Date)
Quantity field2:
SELECT Stock.Quantity WHERE Stock.Date = MAXIMUM(Stock.Date)
Hope this helps clarify what I'm after
Create two SQL expression fields:
// {%MIN_DATE}
(
SELECT MINIMUM(Date) FROM Stock
)
// {%MAX_DATE}
(
SELECT MAXIMUM(Date) FROM Stock
)
Then reference them in the record-selection formula:
{Stock.Date} IN [{%MIN_DATE},{%MAX_DATE}]
You can't include Crystal's aggregate functions in the record selection formula because it is self-referential. It's like saying "define set A as the largest element of set A". In your case, you're effectively saying, "Only include records in my report where the date is the most recent record in my report"... doesn't make sense.
Instead, you have to include all records and only "process" the ones where {StockSales.Date}=maximum({StockSales.Date},{StockSales.ItemID}). You can accomplish this by comparing the date of each record to the maximum date for that item ID and saving the stock quantity off in a variable if it is a match. You can then display the variable in the item's group footer.
The first step is to move all your Group Header 1 elements into Group Footer 1 instead. Then you'll need to create 2 new formulas to manage the variable:
//{#Update variable}
// Place this formula in the Details section
whileprintingrecords;
numbervar qty;
if {StockSales.Date}=maximum({StockSales.Date},{StockSales.ItemID})
then qty := {StockSales.Quantity}
//{Display variable}
// Place this formula in the Group Footer 1 section where you want the quantity to display
whileprintingrecords;
numbervar qty;
If your aim is to show the max and min in the report, then you can try the below Steps:
Go to the Group field, Right Click on the object ->Format Object->Display String-> Give the Formula:
CStr (Maximum ({Stocks.Date}));
To show both min and max in the same report, drag the Date field twice into the report and for one object give Minimum Date another with Max date.
For Maximum: CStr (Maximum ({Stocks.Date}));
For Minimum : CStr (Minimum ({Stocks.Date}));
Your Select Expert doesn't make any sense to me.
You are retriving the records from Min Date to Max Date in other words you are retriving the whole table data in to your report in this case what is the use of select expert.
If you don't mention any thing in select expert then also you can whole table data.
If you really want to filter some data then provide some paramters to the user so that you can filter in those parameters then your select expert will become something like.
Stocks.Date>={?StartDate} and Stocks.Date<={?EndDate}
If my understanding is wrong then edit the question clearly with your requirement.
Edit-------------------------------------------------------------------------------------
In this case don't use select expert, Do calculations in your report itself in formula fields.
create a formula as:
#Minimumn
if Stock.Date = MINUMUM(Stock.Date)
then <Stockitemahere>
For Maximum create another formula as:
#Maximum
if Stock.Date = MAXIMUM(Stock.Date)
then <Stockitemahere>
Place both formulas on design part of the report.
Take care date filtering shouldn't be in select expert
I have developed an eCommerce application in C# and ASP.Net. For the Admin users "dashboard" landing page, I would like to give them a GridView that shows them the total sales dollar amount for a couple different time ranges, these would be my columns (ie last day, last week, last month, last year, total ever). I would like to give these values for orders that are in different status' (ie complete, paid but not shipped, in progress). Something similar to this:
|OrderStatus|Today|LastWeek|LastMonth|
|Processed |$10 |$100 |$34000 |
|PaidNotShip|$4 |$12 |$45 |
My question: What is the best/most efficient way to do this? I know that I could write separate SQL statements and union them together and bind the gridview to a sqldatasource:
(select amountForYesterday, amountForLastWeek from sales where orderStatus = processed)
UNION
(select amountForYesterday, amountForLastWeek from sales where orderStatus = paidnotshipped)
But that seems like a pain and very inefficient, since I would effectively be writing a separate query for each value.
I could also do this in the .cs page behind on load and programmatically populate the grid view row by row.
This GridView would only show information for the user's specific organization, so it would have to filter based on that as well.
I'm kind of at a loss as to how to do this without writing a massive query and continually hitting that query and database each time the page is viewed.
Any ideas?
I prefer using LINQ to work with data and/or GridViews (accessing the rows etc.). Have a look at a project I have on GitHub, which does exactly what I am mentioning here, as example. Note that this is just a sandbox I used previously for illustration purposes.
GitHub Repo
https://github.com/pauloosthuysen/int
Other useful info:
http://www.codeproject.com/Articles/33685/Simple-GridView-Binding-using-LINQ-to-SQL
The Sales etc. for LastWeek and LastMonth does not change very often. You could store that in a static Dictionary indexed by organization or summarize it in a separate table for faster access. This way you will not need to select the same huge amount of rows to get the same numbers over and over again. Unless special demands I would stick to the Dictionary solution because it is simple but a combination could also be a good solution
There is no direct way of doing it.
However instead of hitting the DB to the sum of every columns, you can perform the stuff using you datatable which is used for binging to your grid.
All you need to do is use
Dim iSumSal As Integer
iSumSal = StudentTable.Compute("SUM(sal)", "")
similarly you can perform for other columns.
once this is done. then just add a new row to you data table with all the summed values in it.
And then you can bind it to your grid.
optional - you can put some text value in the first column of you new row as "Total:"
thanks
rahul
I have a mysql database. In which there are 50 columns of detail.
Detail 1, Detail2, Detail3...... Detail50.
I have the website locally so i am scrapping from myself. The site is not in order no tags and names data is just in form of text line by line, so this was the only option to take what i get line by line and save to DB. So every line gets a column from 1-50....
Some pages have 10 columns other have 50 and the data is in no order now i have the DB,how can i sort them any suggestion ,idea is welcome.
This image will make it more clear:
So You can see Sometimes its Inner Diameter in Detail4 and sometime in 1, these are just examples i would have hard coded but there are too many possibilities, but the repeating words all have the same staring name just values different .Any chance to atleast make 50 % of the data in order the ones with same 4-5 starting words like
part,inner,diameter,oil filter etc.
Any suggestion or ideas can it be done in mysql or C# code.....
Thank you
your approach is totally wrong, but if you want to go this way, just make a table with two columns 'id' and 'details' ... make an insert for each column for the specific product ID.
After that you can use a SELECT like that:
select SUBSTRING(details, 14) from products where details like 'Inner Diameter%' and id = 'my_product_id';