Hi sorry this is probably a very newbie question, I am teaching myself and can't figure out how to google the answer to this one.
I have a loop in google sheets that goes through each field and updates some cells which pull info from a website that I then need to copy across into each row of the loop. It seems to be working through the loop okay however when trying to copy i cant get it into the correct row.
Im sure its something very simple hoping someone out there can point me in the right direction. I'm pretty sure its to do with the code at line 34 but can't figure out how to correct it.
function myLoop() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Lsheet = ss.setActiveSheet(ss.getSheetByName('Loop'), true);
var rangeData = Lsheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var dataRange = Lsheet.getRange(2,1, lastRow-1, lastColumn-1);
var data = dataRange.getValues();
var len = data.length;
var i = 0
for (i; i < len; i++) {
var row = data[i];
var player = row[4]
var prop = row[6]
var number = row[7]
var overodds = row[8]
var underodds = row[9]
var overreq = row[10]
var underreq = row[11];
if(prop = "Points"){
ss.setActiveSheet(ss.getSheetByName('Stats'), true);
ss.getRange('B1').activate();
ss.getRange("B1").setValue(player);
ss.getRange('AB5').activate();
ss.setActiveSheet(ss.getSheetByName('Loop'), true);
ss.getRange(overreq).activate();
ss.getRange('Stats!AB5').copyTo(ss.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
ss.setActiveSheet(ss.getSheetByName('Stats'), true);
ss.getRange('AB6').activate();
ss.setActiveSheet(ss.getSheetByName('Loop'), true);
ss.getRange(underreq).activate();
ss.getRange('Stats!AB6').copyTo(ss.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
}
}
Modifications of the original code:
Corrected an error in line 24. In your original post, you are using = (assignment operator) to compare your variables. However, you want to use == (equality operator).
Added missing semicolons. Although not necessary, makes for good, consistent style and may prevent some errors.
Moved i declaration inside the for-loop. Makes for cleaner, safer code.
Modified for-loop body so that it uses ranges and setValue(), getValue() methods to copy data.
function myLoop() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Lsheet = ss.setActiveSheet(ss.getSheetByName('Loop'), true);
var rangeData = Lsheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var dataRange = Lsheet.getRange(2,1, lastRow-1, lastColumn-1);
var data = dataRange.getValues();
var len = data.length;
var statsSheet = ss.getSheetByName('Stats');
var loopSheet = ss.getSheetByName('Loop');
for (var i = 0; i < len; i++) {
var row = data[i];
var player = row[4];
var prop = row[6];
var number = row[7];
var overodds = row[8];
var underodds = row[9];
var overreq = row[10];
var underreq = row[11];
if (prop == "Points") {
statsSheet.getRange('B1').setValue(player);
loopSheet.getRange(overreq).setValues(
statsSheet.getRange('AB5').getValues()
);
loopSheet.getRange(underreq).setValues(
statsSheet.getRange('AB6').getValues()
);
}
}
}
Could you try this:
var currentRow = ss.getActiveRange().getRow();
var currentCol = ss.getActiveRange().getColumn();
.
.
.
ss.getRange('State!AB5').copyTo(ss.getRange(currentRow+1, currentCol),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
Related
I need someone to modify this script that I found here to update or replace the row value of the sheet2 from sheet1 when a unique ID is found. This only works up to the 2nd column..I need something to update or replace rows in the sheet2 up to 10 columns or more. I have a sample spreadsheet. If you see on sheet2, some row values are missing or not yet updated, so I need those rows to be updated or replaced what's in sheet1.
Here is the spreadsheet:
https://docs.google.com/spreadsheets/d/100sjGCr0HSdJE1AERCJ9bGKiu3Vs2KxrvGIIjIrOjHw/edit?usp=sharing
Thanks for helping and sharing your knowledge.
function updateEntrees() {
var ss=SpreadsheetApp.getActive();
var sh1=ss.getSheetByName('Sheet1');
var rg1a=sh1.getRange(2,1,sh1.getLastRow()-1,1);
var vA1a=rg1a.getValues();
var rg1b=sh1.getRange(2,2,sh1.getLastRow()-1,1);
var vA1b=rg1b.getValues();
var sh2=ss.getSheetByName('Sheet2');
var rg2a=sh2.getRange(2,1,sh2.getLastRow()-1,1);
var vA2a=rg2a.getValues();
var rg2b=sh2.getRange(2,2,sh2.getLastRow()-1,1);
var vA2b=rg2b.getValues();
for(var i=0;i<vA1a.length;i++) {
for(var j=0;j<vA2a.length;j++) {
if(vA1a[i][0]==vA2a[j][0]) {
vA2b[j][0]=vA1b[i][0]
}
}
}
rg2b.setValues(vA2b);
Try the following code, in the second line, change the value of "numColumns" as per your need:
function updateEntrees() {
var numColumns = 9;
var ss = SpreadsheetApp.getActive();
var sh1 = ss.getSheetByName('Sheet1');
var rg1a = sh1.getRange(2,1,sh1.getLastRow()-1,1);
var vA1a = rg1a.getValues();
var rg1b = sh1.getRange(2,2,sh1.getLastRow()-1,numColumns);
var vA1b = rg1b.getValues();
var sh2 = ss.getSheetByName('Sheet2');
var rg2a = sh2.getRange(2,1,sh2.getLastRow()-1,1);
var vA2a = rg2a.getValues();
var rg2b = sh2.getRange(2,2,sh2.getLastRow()-1,numColumns);
var vA2b = rg2b.getValues();
for( var i=0; i < vA1a.length; i++ ) {
for( var j=0; j < vA2a.length; j++ ) {
if( vA1a[i][0] == vA2a[j][0] ) {
vA2b[j] = vA1b[i];
}
}
}
rg2b.setValues(vA2b);
};
I need to figure out a way to set a drop down value based on if another cell in the same row has a value. So for instance if D2 has a value other than '' or null; H2 needs to be set to "New Issue". The answers found in another similar post don't actually work with this since I am using formRedirector. Things got really weird last time. I tried to delete the earlier post but couldn't.
I have some of the logic figured out, but the issue is that what I have now writes "New issue" to H3 and below. Here is what I have so far:
var NEW_ISSUE = 'New Issue';
function defaultValue() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 900;
var dataRange = sheet.getRange(startRow, 4, numRows);
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var default_status = row[7];
if (default_status != NEW_ISSUE && row == '') {
sheet.getRange(startRow + i, 8).setValue(NEW_ISSUE);
}
}
}
I have a feeling somewhere in the if statement I am messing up somewhere.
This solved the issue, thank you
var NEW_ISSUE ='New Issue';
var row;
var default_status;
function defaultValue() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1;
var numRows = 900;
var dataRange = sheet.getRange(startRow, 4, numRows);
var data = dataRange.getValues();
var statusRange = sheet.getRange(startRow,8,numRows);
var status = statusRange.getValues();
for (var i = 0; data[i] != ''; ++i)
{
if (status[i] == '')
{
sheet.getRange(i+startRow, 8).setValue(NEW_ISSUE);
}
}
}
I'm working on a script that would copy a row from a big database and that way makes it easier to modify.
The main point would be to allow more editor to modify the database parallel. However, if I share the spreadsheet, other users get the following error: Script ... experienced an error. The user encounters this problem by scripts assigned to a button only. onEdit() runs just fine.
It's my first google script file, so I have really no idea that what's the problem and how should I solve it.
The whole code is here:
//copy the chosen row to the appropriate cells of the editor sheet
//if zero sets the cells to default
function copySelectedRow(){
var ss=SpreadsheetApp.getActiveSpreadsheet();
var shData=ss.getSheets()[0];
var shEdit=ss.getActiveSheet();
var idNumber = shEdit.getRange(1,2).getValue();
if(idNumber == 0) {
var arrayData = [["","","","","","","","","","","","","","","","","","","","","","","","",""]];
} else {
var rowNumber=findRow(idNumber);
if(rowNumber == -1) {
SpreadsheetApp.getUi().alert('Nincs ilyen betegszam!');
return;
}
var range1=shData.getRange(rowNumber,1,1,shData.getLastColumn());
var arrayData=range1.getValues();
}
var arrayDataT = new Array(new Array);
var arr = new Array(new Array);
var arrT = new Array(new Array);
arrayDataT = transpose(arrayData);
arrT = arrayDataT.slice(1,6);
arr = transpose(arrT);
shEdit.getRange(5,1,1,5).setValues(arr);
shEdit.getRange(2,4).setValue(arrayData[0][6]);
arrT = arrayDataT.slice(7,11);
shEdit.getRange(7,2,4).setValues(arrT);
arrT = arrayDataT.slice(7,11);
shEdit.getRange(7,2,4).setValues(arrT);
shEdit.getRange(7,3).setValue(arrayData[0][11]);
arrT = arrayDataT.slice(12,16);
shEdit.getRange(7,4,4).setValues(arrT);
arrT = arrayDataT.slice(16,20);
shEdit.getRange(12,2,4).setValues(arrT);
shEdit.getRange(12,3).setValue(arrayData[0][20]);
arrT = arrayDataT.slice(21,25);
shEdit.getRange(12,4,4).setValues(arrT);
}
//trasnspone a 2D array
function transpose(a)
{
return Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
}
//save the cells to the database, checks and writes out if the editor is sure or unsure
function saveData() {
var app = SpreadsheetApp;
var shData = app.getActiveSpreadsheet().getSheets()[0];
var shEdit = app.getActiveSpreadsheet().getActiveSheet();
var idNumber = shEdit.getRange(1,2).getValue();
var row = findRow(idNumber);
if(row == -1) {
SpreadsheetApp.getUi().alert('Nincs ilyen betegszam!');
return;
}
var arr = new Array;
var arrT = new Array(new Array());
var arrayData = new Array(new Array());
var tempArray = new Array(new Array());
arrT = shEdit.getRange(7,2,4).getValues();
arr = transpose(arrT);
arrayData.push(arr);
arrT = shEdit.getRange(7,3).getValue();
tempArray[0][0] = arrT;
arrayData.push(tempArray);
arrT = shEdit.getRange(7,4,4).getValues();
arr = transpose(arrT);
arrayData.push(arr);
arrT = shEdit.getRange(12,2,4).getValues();
arr = transpose(arrT);
arrayData.push(arr);
arrT = shEdit.getRange(12,3).getValue();
tempArray[0][0] = arrT;
arrayData.push(tempArray);
arrT = shEdit.getRange(12,4,4).getValues();
arr = transpose(arrT);
arrayData.push(arr);
tempArray = new Array(new Array);
var count = 0;
for(var i=1; i<arrayData.length; i++){
for(var j=0; j<(arrayData[i][0].length); j++){
tempArray[0][count]=arrayData[i][0][j];
count++;
}
}
shData.getRange(row,8,1,18).setValues(tempArray);
var sure = shEdit.getRange(20,6).getValue();
if(sure) {
shData.getRange(row, 7).setValue("KÉSZ");
shEdit.getRange(2,4).setValue("KÉSZ");
} else {
shData.getRange(row, 7).setValue("BIZONYTALAN");
shEdit.getRange(2,4).setValue("BIZONYTALAN");
}
}
//returns the row number of the id value in the database
function findRow(idNumber) {
var app = SpreadsheetApp;
var shData = app.getActiveSpreadsheet().getSheets()[0];
var matchArray = shData.getRange("A:A").getValues();
for(var count=0; count<matchArray.length; count++){
if(matchArray[count][0]==idNumber) return count+1;
}
return -1;
}
//runs if the id cell is modified
function onEdit(e) {
var range = e.range;
var columnOfCellEdited = range.getColumn();
var rowOfCellEdited = range.getRow();
if (columnOfCellEdited === 2 && rowOfCellEdited === 1) {
copySelectedRow();
collision();
}
};
//increment the value of id by one
function incrementByOne() {
var app = SpreadsheetApp;
var targetSheet = app.getActiveSpreadsheet().getActiveSheet();
var tempNumber = targetSheet.getRange(1,2).getValue();
targetSheet.getRange(1, 2).setValue(tempNumber+1);
copySelectedRow();
collision();
}
//decrement the value of id by one
function decrementByOne() {
var app = SpreadsheetApp;
var targetSheet = app.getActiveSpreadsheet().getActiveSheet();
var tempNumber = targetSheet.getRange(1,2).getValue();
targetSheet.getRange(1, 2).setValue(tempNumber-1);
copySelectedRow();
collision();
}
//writes out if more editors are editing the same line
function collision(){
var ss=SpreadsheetApp.getActiveSpreadsheet();
var allSheets=ss.getSheets();
var idArray = new Array();
var temp;
for(var i=1; i<allSheets.length; i++){
temp = allSheets[i].getRange(1,2).getValue();
idArray.push(temp);
}
var collisionArray = new Array();
for(var i=0; i<idArray.length; i++){
for(var j=i+1; j<idArray.length; j++){
if(idArray[i] == idArray[j]){
collisionArray.push(i);
collisionArray.push(j);
}
}
}
for(var i=1; i<allSheets.length; i++){
allSheets[i].getRange(1,3).setValue("");
}
for(var i=0; i<collisionArray.length; i++){
allSheets[collisionArray[i]+1].getRange(1,3).setValue("SZERKESZTÉS ALATT");
}
}
So if I click the drawing that is associated with incrementByOne, it will give an error, but if I just change the cell, onEdit() can call the same functions easily.
(Sorry for the long code, I don't know which part could be important. If you tell me, I'll make it shorter.)
The solution:
If I share the code with a link, an anonymous editor can not use every script, because of authentication issues (don't ask why it isn't a problem by onEdit() ). Also, if the editor logs in into his/her gmail account and accepts everything, the script will become runable (but maybe a bit slower than on the owners account).
I have worked with code that pulls table information off a site and then places into Google Sheets. While this had worked great for months, it has come to my attention that is has randomly stopped working.
I am getting the message "TypeError: Cannot read property "length" from undefined." From code:
for (var c=0; c<current_adds_array.length; c++) {
I have done extensive searching but cannot come to conclusion as to what is wrong.
Full code seen here:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Get Data')
.addItem('Add new dispatch items','addNewThings')
.addToUi();
}
function addNewThings() {
// get page
var html = UrlFetchApp.fetch("#").getContentText();
// bypass google's new XmlService because html isn't well-formed
var doc = Xml.parse(html, true);
var bodyHtml = doc.html.body.toXmlString();
// but still use XmlService so we can use getDescendants() and getChild(), etc.
// see: https://developers.google.com/apps-script/reference/xml-service/
doc = XmlService.parse(bodyHtml);
var html = doc.getRootElement();
// a way to dig around
// Logger.log(doc.getRootElement().getChild('form').getChildren('table'));
// find and dig into table using getElementById and getElementsByTagName (by class fails)
var tablecontents = getElementById(html, 'formId:tableExUpdateId');
// we could dig deeper by tag name (next two lines)
// var tbodycontents = getElementsByTagName(tablecontents, 'tbody');
// var trcontents = getElementsByTagName(tbodycontents, 'tr');
// or just get it directly, since we know it's immediate children
var trcontents = tablecontents.getChild('tbody').getChildren('tr');
// create a nice little array to pass
var current_adds_array = Array();
// now let's iterate through them
for (var i=0; i<trcontents.length; i++) {
//Logger.log(trcontents[i].getDescendants());
// and grab all the spans
var trcontentsspan = getElementsByTagName(trcontents[i], 'span');
// if there's as many as expected, let's get values
if (trcontentsspan.length > 5) {
var call_num = trcontentsspan[0].getValue();
var call_time = trcontentsspan[1].getValue();
var rptd_location = trcontentsspan[2].getValue();
var rptd_district = trcontentsspan[3].getValue();
var call_nature = trcontentsspan[4].getValue();
var call_status = trcontentsspan[5].getValue();
//saveRow(call_num, call_time, rptd_location, rptd_district, call_nature, call_status);
current_adds_array.push(Array(call_num, call_time, rptd_location, rptd_district, call_nature, call_status));
}
}
saveRow(current_adds_array);
}
//doGet();
function saveRow(current_adds_array) {
// load in sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// find the current last row to make data range
var current_last_row = sheet.getLastRow();
var current_last_row_begin = current_last_row - 50;
if (current_last_row_begin < 1) current_last_row_begin = 1;
if (current_last_row < 1) current_last_row = 1;
//Logger.log("A"+current_last_row_begin+":F"+current_last_row);
var last_x_rows = sheet.getRange("A"+current_last_row_begin+":F"+current_last_row).getValues();
var call_num, call_time, rptd_location, rptd_district, call_nature, call_status;
// iterate through the current adds array
for (var c=0; c<current_adds_array.length; c++) {
call_num = current_adds_array[c][0];
call_time = current_adds_array[c][1];
rptd_location = current_adds_array[c][2];
rptd_district = current_adds_array[c][3];
call_nature = current_adds_array[c][4];
call_status = current_adds_array[c][5];
// find out if the ID is already there
var is_in_spreadsheet = false;
for (var i=0; i<last_x_rows.length; i++) {
//Logger.log(call_num+" == "+last_15_rows[i][0]);
if (call_num == last_x_rows[i][0] && call_time != last_x_rows[i][1]) is_in_spreadsheet = true;
}
Logger.log(is_in_spreadsheet);
//Logger.log(last_15_rows.length);
if (!is_in_spreadsheet) {
Logger.log("Adding "+call_num);
sheet.appendRow([call_num,call_time,rptd_location,rptd_district,call_nature,call_status]);
}
}
}
function getElementById(element, idToFind) {
var descendants = element.getDescendants();
for(i in descendants) {
var elt = descendants[i].asElement();
if( elt !=null) {
var id = elt.getAttribute('id');
if( id !=null && id.getValue()== idToFind) return elt;
}
}
}
function clearRange() {
//replace 'Sheet1' with your actual sheet name
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
sheet.getRange('A2:F').clearContent();}
function getElementsByTagName(element, tagName) {
var data = [];
var descendants = element.getDescendants();
for(i in descendants) {
var elt = descendants[i].asElement();
if( elt !=null && elt.getName()== tagName) data.push(elt);
}
return data;
}
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("C:C");
range.setValues(range.getValues().map(function(row) {
return [row[0].replace(/MKE$/, " Milwaukee, Wisconsin")];
}));
Please be careful when instantiating a new array. You are currently using var current_adds_array = Array(). You're not only missing the new keyword, but also, this constructor is intended to instantiate an Array with an Array-like object.
Try changing this to var current_adds_array = []
I want to concatenate columns that are dynamic, using appscript programmatically.
See the screenshot what my data looks like and what output i am trying to achieve:
I was able to achieve concatenation of static/fixed no. of columns using the below code.
function concatenate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = ss.getSheetByName("Sheet1");
var lr = sheetName.getLastRow();
var lc = sheetName.getLastColumn();
var rangeValue = sheetName.getRange(2, 1, lr-1, lc).getValues();
for(var i=0;i<rangeValue.length; i++) {
var setRange = sheetName.getRange(i+2, lc);
setRange.setValue(rangeValue[i][0] + " " + rangeValue[i][1] + " " + rangeValue[i][2])
};
};
All i want to achieve now is, the same above for DYNAMIC columns. I tried my best to figure it out, but in vain. Any help would be much greatly appreciated.
Splicing in another column
This assumes that you start with only your data columns and that you have not added the header for the new column. It can be made to work both ways but you just need to know what your starting with.
function myFunction() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet 1');
var rg=sh.getDataRange();
var vA=rg.getValues();
for(var i=0;i<vA.length;i++){
if(i==0){
vA[i].splice(vA[i].length,0,'Concatenate');
}else{
vA[i].splice(vA[i].length,0,vA[i].join(' '));
}
}
sh.getRange(1,1,vA.length,vA[0].length).setValues(vA);
}
I believe you can solve this by just looping through the columns using the last column index lc variable you already have. Should look something like this:
function concatenate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = ss.getSheetByName("Sheet1");
var lr = sheetName.getLastRow();
var lc = sheetName.getLastColumn();
var rangeValue = sheetName.getRange(2, 1, lr-1, lc).getValues();
for(var i = 0; i < rangeValue.length; i++) {
var catValues = "";
for (var j = 0; j < lc; j++) {
catValues += rangeValue[i][j] + " ";
}
var setRange = sheetName.getRange(i+2, lc);
setRange.setValue(catValues);
};
};
Or if you wanted to get fancy with .join():
function concatenate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = ss.getSheetByName("Sheet1");
var lr = sheetName.getLastRow();
var lc = sheetName.getLastColumn();
var rangeValue = sheetName.getRange(2, 1, lr-1, lc).getValues();
for(var i = 0; i < rangeValue.length; i++) {
var catValues = sheetName.getRange(i, lc).getValues().join(" ");
var setRange = sheetName.getRange(i+2, lc);
setRange.setValue(catValues);
};
};