Is it possible to perform this SumIf without knowing the target range? [duplicate] - vba

This question already has answers here:
How do I sum data based on a PART of the headers name?
(2 answers)
Closed 6 years ago.
This is my code so far, refer to this question as to what I am trying to do.
=SUM(IF(LEFT(C$2,4)="/111",SUM(C3,G3)))
As you can see, I am defining C2, the point of my header, and in the Sum, I am defining the sum range. I now have this question:
How do I proceed if I do not know where my header is exactly, but I
know that I'm looking for a 'part' of the header. How do I search for
this? With an HLookUp? This is because these headers may be placed in just about any order, because of this, I will need to search for the text rather than define its place.
For example, I have this table:
+-------------+-------------+-------------+-------------+-------------+
| A | B | C | D | E |
+---+-------------+-------------+-------------+-------------+-------------+
| 1 |/650 - Black |/670 - White |/800 - White |/680 - Red |/650 - Black |
+---+-------------+-------------+-------------+-------------+-------------+
| 2 | 250 | 400 | 100 | 300 | 125 |
+---+-------------+-------------+-------------+-------------+-------------+
I want to sum up the row of data where I specify the 4 character LEFT limited header, as it is in the code I posted. The problem here is that the code is more of a, "This.Cell, if it is your desired header, add stuff" when I wanted something more like "Where.Cell matches LEFT limited header, add their stuff (horizontal by other matches, not vertical) I think an Index Match is what I'm looking for, but from what I gathered, the data would have to be defined on a cell, which, as per the table above, does not contain it.
I created a separate question as I believe the requirements were not stated properly the first time, resulting in a different direction and a different answer.
Pure formula is preferred, but if VBA is what you've thought up, I'd still like to read it.
TLDR: In excel, I define several left limited headers, left limited because past the / and four digits, the rest of the text may be different. I search the sheet for these headers, and when found, I sum them up and place them at the point of this formula.
I hope I was able to clarify my requirements clearer this time!
EDIT:
So I just wanted to reiterate that the requirements of this formula is that I have no idea where my headers are located despite the table I wrote above. The idea is that I will always have a /650, a /670, or a /680. The number arrangement doesn't even matter at this point. I don't know if this is possible at all, because, since I don't know where the headers are, only what they are, I don't know what letter the cell will be on, only that it is the "cell where the header was found".
Say I want /670 and a /680. Formula finds the header /670 first, and gets its cellspace like "/670 is on C1! Therefore the number that has to be added is C2!". Proceed to the next, /680 and do the same thing. In the end, I hit enter on the formula and out comes the sum of these two headers = 700.
I'm thinking in terms of C# code where I could probably state that the range to be added is based on the letter of the header I found, no idea if excel can do this much less as a draggable formula, which is why I posted this question.

According to your sample table and your description this is what SUMPRODUCT is for. Sum products of arrays. Here the first array is an array of 0 or 1 where 1 is if the header matches one of the desired headers 0 if not. The second array is the array of values to sum.
So:
=SUMPRODUCT((LEFT($A$1:$E$1,4)={"/670";"/650";"/680"})*$A$2:$E$2)
will result in 1075 = 250 + 400 + 300 + 125.
The desired headers could also be given in a cell range. But this must be a column range (1 column, multiple rows). For example given the folowing
G
1 /650
2 /670
3 /680
then:
=SUMPRODUCT((LEFT($A$1:$E$1,4)=$G$1:$G$3)*$A$2:$E$2)

I assume, what you're looking for is an array formula which is almost the same as the one you already used:
{=SUM(IF(LEFT(A1:A3,4)="/670",B1:B3),IF(LEFT(A1:A3,4)="/680",B1:B3))}
Hit CTRL + SHIFT + ENTER

Related

Need to use space separated values in AG-Grid filter to return each match

