Counting multiple criteria - vba

I'm trying to count multiple criteria and got the code to work somehow with SUMPRODUCT.
Range("i2") = [SUMPRODUCT(($CZ$2:$CZ$61410="condition 1")*($DD$2:$DD$61410="condition 2")*($CU$2:$CU$61410=$A$2 <-/date/)*($CY$2:$CY$61410="condition 3"))]
There's around 40 colums with different conditions. So I have to code for each condition. But that's not really working for me, because I have to do the same thing for the whole month.
Explanation
Cells A2 to A32 hold dates, let's say from 1st of August 'til 31 of August.
Raw data table (on the same sheet) has dates on the CU column (might be 60000+ lines).
Column CZ, DD, CY, etc. have conditions that have to be met to be counted.
Question
What I want to do is if the date in column CU = the date in A2 then it will be counted to row 2, if the date in column CU = the date in A3 then it will be counted to row 3.
That way I can write one code for the whole month, not each day separately.

I offer first a solution of a formula (WorksheetFunction if preferred) of this type:
=COUNTIFS(CZ:CZ,"=1",DD:DD,"=2",CY:CY,"=3", ... CU:CU,"="&A2)
and an image showing what this results in (the yellow cell) depending upon the date chosen:
This counts the number of instances, on the date chosen in A2, that match the hard-coded criteria displayed in Row1 for illustrative purposes.
Without the hard-coding of criteria but with possibly a slightly better 'match' to the OP and with more examples:
Apart from the highlighting, the contents of C6 were entered via the following macro:
Sub Macro1()
Range("C6").Select
ActiveCell.FormulaR1C1 = "=COUNTIFS(C[101],R1C[101],C[105],R1C[105],C[100],R1C[100],C[96],""=""&RC[-2])"
End Sub

Related

Complex conditional

I have the following sheet called DailyReport:
I am currently calculating Column M with:
=SUMPRODUCT(A2:A200=A2, G2:G200)
Then on a secondary sheet I have the following second sheet WeeklyReport:
Now what I want to do is, if WeeklyReport Column A2 == DailyReport Column A, then take the date in DailyReport Column B and test it to fall in the date range in WeeklyReport Column B and Column C with:
=IF(AND(DailyReport.B2>=B2,DailyReport.B2<=C2),1, 0)
and if that is true add the Total Daily Hours to the total in WeeklyReports Column D from DailyReports Column M.
I think summing values from column M, which is itself a sum, would not meet the goal. Summing sums would make too big a value, and column M is not filtered by date, so numbers from the wrong dates would be included.
I like better the idea of extending the way you used SUMPRODUCT to get the column M numbers. Instead of just checking for a matching name, add two more parameters to check for a date later or equal to the "Week Start Date" and earlier or equal to the "Week End Date".
So three true/false or 1/0 parameters (where multiplying by 1 for true keeps the value and multiplying by 0 for false removes the value) and the fourth parameter of the hour values to be summed:
=SUMPRODUCT(DailyReport.A$2:A$200=A2, DailyReport.B$2:B$200>=B2, DailyReport.B$2:‌​B$200<=C2, DailyReport.G$2:G$200)
The poster also came very close to a solution using SUMIFS (in the comments). The default condition test is =, but for the date comparisons we want to use greater than and less than operators. The LibreOffice/OpenOffice syntax for this is to put the relational operators in double quotes, then use & to connect them to the cell address that contains the test value:
=SUMIFS(DailyReport.G$2:G$200, DailyReport.A$2:A$200, A2, DailyReport.B$2:B$200, ">=" & B2, DailyReport.B$2:B$200, "<=" & C2)
In both these cases I have included $ signs to make the row numbers absolute. Absolute cell addresses will not change if the formula is copy-pasted; in this case the copy-paste might be over multiple rows on the WeeklyReport sheet to get hour totals for multiple people.

Sumproduct dates

