Google AppScript GetRange Shorten Script - google-apps-script

I was wondering if there was any way I could shorten the script below? As you can see, I copied the eight lines (B13-I13) to make a new one with a different row (B4-I14). However, I must continue it until row 23.
var values = [[formS.getRange("C7").getValue(),
formS.getRange("C8").getValue(),
formS.getRange("D9").getValue(),
formS.getRange("B13").getValue(), <--- shorten this
formS.getRange("C13").getValue(),
formS.getRange("D13").getValue(),
formS.getRange("E13").getValue(),
formS.getRange("F13").getValue(),
formS.getRange("G13").getValue(),
formS.getRange("H13").getValue(),
formS.getRange("I13").getValue(), ----> to this
formS.getRange("B14").getValue(), <--- shorten this
formS.getRange("C14").getValue(),
formS.getRange("D14").getValue(),
formS.getRange("E14").getValue(),
formS.getRange("F14").getValue(),
formS.getRange("G14").getValue(),
formS.getRange("H14").getValue(),
formS.getRange("I14").getValue(), ----> to this
]];
This is the script that I'm using..
function SaveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("Form");
var dataS = ss.getSheetByName("Data");
--> LOCATION OF THE SCRIPT ABOVE <---
dataS.getRange(dataS.getLastRow()+1,1,1,11).setValues(values);
ClearCell();
}
Please see the sample picture below where I encode the data.
This is the sample image of the sheet where the data were being saved.
SAMPLE SPREADSHEET

In your situation, how about the following modification?
Modified script:
function sample() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("Form");
var dataS = ss.getSheetByName("Data");
var values = [
...formS.getRange("C7:C8").getValues().flat(),
formS.getRange("D9").getValue(),
...formS.getRange("B13:I23").getValues().flat()
];
dataS.appendRow(values);
}
From However, I must continue it until row 23., I used B13:I23.
In this modification, the values of "C7:C8" and "D9" and "B13:I23" of "Form" sheet are copied to the last row of "Data" sheet as one row.

Related

How do i copyPaste through AppScript into another file instead of a sheet

Right now I am using this formula to copy and paste to another Sheet. Though due to the file getting bigger and bigger, we want to place it in a seperate file which we dont really have to open.
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Kenmerken Script");
var pasteSheet = ss.getSheetByName("CopyPaste");
// get source range
var source = copySheet.getRange(3,3,300,6);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+2,1,500,4);
// copy values to destination range
source.copyTo(destination);
// clear source values
source.clearContent();
}
I tried to use getsheetbyURL instead. This did not work as it gave an error.
I also tried to find more information on https://developers.google.com/apps-script/reference/spreadsheet/sheet#copyTo(Spreadsheet). Though I cannot find an clear answer here.
I tried to add another "var" but "var sss = SpreadsheetApp.getActiveSpreadsheet. And then put pastesheet = sss.getsheetbyURL". This didnt work either.
I understand the things in the code which I have now. I only need to find the correct string.
I believe your goal is as follows.
You want to copy C3:H302 of a source sheet of Spreadsheet "A" to the last row of a destination sheet of Spreadsheet "B".
You want to use Spreadsheet URL for retrieving the Spreadsheet.
In this case, when your showing script is modified, how about the following modification?
Modified script:
function copyInfo() {
var destinationSpreadsheetUrl = "###"; // Please set your Spreadsheet URL.
var destinationSheetName = "###"; // Please set the destination sheet name.
// Source sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Kenmerken Script");
// Destination sheet.
var dstSS = SpreadsheetApp.openByUrl(destinationSpreadsheetUrl);
var dstSheet = dstSS.getSheetByName(destinationSheetName);
var temp = copySheet.copyTo(dstSS);
temp.getRange(3, 3, 300, 6).copyTo(dstSheet.getRange(dstSheet.getLastRow() + 2, 1));
// clear source values
copySheet.getRange(3, 3, 300, 6).clearContent();
// Remove temp sheet.
dstSS.deleteSheet(temp);
}
When this script is run, the values of "C3:H302" are copied from the source sheet of the active Spreadsheet to the destination sheet of another Spreadsheet. And, "C3:H302" of the source sheet is cleared.
If you want to use Spreadsheet ID, please use SpreadsheetApp.openById() instead of SpreadsheetApp.openByUrl().
If you want to copy only the values, I thought that getValues and setValues can be also used.
References:
openByUrl(url)
copyTo(spreadsheet)
Added:
From your following reply,
The formula itself works which is great. But it seems to take the formulas and not only the values. See picture: i.imgur.com/VRYCuTP.png . This causes an error since this file is not aware of any sheet named X. Would there be a way to only copy the values?
In this case, how about the following sample script?
Sample script:
function copyInfo() {
var destinationSpreadsheetUrl = "###"; // Please set your Spreadsheet URL.
var destinationSheetName = "###"; // Please set the destination sheet name.
// Source sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Kenmerken Script");
var temp1 = copySheet.copyTo(ss);
var r = temp1.getDataRange();
r.copyTo(r, { contentsOnly: true });
// Destination sheet.
var dstSS = SpreadsheetApp.openByUrl(destinationSpreadsheetUrl);
var dstSheet = dstSS.getSheetByName(destinationSheetName);
var temp2 = temp1.copyTo(dstSS);
temp2.getRange(3, 3, 300, 6).copyTo(dstSheet.getRange(dstSheet.getLastRow() + 2, 1));
// clear source values
copySheet.getRange(3, 3, 300, 6).clearContent();
// Remove temp sheets.
ss.deleteSheet(temp1);
dstSS.deleteSheet(temp2);
}

