get A1Notation of unprotected range on google sheet - javascript

Is there a way to get the range of a unprotected cells of a sheet in A1Notation?
I have this function but don't show me the A1Notation, and I don't know what more do:
function parametrosdeProceso() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var hoja = ss.getSheetByName("KMD108");
var protection = hoja.protect();
var unprotected= protection.getUnprotectedRanges();
Logger.log(unprotected);
}

Try, for one sheet
function listOfUnprotectedRanges() {
var p = SpreadsheetApp.getActiveSheet().getProtections(SpreadsheetApp.ProtectionType.SHEET)[0];
var ranges = p.getUnprotectedRanges().map(r => r.getA1Notation())
console.log(ranges)
}
for the whole spreadsheet
function listOfUnprotectedRanges() {
var p = SpreadsheetApp.getActiveSpreadsheet().getProtections(SpreadsheetApp.ProtectionType.SHEET);
p.forEach(x => {
var ranges = x.getUnprotectedRanges().map(r => r.getA1Notation())
console.log(ranges)
})
}

Related

Apps Script: how to copy hyperlink from a cell to another sheet

I need to copy this data from one sheet to another but with all the links active, because with this formula, copy just like a text.
I really don't know what do and what do I have to change to copy every data from the original sheet.
function SubmitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var dataS = ss.getSheetByName("ToCompleteProyect");
var values = [
[formS.getRange("D1").getValue(), formS.getRange("D2").getValue(), formS.getRange("D3").getValue(), formS.getRange("D4").getValue(), formS.getRange("D5").getValue(), formS.getRange("D6").getValue(), formS.getRange("D7").getValue(), formS.getRange("D8").getValue(), formS.getRange("D9").getValue(), formS.getRange("D10").getValue(), formS.getRange("D11").getValue(), formS.getRange("D12").getValue(), formS.getRange("D13").getValue(), formS.getRange("D14").getValue(), formS.getRange("D15").getValue(), formS.getRange("D16").getValue(), formS.getRange("D17").getValue(), formS.getRange("D18").getValue(), formS.getRange("D19").getValue(), formS.getRange("D20").getValue(), formS.getRange("D21").getValue(), formS.getRange("D22").getValue(), formS.getRange("D23").getValue(), formS.getRange("D24").getValue(), formS.getRange("D25").getValue(), formS.getRange("D26").getValue(), formS.getRange("D27").getValue(), formS.getRange("D28").getValue(), formS.getRange("D29").getValue(), formS.getRange("D30").getValue(), formS.getRange("D31").getValue(), formS.getRange("D32").getValue(), formS.getRange("D33").getValue(), formS.getRange("D34").getValue(), formS.getRange("D35").getValue(), formS.getRange("D36").getValue(), formS.getRange("D37").getValue(), formS.getRange("D38").getValue(), formS.getRange("D39").getValue(), formS.getRange("D40").getValue(), formS.getRange("D41").getValue(), formS.getRange("D42").getValue(), formS.getRange("D43").getValue(), formS.getRange("D44").getValue(), formS.getRange("D45").getValue(), formS.getRange("D46").getValue(), formS.getRange("D47").getValue(), formS.getRange("D48").getValue(), formS.getRange("D49").getValue(), formS.getRange("D50").getValue(), formS.getRange("D51").getValue(), formS.getRange("D52").getValue()]
];
dataS.getRange(dataS.getLastRow() + 1, 1, 1, 52).setValues(values);
ClearCell();
RE-EDIT:
Complete project with Submit, Search and Update buttons!
function ClearCell() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var RangeToClear = [ "D1:D52"];
for (var i=0; i<RangeToClear.length; i++) {
formS.getRange(RangeToClear[i]).clearContent();
}
}
//-------------------------------------------------------------------------------
function SubmitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var dataS = ss.getSheetByName("ToCompleteProyect");
var lastRow = dataS.getLastRow() + 1
formS.getRange("D1:D52").copyTo(dataS.getRange(lastRow, 1, 1, 52), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true)
dataS.getRange(lastRow,1).clearDataValidations()
ClearCell();
}
//----------------------------------------------------------------------------
function Search() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var str = formS.getRange("D1").getValue();
var dataS = ss.getSheetByName("ToCompleteProyect")
var values= dataS.getDataRange();
Logger.log(values.getLastRow())
for (var i = 0; i < values.getLastRow(); i++) {
var row = dataS.getRange(i+1,1).getValue();
if (row == str) {
dataS.getRange(i+1,2,1,51).copyTo(formS.getRange("D2:D52"),SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true)
}
}
}
//------------------------------------------------------------------------------
function Update(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var str = formS.getRange("D1").getValue();
var dataS = ss.getSheetByName("ToCompleteProyect")
var values= dataS.getDataRange();
Logger.log(values.getLastRow())
for (var i = 0; i < values.getLastRow(); i++) {
var row = dataS.getRange(i+1,1).getValue();
if (row == str) {
formS.getRange("D2:D52").copyTo(dataS.getRange(i+1, 2, 1, 51), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true)
ClearCell();
}
}
}
EDIT:
One simple way to do it is just to copy-paste but not only the values but the cells transposed as one would do with the Copy and Paste Special. It's indeed a much simpler code and it seems to me that does the trick, you just need this line:
formS.getRange("D1:D52").copyTo(dataS.getRange(lastRow, 1, 1, 52), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true) ---> this last TRUE value is the one which transposes the data
And the full function:
function SubmitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var dataS = ss.getSheetByName("ToCompleteProyect");
var lastRow = dataS.getLastRow() + 1
formS.getRange("D1:D52").copyTo(dataS.getRange(lastRow, 1, 1, 52), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true)
ClearCell();
}
Was it useful??
OLD: If the links is always in the same column/s of the last row, you can then pass them through this second function. I took myself the liberty also of suggesting a way of simplifying grabbing the values of the form ;)
function SubmitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("ProyectStatus");
var dataS = ss.getSheetByName("ToCompleteProyect");
var values = formS.getRange("D1:D52").getValues() //Here I took the entire range
values = [values.map(function(n){return n[0]})] // and turn that column into a row
var lastRow = dataS.getLastRow() + 1
dataS.getRange(lastRow, 1, 1, 52).setValues(values);
linkCellContents(dataS.getRange(lastRow, 10, 1, 1)) // assuming you need to make a link the value in column number 10 (J)... repeat this line with each column you need to convert
ClearCell();
}
function linkCellContents(range) {
var value = range.getValue()
var richValue = SpreadsheetApp.newRichTextValue()
.setText(value)
.setLinkUrl(value)
.build();
range.setRichTextValue(richValue);
}