I have a spreadsheet worksheet called “ISO Procedure Master List” where the date a procedure is requested is in column G (Format m/dd/yyyy).
In column H the date the procedure is completed is entered. Column H uses the same date format but may contain blanks (procedure not completed yet).
There are currently 67 rows of information in the spreadsheet that span from 2011 to 2015 and that number will continue to grow.
QUESTION, I would like to get the average time (in days) it took from a procedure request (column G) to the completion of procedure (column H) for all of the procedures requested in a given year.
In other words the average (in days) time it took to complete procedures in a given year.
This answer will be in a cell C34 in the same workbook but a different worksheet called “ISO Matrix”. (This information probably does not matter but I thought I would add I just in case)
I have tried several Sumproduct variations with no success.
Assumptions:
Dates in columns G and H are dates, not text string,
Data start in row 2, using row 1 for headings.
For convenience, I assume you have named the ranges you wish to average requestDate and completeDate
You wish do ommit the rows where the procedure is not finished from the average calculation.
After naming your ranges, input the following formula into C34 on "ISO Matrix" tab:
=AVERAGE(IF(completeDate<>"";completeDate-requestDate))
This is an array formula, so when normally pressing enter, remember to press CTRL+SHIFT+ENTER instead. When highlighting the cell, it will then look like this:
{=AVERAGE(IF(completeDate<>"";completeDate-requestDate))}
NOTE: My language pack uses ; as formula separator, so if you language uses , instead, change the formula to:
=AVERAGE(IF(completeDate<>"",completeDate-requestDate))
EDIT: So, I didn't catch that you needed to average by year. In line with my recent formula, it could be update to suit your request.
=AVERAGE(IF(completeDate<>"";IF(YEAR(requestDate)=A15;completeDate-requestDate)))
where A15 holds the year you are interested in. I tried it with an AND in the first IF instead of two IFs, but that did not seem to work. Mind you, you might still need to change ; to , and you also need CTRL+SHIFT+ENTER for this one.
You could also add the code below, to handle the case where you test a year that is not present in the list:
=IFERROR(AVERAGE(IF(completeDate<>"";IF(YEAR(requestDate)=A15;completeDate-requestDate)));"No such year")
...or something like that

Excel Formula to calculate number of user hits in a system everyday

