Excel 2013 advanced date range lookup using sumproduct - excel

I am new to Stackoverflow, so please let me know me if there is not enough information. I have had many helpfull insights by using StackOverflow in the past, but I cannot find any helpful thread online, so I hope you can help me.
I've been working on a excel (2013) problem for a while now. I am trying to build a marketing agenda to store and keep track of our mailing campaigns. The campaigns themselves are send via another system, but we miss the ability to plan our mailing campaigns in advance. Since we are active on different markets in Europe, we decided to have a general mailing (for all regions) and a region specific mailing campaign (both are in the same agenda). Besides this we also want to display the mailing focus (different brands). It is my idea to return this as visual as possible (to make it usable for all users). I have add a small picture to show my desired end-result (however without any data at this moment).
At this moment, the users are going to use a (Google)form to enter the campaign information and this data is downloaded to the worksheet (by doing so all users can add new campaigns and everyone always has access to the most recent data). This part works well.
I am using a helper sheet to check if the dates fall in a campaign range, if it does fall in a campaign range it should return the mailing ID (also the row number). I have another form which uses this data to search for the right brand and displays visually (with a lot of conditional formatting).
The problem arises in the helper sheet (when I check if a date fall into a campaign range). I have been able to get it working (more or less) with the following formula:
=IF(SUMPRODUCT(--(CountryHelper!$C$2:$C$100<=$B4);--(CountryHelper!$D$2:$D$100>=$B4);RIJ(CountryHelper!$C$2:$C$100))=0;"";INDEX(CountryHelper!$A$2:$A$100;SOMPRODUCT(--(CountryHelper!$C$2:$C$100<=$B4);--(CountryHelper!$D$2:$D$100>=$B4);ROW(CountryHelper!$A$2:$A$100))))
In this formula, CountryHelper!C:C is referencing the StartDate of the mailing campaing. D:D will reference the column of the EndDates and A:A has the mailing ID. Cell B4 is the date that needs to be checked.
At first it looked this worked perfectly. If a date fell in a date range then it would return the ID. After a little playing around with this a problem came to light. It only works with non overlapping dates, once dates overlap excel will add the row numbers together and it would not work any more.
Is it possible to get the sumproduct formula working and returning only the first ID. I am aware that I then have to make another 2 formulas which return the second and third ID ( I am certain we do not get more than 3 overlapping dates). This is also the part where I get lost. I've tried to use a MIN and MAX variation wit the following sumproduct formula:
=SUMPRODUCT(--(CountryHelper!$C$2:$C$100<=$B4);--(CountryHelper_RSEU!$D$1:$D$100>=$B4);ROW(CountryHelper!$C$1:$C$100))
This will return either a 0 (with MIN) or 100 (With MAX). I think this is caused by the formula (for now it only searches the first 99 rows). I also have ventured into VBA / UDF to get this done, but as I understand it this is not possible.
Anyway, I am sorry for the long story, I hope that my problem is clear and you can help me. If you need any more information.
Thank you!
empty Marketing Agenda overview

The SUMPRODUCT is a kind of swiss army knife Excel function. But here it is wrong because, as you already have seen, it really calculates a SUM at the end. Mostly it works because it first multiplies the 0 or 1 of the conditions with the row numbers so only the row numbers which fulfills the conditions comes into the sum. But if two or more row numbers fulfil the conditions then they were added together.
Are you familiar with array formulas? The following array formula should be what you want:
{=INDEX(CountryHelper!$A$2:$A$100;MIN(IF((CountryHelper!$C$2:$C$100<=$B4)*(CountryHelper!$D$2:$D$100>=$B4);ROW(CountryHelper!$A$2:$A$100)-1)))}
To create a array formula put the formula into the cell without the curly brackets and then press [Ctrl]+[Shift]+[Enter]. Then the curly brackets should appear automaticaly.
How it works:
{IF((CountryHelper!$C$2:$C$100<=$B4)*(CountryHelper!$D$2:$D$100>=$B4);ROW(CountryHelper!$A$2:$A$100)-1)}
Gets a array of row numbers or FALSE {FALSE, rowNumber, FALSE, ...}. If both conditions are fulfilled then it gets the row number - 1, if not then it gets FALSE.
The MIN function then gets the smallest (row number - 1) from this array.
The INDEX then indicates this smallest (row number - 1) which fulfills the conditions.
It subtracts 1 from the row number because your INDEX range starts at row 2. If the row number 2 fulfills the conditions then it is the index 1 within this range, if row number 3 fulfills the conditions, it is the index 2 and so on.
Why it only works as array formula? Because the IF function do not creates a array by default even if their "Value_if_true" is a range. Within the array context it does exact this.

Related

Execute excel formula only for specific cells

