I need help with the following:
I have a worksheet containing some data. Row 1 is header and from row 2 downward is the data. At the end there is total for all the data above. This worksheet is dynamic, i.e., if week 1 has 200 rows of data, then week 2 could have 250 or 190 rows of data.
Likewise, the columns across, change every week. This week I have 18 columns and next week I could have 20 columns.
Within row # 1, the header, I have two headings "CTAEO1P" and "CTAEO2P".
On another worksheet, I want to add the "totals" of both of those columns i.e., Individual totals of CTAEO1P = 32.98 + CTAEO2P = 46.25 = 79.23
I am using named ranges and named the whole of the worksheet with data as "MT". The range is whole of the worksheet so when next week I copy the data over from another worksheet, I should not have to adjust the range.
I am using the following formula, courtesy of another expert on this forum:
=HLOOKUP("CT*",MT,MATCH(9^99,INDEX(MT,0,MATCH("CT*",INDEX(MT,1,0),0))),0)
This formula look for any column that starts with "CT" and then "Match(9^99" and "index" finds the last number within that column (the total in this case) and then return that value on the worksheet. In this case this formula is returning "32.98" only, as this is the first occurrence.
I think I can use "Sumproduct" formula here but then a) I would have to create more than one named range, one for the header row and another for the "Total" row, b) every week I would have to adjust the range for "Total" row. Unless, if I can nest "Match(9^99..." part within "SUMPRODUCT" function.
I want to use "MT" range alone and want to add the totals of all the columns that start with "CT".
I hope I have been able to explain my problem better enough to make some sense, however, if you need any further information, then please let me know.
Regards
Tariq
I will forget about the MT range, as long as your data starts in A1 this will work
=SUMPRODUCT(ISNUMBER(SEARCH("CT*";OFFSET(A1;0;0;1;MATCH(9^99;2:2))))*OFFSET(A1;MATCH(9^99;A:A)-1;0;1;MATCH(9^99;2:2)))
Depending on your regional settings you may need to replace field separator ";" by ","
I think you can use a relatively simple SUMPRODUCT solution like this
=SUMPRODUCT((LEFT(INDEX(MT,1,0),2)="CT")*ISNUMBER(MT),MT)/2
SUMPRODUCT will total all values in the relevant columns, including the totals so divison by 2 will ensure you get the correct count
If you don't like that approach then assuming first column of MT always has data and that the totals for each column will all be in the same row you can use SUMIF like this
=SUMIF(INDEX(MT,1,0),"CT*",INDEX(MT,MATCH(9^99,INDEX(MT,0,1)),0))
That should be more efficient than the first version
Related
I have two table, this one is the initial table that contains raw data (on Sheet 2)
And the second table (on Sheet 1) contains formula based on data from first table
I use this formula to calculate the data, but as we can see on the picture, it doesn't produce right result. Could you please help me to modify the formula?
=IFERROR(INDEX(Sheet2!$E$2:$E$12,MATCH(Sheet1!$B$1&Sheet1!B$2&Sheet1!$A3,Sheet2!$C$2:$C$12&Sheet2!$B$2:$B$12&Sheet2!$D$2:$D$12,0)),"")
First the auxiliar column, using the concatenate operator & :
Then the formula would be:
=VLOOKUP(B$2&$E$1&$A3;Sheet2!$A:$G;6;0)
Change 6 for 7 if you want the description instead of Activity.
Please try this formula. It should go into cell Sheet1!B3 where it must be confirmed with Ctl+Shift+Enter because it's an array formula. (017)
=IFERROR(INDEX(Table,MATCH(1,(INDEX(Table,,3)=$A$1)*(INDEX(Table,,2)=B$2)*(INDEX(Table,,4)=$A3),0),5),"")
In preparation of this formula to work you need to set up a named range by the name of "Table" which comprises of Sheet2!A2:Fxx. Better set this range up dynamically so that it expands as you add more data but you can also declare it as Sheet2!A2:F1000 where 1000 is a number of rows you expect never to need.
This table has 6 columns, A:F which I intentionally made to include column A, which you don't need so that range columns and sheet columns are identical. Table,,3 simply defines the 3rd column. You can replace it with Sheet2!$C$2:$C$1000. If you do, make sure that all your ranges have identical sizes.
The 5 near the end of the formula, at ,0),5),"") identifies the 5th column of the range Table from which the result is returned if the 3 criteria match. Change this number to 6 to return the result from column F or to 1 if you ever need the value from column A.
I have a problem to create a formula so I want to ask you for your help.
Excel sheet has 150 000 rows and with this formula I want to safe a time.
I have a Date, Name and Status and I need to see in other cell which Name was 4x or more time in consecutive GOOD or OK
Example of input:
https://imgur.com/aRALd9S
I think IF + AND + DATE Range it’s enough, but I don’t know how to put it together.
Thanks a lot for your suggestions !
Here is what i have so far: https://imgur.com/Y5WAov5
=COUNTIFS($D$2:$D$15;D2;$C$2:$C$15;"OK";$D$2:$D$15;D2;$E$2:$E$15;">="&E2;$E$2:$E$15;"<="&E2+7)+(COUNTIFS($D$2:$D$15;D2;$C$2:$C$15;"GOOD"))
With this i'm able to count how many times i have a Name, which is OK or GOOD and is in one week range, but i still don't know, what i have to change, that i will stop to count when false is there
Well here's something you could try. You could do it in one formula with an array formula, but with 150K rows it seems much better to try and avoid array formulas and use helper columns where necessary.
The first helper column just contains the person's ID if the row contains FALSE:
=IF(H2=FALSE,I2,"")
The second helper column contains the offset from the current row to the next FALSE for the same person:
=IFERROR(MATCH(I2,K2:K$15,0)-1,16-ROW())
So now you can use basically your same COUNTIFS formula but replacing each range with an INDEX which specifies how many rows you should count:
=IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$15,L2),I2,H2:INDEX(H2:H$15,L2),"GOOD",J2:INDEX(J2:J$15,L2),">="&J2,J2:INDEX(J2:J$15,L2),"<="&J2+7))+
IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$15,L2),I2,H2:INDEX(H2:H$15,L2),"OK",J2:INDEX(J2:J$15,L2),">="&J2,J2:INDEX(J2:J$15,L2),"<="&J2+7))
Note 1
The 16 in the second equation is to allow for the case where there are no more rows labelled FALSE after the current row, so the MATCH fails. This makes the Countifs count everything from the current rows to the end of the data.
Note 2 - expanding to a larger range of data
You should be able replace the figure 16 with countA(I:I), the size of the data plus headers.
There shouldn't be a problem with using a larger range for the Index e.g.
=IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$150000,L2),I2,H2:INDEX(H2:H$150000,L2),"GOOD",J2:INDEX(J2:J$150000,L2),">="&J2,J2:INDEX(J2:J$150000,L2),"<="&J2+7))+
IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$150000,L2),I2,H2:INDEX(H2:H$150000,L2),"OK",J2:INDEX(J2:J$150000,L2),">="&J2,J2:INDEX(J2:J$150000,L2),"<="&J2+7))
but increasing the search range in the MATCH to 150K rows in the second formula does seriously affect performance when repeated 150K times. The only solution I can think of at the moment is to see if a maximum can be placed on the distance from any occurrence of a name to the next occurrence of the name with FALSE next to it.
I have two sheets within a workbook, the first with several thousand lines of expenses, separated by individuals, and the second a summary of totals and such.
On the second sheet, I've created a reference to the first to insert each individual's name (i.e. B4: ='Card Transactions'!D89). I'm having difficulty with the syntax for returning the total of each individual's total, which is in a predictable cell in the first sheet relative to the name (down 1, right 7).
I've tried the following:
=offset(indirect(B4),1,7) with only a reference error in return. This seems like it should be relatively simple but I'm not having any luck. . . any suggestions?
use this:
=OFFSET(INDIRECT(MID(FORMULATEXT(B4),2,300)),1,7)
note:
this only works if the formula in B4 only contains the one cell reference.
This is a volatile function and will cause a noticeable lag in calculations if used too many times.
The following should work for you as long as your data follows these rules:
Your columns have headers
The names are all in the same column
And you are able to set the range with row numbers and not just full columns
Let's say your first sheet is set out like this:
And you want your second sheet like this:
And your sheets are named:
Sheet1
Sheet2
This is the formula in B2 of Sheet2:
=INDEX(Sheet1!$A$1:$H$9,MATCH(A1,Sheet1!$A$1:$A$9,0)+1,MATCH("Column 8",Sheet1!$A$1:$H$1,0))
And here's what it does:
Your index array is the entire blue area, this can be the whole sheet but can't be a full column reference, the row number must be specified. In this example, the index array is $A$1:$H$9 and the $ signs mean the range won't move when you drag down the formula, so they are important!
Your first match finds the row number, it uses the name (in this case 'bart') as the lookup value, and the purple area as the array. In this example the row array is $A$1:$A$9 and the row numbers must match the row numbers in the index array. The match has a "+1" at the end, so it will find the matching row, then add one row down to get your offset.
Your second match finds the column number, it will need to use the name of your column. In this example the column array is $A$1:$H$1 and the column letters must match the column letters in the index array.
Let me know if this doesn't fit your problem, I'm sure we can figure it out.
Thanks.
I have a table that is pulling thousands of rows of data from a very large sheet. Some of the columns in the table are getting their data from every 5th row on that large sheet. In order to speed up the process of creating the cell references, I used an OFFSET formula to grab a cell from every 5th row:
=OFFSET('Large Sheet'!B$2572,(ROW(1:1)-1)*5,,)
=OFFSET('Large Sheet'!B$2572,(ROW(2:2)-1)*5,,)
=OFFSET('Large Sheet'!B$2572,(ROW(3:3)-1)*5,,)
=OFFSET('Large Sheet'!B$2572,(ROW(4:4)-1)*5,,)
=OFFSET('Large Sheet'!B$2572,(ROW(5:5)-1)*5,,)
etc...
OFFSET can eat up resources during calculation of large tables though, and I'm looking for a way to speed up/simplify my formula. Is there any easy way to convert the OFFSET formula into just a simple cell reference like:
='Large Sheet'!B2572
='Large Sheet'!B2577
='Large Sheet'!B2582
='Large Sheet'!B2587
='Large Sheet'!B2592
etc...
I can't just paste values either. This needs to be an active reference, because the large sheet will change.
Thanks for your help.
And here is one last approach to this that does not use VBA or formulas. It's just a quick and dirty use of AutoFilter and deleting rows.
Main idea
Add a reference to a cell =Sheet1!A1 and copy it down to match as many rows as there are in the main data.
Add another formula in B1 to be =MOD(ROW(), 5)
Filter column B and uncheck the 0s (or any single number)
Delete all the rows that are visible
Delete column B
Voila, formulas for every 5th row
Some reference images, these are all taken on Sheet2.
Formulas with AutoFilter ready.
Filtered and ready to delete
Delete all those rows (select A1, CTRL+SHIFT+DOWN ARROW, SHIFT+SPACE, CTRL+MINUS)
Delete column B to get final result with "pure" formulas every 5th row.
If you want to take a VBA approach to this, you can generate the references very quickly using simple For loops.
Here is some very crude code which can get you started. It uses hard-coded sheet names and variables. I am really just trying to show the i*5 part.
Sub CreateReferences()
For i = 0 To 12
For j = 0 To 5
Sheet2.Range("H1").Offset(i, j).Formula = _
"=Sheet1!" & Sheet1.Range("A5").Offset(i * 5, j).Address
Next
Next
End Sub
It works by building a quick formula using the Address from a reference to a cell on Sheet1. The only key here is have one index count cells in the "summary" rows and multiply by 5 to get the reference to the "master" sheet. I am starting at A5 just to match the results from INDEX.
Results show the formula input for H1 and over. I am comparing to the INDEX results generated above.
Here is one approach using INDEX instead of OFFSET. I am not sure if it is faster, I guess you can check. INDEX is not volatile, so you might get some advantage from that.
Picture of ranges, you can see that Sheet1 has a lot of data and Sheet2 is pulling every 5th row from that sheet. The data in Sheet1 goes from A1:F1000 and just reports the address of the current cell.
Formulas use INDEX and are copied down and across from A1 on Sheet2.
=INDEX(Sheet1!$A$1:$F$1000,ROW()*5,COLUMN())
What is the best way to find cells whose formulas refer to blank cells in Excel VBA. I'd like to delete any cell that references a blank cell.
More concretely, I have a two sheets: One sheet contains the actual values:
Product Month1 Month2 Month3
Sample1 1 3 5
Sample2 5 7 6
Sample3 3 8 2
The other is a summary view, with formulas to sum up the values, with the following formulas:
Product Month1
=values!A2 =SUM(values!B2:D2)
=values!A3 =SUM(values!B3:D3)
=values!A4 =SUM(values!B4:D4)
=values!A5 =SUM(values!B5:D5)
TOTAL =SUM(values!B:D)
Now in the previous example, the last raw refers to a blank row, namely the fifth row. Excel will show those cells as "0". Is there a mechanism to delete those cells within VBA?
Please note I prefer deleting the rows, to keep the TOTAL row close to the actual last value. Otherwise, the Total row might be distant from the rest of the values. Also, having blank cells with formulas may lead to a large Excel file.
EDIT: Clarified the question to role out the keeping the cells blank.
Is it always the last row, that could evaluate to 0?
If so u Could use a IF statement like:
=IF(SUM(values!B2:D2) > 0 ,values!A2,"") =IF(SUM(values!B2:D2),SUM(values!B2:D2),"")
No VBA needed...
I think Autofilter is the way to go here. If there's a zero in column A, I'm guessing you want to hide that whole row. You say delete, but I wonder if hide is a better way.
Put a filter on the range and for column A select everything except 0.
You could do this without having to write code to delete rows. I would use a variant of Arnoldiuss' solution.
For the Month total use:
=IF(LEN(values!A2)>0,SUM(B2:D2),"")
In this way, you can simply fill-down all the formulas and not have to worry if you reference a non-existent product.
Based on your edit i guess a pivot table fits your needs.
Add the products to the rowlabels and add the following calculated field to the values
=SUM(Month1,Month2,Month3)
Then add a value filter > 0
I would not recommend deleting rows in the "formula worksheet", for future use the series would wrecked, because of the missing references.