I'm tasked with moving some UI-Grids to AG-Grid.
I need to allow the user to use a space delimited string for a column filter so "1 4 23 88" would return all rows where column has 1 or 4 or 23 or 88 as a value.
AG-Grid has the drop down OR option but is added clicks and only allows two values.
With UI-Grid the filter parameter in columnDefs can have a condition:
filter:{condition: filterFunction}
FilterFunction simply has the custom logic and returned true or false.
Is there something similar with AG-Grid? Reading through the docs it seems to get overly involved to create a custom filter. The UI-Grid solution is like 6 lines of code.
CentOS 7, VueJS
I ended up using:
filter:'agTextColumnFilter', filterParams: {textCustomComparator: this.filterFunction}
With filterFunction holding the logic.
https://www.ag-grid.com/javascript-grid/filter-text/#text-custom-comparator
Though I'm using a number column there is not a comparator filterParam for numbers, only 'comparator' for dates and 'textCustomComparator' for text.
This seems to work fine for what I need.

Freemarker: Removing Items from One Sequence from Another Sequence

This may be something really simple, but I couldn't figure it out and been trying to find an example online to no avail. I'm basically trying to remove items found in one sequence from another sequence.
Example #1
Items added to the cart is in one sequence; items removed from cart is in another sequence:
<#assign Added_Items_to_Cart = "AAAA,BBBB,CCCC,DDDD,EEEE,FFFF">
<#assign Deleted_Items_from_Cart = "BBBB,DDDD">
The result I'm looking for is: AAAA,CCCC,EEEE,FFFF
Example #2
What if the all items added to and deleted from cart are in the same sequence?
<#assign Cart_Activity = "AAAA,BBBB,BBBB,CCCC,DDDD,EEEE,DDDD,FFFF,Add,Add,Delete,Add,Add,Add,Delete,Add">
The result I'm looking for is the same: AAAA,CCCC,EEEE,FFFF
First things first: You ask about sequence but the data you are dealing with are strings.
I know you are using the string to work as a sequence (and it works), but sequences are sequences and strings are strings, and they have diferente ways of dealing with. I just felt this was important to clarify if someone who is starting to learn how to program get to this answer.
Some assumptions since you're providing strings with data separated by comma:
You want a string with data separated by comma as a result.
You know how to properly create strings with data separated by comma.
You dont have commas in your items names.
Observations:
I'll give you the logic but not the code donne, as this can be a great chance for you to learn/practice freemarker (stackoverflow spirit, you know...)
You question is not about something specific of freemaker (it just happens to be the language you want to work with). Think about adding the logic tag to you question. :-)
Now to the answer on how to do what you want on a "string that is working as a sequence":
Example #1
Change your string to a real sequence :-)
1 - Use a built-in to split your string on commas. Do it for both Added_Items_to_Cart and Deleted_Items_from_Cart. Now you have two real sequences to work with.
2 - Create a new string tha twill be your result .
3 - Iterate over the sequence of added itens.
4 - For each item of the added list, you will check if the deleted list also contains this item.
4.1 - If the deleted list contains the item you do nothing.
4.2 - If the deleted list do not contains the item, you add that item to your string result
At the end of this nested iteration (thats another hint) you should get the result you're looking for.
Example #2
There are many ways of doing it and i'll just share the one that pops out of my mind right now.
I think it's noteworthy that in this approach you will always have an even sized list, as you always insert 2 infos each time: item and action.
So always the first half will be the 'item list' and the second half will be the 'action list'.
1 - Change that string to a sequence (yes, like on the other example).
2 - Get half of its size (in your example size = 16 so half of it is 8)
3 - Iterate over a range from 0 to half-1 (in your example 0 to 7)
4 - At each iteration you'll have a number. Lets call it num (yes I'm very creative):
4.1 - If at the position num + half you have the word "Add" you add the item of position num in your result string
4.2 - If at the position num + half you have the word "Delete" you remove the item of position num from your result string
And for the grand finale, some really usefull links that will help you in your freemarker life forever!!!
All built-ins from freemarker:
https://freemarker.apache.org/docs/ref_builtins.html
All directives from freemarker:
https://freemarker.apache.org/docs/ref_directive_alphaidx.html
Freemarekr cheatsheet :
https://freemarker.apache.org/docs/dgui_template_exp.html#exp_cheatsheet

Sumo Logic: Count every matching string within a field

