I am trying to figure out how to pull only specific rows and columns using Google apps script. The =QUERY is not an option to use. Need to keep all of the logic in the script - my actual data set is quite large. To illustrate what I'm trying to solve. I have a little table of test data. TestData From which I only want columns 2,3,5 (zero based index) and only the rows with "fur".
function testFour(sheetID, fromTabName, toTabName) {
var sourceTab = SpreadsheetApp.openById(sheetID).getSheetByName(fromTabName);
var values = sourceTab.getDataRange().getValues();
var columns = [2,3,5]; //only want these columns
var output = new Array();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[0].length; j++) {
if (values[i][4] == "fur") { // only want these rows
if (j in columns) {
output.push(values[i][j]);
}
}
}
}
var targetTab = SpreadsheetApp.openById(sheetID).getSheetByName(toTabName);
targetTab.getRange(1, 1, output.length, columns.length).setValues(output);
}
This code bit works but it is not very maintainable if there are many columns:
for(n=0; n < values.length; ++n) {
var columns = [2,3,5];
if (values[n][4] === 'fur') {
output.push( [values[n][2], values[n][3], values[n][5]]);
}
When I run the testFour function I get an error about "Cannot covert Array to Object[][] on this line of the code:
targetTab.getRange(1, 1, output.length, columns.length).setValues(output);
Appreciate any help. I was really surprised to not have found any examples of this. Every solution was using the =QUERY on the sheet.
Based on Cooper's suggestion above this was how I was able to get this to work:
function testFourNew(sheetID, fromTabName, toTabName) {
var sourceTab = SpreadsheetApp.openById(sheetID).getSheetByName(fromTabName);
var targetTab = SpreadsheetApp.openById(sheetID).getSheetByName(toTabName);
var srcrg = sourceTab.getDataRange();
var srcvA = srcrg.getValues();
var desvA=[];
// var columns = [2,3,5]; //only want these columns
var columns = String("2,3,5").split(','); //only want these columns
var tstVal = "fur";
var tstCol = 4;
for (var i=0;i<srcvA.length;i++) {
var tA=[];
if (srcvA[i][tstCol] ==tstVal) {
for (var j=0;j<columns.length;j++) {
//Logger.log(srcvA[i][columns[j]]);
tA.push(srcvA[i][columns[j]]);
}
desvA.push(tA);
}
}
targetTab.getRange(1, 1, desvA.length, desvA[0].length).setValues(desvA);
}
Thank you Cooper your direction and suggestions!
EDIT:
Don't need [] around output if using this line to push to output -
output.push( [values[n][2], values[n][3], values[n][5]]);
To set values by row, data has to be in this format -
[ row,
row ]
or,
[ [1,2,3],
[4,5,6] ]
Cannot covert Array to Object[][] error is shown when range and value format do not match.
Try this line -
targetTab.getRange(1, 1, output.length, columns.length).setValues([output]);
Report Builder
I'm guessing that you want to use this function to build different reports from the same dataset. So I might try something like this:
The Function:
function testFour(t4Obj) {
var ss=SpreadsheetApp.openById(t4Obj.ssId);
var srcsh=ss.getSheetByName(t4Obj.srcShName);
var dessh=ss.getSheetByName(t4Obj.desShName);
var colA=String(t4Obj.zbcols).split('~~~');
var tstCol=Number(t4Obj.zbtstCol);
var tstVal=t4Obj.tstVal;
var srcrg=srchsh.getDataRange();
var srcvA=srcrg.getValues();
var desvA=[];
for (var i=0;i<srcvA.length;i++) {
var tA=[];
if (srcVa[i][tstCol]==tstVal) {
for (var j=0;j<colA.length;j++) {
tA.push(colA[j]);
}
desvA.push(tA);
}
}
dessh.getRange(1, 1, desvA.length, desvA[0].length).setValues(desvA);
}
The t4Obj Data Table:
Of course you would have to build yourself a function that loads tthe t4Obj from the above table. From looking at your code, I'd guess that will be no problem for you.
And please note I have not tested any of this code so it is extremely unlikely to work the first time out of the box. You can sharpen your debugging skills on it.
Let's try making a array for a square range where the number incremented in by one in the same column position down each row. The array would look like this:
var A=[[1,6,11,16,21],[2,7,12,17,22],[3,8,13,18,23],[4,9,14,19,24][5,10,15,20,25]];
Make an Array by hand
function makeArray() {
var A=[[1,6,11,16,21],[2,7,12,17,22],[3,8,13,18,23],[4,9,14,19,24],[5,10,15,20,25]];
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getRange(5,5,5,5);//could be this way
//var rg=sh.getRange(5,5,A.length,A[0].length);//or in most programs this way
rg.setValues(A);
}
Having a weird issue with the Excel Online JS Api. I'm creating a new sheet and adding a table with data from an API call. There is a specific case where the first column of the table has a hyperlink function ('=HYPERLINK("somelink", "Go to Wherever")') and after it is being added to the table.rows, one of the rows is being created as the total row.
It always picks the same row to be the total row for the same set of data, but will pick a different row between sets of data. So, it's not always the same index being used.
Here is a snippet of how I'm adding the rows. It's pretty straight forward:
.then(function(){
var dataTable = ctx.workbook.tables.add(topLeftCell.address + ':' + topRightCell.address.split('!')[1], true);
var headers = data[0];
var headerRange = dataTable.getHeaderRowRange();
headerRange.values = [headers];
for (i = 1; i < data.length; i++) {
if (!data[i] || data[i].length !== data[i - 1].length) {
break;
}
dataTable.rows.add(-1, [data[i]]);
}
dataTable.getRange().format.autofitColumns();
return util.ctxSync(ctx);
})
.then(function(){
worksheet.activate();
return util.ctxSync(ctx);
})
The worksheet and the table create just fine, but having any formula as the first value in the row will cause one row to be created as the table's total row instead of a normal row. It can get gotten with dataTable.getTotalRowRange(), but is not in dataTable.rows. It's strange.
I've assumed this is an Excel bug and I can fix it by adding a dummy column with any value that isn't a formula as the first column and then deleting it before the autofitColumns().
Would anyone have any ideas towards a better fix? Any insight is appreciated.
My question is that I have found the code to traverse every row and cell but I am not able to understand how do i fetch every cell value with this code ? Can anyone help me with this code. I want to use this code only in my project.
Here is my js code
var table = document.getElementById('tblOne');
var rowCount = $('.table tr').length - 1;
for(var i=0; i<rowCount; i+=1){
var row = table.rows[i];
//your code goes here, looping over every row.
//cells are accessed as easy
var cellLength = row.cells.length;
for(var y=0; y<cellLength; y+=1){
var cell = row.cells[y];
console.log(cell);
//do something with every cell here
}
}
Following will help
var cell = row.cells[y];
console.log($(cell).text());
when i try to place an unorderd list fetched from the database column, into a dynamically created row of a table(using createElement) it shows the list tags along with the data. but doesn't appear formatted.
here is the code
var table1 = document.getElementById('pc');
for (var x = 1; x < len; x++) {
var vals = result[x];
var row = document.createElement('tr');
row.textContent = vals;
table.appendChild(row);
}
result is from ajax and it has the lists.
By "it shows the list tags along with the data" do you mean it is actually showing the <li> tag instead of actually making a list item?
It might be storing it in your database as < instead of <.
I am trying to write a script in Google Apps Script that takes cell information from one sheet and copies it to another sheet, both for just grabbing certain columns to display on the second sheet and also a condition based on the values inside cells in a certain column. Here is what I have so far:
function onMyEdit() {
var myMaster = SpreadsheetApp.openById("xxxxx");
var masterSheet = myMaster.setActiveSheet(myMaster.getSheets()[0]);
var myNames = SpreadsheetApp.openById("xxxxx");
var namesSheet = myNames.setActiveSheet(myNames.getSheets()[0]);
var row1 = masterSheet.getRange(1, 1, masterSheet.getLastRow(), 1);
var rowV = row1.getValues();
var firstArray = masterSheet.getDataRange().getValues();
var dataList = [];
for (var i = 1; i < rowV.length; i++) {
dataList.push(firstArray[i][0]);
dataList.push(firstArray[i][1]);
dataList.push(firstArray[i][2]);
dataList.push(firstArray[i][3]);
}
for (var j = 0; j < rowV.length - 1; j++) {
namesSheet.getRange(2, j + 1, 1, 1).setValue(dataList[j]);
}
}
So as of now it only works on one row, starting from the second row (to allow for column headers). And I suppose when I want to grab rows conditionally based on cell data, I will use an 'if' statement for the condition inside the 'for' loop, but I want the data to copy to the next available row in both sheets. I suppose I'd use something like:
' getLastRow + 1 '
or something like that. I need this code to be as efficient as possible because of the amount of data and its purpose. I am pretty new to programming so please explain in detail, and thanks again.
I'm not sure I understood exactly what you wanted to do but -from what I understood- this code snippet should give you a better way to start with...
(I added a few comments to explain in the code itself)
function onMyEdit() {
var myMaster = SpreadsheetApp.openById("MasterSheet ID");
var masterSheet = myMaster.getSheets()[0]; // get 1rst sheet
var myNames = SpreadsheetApp.openById("NamesSheet ID");
var namesSheet = myNames.getSheets()[0]; // get 1rst sheet
var firstArray = masterSheet.getDataRange().getValues();
var dataList = [];
for ( r = 1; r < firstArray.length; r++) { // iterate the first col of masterSheet
if(firstArray[r][0]=='some condition'){ // if value in the first column == 'some condition get the second column cell in the new array (here you could change what you want to get)
dataList.push([firstArray[r][1]])
}
}
Logger.log(dataList)
if(dataList.length>0){
namesSheet.getRange(1,namesSheet.getLastColumn()+1,dataList.length,1).setValues(dataList);//copy data in a column after last col
}
}