Script to copy values only from multiple tabs to another spreadsheet

I have found so many scripts to copy values only from one spreadhseet to another. However, all of them is to copy the whole spreasheet.
I am very new with google script and cannot find a way to copy values only from specific tabs to another spreasheet adding these new tabs to it.
function temp() {
var sss = SpreadsheetApp.openById('XYZ'); // sss = source spreadsheet
//var ss = sss.getSheets()[4]; // ss = source sheet
var ss = sss.getSheets(); // ss = source sheet
var id=4; //default number
for(var i in ss)
{
var sheet = ss[i];
if(sheet.getName()== "ABC")
{ id=i;
break;
}
}
console.log(id);
ss=sss.getSheets()[id];
//Get full range of data
var SRange = ss.getDataRange();
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
SpreadsheetApp.flush();
var tss = SpreadsheetApp.getActiveSpreadsheet(); // tss = target spreadsheet
var ts = tss.getSheetByName('ABC'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
}
Thanks a lot in advance.
Issue:
You can to copy the values from a specific set of sheets to a new spreadsheet.
I assume that you don't want to copy the sheet itself, but only the values from the source sheet.
Modifications:
Use filter to get an array of your desired sheets (based on sheet name).
If the target spreadsheet doesn't have a sheet with that name, create it with Spreadsheet.insertSheet.
Code sample:
function temp() {
var sheetNames = ["ABC", "DEF"]; // Change accordingly
var sss = SpreadsheetApp.openById('XYZ');
var sheetsToCopy = sss.getSheets().filter(s => sheetNames.includes(s.getSheetName()));
sheetsToCopy.forEach(ss => {
var sourceSheetName = ss.getSheetName();
var SRange = ss.getDataRange();
var A1Range = SRange.getA1Notation();
var SData = SRange.getValues();
var tss = SpreadsheetApp.getActiveSpreadsheet();
var ts = tss.getSheetByName(sourceSheetName);
if (!ts) ts = tss.insertSheet(sourceSheetName);
ts.getRange(A1Range).setValues(SData);
});
}
Copy these sheets to another spreadsheet
function copythese() {
const ss = SpreadsheetApp.getActive();
const these = ['Sheet0','Sheet1'];//Put your sheetnames here
const another = SpreadsheetApp.openById("another id");//put the other spreadsheet id here
ss.getSheets().filter(sh => ~these.indexOf(sh.getName())).forEach(sh => {
sh.copyTo(another);
});
}
Append These Values to another spreadsheet
function appendthesevalues() {
const ss = SpreadsheetApp.getActive();
const these = ['Sheet0','Sheet1'];
const another = SpreadsheetApp.openById("another id");
ss.getSheets().filter(sh => ~these.indexOf(sh.getName())).forEach(sh => {
let vs = sh.getDataRange().getValues();
let nsh = another.getSheetByName(sh.getName());
if(!nsh) {
nsh = another.insertSheet(sh.getName());
SpreadsheetApp.flush();
}
if(nsh) {
nsh.getRange(nsh.getLastRow() + 1, 1 ,vs.length, vs[0].length).setValues(vs);
}
});
}

I need to copy variable range of data into a new empty row of another sheet. How do I need to change those scripts?

function saveData(){
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var formSheet = spreadsheet.getSheetByName("Receipt");
var dataSheet = spreadsheet.getSheetByName("Historical Sales")
var fieldRange = \["B12:X"\]
var fieldValue = fieldRange.map(f =\>
formSheet.getRange(f).getValue())
//console.log(fieldValue)
dataSheet.appendRow(fieldValue)
};
function exp5() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('W12').activate();
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.PREVIOUS).activate();
currentCell.activateAsCurrentCell();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Historical Receipts'), true);
spreadsheet.getRange('X963').activate();
spreadsheet.getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).activate();
spreadsheet.getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.UP).activate();
spreadsheet.getRange('A14:V23').activate();
spreadsheet.getRange('Receipt!B12:W21').copyTo(spreadsheet.getActiveRange(),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
This is how I'd do it:
//Not tested, but it can give you a direction
function moveData () {
var formSheet = spreadsheet.getSheetByName("Receipt");
var formRng = formSheet.getRange(); //Specify the data range here
var formData = formRng.getValues();
var dataSheet = spreadsheet.getSheetByName("Historical Sales");
//It gets the first empty row in column A and "pastes" the data set (form Data) .
datasheet.getRange(datasheet.getLastRow()+1,1,formData.length,formData[0].length).setValues(formData);
}

Trigger onEdit(e) does not trigger

When I've tried just to setValue("random") to some cell with this trigger it does work, but when I've tried to execute this code(for returning certain sheet names from selected spreadsheet) it doesn't work! When I run that chunk of code as separate function it does work and return sheets normally.
So, why it doesn't execute part of code from "//RETURNING JUST BUILDING LIST" part when I change value in D2 cell?
function onEdit(e) {
var range = e.range;
var rangeEdit = e.range.getA1Notation();
if(rangeEdit == "D2"){
//RETURNING JUST BUILDING LIST
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheetsByName("OVERVIEW").getRange('A2').setValue("OK")
var sRNG = ss.getSheetByName("KEYS").getRange('A1:A12').getValues();
for (var z=0; z<sRNG.length; z++)
if (sRNG[z][0] == ss.getSheetByName("OVERVIEW").getRange('G3').getValue()) {
var xyz = z + 1;
}
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = ss.getSheetByName("OVERVIEW").getRange(1, 8, 50, 1);
range.clear();
var shArray = [];
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var spreadSheetsInA =
SpreadsheetApp.openByUrl(ss.getSheetByName("KEYS").getRange('B' + xyz).getValue()).getSheets();
shArray = spreadSheetsInA.map(function(sheet) {
return [sheet.getName()];
});
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = ss.getSheetByName("OVERVIEW").getRange(1, 8, shArray.length, 1);
range.setValues(shArray);
var rDEL = 1
for (var xdel = 0; xdel<shArray.length; xdel++){
if(shArray[xdel][0].indexOf("Overview")>-1 | shArray[xdel][0].indexOf("Cashflow")>-1 | shArray[xdel][0].indexOf("Dates")>-1){
var delSHT = ss.getSheetByName("OVERVIEW");
delSHT.getRange('H' + rDEL).clear();
}
rDEL++
}
}
}
Even when I've tried this, it doesn't work...
function onEdit(e) {
var range = e.range;
var rangeEdit = e.range.getA1Notation();
if(rangeEdit == "D2"){
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheetsByName("OVERVIEW").getRange("A2").setValue("ok")
}
}
Basically, I just need to execute code if value in D2 in sheet Overview is changed!

Google Sheets Script for passing a few cell values on one sheet to new sheet row

I have looked and looked and tried to adapt some scripts but am stuck.
Can someone help/show me how to add a collection of specific cells on one sheet and populate the next available row on a second sheet with these values? Please. This is what I have:
function AddToDB2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("PurchaseOrder");
var targetSheet = target.getSheetByName("DataBase");
var range = ss.getDataRange();
var values = range.getValues();
var date1 = values[1][6]; //these values are collected from multiple cells not in a specific row or col
var po = values[2][6];
var vendor = values[7][0];
var shipto = values[7][3];
//this was for testing that the values were grabbed correctly.
var data = [date1,po,vendor,shipto];
// I don't think this part is even close
var lastRow = targetSheet.getLastRow()
var rowData = values[0]
var newData = []
for(n=1;n<lastRow;++n){newData.push(rowData)}
targetSheet.getRange("C2:H"+lastRow).setValues(newData);
}
This is the other way I came up with:
function addToDB() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("PurchaseOrder");
var targetSheet = target.getSheetByName("DataBase");
var sourceRangePO = sourceSheet.getRange("G3");
var poValues = sourceRangePO.getValues();
if(poValues != "") {
var sourceRangeDate = sourceSheet.getRange("G2");
var targetRangeDate = targetSheet.getRange("A2");
var dateValues = sourceRangeDate.getValues();
targetRangeDate.setValues(dateValues);
var sourceRangePO = sourceSheet.getRange("G3");
var targetRangePO = targetSheet.getRange("B2");
var poValues = sourceRangePO.getValues();
targetRangePO.setValues(poValues);
var sourceRangeVendor = sourceSheet.getRange("A8");
var targetRangeVendor = targetSheet.getRange("C2");
var vendorValues = sourceRangeVendor.getValues();
targetRangeVendor.setValues(vendorValues);
var sourceRangeShipTo = sourceSheet.getRange("D8");
var targetRangeShipTo = targetSheet.getRange("D2");
var shipToValues = sourceRangeShipTo.getValues();
targetRangeShipTo.setValues(shipToValues);
targetSheet.insertRowAfter(1);
Browser.msgBox("Your PO has beed saved!");
}
else { Browser.msgBox("Please enter a PO number"); }
}
You were very close. Try this. I was a little confused by your setValues C:H. You only have 4 values to set. I set them in D-G. You can adjust as needed.
function AddToDB2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("PurchaseOrder");
var targetSheet = ss.getSheetByName("DataBase");
var range = sourceSheet.getDataRange();
var values = range.getValues();
var date1 = values[1][6]; //these values are collected from multiple cells not in a specific row or col
var po = values[2][6];
var vendor = values[7][0];
var shipto = values[7][3];
var data = [date1,po,vendor,shipto];
var lastRow = targetSheet.getLastRow()
var newData = []
for(n=0;n<data.length;++n){newData.push([data[n]])}
var rng =targetSheet.getRange(lastRow+1,1,1,4) // Col A-D
rng.setValues([newData]);
}

Categories