SpreadsheetApp.openById error using appscript - javascript

I'm importing data from one sheet to another sheet using Google Appscript. However when I run the code there's an error occuring.
function importdata() {
var mainfile = SpreadsheetApp.getActive().getSheetByName('Data1');
var secondfile = SpreadsheetApp.openById('1232131231231abcc').getSheetByName('RAW');
var datas = secondfile.getRange('C:C').getValues();
var paste = mainfile.getRange('A:A').setValues(datas);
}
Message details
Exception: The number of rows in the data does not match the number of rows in the range. The data has 27441 but the range has 27509. (line 6, file "Code")

setValues expects your range to have the same length as the length of data you are trying to set (must match dimensions of your range).
try something like
var datas = mainfile.getRange('A:A').getValues()
var range = secondfile.getRange(1,1,datas.length);
range.setValues(datas);
Update: I actually think you might have "hidden" rows in your dataset, this might cause range to be confused with length.

Related

getLastRow() stops at row 68

I have this function that is supposed to pull form data from one sheet then add it to another but it stops at row 68.
function fData(){
const os = SpreadsheetApp.openById("ID of Sheet with data to copy");
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Data");
const dataToCopy = os.getSheetByName("Form Data").getRange(1,1,os.getLastRow(),7).getValues();
const dataDst = ss.getRange(1,1,os.getLastRow(),7).clearContent().setValues(dataToCopy);
// Logger.log(dataToCopy);
}
When I change os.getLastRow() to 192 in both locations where it appears in the function, all the information is copied over correctly. I would like to not have to specify the number of rows every time I run the function.
I think there is something wrong with my implementation of getLastRow() or the fact that both the copy and paste sheets share the same name but I am unsure if that is what causes the issue.
Here is the solution that got the desired result. There might be a better way but this worked.
function fData(){
const os = SpreadsheetApp.openById("ID of Sheet with data to copy");
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Data");
const dataToCopy = os.getSheetByName("Form Data").getDataRange().getValues();
const lr = os.getSheetByName("Form Data").getDataRange().getLastRow();
const dataDst = ss.getRange(1,1,lr,7).clearContent().setValues(dataToCopy);
// Logger.log(dataToCopy);
}
I used getDataRange to pull the data, then defined lr as the last row of that data set. If you just replace the first instance of getLastRow with getDataRange you run into an error in which the target range and data set do not match in rows and columns and the function with push an error.
getLastRow(): this will get the last row in a Google Sheet that has data in it. It determines the last row based on the last available row value in all columns in the spreadsheet.
getDataRange(): this will get the range up to the last row and column with values in it.
Use getDataRange() instead. One of your columns must not have data in row 68.
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getdatarange

Copy filtered range from one spreadsheet to another - Google app script

I have a large google sheet with 30275 rows and 133 columns in a google sheet. I want to filter the data and copy column AZ to another spreadsheet.
Link to spreadsheet: https://docs.google.com/spreadsheets/d/1aiuHIYzlCM7zO_5oZ0aOCKDwPo06syXhWvhQMKgJE2I/edit?usp=sharing
I have been trying to follow this link
I am not that familiar with javascript and the code is designed to exclude items from filter rather than including items on filter. I have 500+ items to exclude so need to work out something that will be efficient in filtering large dataset in short time before execution limit is reached.
Here is my code so far. Any help to get this working would be appreciated.
NOTE: Filter/ Query with importrange formulas dont work due to the large volume of data. So I need an efficient script to filter large dataset and move them to another sheet before execution time limit.
function filtered() {
var ss = SpreadsheetApp.openById('1u9z_8J-tvTZaW4adO6kCk7bkWeB0pwPcZQdjBazpExI');
var sheet = ss.getSheetByName('Sheet1');
var destsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('JockeyList');
var demosheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Betting data - Demo');
var jockey = demosheet.getRange('L14').getValues();
// Get full (non-filtered) data
var values = sheet.getRange('A:EC').getValues();
// Apply filter criteria here
//Logger.log(jockey);
var hiddenValues = jockey;
values = values.filter(function(v) {
return hiddenValues.indexOf(v[51]) == 1;
});
Logger.log(values.length);
// Set filtered data on the target sheet
destsheet.getRange(10, 5, values.length, 2).setValues(values);
}
Ok so it seems like you want to copy only the values from AZ in 'Sheet1' that are equal to whatever string value is contained in cell L14 of sheet 'Betting data - Demo.' If that is the case, then here is a change to your original code that will accomplish that:
function filtered() {
var ss = SpreadsheetApp.openById('1u9z_8J-tvTZaW4adO6kCk7bkWeB0pwPcZQdjBazpExI');
var sheet = ss.getSheetByName('Sheet1');
// this assumes that your destsheet and demosheet are in the same spreadsheet. Keep in mind that opening spreadsheets with SpreadsheetApp is costly so you want to minimize your calls to new sheets.
var destsheet = ss.getSheetByName('JockeyList');
var demosheet = ss.getSheetByName('Betting data - Demo');
var jockey = demosheet.getRange('L14').getValue();
var searchTerm = new RegExp(jockey);
// Get full (non-filtered) data
var values = sheet.getRange('A:EC').getValues();
// Apply filter criteria here and return ONLY THE VALUE IN COLUMN AZ
var filteredValues = values.reduce(function(resultArray, row) {
if (searchTerm.test(row[51])) resultArray.push([row[51]]);
return resultArray;
}, [])
// Set filtered data on the target sheet
// Note* not clear why you are starting at row 10, but as is this will overwrite all of the data in column 5 of destsheet starting from row 10 every time this function runs
destsheet.getRange(10, 5, filteredValues.length, 1).setValues(filteredValues);
}
As it says in the code sample, this will only copy and paste the value in column AZ of 'sheet1'. It does not alter 'sheet1' in any way. If that is really all you want to do, then this function works, but it's overkill. Since you are just filtering values in AZ against a single string value, it would be more efficient to simply count the number of times that string occurs in column AZ and then add the string that number of times to your destination sheet.
Also note that your original function is pasting values into destsheet into a constant row (row 10). That means that every time your function runs, the data from row 10 on will be overwritten by whatever data you are copying from 'sheet1'