I am trying to create a formula that checks for several things at the same time but I am having trouble with one part of it.
The formula is the following:
=IF(COUNTIFS($N$2:$N$17095,N3,$K$2:$K$17095,"<>"&"")>6,
IF((SUMPRODUCT(--(ROUND($K$2:$K$49,2)=ROUND(K3,2)))>9),"Always Late / Possible Automation",
IF(COUNTIFS($N$2:$N$17088,N3,$K$2:$K$17088,"<3.5")>0,"Delivered Earlier At Least Once",IF(COUNTIFS($N$2:$N$17088,N3,$K$2:$K$17088,">3.5")>6,"Always Late","False"))))
The first part checks how many entries in the range having the same value as it is in cell N3 have values different to blank and we want those to be more than 6.
Second part is the tough one, it is supposed to check how many values in the rounded range match the rounded value in cell K3. The issue is the formula checks the whole range and I want to check only for the values which match N3 (in essence like the CountIf works only for that value).
The rest is not so relevant.
Some example data:
![enter image description here][1]
As you see in the end of the table the formula with the rounding works but only because I have limited the data shown to 3 unique values in column N. Even here though if i have a blank it doesnt work becaus ei haven't considered it.
Thanks in advance.
Assuming you have Office 365 compatibility/Excel version, use a bunch of filters. To avoid an unwieldy formula I've extended ranges to maximum number of rows (customize as required)...
=LET(x_,$E$3:$E$25,a_,FILTER($E$3:$E$25,--(x_=E3)),b_,FILTER($B$3:$B$25,--(x_=E3)),IF(SUM(--(a_=E3)*(b_<>""))>6,IF((SUMPRODUCT(--(ROUND(b_,2)=ROUND(B3,2)))>9),"Always Late / Possible Automation",IF(SUM(--(a_=E3)*(b_<3.5))>0,"Delivered Earlier At Least Once",IF(SUM(--(a_=E3)*(b_>3.5))>6,"Always Late","False")))))
Note: filter does not appear to work too well within countifs for some reason (must be related to syntax RE: arrays vs. criteria TBC). Thus have replaced countifs(filter_range,X) eqn 'types' with sum(--(filter_range=X)) which works as intended.

Invoice total in row n, payment in row n+k, using dates

I have a table of payments to calculate interest. The column where the payment is applied takes its values from the column where the invoice totals are listed, however, the payment is applied k days after the period ends.
I had partial success doing it using this formula:
IFERROR(INDEX($F$12:$F$25,MATCH(D12,$G$12:$G$25,1)),0)
Where column G is a helper column with the dates of payment, basically period end + k, but since it only accounts for the period end, in monthly and semimonthly periods, sometimes the nearest lower date of payment was on the same period, so I MUST also account for the period start for this to not happen. I've been helped using an array formula like this:
=IFERROR(INDEX(F:F,SMALL(IF(F$12:F12>0,ROW(F$12:F12)),COUNT(1/((C$12:C12-C$12>C$7)+(D$12:D12-C$12>C$7))))),0)
And it works well and it does not require a helper column. But since it's an array formula, and this table is not for my usage, that's not suitable.
I would like to know if I can do this without an array formula and built-in excel 2013 functions.
Edit:
This formula does it:
=SUMPRODUCT(($D$12:$D$25+$C$7>=C12)*($D$12:$D$25+$C$7<=D12)*($F$12:$F$25))
But if there are blanks in column D that result from a formula, it returns an error. So the following formula is more stable:
=SUMIFS($F$12:$F$25,$D$12:$D$25,">="&C12-$C$7,$D$12:$D$25,"<="&D12-$C$7)
This one effectively places the payment rows within the range of dates it belongs to.
At least you can replace SMALL with AGGREGATE like this:
=IFERROR(INDEX(F:F;AGGREGATE(15;6;(ROW(F$12:F12)/(F$12:F12>0));COUNT(1/((C$12:C12-C$12>C$7)+(D$12:D12-C$12>C$7)))));0)
AGGREGATE(15;6;;) is the same as SMALL, but it ignores errors. This lets you switch out the IF(F$12:F12>0,ROW(F$12:F12)) for the quotient (ROW(F$12:F12)/(F$12:F12>0)). Every row-number divided by a FALSE produces an error which gets ignored by AGGREGATE.
For the COUNT-part I cannot say, what it is doing, as my results don't look like yours (i copied your formula).
I guess it works as an offset.
Can you test my formula and tell me if it is working without cse? Else we need to find a replacement for the COUNT-part. I currently cant test it as I am on Office 365 and don't know if i can activate the old CSE-functionality.

How do I sum several rows by category? (EXCEL)

