I'm trying to add on a column in which I calculate a count column. This count columns is at the User>Timestamp level, so if you start with an ordered table, you would go down from top to bottom, incrementing the count by 1, and setting it to 0 every time you get to a new user.
The way I thought I'd do this is using a Select statement to generate the ordered results, then iterate through each row and insert each row back into a new table, but also work out the count in the process.
In this case how do I use the row object returned by
for row in c.execute(sqlStr):
and easily re-insert all the columns in this row back into a new table but also add in a new column in the process?
I'm trying to avoid having to go through all the column names returned by row and construct a messy sql string (i.e. I only want to have to specify the new column and not type out all the existing column names).
Actually think I figured it out, though not sure if it's the best way of doing it.
I've gone with doing something like:
for row in c.execute(sqlStr):
a = str(row)[:-1] +', ' + newValue
Related
I have a list of keys that I want to return another key if another column matches that key and is greater than one. Then it will return the key if that same other column is equal to 1. I will attempt to explain this better with visuals below. I would appreciate any assistance or at least how I would go about doing this.
What I am Starting With:
What I would like to end with:
Use INDEX/AGGREGATE:
=IFERROR(INDEX($B:$B,AGGREGATE(15,7,ROW($A$2:$A$9)/($A$2:$A$9=$E2),COLUMN(A1))),"")
Put that in the first cell and copy over as far as desired and down the unique list:
If one has Office 365 Excel then put this in the first cell and drag down the unique list and it will spill to the right as needed:
=TRANSPOSE(FILTER(B:B,A:A=E2,""))
You can use a pivot table and put Key1 in the rows and Key 2 in the columns. Then you can drag the Quantity fields into the filter and make sure you only get the columns = 1.
Finally, if you want to initial Key for the quantity that is > 1 you could either use a second pivot or you order die initial table descending by quantity and use index match or vlookup to return the first match (which if ordered correctly will be the key for the quantity > 1).
I am trying to filter the highest number in each of four columns in Power BI.
For specific occurences of a string in the column of another excel file loaded in my Power BI, I want to select one of the four number and increment it.
I have several difficutlies:
- I cannot select the highest number
- I do not know how to create a costum column referencing another sheet
- I do not know how to "store" a value dinamically for each occurence
Here is the input excel workbook:
Here is the excel workbook with data to increment (in Power Bi I already suprressed the strings, seperated my column in four columns each needing to be incremented, becauseI did not know to do it in another way. Having strings character at the begining for example, was a clear issue to increment).
Here is the resulting excel: each time a specific name appears I add one to the higest value of each iteam in my column :
I need to search for the highest number in each of these columns:
When I see "ItalyB", "ItalyZ", "UKY" or "UKM", I need to increment the highest number.
The first incrementation will be equal to the highest number from the column + 1, and the second, to the result + 1.
The highest number between ABE0000 and ABE4000, once found, I add one to AB for each "ItalyZ" elements. i.e AB0003 for one element "ItalyZ", the next "ItalyZ" wil get AB0004
The highest number between ABE4000 and ABE9000, once found, I add one to AB for each "ItalyB" elements. i.e AB4003 for one element "ItalyB", the next "ItalyB" wil get AB0004
The highest number between BC0000 and BC4000, once found, I add one to BC for each "UKY" elements. i.e BC0003 for one element "UKY", the next "UKY" wil get BC0004
The highest number between BC4000 and BC9000, once found, I add one to for each "UKM" elements. i.e BC4003 for one element "UKM", the next "UKM" wil get BC4004.
I do not know how to do that. I have added a date:
And I am trying to increment given the date, but I am having difficutlies:
Although I didn't understand your question as it is not explained well (you are directly referring to column codes 'ABE0000' etc. without showing which excel or sheet you are referring)
But I can answer one part which I understood. Create a new column which increments highest number in it by 1.
Lets call the calculated column as ABERangeLowIncrement:
ABERangeLowIncrement =
var maxABERangeLow =
Calculate(max('ABE Range Low'),ALL(TableName'ABE Range Low'))
return
if(TableName'ABE Range Low' = maxABERangeLow,maxABERangeLow +1, TableName'ABE Range Low')
I'm attempting to grab each instance of the largest value within a range and display the five adjacent columns of data associated with each instance.
Sample
I was able to grab the largest data using this:
=IFERROR(LARGE($A$3:$A$100,ROW(1:1)),"NONE")
Unfortunately, I'm unable to figure out how to grab the adjacent data associated with the next instance of the duplicate value.
Note:
The archive table is in ascending order because that is the only way I can think of to ease copying and pasting the latest data.
If you do not want to use a sorted order, you can simply use this array formula at H3 and then auto-fill it to M8:
=IFERROR(INDEX($A$3:$F$18,SMALL(IF($A$3:$A$18=MAX($A$3:$A$18),ROW($1:$16)),ROW(A1)),COLUMN(A1)),"NONE")
This is an array formula and must be confirmed with Ctrl+Shift+Enter!
If you still have any questions, just ask ;)
EDIT:
The core is IF($A$3:$A$18=MAX($A$3:$A$18),ROW($1:$16)) which returns an array of rows and False like {FALSE,2,FALSE,FALSE,5,FALSE.....}. Knowing that SMALL ignores FALSE, You get with SMALL(...,1) the first row with the max value. (this way SMALL(...,2) will output the second row .....).
Using ROW(A1) and COLUMN(A1) as non static ref, you get the k for our SMALL and the column for our INDEX :)
Step 1)
Take your large function and compare it to the max from your source range, if it is less than max display none, if otherwise have it display the max.
Step 2)
Since your data is sorted in ascending order find the position in the range of the first instance of your maximum value.
=MATCH(MAX($A$3:$A$18),$A$3:$A$18,0)
We will use this to return the corresponding values in the adjacent columns by substituting it into an index formula for each column to be returned
=INDEX(B$3:B$18,MATCH(MAX($A$3:$A$18),$A$3:$A$18,0))
Place the above in I3 and copy it to right
Step 3)
Since your Data is sorted in order it means the next row down in column A of the max value will be still max value or end of the list. There for match value need to be increased by 1 for each consecutive row and needs some error handling
So we can use our formula from row 3 and adjust it as follows:
=IFERROR(INDEX(B$3:B$18,MATCH(MAX($A$3:$A$18),$A$3:$A$18,0)+1),"NONE")
OR
=IF(H4="NONE","NONE",INDEX(B$3:B$18,MATCH(MAX($A$3:$A$18),$A$3:$A$18,0)+1)
then change the +1 to a +2 then +3, etc however since we don't know wow many times this process will complete we can use the row reference which you started with and change the formula as follows:
=IFERROR(INDEX(B$3:B$18,MATCH(MAX($A$3:$A$18),$A$3:$A$18,0)+(row()-3)),"NONE")
OR
=IF(H4="NONE","NONE",INDEX(B$3:B$18,MATCH(MAX($A$3:$A$18),$A$3:$A$18,0)+(ROW()-ROW($A$3))))
the -3 being the hardcoded value for your first row of data which could also be changed to -ROW(A3) where A3 is a cell in the first row of your new table.
ERROR CORRECTION
I was adding the row bump to the match portion inside the match formula. This was a mistake. adding the +1,+2 or whatever needs to be added to the results of the match formula but still within the index formula. I have updated the formulas above to reflect this.
I have a sheet setup that calculates totals. Easy enough if the data is already there but not if adding new data. So what I would like to be able to do is to not specify a specific end cell for the sum formula but let it update as more columns are added.
How can I do this with =SUM(m4:m?)
Suppose you need totals for data in M4:M10.
To make just open-ended range, you can make lower limit "too far": =SUM(M4:M100000).
Alternatively you can make it as =SUM(M:M) - SUM(M1:M3)
But this is not applicable when you need to have totals value just below the set of values. In this case you have 2 ways.
Using Excel embedded features
The formula will look like his: =SUM(M4:M10). If you insert a new row between M4 and M10 (for instance, select row 5, right-click, insert row), you formula will be automatically adjusted to =SUM(M4:M10).
The problem may happen if you want to insert a new value above the first row (select row 4, right-click, insert row) or below the last row (select row 11, right-click, insert row). In these cases totals formula will not be adjusted.
Possible workarounds:
For the "above first row" issue, I prefer to make some empty row above and hide it. In our case I would hide row 3 and make totals formula look like =SUM(M3:M10), so, when you insert a new row above the first row, in fact you insert a row to the middle of the table, and totals formula will be adjusted.
For the "below last row" - leave empty row below; but in this case you cannot hide it; just make it different color and make some remark like "new values shall be inserted ABOVE this line".
INDEX()
Interesting trick is using INDEX() function, which returns a reference to a cell in the array. For our case, the array can be the whole M row and, the index - row number.
For the "above first row" issue make totals formula like this =SUM(INDEX(M:M;4):M10). So, calculation will always start at row 4, even if some lines will be added/deleted.
"below last row". Suppose you have your "totals cell" in M13 and you want to have totals for all value between M4 and the "totals cell". The formula may look like =SUM(M4:INDEX(M:M;ROW(M13))) or, considering "above first row" case: =SUM(INDEX(M:M;4):INDEX(M:M;ROW(M13)))
Hope this helps
Sum(m4:m?) insinuates that you are looking to add more rows as opposed to adding column data.
If you want to auto sum a row data you can use something like:
=SUM(OFFSET(A1;0;0;COUNT(A:A);1))
However this assumes that the data is contiguous in each cell and also empties are not allowed for 0 because it gets the count wrong.
However: You could also define a table for the data range. If you add data to columns/rows that are in that data range, they will be included in the adjusted formula automatically - very nice indeed.
Select your data range, then Select Insert:Table. This will give your table a name like Table1.
Your sum function would now be adjusted to look something like:
=SUM(Table1)
Now, as you add to the range, the table resizes, and your function just works.
The beauty of using a table, is that if you add data to the row/column immediately after the table it resizes and includes that range. This is hard to do without a table. You can also change the format of the table, or make the format colours invisible but you're probably better off with some format to show the data area of the table to the user.
You can compute the last row containing a number using this formula:
=LOOKUP(2,1/ISNUMBER($J:$J),ROW($J:$J))
This formula would not have a problem if you had text or blanks in the range.
You could then define that formula as a Defined Name
and use the formula:
=SUM(OFFSET(J4,0,0,LastRow-3))
to Sum the range. Note the -3 at the end to compensate for the first cell being in row 4.
Another option would be to just set your range to a fixed range that you can guarantee will be larger than any range you might actually use:
=SUM(J4:J1000)
You can use a counta to find the max row number. Then pushing that into an indirect will give you the range you need.
=SUM(INDIRECT("A1:A" & COUNTA(A1:A1000000);TRUE))
Assumptions:
Data are on column A
Data start from first row
There are no blanks rows
My task is to return a list of items from the records in one table (with structured referencing), from another table (with structured referencing), if the record in the first table "KitList" has a quantity of 1 or greater.
Currently my closest result is using the following formula
=INDEX(KitList[Item],SMALL(IF(KitList[Quantity]>0,ROW(KitList[Quantity])),ROW(1:1)))
However, this returns incorrect values. Specifically, it returns the row after the row containing 1 (or greater), and skips the first row. i.e.
KitList
[Item]|[Quantity]
Item a | 1
Item b | 0
Item c | 2
Item d | 1
Item e | 0
Return
Item b
Item d
Item e
I think this is due to some interaction of the ROW commands counting the headers of the tables, as well as the data in them, therefore reading the range as a whole with the header, and giving an extra row in the return value. Is there a way, in the final ROW command to specify the row I need through structured referencing? Would that fix the problem?
The ROW function will return the row in the spreadsheet, not the row of the structured data. Easy solution ROW - 1
EDIT: My original answer didn't produce the desired result when copied down.
I think this is what you want:
=INDEX(KitList[Item],SMALL(IF(KitList[Quantity]>0,ROW(KitList[Quantity])-ROW(KitList[#Headers])),ROW(1:1)))
This will also allow you to move the source Table anywhere you want, i.e. the header row doesn't have to be 1:1, and the results can also be located anywhere as well.
{=INDEX(KitList[[#All],[Item]],SMALL(IF(KitList[Quantity]>0,ROW(KitList[Quantity])),ROW(1:1)))}
By specifing to the index that I want to include 'all' of the kit list table, the data and the header, not just the header, I've managed to fix the problem. Still seems awkward though.