This is the continuation of my previous questions and I have included my global aim with project.
Excel Link:
https://drive.google.com/file/d/0B5W4CgZKsARFSmhqV0ZSM1lBSkE/view?usp=sharing
Task:
The task is to collect the "number hits" of a user in an application "on each day". I can collect a log from the system which will give me the name of the users and their last hit date and total number of hits.(This total number of hits in not on daily basis, but sum of all days). and I need to make a formula to segregate these on daily basis
Screenshot:
To understand in better way I have created few screenshot, which I am looking to implement.
The excel has two tabs raw_data and value_capture. I will use raw_data to paste my raw data collecting from system log and value_capture to generate day by day hit statistics
Raw_data tab:
It has three details, 1. date. 2. name and 3 totals hits(This total hits are overall hits of that user on all days)
value_capture:
This has all user names and all dates to mark each day and a column to display all hits.
Now, considering an example of date 20141120, all users hits are 0.
raw_data shows 0 against all users
so value_capture are has to be updated with same
Now on next day 20141121, there is some hits against some users. (Note : if there is no hit against a user, it will only the previous date ie,date will update only if there is a hit on that day)
value_capture updated with that details
On 20141122, there are some more hits against the users
value_capture updated with the details. since the raw_data will show total number of hits against a user, the way of calculating on a particular will be total hits- previous date hit
I am stuck at a way to develop the excel formula here.Looking for an idea to implement this.
Note :
Users name will be fixed on both tabs, but that may come in different order in raw_data tab.
UPDATE
My raw_data sheet will be updated everyday and I want my formula results be fixed in the value_capture sheet after the values are updated (removed) from sheet raw_data
So as i mentioned in my answer to your previous question, the only way to save the results of a formula after deleting/removing its reference cells, is to use a macro.
First of all
you need a proper formula to pull the data from the raw_data sheet and then calculate the difference between that particular cell where the formula resides and the sum of previous cells in that row.
we need two formulas:one for the column B of your value_capture sheet. and the second one for the rest of your table. why? because in the first column you don't calculate the difference between itself and the previous cells, because there aren't any. So there is a little difference in the formula.
FORMULA ONE:(paste in B3 and drag and fill down)
=SUMIFS(raw_data!$C:$C;raw_data!$B:$B;$A3;raw_data!$A:$A;B$2)
FORMULA TWO:(paste in C3 and drag and fill down and to the right)
=IF(SUMIFS(raw_data!$C:$C;raw_data!$B:$B;$A3;raw_data!$A:$A;C$2)-IF(ISNUMBER(B3);SUM($B3:B3);0)>0;SUMIFS(raw_data!$C:$C;raw_data!$B:$B;$A3;raw_data!$A:$A;C$2)-IF(ISNUMBER(B3);SUM($B3:B3);0);0)
As you see in my screenshot for user in cell A3, we have value of 4 for the date 20141120 and the next day the value is 14 but the cell gets the difference, that is 10, and then then next day, the value increases to 16, so the cell value for D3 becomes 2 which is the different of 16 for that day and the sum of previous ones. This continues until today's value which is 24 so the cell gets 7 because the sum of previous ones is 17.
Now that you have your values captured correctly, with respect to the difference with the sum of previous days, it is time to make them fixed and eternal.
For this you need a macro:
Sub saveMyData()
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Range("B3:L18").Copy
ws.Range("B3").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End Sub
So obviously you need to update this range "B3:L18" this is what I have in the example sheet only.
Now this macro, copies and pastes all the values from that range onto itself, so you lose your formulas.So each day, you need to go to *line 21** of the same sheet and get the formula from C21 and paste it on somewhere on row 3 from where you want to continue capturing the new day's data. (you won't need the first formula, because it is only used once in the first column, the first day.)
This was the only way to capture the values using formulas and then save the results of the formulas in their place and go and fetch new data. I couldn't think of any other strategy to make it more automatic, except for writing mova VBA and letting excel go and find where you left the day before and paste the formulas in their right place and repeat the task.
all these formulas are array formulas, so press ctrl+shift+enter to calculate the formulas.
Remember to adjust the formulas to your regional settings, i suppose, by replacing the ";" with ",".
here is the example sheet downloadable from this link
Tell me if you have problems anywhere and don't forget to answer my question in the comments about the way you update your dates in row 2 of value_capture.
The formula that you are looking for is SUMIFS
=SUMIFS([SUM RANGE],[RANGE 1],[VALUE 1],[RANGE 2],[VALUE 2])
SUM RANGE is the column of values that you want to SUM so that is your column C. For Range 1 you want to select the range of IDs. The VALUE 1 will be equal to the value in Column A Row X. For RANGE 2 it will be the Date column. For VALUE 2 it will be the value in the column header.
Put this together and you have something akin to:
=SUMIFS(raw_data!$C:$C,raw_data!$B:$B,$A3,raw_data!$A:$A,B$2)
This would be in cell B3 and you could fill the other cells from there.
If total hits for a day is a rolling count of ALL hits ever then at the end of your equation you need to subtract the sum of the prior days.
For example:
=SUM(B3:B4)
This would only need to be added to subsequent columns (not the first).
So the equation in C3 would be
=SUMIFS(raw_data!$C:$C,raw_data!$B:$B,$A3,raw_data!$A:$A,C$2)-SUM(B$3:C3)
Then in D3 it becomes
=SUMIFS(raw_data!$C:$C,raw_data!$B:$B,$A3,raw_data!$A:$A,D$2)-SUM(B$3:D3)
Try Sumifs formula
=SUMIFS(raw_data!$C:$C,raw_data!$B:$B,$A3,raw_data!$A:$A,B$2)-IF(ISNUMBER(A3),A3,0)