Apps script copy multiple range from 1 sheet to another spreadsheet

I am trying to copy data from 1 spreadsheet to another, I have successfully implemented something i found online that works with a specific range
function cloneGoogleSheet() {
// source doc
var sss = SpreadsheetApp.openById("spreadsheetkey1");
// source sheet
var ss = sss.getSheetByName('_tab_name_source');
// Get full range of data
var SRange = ss.getRange(7,3,5,1);
// get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
// get the data values in range
var SData = SRange.getValues();
// target spreadsheet
var tss = SpreadsheetApp.openById("spreadsheetkey2");
// target sheet
var ts = tss.getSheetByName('tab_name_destination');
// Clear the Google Sheet before copy
//ts.clear({contentsOnly: true});
// set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
};
The above piece coding work perfectly however I need to copy 18 different ranges that i cant just merge into 1 range. I considered the option of using the above however "multiplying" it 18 times for each range that however seems like a very inelegant solution.
I found a working solution that works if it stays within the same spreadsheet since it uses copyto instead of get/set values. The values part works perfectly since it doesnt mess with merge cells formatting. I have been struggling past 2-3 hours in merging the below-working code with elements from the first code to make a working script.
function test () {
try {
var spread = SpreadsheetApp.openById("spreadsheetkey");
var sheet = spread.getSheetByName("tab_name_source");
var rlist = sheet.getRangeList(["c7:c11", "g7:g11", "k7:k11"]);
sheet = spread.getSheetByName("tab_name_destination");
for( var i=0; i<rlist.getRanges().length; i++ ) {
var r1 = rlist.getRanges()[i];
var r2 = sheet.getRange(r1.getA1Notation());
r1.copyto(r2);
}
}
catch(err) {
Logger.log(err);
}
}
I tried initially to adapt the 2nd piece of coding to using setvalues however i had not been able to succesfully implement the part of getvalues within the scope of this code. I figured once I got this piece of code working with get and set values instead of Copyto i would only need to add the spreadsheetid of the other spreadsheet to get the final result
Try this:
function myFunction() {
var sourceSS = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = sourceSS.getSheetByName("sheetname");
var targetSS = SpreadsheetApp.openById("spreadsheet id here");
var targetSheet = targetSS.getSheetByName("Sheet1");
var ranges = ["C7:C11", "G7:G11", "K7:K11"];
ranges.forEach(range => {
var data = sourceSheet.getRange(range).getValues();
targetSheet.getRange(range).setValues(data);
})
}
Source sheet:
Destination sheet:
References:
setValues()
getValues()

How can I duplicate and rename a spreadsheet using a Script?