How can i combine rows range into json format?

I have a google sheet like this
The number of columns and rows may be different (not static). I want my google script to look for last row and column, then run a for loop and combine data of each row into this json format like this.
[["1","Lee","Blue","Active"],["2","Mike","Green","Disabled"],["3","Chan","Yellow","Active"]]
I learned about the JSON.stringify() function that helps and I am able to combine data or each row into json format BUT i want each row data separated by a comma (,), not sure how to add that in the logic since I DO NOT want comma to be added after LAST row.
I have tried creating this code and need help with the logic to dynamically run the loop based on number of columns and rows instead of hard-coding any range and add comma.
var mysheet = SpreadsheetApp.getActive().getSheetByName('mysheet');
function combine_val() {
GetRowsCount();
var startRow = 2; // First row of data to process
var numRows = LastAudienceRow; // Number of rows to process
for (var i = 0; i < numRows; ++i) {
var dataRange = mysheet.getRange(startRow, 1, 1, 4);
var data = dataRange.getValues();
startRow = startRow+1;
var data2= JSON.stringify(data);
}
SpreadsheetApp.getUi().alert(data2);
}
function GetRowsCount() {
LastAudienceRow = mysheet.getLastRow() - 1;
return LastAudienceRow;
}
You've rather over complicated the whole situation, as much of this is done automatically. This script is also not very efficient and when you add more runs, will take too long to execute, eventually hitting the App script limit for maximum execution time.
Here you are trying to get the data from each row individually, and add it to an array. This is very inefficient, and it's much better/faster to just specify the range of data you want. Happily, this also formats it's pretty much as you like.
Here's a sample script:
var mysheet = SpreadsheetApp.getActive().getSheetByName('mysheet');
function combine_val() {
var startRow = 1; // First row of data to process.
var startColumn = 1; //First Column to process, in case that changes.
var numRows = mysheet.getLastRow(); // Number of rows to process
var numCols = mysheet.getLastColumn(); //Also the number of columns to process, again in case that changes.
var dataRange = mysheet.getRange(startRow, startColumn, numRows, numCols);//Get the full range of data in the sheet dynamically.
var data = JSON.stringify(dataRange.getValues());//Get the value of the range, AND convert it to a JSON string in one line.
Logger.log(data); //Use the in built logger to read the values that are returned. You can read this by pressing 'ctrl+enter'.
}
I've also added in some sample dynamic improvements which will mean you are hard coding less of your values into your scripts, preventing it from breaking if the data changes.
Additionally, I have added in a sample of how to read the data via the inbuilt logging tool, rather then via a cumbersome pop up after every run.
JSON.stringify already returns row data separated by commas.
var arr = [["1","Lee","Blue","Active"],["2","Mike","Green","Disabled"],["3","Chan","Yellow","Active"]];
console.info(JSON.stringify(arr))
The above example prints the following string to the console
[["1","Lee","Blue","Active"],["2","Mike","Green","Disabled"],["3","Chan","Yellow","Active"]]
The following example prints each row values separated by comma.
var arr = [["1","Lee","Blue","Active"],["2","Mike","Green","Disabled"],["3","Chan","Yellow","Active"]];
for(var i = 0; i < arr.length; i++){
console.info(JSON.stringify(arr[i]).replace(/[\[\]]/g,''));
}
To use it on as a Google Sheets / Apps Script instead of assigning a literal to arr use getValues() . You could replace console.info by SpreadsheetApp.getUi.alert(message) too.

