I have this Excel
now i want to make some reports using a VBA Macro
Report 1 (select all tasks)
Select the number of total tasks no matter if they are completed or not
IMPORTANT! Keep in mind that here are 5 tasks, in another excel may be 20 30 , but all have the same format C6 - task_id, D6 - task_name, E6 task_name ... and so on
Report 2 (select all WHERE completed is 100%)
Select the number of total tasks where completed column is 100%
IMPORTANT! Keep in mind that here are 5 tasks, in another excel may be 20 30 , but all have the same format C6 - task_id, D6 - task_name, E6 task_name ... and so on
Report 3 (select all users and retrive information about their productivity)
Here basicaly i need something like
SUM(I6:I10) - SUM(K6:K10) WHERE task_given_to = 'OM'
SUM(I6:I10) - SUM(K6:K10) WHERE task_given_to = 'MN'
SUM(I6:I10) - SUM(K6:K10) WHERE task_given_to = 'NM'
IMPORTANT! Keep in mind that here are 5 tasks, in another excel may be 20 30 , but all have the same format C6 - task_id, D6 - task_name, E6 task_name ... and so on
Any help with that?
I must say, in SQL it would be easy ...
Is there any requirement to use VBA ? Unless there is something I am missing, a simple pivot table would be able to do that.
Just put the task name as the row field.
Apply a filter on completion.
User as row field, productivity as data, task type as column.
Isn't it what you are trying to achieve ?
Oh and FYI if this does come from Access you can use MS Query.
Data => Other sources => MS Query => Access database
Then you can just use an SQL query to retrieve data. I'd then make 3 data sheets with 3 different queries and 3 report sheets which would format the data to a more report-like format.
Related
I have a MS Access Table with the following information
DA Attendance
Attendance ID (Key)
Date
DA
Attendance Record (Dropdown with 6 options)
Note
I am trying to create a cross tab query that will display the following:
Query Result Example
I am able to get the crosstab query without any date parameters to work as intended. The picture above is how it looks. However, when I add the parameter I get the following error: "The expression is typed incorrectly, or is too complex to be evaluated..." . I have a form in which the user inputs a specific day for which to create the query.
Query Design 1
Query Design 2
Raw Data Example
Attendance ID
DA
Date
Attendance Record
Note
1
65
2021-09-16
Present
2
37
2021-09-16
No Call No Show
No text response
3
25
2021-09-16
Tardy
1155 AM arrival
4
58
2021-09-16
Present
PARAMETERS [Forms]![DA Attendance Form]![DA_Attendance_Date] DateTime;
TRANSFORM Count([DA Attendance].[Attendance ID]) AS [CountOfAttendance ID]
SELECT [DA Attendance].DA
FROM [DA Attendance]
WHERE ((([DA Attendance].Date)=[Forms]![DA Attendance Form]![DA_Attendance_Date]))
GROUP BY [DA Attendance].DA
PIVOT [DA Attendance].[Attendance Record];
Figured out the issue. MS Access is acting as the front end for a SQL Server database. The field "Date" was declared as type Date() in SQL Server which for whatever reason pulled as "Short Text" in Access. Edited the field type to DateTime() in SQL Server and it solved the issues when running the query.
I have some issue in my sales report . I want to make a report like this, in which two columns are there..
Team TotalSales
Team A 1000
a1 500
a2 500
Team B 400
Team C 800
Total 2200
here a1 and a2 are sub part of Team A.1000 is sum of a1 and a2 ToltSales.
Please help..
Start with the Table Wizard - set your team name to the grouping field, and your values in the details field. Enable totals lines and the layout you'd prefer. The resulting table will be pretty close to what you need logic-wise, you'll just need to format it how you'd like.
I'd advise taking some time to look at how the wizard sets up grouping properties, as the wizard won't be useful at all when you need to get into very complicated tables with multiple levels of grouping.
I'm trying to create a report in SSRS where I have a matrix, which has gender as the column headings and specifically defined agegroups as the rows. The report is sorted by date (ie, the records being displayed are filtered by the modifedAt value). My problem is that i wish for all of the age group categories to be displayed, even if the dataset does not return any data for that row.
So, for example, if i set the date to be a date where there are no db rows where there are Age5-16 children in - I still want to display the category name, but just have the cells related to that row to display '0'. Instead, the report just drops the whole row because, obviously the query returns no data.
Is the solution to have a separate dataset that brings back the entire list of categories and then somehow fit them together? I'm stuck here so any help is appreciated!
I can think of a few ways to do this:
DataSet level
Instead of just returning the relevant data in the underlying data in the DataSet, include all the categories you want to display in all cases.
e.g. For a database query it might be the difference between an inner and left join, i.e. going from something like:
select *
from AgeGroup
inner join MyData on ...
to:
select *
from AgeGroup
left join MyData on ...
So the report always has all the age groups to display. Where there are NULL values, just display 0.
I think this is the best option if you have control over the DataSet - you won't have to update your report at all, with luck the actual DataSet changes should be minimal, there is still only one DataSet call, and it's by far the simplest to maintain.
Hard code groups into the report
Here you include a table header row for each group you want to display, so these are always displayed in all cases.
Here you have some sort of conditional expression to display the values, e.g. For each group row it will be tailored to that group:
=Sum(IIf(Fields!AgeGroup.Value = "5-16", Fields!Amount.Value, Nothing)
This is not too flexible and will need updates as you change groups, and doesn't have as many options for layout. There is still only one DataSet call, so that is a plus.
Subreports
You can have a parent DataSet that displays one row for each age group, then embed a subreport in each row that displays the data you want for that row.
This allows you flexibility in layout but it will add complexity to the report(s) and will mean that you make a lot of DataSet calls that could be avoided with other options.
I know this is old, but I wanted to elaborate on Ian's section 1 above using joins at the dataset level. (His answer was super helpful to me for a report I'm working on.)
per op:
Is the solution to have a separate dataset that brings back the entire list of categories and then somehow fit them together?
That is how I've handled it successfully, but you can do so without actually creating a separate dataset by using common table expressions (or temp tables, of course).
For these example tables:
AGE_Table
ID Group Group_Desc Toys
1 A 00-10 Teddy Bear
2 B 11-20 Video Game
3 C 21-30 Sports Car
4 D 31-40 Mansion
5 E 41-50 Jewelry
People_Table (filtered for whatever date)
ID Name Age Gender Age_Group
1 Ariel 07 F A
2 Brandon 23 M C
3 Chelsea 27 F C
4 Derek 06 M A
You want to see 2 results for the 00-10 row, 2 for the 21-30 row, and then still see rows for the other age groups even if there aren't any results.
We want to create a dataset with all the different age groupings and then join on it. Behold a solution using common table expressions:
with CTE_Age AS
(SELECT Distinct Age_Group from AGE_Table)
SELECT ID, Name, Age, Gender, CTE_Age.Age_Group FROM People_Table
RIGHT JOIN CTE_Age ON
People_Table.Age_Group = CTE_Age.Age_Group
This will return:
ID Name Age Gender Age_Group
1 Ariel 7 F A
4 Derek 6 M A
NULL NULL NULL NULL B
2 Brandon 23 M C
3 Chelsea 27 F C
NULL NULL NULL NULL D
NULL NULL NULL NULL E
Once you have that in your dataset, you can change NULL values to 0 on the report builder side -- I think in 2008R2 the default is just blank.
I've been racking my brain about how to do this in one query without PHP code.
In a nutshell, I have a table that records email activity. For the sake of this example, here is the data:
recipient_id activity date
1 delivered 2011-08-30
1 open 2011-08-31
2 delivered 2011-08-30
3 delivered 2011-08-24
3 open 2011-08-30
3 open 2011-08-31
The goal: I want to display to users a single number that tells how many recipients open their email within 24 hours.
E.G. "Users that open their email within 24 hours: 13 Readers"
In the case of the sample data, above, the value would be "1". (Recipient one was delivered an email and opened it the next day. Recipient 2 never opened it and recipient 3 waited 5 days.)
Can anyone think of a way to express the goal in a single query?
Reminder: In order to count, the person must have a 'delivered' tag and at least one 'open' tag. Each 'open' tag only counts once per recipient.
** EDIT ** Sorry, I'm using MySQL
Here is a version in mysql.
select count(distinct recipient_id)
from email e1
where e1.activity = 'delivered'
and exists
(select * from email e2
where e1.recipient_id = e2.recipient_id
and e2.activity = 'open'
and datediff(e2.action_date,e1.action_date) <= 1)
The basic principle is that you want to find a delivered row for a recipient that also has an open within 24 hours.
The datediff() is a good way to do the date arithmetic in mysql -- other dbs will vary on exact methods for this step. The rest of the sql will work anywhere.
SQLFiddle here: http://sqlfiddle.com/#!2/c9116/4
Untested, but should work ;) Don't know which SQL dialect you use, so I've used TSQL DATEDIFF function.
select distinct opened.recipient_id -- or count(distinct opened.recipient_id) if you want to know number
from actions as opened
inner join actions as delivered
on opened.recipient_id = delivered.recipient_id and delivered.activity = 'delivered'
where opened.activity = 'open' and DATEDIFF(day, delivered.date, opened.date) <= 1
Edit: I'd confused opened with delivered - now replaced.
Assumptions: MySql, table is called "TABLE"
Ok, I am not 100% on this, because I don't have a copy of the table to run it against, but I think that you could do something like this:
SELECT COUNT(DISTINCT t1.recipient_id) FROM TABLE t1
INNER JOIN TABLE t2 ON t1.recipient_id = t2.recipient_id AND t1.activity != t2.activity
WHERE t1.activity in ('delivered', 'open') AND t2.activity in ('delivered', 'open')
AND ABS(DATEDIFF(t1.date, t2.date)) = 1
Basically, you are joining a table onto itself, where the activities don't match, but recipient_ids do, and the status is either 'delivered' or 'open'. What you would end up getting, is a result that looks like this:
1 delivered 2011-08-30 1 open 2011-08-31
You are then doing a diff between the two dates (with an absolute value, because we don't know which order they will be in) and making sure that it is equal to 1 (or 24 hours).
I am trying to calculate a SUM in an MS Access report the following way:
Group1header - label
Group2header - value
Detail - example
Detail - example
Group2header - value
Detail - example
Group1footer [sum of Group2header value]
Somehow, when more detail rows appear, the sum in group1footer is incorrectly calculated (adds value for each detail).
I can not calculate the sums in the query, because the "value" is already a calculated in the query (a subquery would return to many rows):
(
(
(sl_ticketdetail.weight,0) * sl_ticketdetail.amount
- (
SELECT SUM(sl_invoicedetail.amount)
FROM sl_invoicedetail
WHERE ticketdetailid = sl_ticketdetail.ticketdetailid
)
/ 1000
)
* sl_ticketdetail.cost
)
/ 1000
Any idea on what could be going wrong?
Are you saying your are getting results like this:
Group 1a
Group 2a
Foo1 1
Foo2 1
foo3 2
Group 2a Sum 4
Group 2b
Foo1 3
Foo2 3
Group 2a Sum 6
Group 1a Sum 10
Group 1b
Group 2a
Foo1 4
Foo2 1
foo3 2
Group 2a Sum 7
Group 2b
Foo1 4
Foo2 3
Group 2a Sum 14
Group 1b Sum 21
This is the behaviour I would expect. I was able to do it by putting =Sum([value]) in an unbound field in each group footer (and even in the report footer).
I know 'works for me' isn't very helpful.
Have you labelled the detail's values fields (or the summary fields) with the same name as the data source? Sometime MS Access has weird behaviour if your fields have the same name as their bound data source (I tend to rename them slightly so I'm sure what I'm referring to in code).
Since you already have the Group2 sums pre-calculated in your query they will be repeated for each row of results and therefore cannot be used (as you found out) to calculate the Group 1 totals.
You have two solutions
1) pre-calculate the Group1 totals in your query as well and simply report them liek you do the Group2 totals
2) use code in the Group2 footer format/print events to capture the value and manually increment a running Group1 total
I would say 1) is the easiest - 2) is a little hairy and sometimes results in inaccurate totals if the users pages back and forth
You would have to have the record source of the main report to include the totals for Group 2. Then you would need a sub report with a different record source that is on the detail level.
I think your best bet, is to omit the totals in the query and just let the report do the totals on the details. Later, the user may want totals on the same date but a different grouping (yes, you could create another record source). This should also address if a user applies a filter on the report (You may or may not have given them this option.) on a field other than the grouping.