I have a parsed field and I need to count the number of times a given string appears within it. It seems relatively simple, but I've been searching through Sumo documentation and now I'm not sure this is even possible. Please help!
I have an idea for a hacky solution using replace() regex variant.
If inputField is your input field and you want to count the number of times is happens in the inputField, then
| "This is a very hacky solution which might get you in trouble" as inputField
| replace(inputField, /is/, "#") as matched
| replace(matched, /[^#]/, "") as skipTheRest
| length(skipTheRest) as finalCount
The solution assumes # is not present in the input field.
Disclaimer: I am currently employed by Sumo Logic.
If I understand question correctly, we have a field A which we have parsed and now we want to match if it contains some string s.
In that case, below can be appended to your query.
| if(A matches "*s*", 1, 0) as ct
| sum(ct)

Adding various number of dots in excel

I have a lot of excel files looking like that:
Example:
My goal is to make it look like that:
To do that, I used very simple excel's function:
=F7&" "&G7&".........cat."&" "&H7&" times "&I7&CHAR(10)&F8&" "&G8&".........cat."&" "&H8&" times "&I8&CHAR(10)
The thing is, the number of dots placed before "cat" is not constant. It depends where the previous sentence ends and my formula doesn't take it into account - it always adds 9 dots, which means I have to add the rest of the dots manually.
Any ideas how to make it work? :D
The REPT function can do this. Use LEN to calculate the length of what you're adding the dots to, then subtract that from the desired width of the result. That will repeat the dot enough times to fill the column. For example, if you want the text with dots to be 40 characters, right padded with .:
=F1&" "&G1&REPT(".",40-LEN(G1))&"cat."&" "&H1&" times "&I1&CHAR(10)&F2&""
=LEFT(A1 & REPT(".",22-LEN(A1))&"cat",25)
22 = fixed width - len("cat"), 25 - fixed width.
edit - i revised because my original answer was not correct but I see Comintern has posted a similar response since.

How to display comparisons with set expression?

My dataset has WeekEndingDate and Sales. I am displaying a straight table with all the selected data but I need to have another table showing the following:
Sales (other columns...)
First week : 1,000
Last week : 1,350
Difference : 350
Difference %: 35%
My questions:
a) Can I have the above in one chart/table, or I need 4 different charts showing columns filtered by set expressions?
b) My strategy is having 2 variables (vMinWeek and vMaxWeek), and using them in set expressions. Is that the best route?
c) My set expressions (below) are not working - they sum the whole data set. Would you please help me understanding why?
=max ({$<WeekEndingDate={'$(vMinWeek)'}>} Sales)
Thank you for your help!
Mara
I think the reason your set isn't working is that your WeekEnd date is formatted as a date and your variable is formatted as a number.
The trick with Set Analysis is always to think what you would have to type in a list box to get to your answer. So even though QlikView stores WeekEnd 2014/08/18 as 41869 you can't type 41869 in the WeekEnd list box and get back that date. So I would make your variables of the form =date(min(WeekEnd)).
The second part of your question; getting the table you want. I would do like this. I make a loose table with the dimension values, dual is so that it sorts correctly in the chart we are going to build.
load dual(D,N) as DIM inline [
D,N
First Week,1
Last Week,2
Difference,3
Dif %,4
];
I like defining my variables in the script as well, so I would do this.
set vFirstWeek='=date(min(WeekEnd))';
set vLastWeek='=date(max(WeekEnd))';`
Then when building the straight table we use the dimension as DIM but because DIM isn't connected to anything we have to do some work to get it to display values that fit those dimension values. The num(,'# ##0') is just to format the % differently from the sums. For this to work the number format in the Number tab of the chart must be set to Expression Default.
if(DIM='First Week',num(sum({<WeekEnd={'$(vFirstWeek)'}>} Sales),'# ##0'),
if(DIM='Last Week',num(sum({<WeekEnd={'$(vLastWeek)'}>} Sales),'# ##0'),
if(DIM='Difference',num(sum({<WeekEnd={'$(vFirstWeek)'}>} Sales)-sum({<WeekEnd={'$(vLastWeek)'}>} Sales),'# ##0'),
if(DIM='Dif %',num((sum({<WeekEnd={'$(vFirstWeek)'}>} Sales)-sum({<WeekEnd={'$(vLastWeek)'}>} Sales))/sum({<WeekEnd={'$(vLastWeek)'}>} Sales),'0.00%')))))