I have this script which I found here which mimicks the 'make a copy' function, but also renames the sheet all within a single action.
function onOpen() {
var menu = [{name: "Duplicate and name", functionName: "dupName"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("Custom", menu);
}
function dupName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var name = Browser.inputBox('Enter new sheet name');
ss.insertSheet(name, {template: sheet});
}
I want to take this script a step farther and use it to increase the number in the name of the previous sheet, by 1.
For example, A sheet will be called 'Sheet 1' and when I duplicate the sheet using this script, I want the new one to be called 'Sheet 2'.
Is this possible?
If so, how can I modify this script to do that?
Or is there a better way to write it in the first place?
(considering the post I'm referencing to is 4 years old).
The following script can duplicate the sheets and also rename the same with your custom name and add protection to either selected range or complete sheet as defined in the protection line:
function script() {
var spreadsheet = SpreadsheetApp.getActive();
var myValue = SpreadsheetApp.getActiveSheet().getSheetName();
spreadsheet.duplicateActiveSheet();
var totalSheets = countSheets(); //script function
myValue = "CUSTOMTEXT" + totalSheets; //sample CUSTOMTEXT1
SpreadsheetApp.getActiveSpreadsheet().renameActiveSheet(myValue);
var protection = spreadsheet.getActiveSheet().protect();
protection.setUnprotectedRanges([spreadsheet.getRange('C2:E5')])
.removeEditors(['user1#gmail.com', 'user2#gmail.com']);
protection.addEditor('user0#gmail.com');
SpreadsheetApp.flush();
};
function countSheets() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets().length;
}
If the same function is triggered using the doget(e) function you can be the owner of the sheet irrespective to the triggering user. Kindly follow the following for more details on it: Changing Owner of the Sheet irrespective of the duplicator
You can use this script:
function onOpen() {
var menu = [{name: "Duplicate and name", functionName: "dupName"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("Custom", menu);
}
function dupName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var array = sheet.getName().split(" ");
var ssnum = Number(array[array.length-1]);
array[array.length-1] = ++ssnum;
ss.insertSheet(array.join(' '), {template: sheet});
}
Note that you need to have a space delimiter between the text part and the number part of the sheet name in order to use this script.
Sample Spreadsheet:

Script to copy and paste values to the first empty row in Google spreadsheets with zero in front of other numbers

So the code copies the content of Sheet1 B2:G2, B2 cell contains a code that often starts with multiple 0. Everything is okay in Sheet1, but once the script is executed and it is copied to Sheet2, the format changes to "Automatic and "000001" becomes just "1". I can't seem to find a away to make it instantyl format as plain text to keep the 0 in front. Also, the G cell contains €, so I don't want to set entire row as plain text, just the B column.
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange("Sheet1!B2:G2");
var destSheet = ss.getSheetByName("Sheet2");
destSheet.appendRow(source.getValues()[0]);
}
How about this modification? I think that there are several solutions for your situation. So please think of this as just one of them. In this modification, 2 lines were added to your script.
Modification point:
After appendRow() was run, the format of "Sheet1!B2:G2" is copied to the appended row. By this, "000001" is displayed.
Modified script:
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange("Sheet1!B2:G2");
var destSheet = ss.getSheetByName("Sheet2");
destSheet.appendRow(source.getValues()[0]);
var destination = destSheet.getRange(destSheet.getLastRow(), 1); // Added
source.copyTo(destination, SpreadsheetApp.CopyPasteType.PASTE_FORMAT) // Added
}
References:
copyTo()
Enum CopyPasteType
If this was not the result you want, please tell me. I would like to modify it.
Thank you for this thread. I had a slightly different problem to solve but this gave me the inspiration to do it and thought I'd share. I wanted to update columns D:I with existing formulas from D7:I7 any time an edit was made to the spreadsheet. (In my case, that is most often just adding data to a new row A:C.) I only wanted it to fire if one particular Sheet was modified (not the other sheets).
This seems to do the trick nicely.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sName = ss.getSheetName();
Logger.log('Starting script...');
if (sName == 'Data'){
Logger.log('We are editing the sheet name: "' + sName +'"'
);
var source = ss.getRange("Data!D7:I7");
var destSheet = ss.getSheetByName("Data");
var lastRow = destSheet.getLastRow();
var destination = destSheet.getRange("D"+lastRow);
destination.activate();
source.copyTo(destination, SpreadsheetApp.CopyPasteType.PASTE_FORMULA)
} else
Logger.log('Nothing Done. Sheet name: "' + sName + '"' );
}

How could you retrieve a range of user highlighted cells in Google Sheets using Google Apps Script?

At the moment this is the function I'm using but I have no way of testing if it will work in the spreadsheet until I publish the application.
function readSelection() {
//The commented lines aren't needed if the sheet is open already
//var sheetid = "sheet id here";
//var spreadsheet = SpreadsheetApp.openById(sheetid);
//SpreadsheetApp.setActiveSpreadsheet(spreadsheet);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
//sheet.setActiveSelection("B2:B22");
var activerange = sheet.getActiveRange();
var activecells = activerange.getValues();
return activecells;
};
I assume you mean highlighted == selected
The result depends on whether the cells are contiguous or not (non contiguous cell selection is available in the new spreadsheets features http://googleblog.blogspot.co.nz/2013/12/new-google-sheets-faster-more-powerful.html
For contiguous cells selected your code returns the values of the selection as an array, for non-contiguous cells your code will return the an array with the single value of the LAST selected item.
I suggest that this is a bug in the implementation of the new spreadsheet. If it is important to you, I suggest you raise an issue. For the old spreadsheets, you can only select contiguous cells (eg B2:B22) so it will work as you expect.
The easiest way to answer this Q is to run the code you have written! You don't have to publish anything just run the code in the script editor of the spreadsheet you are examining
and look at the log.
function readSelection() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var activerange = sheet.getActiveRange();
var activecells = activerange.getValues();
Logger.log(activecells)
return
};
There is no way to do this at the moment or to obtain the selected ranges from a script.
A request is pending and you can support it here : https://code.google.com/p/google-apps-script-issues/issues/detail?id=4056
by adding a star to the request.
If/when this function is implemented your code would look as follows:
function readSelection() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var activeranges = sheet.getSelectedRanges();
var activecells = [] ;'
for (var ar in activeranges)
activecells = activecells.concat(activeranges[ar].getValues()) ;
Logger.log(activecells)
return ;
}
note that selected ranges may overlap, so some cell contents could be added twice.