I have created an excel sheet to have an overview over costs in my projects, however, I also need an overview of costs per category in my projects. I googled it and tried to find examples online, however, it only returns a value of 0, which shouldn't be the case. Can anyone help me? The sheet looks like below.
I am going by the SUMIF function to group by category but my excel sheet is a bit more complex than that so I tried to adjust it accordingly as seen in the code below. No matter what I do it either returns an error or 0.
=IF(B12=B8;"";SUMIF(B12:B39;B12;J12:BE39))
In the formula above I am trying to sum the costs of a category that could be written in B12, for example, Software development. For confidential reasons, I cannot show the actual filled out excel sheet.
sumif does not work with summing multiple columns. Instead use a sumproduct statement instead like so:
=IF($B12=$B$8;"";SUMPRODUCT(($B$12:$B$39=$B12)*($J$12:$BE$39)))
A detailed explanation to how this works can be found here
Edit:
I sense a follow up question coming, how to skip certain columns. Because as you have set it up now, it will count the entire range from J12 to BE39, in which you have both forecast costs and actual costs. I guess this is to compare the costs to what was projected and what the actual costs are. Right now it will count both the projected and actual cost, doubling up. To prevent this you can enter every second column separated by a + like so:
=IF($B12=$B$8;"";SUMPRODUCT(($B$12:$B$39=$B12)*($J$12:$J$39+$L$12:$L$39+$N$12:$N$39)))
Also I have added $ signs to all non-changing values so it will work when dragging down the fill handle on the formula to populate the below cells.

Using COUNTIF but not including blanks with other formula

Firstly, apologies if this is covered somewhere deep within the site, I have looked through a lot of other posts and none of the solutions have worked for me.
I'm creating a workbook for a local league I'm involved in and this is the only sticking point I'm coming up against.
In cell J55, I have the formula:
=IF(C11=H55, COUNTIF(D11, "="&E11),0)+IF(C19=H55, COUNTIF(D19, "="&E19),0)
(I've simplified this to only look at rows 11 & 19 for the purposes of this question)
So what I'm essentially saying is if the team name is equal to the corresponding name in the table, count if the scores for both teams are equal. Basically I'm trying to get the number of games that end in a draw.
So at it's core, my formula is looking for whether 2 cells are equal. This is fine, other than it is counting even if the score cells are blank.
So if you refer to the below image, in J55, I'm getting the returned value of "2". However for the values I've populated in the results (just the scores in the first game) it should be returning a value of "1".
If anybody can help in any way it would be a great help.
To count the number of Draws this formula which performs array like calculations will count the number of occurences where where the team name in H55 is equal to the team name in column D or F and when the scores in column D and E are equal:
=SUMPRODUCT((($C$11:$C$21=H55)+($F$11:$F$21=H55))*($D$11:$D$21=$E$11:$E$21)*($D$11:$D$21<>"")*($E$11:$E$21<>""))
Copy down as required.
COUNTIFS options
Based on your formula above, adding the checking for not blank cells using COUNTIFS.
=IF(C11=H55, COUNTIFS(D11, "="&E11,D11,"<>"&""),0)+IF(C19=H55, COUNTIFS(D19, "="&E19,D19,"<>"&""),0)
COUNTIFS is probably the slightly better option as it does not use array calculations. However for a small data set it wont make a noticeable difference in calculation time for most users.

Formula to follow addition of rows

New to VBA, please help. My apologies. I have not done a good job of making myself clear. Let me try one more time.
My sales reps enter every call into a call sheet. They call on 50-60 people a week; some they will see more than once a week, some only a couple of times a year. On this call sheet are 4 columns; date of call, customer, numerical date, and days since last call. This sheet may have hundreds of rows, many are duplicate customers called on a different date.
I have written code that will eliminate duplicates as needed (works fine). New calls are added using NextRow=_ (also works fine). $C$2 is set at TODAY().
Formula in column C is $C10=$A10(Column C is formatted to number). Column D is number of days since last call; $C$2-$C10 etc. Simple and works fine.
Issue is that say I have 50 rows (all different customers) sorted ascending and a new customer is added, key being new. I need the formulas in C and D to drop down one row automatically when the new customer is added. I can drag the formulas down a head of time and everything will work until I sort, then my data is a the bottom of my sort because all rows in column A without a date will produce a 0 in both C and D. My finished product should be a range of different customers (no duplicates); with the customer that has not been called on the longest at the top.
I hope this is a better explanation. Can I write code to ignore the 0's?
I am going to go a little out on a limb here and say maybe your formulas need refactoring...
For instance. If the aim is to calculate the days since the last call was made to a customer, a simple formula such as this would work
=(max(C:C)-Today())
This gets the largest value in column C and subtracts today from it.
If you want to get the value in column D which corresponds to this entry then VLOOKUP() is your friend. you would use it as such:
=VLOOKUP(MAX(C:C),C:D,2,FALSE)
Hope this helps.
Incidentaly, the best way to do your problem in VBA, the simplest way would be to create a Named Range. You can then replace the $C$2-$D11 with the name of the named range. The simplest way to do this would be to say:
Range(Range(C2),Range(C2).End(xlDown)).Name = NAmeOfYourRange
This effectively just gets cell C2, goes to the last non blank cell in the downward direction and names that range NameOfYourRange
Hope this helps :)

Resources