Formula to work out whether all filled in fields are the same, but ignores those that aren't filled?

I'm trying to work a formula so that a cell reads "Days" if all of the filled in cells in a selection are equal, but ignoring those that equal 0 (or blank, whichever's easier).
I've got a start with all the fields I believe I need (don't have the rep for a screen shot but I'll try and explain)
The sheet is to work out holidays based on hours entered in the "hours" row, with Monday K16, Tuesday L16 etc.
The rows are labelled as follows: hours = manual entry, bank hols = bank holidays between two dates (elsewhere on sheet), hours in bank = total hours that would be worked on bank holidays, is a work day = if(hours="0","0","1").
The cell I want would be somewhere below these, but it wouldn't particularly matter as it will be hidden anyway.
Is there a way to work out whether all the values in the manual input "hours" are equal while ignoring all those in the range if they equal 0 (or are blank).
From this I am wanting to display "Days" if they are the same, else show "hours".
I'm also aware that this may require a bit of VBA which I'm currently looking at, but it'd still be nice to get some feedback on here.
Try this:
=IF(COUNTIF(A1:E1,AVERAGEIFS(A1:E1,A1:E1,">"&0))=COUNTIF(A1:E1,">"&0),COUNTIF(A1:E1,">"&0)&" Days",SUM(A1:E1)&" Hours")
Where the values are in A1:E1
EDIT: edited original formula, please use above corrected formula
Say we want to test A1 thru A13
=IF(SUMPRODUCT((A1:A13<>"")/COUNTIF(A1:A13,A1:A13&""))=1,"Days","Hours")
blanks will be ignored.
Assuming that you are only checking one linear set of data IE:
HRS = 1
Bank Holiday Hrs = 1
Hrs in Bank = 1
then you can try
=IF(MOD(SUM(A2:C2),2),"days","hours")
Where A2:C2 are your rows with the data.
If this requires a unique check of actual hrs then it wont work with any values other than 1 or 0 of course.

VBA Function able to search through cells?

Back Story
At my job we use a desk calendar to keep track of a multitude of random details that occur: Everyone's daily hours, what type and how many reports were sent, etc. To help us in filling out a few forms my boss decided he wanted to create a spreadsheet for the month and keep it as up-to-date as possible day by day. He went on vacation before this month started, so I've been taking over his duties. Something I noticed is that he hardwired the calculations for the totals (everyone's total hours, total reports sent, etc), so that when I changed the dates from January to February we had some left over ones that lead into March. I deleted them and then the formulas all threw #REF! errors because of it.
How the data is set up is simple:
AB 2.50
CD 3.50
EF 8.00
...ETC...
With the AB,CD,EF being in one column, and the values being in the adjacent column.
The Question
I tried to get this to work, with no luck, so I'm thinking it might be impossible but I thought I'd ask a group of people who know more about the subject than I do: in a function I made I have it accept a string parameter to search for, if it finds it, it moves to the adjacent cell and adds that value to the running total. It then returns that number at the end, so a call to this function would resemble
=getTotals("AB") ' this would display whatever the total for AB is
But when I tried this all I got was a #VALUE! error in the cell.
Is there any way I can get this to work the way I want it to, without the use of a full macro?
The Function
I got this function to work, how I wanted to
Function getTotal(rng As Range, search As String) As Double
Dim r As Range
getTotal = 0
For Each r In rng
If r.Value = search Then
getTotal = getTotal + r.Offset(0, 1).Value
End If
Next
End Function
Calling it like so: =getTotal(A1:D2, "AD")
SUMIF should get you what you need:
=SUMIF(A1:A10,"AB",B1:B10)
Assuming your 'AB' values are in column A, rows 1-10 and the number values are in column B, rows 1-10.
The first argument in SUMIF is the range to check, the second argument is the condition that must be met (search criteria), and the 3rd [optional] argument is the corresponding range from which to get the values to be summed.