I would like to know how to clear the contents of all lines that are being hidden through this code, specifically in the two IFS.
I tried to include this excerpt:
ss.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});}
but it is only cleaning the contents of the selected cell itself
function remcausa() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var cell=sh.getActiveCell();
var row=cell.getRow();
if (row<47) {
sh.hideRows(row + 0, 4);ss.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});}
else { if(row>50) {sh.hideRows(row -1, 4)};
ss.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});}
}
the expected result would be to clear the contents of all the lines being hidden.
Thanks
How about this?
function remcausa() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var cell=sh.getActiveCell();
var row=cell.getRow();
if (row<47) {
sh.hideRows(row, 4);
sh.getRange(row,1,4,sh.getLastColumn()).clearContent();
}else if(row>50) {
sh.hideRows(row-1, 4);
sh.getRange(row-1,1,4,sh.getLastColumn()).clearContent();
}
}
Related
I've been using the script below to copy and paste all previous rows in an inserted row before on Google Sheets.
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('20:20').activate();
spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getActiveRange().getRow(), 1);
spreadsheet.getActiveRange().offset(0, 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
spreadsheet.getRange('21:21').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
spreadsheet.getRange('L20').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('H20').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
};
As I will have insertions below each other, whenever I use the top ones will change the line to be copied to the others. I would like to remove dependency on expression ('20:20'), and a think that NamedRange is the way.
Is it possible to copy the values of a whole row or named range in one sheet and paste them in the same sheet, just creating a line above?
Using the Porperties Service [1] you can fix your problem, I edited the code linked to your example Spreadsheet as follows:
function PlusMP() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('5:5').activate();
spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getActiveRange().getRow(), 1);
spreadsheet.getActiveRange().offset(0, 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
spreadsheet.getRange('6:6').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
spreadsheet.getRange('L5').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('H5').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
//Set offset property
var scriptProperties = PropertiesService.getScriptProperties();
var offset = Number(scriptProperties.getProperty('offset'));
if ( offset == null) {
scriptProperties.setProperty('offset', 1);
}
else {
scriptProperties.setProperty('offset', offset + 1);
}
};
function PlusCOMP() {
//Get offset property
var scriptProperties = PropertiesService.getScriptProperties();
var offset = Number(scriptProperties.getProperty('offset'));
if(offset == null) {
offset = 0;
}
var row = 10 + offset;
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange(row + ':' + row).activate();
spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getActiveRange().getRow(), 1);
spreadsheet.getActiveRange().offset(0, 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
spreadsheet.getRange(row + ':' + row).copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
spreadsheet.getRange('L' + row).activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('H' + row).activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
};
function resetOffset() {
PropertiesService.getScriptProperties().setProperty('offset', 0);
}
When the PlusMP function is run it'll set or update the offset property, and when PlusCOMP function is run it'll use the same offset property to insert the rows accordingly.
[1] https://developers.google.com/apps-script/reference/properties/properties
I have reviewed previously asked questions on this but still can't work out the code. I have a sheet with a significant number of rows of data in it. Rather than scroll down to the first empty row, I have created a button and on click of that button, I want the cursor to take me to column A of the first empty row. This is my script at this point but I keep getting errors:
Can someone please help me.
Try this:
function getLastRow() {
var sss = SpreadsheetApp.getActiveSheet();
sheet.getRange(sss.getLastRow()+1,1).activate();
}
If I understand your question correctly, you just want to go the first empty row in your sheet, not the first empty cell in column A. If that's the case, this small piece of code should do it:
function getLastRow() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
sheet.getRange(lastRow + 1, 1).activate();
}
I hope this is what you wanted to accomplish.
Please try this:
function TestFindBlank() {
//Jojo is rank that can be used for next
var Jojo=GetFirstBlank('Sheet1','F6');
};
function GetFirstBlank(mysheetName, myrangeStr)
{
var spreadsheet = SpreadsheetApp.getActive();
var Mysheet=spreadsheet.getSheetByName(mysheetName);
var Jojo=spreadsheet.getRange(myrangeStr).getNextDataCell(SpreadsheetApp.Direction.DOWN);
if (Jojo.offset(1,0).isBlank() ) {
return Jojo.offset(1,0);
}
var Jojo=spreadsheet.getRange(Jojo.getA1Notation()).getNextDataCell(SpreadsheetApp.Direction.DOWN);
return Jojo.offset(1,0);
}
Just run setupStartUpTrigger() one time to set it up. Then close and open again and give it a little time and you'll end up at the bottom.
function startUp() {//You can put your menu in here too
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Item Name', 'functionName')
.addToUi();
var sh=SpreadsheetApp.getActive().getSheetByName('Sheet1');
sh.getRange(sh.getLastRow()+1,1).activate();
}
//setup an installable onOpen() trigger
//this will fire on opening the spreadsheet
function setupStartUpTrigger(){
var ss=SpreadsheetApp.getActive();
if(!isTrigger('startUp')){
ScriptApp.newTrigger('startUp').forSpreadsheet(ss.getId()).onOpen().create();
}
}
//this is nice to use to keep you from creating unnecessary triggers
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}
Here next alternative to next blank or to next non blank cell:
function TestNextBlank_or_NotBlankUse() {
var spreadsheet = SpreadsheetApp.getActive();
var mysheet=spreadsheet.getSheetByName('Sheet1');
var myrange=mysheet.getRange('Q1');
var myrange=nextNonBlank(myrange); //First Non Blank
Logger.log(myrange.getA1Notation());
var myrange=nextNonBlank(myrange); //Second Non Blank
Logger.log(myrange.getA1Notation());
var myrange=nextNonBlank(myrange); //Third Non Blank
Logger.log(myrange.getA1Notation());
var myrange=mysheet.getRange('Q1');
var myrange=nextBlank(myrange); //First Blank
Logger.log(myrange.getA1Notation());
var myrange=nextBlank(myrange); //Second Blank
Logger.log(myrange.getA1Notation());
var myrange=nextBlank(myrange); //Third Blank
Logger.log(myrange.getA1Notation());
};
function nextBlank(theRange)
{
if (theRange.offset(1, 0).isBlank()) return theRange.offset(1, 0);
theRange=theRange.offset(1, 0);
if (theRange.offset(1, 0).isBlank()) return theRange.offset(1, 0);
theRange=theRange.getNextDataCell(SpreadsheetApp.Direction.DOWN).offset(1, 0);
return theRange;
}
function nextNonBlank(theRange)
{
if (theRange.offset(1, 0).isBlank()==false) return theRange.offset(1, 0);
theRange=theRange.offset(1, 0);
if (theRange.offset(1, 0).isBlank()==false) return theRange.offset(1, 0);
theRange=theRange.getNextDataCell(SpreadsheetApp.Direction.DOWN);
return theRange;
}
function TestFindBlankRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh=ss.getSheetByName('Sheet1');
//Column A to T because you have formula in column U
var Rslt=FirstBlankRange(sh,'A','T'); //0 : If Not Found
Logger.log(Rslt);
var Rslt=NextBlankRange(sh, Rslt, 'A','T'); //0 : If Not Found
Logger.log(Rslt);
var Rslt=LastBlankRange(sh,'A','T'); //0 : If Not Found
Logger.log(Rslt);
};
function FirstBlankRange(Sheet, FirtColumn, LastColumn)
{
for (a=1;a<Sheet.getLastRow()+1;a++)
{
var rr=Sheet.getRange(FirtColumn + a + ':' + LastColumn + a);
var Rslt=rr.getValues().toString();
if ((Rslt.length+1)==rr.getNumColumns())
{
return a;
}
}
return 0;
}
function NextBlankRange(Sheet, CurPos, FirtColumn, LastColumn)
{
for (a=CurPos+1;a<Sheet.getLastRow()+1;a++)
{
var rr=Sheet.getRange(FirtColumn + a + ':' + LastColumn + a);
var Rslt=rr.getValues().toString();
if ((Rslt.length+1)==rr.getNumColumns())
{
return a;
}
}
return 0;
}
function LastBlankRange(Sheet, FirtColumn, LastColumn)
{
for (a=Sheet.getLastRow();a>1;a--)
{
var rr=Sheet.getRange(FirtColumn + a + ':' + LastColumn + a);
var Rslt=rr.getValues().toString();
if ((Rslt.length+1)==rr.getNumColumns())
{
return a;
}
}
return 0;
}
The script deletes all values in the selected cells. I would like to write in exceptions if the value is something I don't want to be deleted.
Haven't tried anything because I'm not that good.
function Gtown() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('O38:P39').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('A38:B39').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('O26:P27').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('I26:J27').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('G26:H27').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('A26:B27').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('O16:P17').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('I16:J17').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('G16:H17').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('A16:B17').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('O6:P7').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('I6:J7').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('G6:H7').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange('A6:B7').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
};
No messages. I only want to delete certain values.
First of all, please, use a loop! Right now your script is very "heavy":
function Gtown() {
var ss = SpreadsheetApp.getActive();
var rl = ss.getRangeList(['A1:A5','B1:B5']); //put any Range references here;
var rs = rl.getRanges();
var opts = {contentsOnly: true, skipFilteredRows: true};
rs.forEach(function(range){
range.clear(opts);
});
}
Then, inside the forEach "loop", instead of unconditional cleanup, wrap clear() method in an if...else statement (Range values can be accessed via getValue() or getValues() method calls)
Try this:
function clearSelectedLocations() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rA=['O38:P39','A38:B39','O26:P27','I26:J27','G26:H27','A26:B27','O16:P17','I16:J17','G16:H17','A16:B17','O6:P7','I6:J7','G6:H7','A6:B7'];
var rgA=sh.getRangeList(rA).getRanges();
for(var i=0;i<rgA.length;i++) {
rgA[i].clear({contentsOnly: true, skipFilteredRows: true});
}
}
Try this:
function clearSelectedLocations() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getValues()
for(var i=0;i<vA.length;i++) {
if(sh.isRowHiddenByFilter(i+1)) {
continue;
}else{
for(var j=0;j<vA[i].length;j++) {
if(vA[i][j].toString()=="On Duty") {
sh.getRange(i+1,j+1).clear({contentsOnly: true});
}
}
}
}
If you have more than one values to clear:
function clearSelectedLocations() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getValues();
var clA=["On Duty"];
for(var i=0;i<vA.length;i++) {
if(sh.isRowHiddenByFilter(i+1)) {
continue;
}else{
for(var j=0;j<vA[i].length;j++) {
if(clA.indexOf(vA[i][j].toString())>-1) {
sh.getRange(i+1,j+1).clear({contentsOnly: true});
}
}
}
}
I have a sheet that I want to dynamically add borders to filter results. I have it working where it adds the borders, but when i select another filter it keeps the rows with previous data borders. So if data set is smaller it has all empty borders under it. How would I fix this with this script?
function onEdit(ss) {
var classeur = SpreadsheetApp.getActiveSpreadsheet();
var ss = classeur.getActiveSheet();
var range = ss.getRange("A5:a"); // Modified
range.setBorder(false, false, false, false, false, false);
var values = range.getValues();
var offsetRow = range.getRowIndex(); // Added
for (var i = 0; i < values.length; i++) {
if (values[i][0]) { // Modified
ss.getRange("A" + (i + offsetRow) + ":P" + (i + offsetRow))
.setBorder(true, true, true, true, true, true, "black",
SpreadsheetApp.BorderStyle.SOLID_MEDIUM) // Modified
.setBackground('#FFFFFF');
}
}
}
Try this:
function onEdit(e) {
var sh=e.range.getSheet();
sh.getRange(1,1,sh.getMaxRows(),sh.getMaxColumns()).setBorder(false, false, false, false, false, false);
var range = sh.getRange(5,1,sh.getLastRow()-4,1); // Modified
range.setBorder(false, false, false, false, false, false);
var values = range.getValues();
for (var i=0;i<values.length;i++) {
if (values[i][0]) { // Modified
sh.getRange(i+5,1,1,16).setBorder(true, true, true, true, true, true, "black",SpreadsheetApp.BorderStyle.SOLID_MEDIUM).setBackground('#FFFFFF');
}
}
}
You cannot call this function from the script editor unless you supply the event object.
Got help with my script from Cooper yet i need some modification, the script basically moverows with a custom dialog if a cell in the row is left blank.
What i like to accomplish is that only the specific cells in a row will be checked.
e.g. row 1 and 4 are mandatory and row 2 and 3 are not.
This is the code what I've got so far.
function Moverows57654() {
var ss=SpreadsheetApp.getActive();
var sourceSheet=ss.getSheetByName("sheet1");
var targetSheet=ss.getSheetByName("sheet2");
var sourceRange=sourceSheet.getRange("A2:T2");
var values=sourceRange.getValues();
var range0=sourceSheet.getRange("A2:B2");
var range1=sourceSheet.getRange("D2:E2");
var firstFreeRow=goToFirstRowAfterLastRowWithData(targetSheet, "A:AD");
var noBlanks=true;
var bA=[];
var ro=sourceRange.getRow();
var co=sourceRange.getColumn();
for(var ri=0;ri<values.length;ri++) {
for(var ci=0;ci<values[ri].length;ci++) {
if(!values[ri][ci]) {
noBlanks=false;
bA.push(sourceSheet.getRange(ri+ro,ci+co).getA1Notation());
}
}
}
if(noBlanks) {
targetSheet.getRange(firstFreeRow,1,values.length,values[0].length)
.setValues(values); targetSheet.getRange(firstFreeRow, 1, values.length, values[0].length)
.setValues(values);
range0.clearContent();
range1.clearContent();
//createPdf()//function gets started
}else{
SpreadsheetApp.getUi().alert('Sorry there are blanks in the following cells: ' + bA.join(', '));
return;
}
Try this:
function Moverows57654() {
var ss=SpreadsheetApp.getActive();
var sourceSheet=ss.getSheetByName("sheet1");
var targetSheet=ss.getSheetByName("sheet2");
var sourceRange=sourceSheet.getRange("A2:T2");
var values=sourceRange.getValues();
var range0=sourceSheet.getRange("A2:B2");
var range1=sourceSheet.getRange("D2:E2");
//var firstFreeRow=targetSheet.getLastRow() + 1;
var firstFreeRow=goToFirstRowAfterLastRowWithData(targetSheet, "A:AD");
var noBlanks=true;
var bA=[];
var skA=[1,2];//column -1
var ro=sourceRange.getRow();
var co=sourceRange.getColumn();
for(var ri=0;ri<values.length;ri++) {
for(var ci=0;ci<values[ri].length;ci++) {
if(!values[ri][ci] && skA.indexOf(ci)==-1) {
noBlanks=false;
bA.push(sourceSheet.getRange(ri+ro,ci+co).getA1Notation());
}
}
}
if(noBlanks) {
targetSheet.getRange(firstFreeRow,1,values.length,values[0].length)
.setValues(values); targetSheet.getRange(firstFreeRow, 1, values.length, values[0].length)
.setValues(values);
range0.clearContent();
range1.clearContent();
//createPdf()//function gets started
}else{
SpreadsheetApp.getUi().alert('Sorry there are blanks in the following cells: ' + bA.join(', '));
return;
}
}