I am trying to perform a calculation on each row using the Array Formula function. When I try to use a range A2:A it tries to perform a calculation on the entire range as opposed to per row.
Which part am I missing to calculate per row?
={"id";ArrayFormula(TEXTJOIN("", TRUE,(LEFT(B2,2)),(A2*86400000)))}
Here is the formula active in a Google Sheet
https://docs.google.com/spreadsheets/d/1YXA_yC_beoe7UXgXZvbj9knNU8ms1MPMgLKrro4G-T0/edit?usp=sharing
Some formulas like Textjoin won't work in an arrayformula. If the formula already takes a range, then it doesn't understand that you want it to calculate row by row. Try this formula. I got rid of the textjoin part, and just used an ampersand to join columns A and B.
={"id";ArrayFormula(iferror(if(A2:A="",,LEFT(B2:B,2)&(A2:A*86400000))))}
`
Related
I have a large workbook that pulls in weekly data (columns) for hundreds of metrics on several tabs. It pulls this data in via SUMIFS formulas, and on most tabs there are several rows that contain ratios/rates calculated from these SUMIFS formulas.
Here is a toy example.
For each sheet, I would like to paste values only for formulas that are based on 'SUMIFS', and leave the other calculations. I was able to select a range and loop cell-by-cell to accomplish this, but it takes a long time due to the size of the workbook. Is there a way to do this at once in a batch-fashion? Basically, I want to copy and paste-values only if a certain condition exists.
Solution:
Updated - Slight improvement to make it faster by Iamblichus.
I am not quite sure what you have tried so far, but this one works relatively fast for a couple of sheets:
function myFunction() {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheets = ['Sheet1','Sheet2'].map(sh=>ss.getSheetByName(sh));
sheets.forEach(sh=>{
let range = sh.getDataRange();
let formula = range.getFormulasR1C1();
let values = range.getValues();
formula.forEach( (fr,fx) =>
{fr.forEach((fc,fy)=>{
let outR=sh.getRange(fx+1,fy+1);
if (fc.toUpperCase().includes('SUMIFS')) outR.setValue(values[fx][fy]);
})})});
}
Please adjust ['Sheet1','Sheet2','Sheet3'] to your needs.
Explanation:
I am iterating through each sheet and I am checking whether the cells contain SUMIFS formula or not. If they do, I overwrite them with their value, otherwise I keep their formula.
Script lab shows examples of how to get a range using rows, columns and cell values here:
https://learn.microsoft.com/en-us/office/dev/add-ins/excel/excel-add-ins-ranges-advanced
However, all the values in examples were hardcoded. I could not find on any page any example of how to use variables in the get range? Maybe its a simple javascript thing but I am totally new to it. Can anyone share an example of how to do say?
sheet.getRange("4:9") using variables for number 4 and number 9?
And if you do know that answer for above, can you also share, how to do this using cell references in the below example?
Assume that I can find the values of rows and column names and set them in some variables. How would I use it in below code replacing the values for G1, A1 and E1?
sheet.getRange("G1").copyFrom("A1:E1");
Thanking you in advance for your help!
P.S: I already tried searching on stack overflow with keywords for "script lab range variables" but found no answers. Hence asking here.
Excel.run(function (context) {
var sheet = context.workbook.worksheets.getItem("Sample");
// Group the larger, main level. Note that the outline controls
// will be on row 10, meaning 4-9 will collapse and expand.
sheet.getRange("4:9").group(Excel.GroupOption.byRows);
// Group the smaller, sublevels. Note that the outline controls
// will be on rows 6 and 9, meaning 4-5 and 7-8 will collapse and expand.
sheet.getRange("4:5").group(Excel.GroupOption.byRows);
sheet.getRange("7:8").group(Excel.GroupOption.byRows);
// Group the larger, main level. Note that the outline controls
// will be on column R, meaning C-Q will collapse and expand.
sheet.getRange("C:Q").group(Excel.GroupOption.byColumns);
// Group the smaller, sublevels. Note that the outline controls
// will be on columns G, L, and R, meaning C-F, H-K, and M-P will collapse and expand.
sheet.getRange("C:F").group(Excel.GroupOption.byColumns);
sheet.getRange("H:K").group(Excel.GroupOption.byColumns);
sheet.getRange("M:P").group(Excel.GroupOption.byColumns);
return context.sync();
}).catch(errorHandlerFunction);
So, I got an answer on this here: https://github.com/OfficeDev/office-js-docs-pr/issues/1699
Thanks to AlexJerabek (you can find his id on the above github link).
In summary:
The getRange method takes in a string representing a cell range in the worksheet, such as "A1:D4", "A:D" for just the columns, or "1:4" for just the rows. As long as your variables map to Excel rows or columns, you can use string concatenation to build the argument. You may need to use range.columnIndex, range.rowIndex, and range.getCell to translate to and from zero-based numbers into the letter-based columns.
Based on this answer, I tried below (and it worked):
const sheet = context.workbook.worksheets.getActiveWorksheet();
var firstrow = 1
var lastRow = 6
var range = sheet.getRange(firstrow + ":" + lastRow)
So I've built a script which grabs (public) data from Instagram, dumps it in a table and then I construct a dashboard based on it.
It looks like this:
Now, I've built a formula that calculates the daily new followers if there is a value filled in:
=if(B3<>"",B3-B2,"")
However, in my script I use sheet.appendRow to (job-based) auto-populate the spreadsheet with new data every night at 12. The issue I have is that when I drag my formula down, say 20 lines to not have to go in everyday to drag down the formula), my sheet.appendRow will paste it below those 20 lines (which essentially, are visually blank).
I've been looking around on Google (and stack) to find a function that can do the same as my formula, and will calculate the new daily followers every time at night (when the job runs), but my knowledge of Scripting is to limited to find a solution that works. So basically: the value from the current row in column B - the value from the row above in column B = New Daily Followers.
I prefer to solve this with a Google Script, as I'm looking to do additional calculations on other columns in a similar fashion, and can then just adapt the script to calculate these new KPI's.
Can anyone assist me in creating this?
Apend in C1:
={"Header" ; " " ; FILTER(B3:B-B2:B,A2:A<>"")}
and delete all other formulas from column C.
Notes:
The formula will create the filter and it's no need to drag down, will adjust automatically.
assumed all cells from A2:A have go blanks inside the table
"Header" ; " " to leave C2 blank
I have a Google Spreadsheet with 13 sheets. Each sheet has the same formatting and layout but the data varies. The ranges I need from each sheet are F7:G13 and cell F2. Each row within the F7:G13 range should be paired with Cell F2 and placed into 3 adjacent columns in another workbook (we'll call it Workbook2). So if there is a data point in column F there will be a data point in the adjacent G cell. As long as there is data in the G:F range then the contents of cell F2 needs to be copied over too.
Some potential problems...
The number of rows in the F:G range will vary from 0 to 7 on any given sheet.
Workbook2 has some auto-populated cells (range F1:J14) which will do some calculations based on information copied over. I mention this because unless there is a way to use appendRow on a specific cell range (A:C) it will copy the data starting in row 15 which I do not want.
I think i've included everything but I will gladly clarify anything. Thanks in advance for any help.
I have chart of winning positions. http://jsfiddle.net/DhcTV/4/ like this. As you can see the last ones and the biggest postion get's your attention.
How to reverse the columns so the smallest positions get the biggest columns and the last positions gets small column ?
Would this be possible to do with the highcharts or does this requires additional calculation ?
Why don't you just reverse the order of the values? See your code updated.
In order to reverse the values of an array, you can use the reverse(..) function on the values array.