I am having an application with functionality of showing tables for multiple stocks. If two stocks are present, two tables will be created dynamically as below.
Here two tables are present and I want to get the sum of %change in each year. ie sum of %change in 2015 from both tables like 2014=7.88+1.69, 2015=-11.24+6.44 etc. Please help me to do. I need a solution using javascript.
Link to Tables Image
Depending on how the tables are formatted, you could write a function to look at the <td> tags that belong to the %change column and then sum the values in it. The 5th <td> of row 2 and on will have the numerical value in it.
Set up a loop of all stock tables first..
var stocks = ["GE", "GOO"]; // stock codes, to use with table IDs
var num = stocks.length;
var years = {};
for(var loop = 0; loop < num; loop++){ // loop all of our stocks
var tableID = "table_"+stocks[loop]; // make sure this matches tableid structure
var table = document.getElementById(tableID); // get our table
var rowNums = table.rows.length; // number of rows in table
for(var rowLoop=1; rowNums: rowLoop++){ // skip first row (row 0)
var row = table.rows[rowLoop]; // get the row
var year = row.cells[0].innerHTML; // get text inside the cell
var change = rows.cells[5].innerHTML(); // get text inside the cell
change = change.replace("%", ""); // remove % sign
// Strip change percentage here
// Make sure it is proper number that can be added
if(!years.year){
years.year = change;
} else {
years.year += change; // do math to update year change amt
}
}
}
console.log(years);
I wrote this from my phone and it's 3:45am so I haven't had a chance to test it. Although I'm sure any errors could be easily fixed. This code and logic will do what you want. The only thing you have to do is actually remove the percentage signs and do some beta testing to ensure it works for you
You also need to make sure your tables have proper ID :)
SO really needs a code button for mobile... Spacebar 4 times on every line sucks
Related
I'm brand new to java & scripting in Google Sheets & this is my first question on here, so any etiquette tips are appreciated.
I have been learning so much from this site, but I've been stuck on this simple error for weeks now & finally just have to ask since I can't find a solution anywhere.
EDIT to Hopefully be More Clear
I have a sheet with pricing in column "U" with formulas in columns "V" & "W" that change according to the value in "U". I created a button & attached a script that I would like for it to add the value of each cell in V to the value in W of the same row, for one iteration each time I select the button, & returning the new values in the same cell of column W.
Example Sheet
I've tried a lot of script variations that all returned different results, but none just simply adding these two columns together. Below is what I've patched together that almost does exactly what I need, but it needs a tweak somewhere & I can't figure it out.
function testPlus10(){
var colV = SpreadsheetApp.getActiveSheet().getRange("V2:V100").getValue();
var cell = SpreadsheetApp.getActiveSheet().getRange("W2:W100");
var cellValues = cell.getValues().map(function(row) {return [row[0] + colV]});
cell.setValues(cellValues);
}
Instead of adding the value in (From the example above) V2 to W2, V3 to W3, & so on down the column, it only adds the value of V2 to every cell in W. Meaning that from the example: my current script returns values of V2+W2 in W2, V2+W3 in W3, V2+W4 in W4, instead of V2+W2 in W2, V3+W3 in W3, V4+W4 in W4, ect... It adds a $1 to every cell in W.
Hopefully this makes more sense.
Assuming this is the expected behavior, you can use this code, which is pretty simple and can be used for multiple columns of your choice.
function sumColumns(){
var spreadsheet = SpreadsheetApp.getActive();
var currentRow = spreadsheet.getDataRange().getLastRow(); //Get the last row with value on your sheet data as a whole to only scan rows with values
for(var x =2; x<=currentRow; x++){ //Loop starts at row 2
if(spreadsheet.getRange("V"+x).getValue() == ""){ //Checks if V (row# or x) value is null
Logger.log("Cell V"+x+" is empty"); //Logs the result for review
}
else{
var res = spreadsheet.getRange("V"+x).getValue() + spreadsheet.getRange("W"+x).getValue(); //SUM of V & W values
spreadsheet.getRange("W"+x).setValue(res); //Replace W value with "res"
}
}
}
I just want to change a cell in E5 but I can only seem to edit the first column.
var cell = sheet.getRange(2,5)
cell.setValue("TEXT");
All this does is put "TEXT" into cell E2.
EDIT: Below is the entire code.
var sheet = SpreadsheetApp.openById("SheetID").getSheetByName('Sheet1');
function doGet(e) {
var amount = JSON.parse(e.parameter.amount)
var student = JSON.parse(e.parameter.student)
var cell = sheet.getRange(student,2)
cell.setValue(amount);
}
SAMPLE URL
https://script.google.com/macros/s/mygooglesheetID/exec?amount=6&student=6
The code in the question should is adding TEXT to E2 but you want to be added to E5.
The first parameter is the row, the second is the column, so in order to get E5
instead of
var cell = sheet.getRange(2,5)
use
var cell = sheet.getRange(5,5);
Regarding the full code
instead of
var cell = sheet.getRange(student,2)
use
var cell = sheet.getRange(student,5)
Reference
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow-column
NOTE: As a good practice, include a semicolon (;) at the end of the JavaScript statements.
Do you recommend using semicolons after every statement in JavaScript?
I have a dynamically created table with a number of columns, including a input text control.
I read records from the DB and populate this input field accordingly.
It gets populated correctly on the first page, but not for the other pages.
I am using Footable v3
I tried a bunch of things.
The script seems to go through all the records correctly, but the output is not visible page 2 onwards.
function populateNotes(tableId) {
var table = document.getElementById(tableId);
var allRows = FooTable.get(table).rows.all;
var rowItem, rw;
var notesTD, jNo;
// This loop goes through all records correctly
for (rw in allRows) {
rowItem = allRows[rw];
var jNo = rowItem.$el.find("td:nth-child(1)").text();
console.log("populateNotes: Row: ", jNo);
var notesTD = rowItem.$el.find("td:nth-child(12)").find('#kpi-notes');
if (notesTD.length !== 0) {
notesTD.val('' + getKpiNotes(jNo));
}
}
}
I expect to see the input field 'notesTD' containing the correct value, but this happens only on the first page.
Next page onwards, it is empty.
Appreciate any help or pointers.
Did you try using the footable events, I use to do this to manage modification of content or style. It also take less time because you only iterate in the 10 or 15 lines of the pages
For example you can use the afterpaging
"after.ft.paging": function (e, ft) {
var colarray = ft.columns.array; //array is just the records shown on the page
........
I've got this basic script for Google Sheets, in G.Script
var a = [['1','2']];
for (var i = 0; i <5; i++){
var range = sheet.getRange("A"+i+":B"+i);
range.setValues(a);
}
As you can see, I write 5 times the table "a" in the sheet. What I'd like in concatenate all the tables "a" in one table and write this table, once in the sheet.
I've tried with concat(), but it does not work. So maybe I don't use it properly.
Could you please help me ?
Many thanks
B.
I recommend that you create your spreadsheet range based on the size of your array "a". Rather than creating a cell range such as A1:B5, I recommend using number values to define the range that you would like to update.
Also, updates to Google Sheets run much faster if you update an entire range at one time.
function myFunction() {
var data = [];
data.push([1,2]);
data.push([2,3]);
data.push([3,4]);
if (data.length > 0) {
SpreadsheetApp.getActiveSheet()
.getRange(1,1,data.length,data[0].length)
.setValues(data);
}
}
Sorry if this is a bit newbie.
What I'm trying to do is take a column and delete the values in some of its cells if they do not contain a formula.
function clean() {
var ss = SpreadsheetApp.openById("KEY_REMOVED_FOR_OBVIOUS_REASONS");
var sheet = ss.getSheetByName("TEST");
var limit = sheet.getMaxRows();
for(var i = 6; i < limit; ++i){ // Declares variable "i", which represents the row we are currently checking. Basically says "if our row isn't the last one, execute this block then add to i".
var range = sheet.getRange(i,2);
if (range.getValue() != "") { // Leverages the fact that .getValue() cannot return functions. If our range is blank, execute this block.
range.clear();
}
}
}
I established a loop which checks every row one by one. What I'm wondering is, is there a more efficient way to do this than having to call the server every time I do the loop?
getValues() exists of course, but I'm not sure how one might interact with only the desired cells returned by that.
I did some testing. .getValues() will return the computed values if there are formulas.
The following code works for me.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getLastRow();
var range = sheet.getRange(1,1, rows);
var values = range.getFormulas();
range.clear();
range.setFormulas(values);
}
Short answer
Regarding the too many calls issue, use getLastRow() instead of getMaxRows() and use the returned value (number of rows) to get the required range in just one call.
Explanation
getLastRow() returns the position of the last row that has content while getMaxRows() returns the maximum height of a sheet regardless of content.
getRange(row, column, numRows) returns in just one call the complete range.