Google Sheet Script Editor - setValues for array

I`m trying to replace old values with new values using setValues in Google sheet script.
The data is in the below link...
https://docs.google.com/spreadsheets/d/1pSUVkxM9FhSNgizedHbY2MnYGTnC2iiYLfrWsoPmDks/edit?usp=sharing
I`m basically trying to remove first 14 characters and the last 12 characters under "Tracker" column
Below is the code I tried..
function URLReplacement() {
var ss = SpreadsheetApp.getActive().getSheetByName("transformer");
var rng = ss.getRange("G:G");
var data = rng.getValues();
for (var items in data)
{
var newer = data[items][0].substring(14)
// Turn these strings into an array
var newerr = newer.split(" ")
// Turn this into 2 dimensional array to use setValues
ss.getRange("G:G").setValues([newerr])
Logger.log([newer]);
}
}
But now, I get errors with the setValues statement
Saying the range I set there do not match the data
What am I doing wrong here..?
Can anyone please provide me with suggestions / advice?
You want to convert from IMAGE_SUFFIX_"http://google.com"<xxxnouse>" to http://google.com at the column "G".
The format of IMAGE_SUFFIX_"http://google.com"<xxxnouse>" is constant.
If my understanding is correct, how about this modification? The reason of your error is that [newer] is not 2 dimensional array for using setValues(). If this error was removed, the header is removed by overwriting the empty value. So I would like to modify as follows.
Modification points:
When getLastRow() is used, the data size retrieved by it can be reduced from that retrieved by "G:G". By this, the process cost can be reduced.
Header is not retrieved by getRange(2, 7, ss.getLastRow(), 1).
From the format of IMAGE_SUFFIX_"http://google.com"<xxxnouse>", split() was used for parsing this value.
The converted data was put by setValues(). By this, the process cost can be also reduced.
Modified script:
function URLReplacement() {
var ss = SpreadsheetApp.getActive().getSheetByName("transformer");
var rng = ss.getRange(2, 7, ss.getLastRow(), 1); // Modified
var data = rng.getValues();
var convertedData = data.map(function(e) {return e[0] ? [e[0].split('"')[1]] : e}); // Added
rng.setValues(convertedData); // Added
}
Note:
In your shared sample Spreadsheet, the sheet name is "Sheet1". But your script uses "transformer" as the sheet name. Please be careful this.
If the format of actual values in your Spreadsheet is different from your shared Spreadsheet, this might not be able to be used.
References:
split()
setValues()
If this was not the result you want, I apologize.

Write single value on multiple rows in Google Apps Script

I'm new to Google Apps Script and I'm trying to make a script where I'll take a single string value and copy to multiple rows in a google sheet. I've taken an array to save the single value multiple times. But still I can't get it done. Every time I run the script, I get this error,
Cannot convert Array to Object[][]
Here are my codes,
function myFun() {
var ss = SpreadsheetApp.openById(SHEET_ID);
var sheet = ss.getSheetByName("Form Responses");
var new_vals = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
var master_ss = SpreadsheetApp.getActiveSpreadsheet();
var master_sheet = master_ss.getSheetByName("Sheet1");
var lr = master_sheet.getLastRow()+1;
var ss_real_name = "District";
var ss_real_names = [];
for (var i=0; i<new_vals.length; i++)
{
ss_real_names.push(ss_real_name);
}
master_sheet.getRange(lr, 1, new_vals.length).setValues(ss_real_names);
}
Is there something wrong in my code? How can I save the single string value in multiple rows?
Google Apps script writes values as arrays of arrays with every array inside of the outer array being a row and the elements in the inner arrays going into the columns.
If you want to write the data as rows you need to create an array filled with one element arrays. Try ss_real_names.push([ss_real_name]);.
If you wanted to write them as a column vector you could just say setValues([ss_real_names]) instead.

Categories

Resources