I have made a script that automatically sorts data when i make a change. It workds fine on the one sheet but i cannot find a way to apply it on sheet2 too.
So i need it to sort both sheet1 and 2 (the sheets are simular so the same sort range and everything needs to be the same - i just need it to apply on sheet2 also-
I have tried to make a copy of the code and change sheet_name to sheet2.
I Insert picture of the code. I would be very happy if you could help.
Explanation:
Take advantage of the event object. This will give you very important information regarding the edit/event which took place.
The idea is to use the script for multiple sheets. One way to do that is to construct an array of the sheet names you want to include:
const sheet_names = ["Management Associate","Finance Associate"];
and check if the name of the active sheet is included in this list:
if(sheet_names.includes(sheet.getName())){
// the rest of the code here
}
As a more complete implementation, I modified the last line of your code to include the name of the sheet that was edited. To do that, I used template literals but of course this approach is optional:
ss.toast(`Sort complete in ${sheet.getName()}`);
Solution:
function onEdit(e) {
const sheet_names = ["Management Associate","Finance Associate"]; // add sheets here
const sort_data_range = "A2:H999";
const sort_order = [{column:6, ascending:true}];
const ss = e.source;
const sheet = ss.getActiveSheet();
if(sheet_names.includes(sheet.getName())){
const range = sheet.getRange(sort_data_range);
range.sort(sort_order);
}
ss.toast(`Sort complete in ${sheet.getName()}`);
}
Related
In google sheet, I list dropdown options in a column. I get the options of this dropdown from a certain range in the other sheet.
Data validation for single cell(g2)
As you can see in the example, my data validation lookup criterion for the G2 cell is F133 to F260 in the "Lookup" Sheet.
What I want here is to get this data from the next column in the Lookup sheet in each cell that continues as G3-G4-G5.... For instance: "G133-G260" for G3, "H133-H260" for G4.
I can do this manually one by one with creating a individual data validation per cell, but is there a quick way to do it?
I believe your goal is as follows.
You want to create the data validation rules into the cells "G3:G" of the target sheet.
The data validation rules use the range of Lookup!F133:F260, Lookup!G133:G260, Lookup!H133:H260,,, to "G2", "G3", "G4",,, of the target sheet, respectively.
You want to achieve this using Google Apps Script.
In this case, how about the following sample script?
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet and set your target sheet name. And, save the script.
function myFunction() {
const sheetName = "Sheet1"; // Please set your target sheet name.
let offset = 6;
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const loopupSheet = ss.getSheetByName("Lookup");
const range = sheet.getRange("G2:G" + sheet.getLastRow());
const dataValidations = range.getValues().map(_ => [SpreadsheetApp.newDataValidation().requireValueInRange(loopupSheet.getRange(133, offset++, 128)).build()]);
range.setDataValidations(dataValidations);
}
When this script is run, the ranges of Lookup!F133:F260, Lookup!G133:G260, Lookup!H133:H260,,, are used as the data validation rules, and they are put to the cells "G2", "G3", "G4",,,.
In this case, sheet.getRange("G2:G" + sheet.getLastRow()) is used as the destination range. If you want to manually set the range, please modify it with like sheet.getRange("G2:G10").
let offset = 6; means that the 1st column is column "F". If you want to change this, please modify it.
References:
map()
setDataValidations(rules)
You could do this without script if you're willing to have an auxiliary sheet. Just put in your Auxiliary sheet: =TRANSPOSE(Lookup!G133:260)
Then, go back and select your range in column G. Select all the cells and put in Data Validation from a Range: =Auxiliary!1:1 - Be sure you don't put any "$", that way each cell will go and look in the next row and so on
I've got a Google App Script which is copying rows from one sheet to another, performing various transformations. This logic ultimately gets rows onto the new sheet using sheet.appendRow(row detail). I would like these newly created rows to have a background colour (my intention is to hold a 'latestColour' so I can alternate the shading).
So, is there anyway to add shading within the appendRow method itself, or easily determine the range that the appendRow method processed, such that I can apply additional logic to add the shading.
You can use conditional formatting
=and(A1<>"",A2="")
Although I'm not sure whether I could correctly understand your situation, from your question, I thought that you might be using [Format] --> [Alternating colors] in Google Spreadsheet. And, when a new row is appended by putting the values, you might want to reflect "Alternating colors" in the appended row. If my guess is correct, how about the following sample script?
Sample script:
function myFunction() {
const addValues = ["sample1", "sample2", "sample3"]; // This is a sample appending value. Please replace this for your value.
const sheetName = "Sheet1"; // Please set the sheet name.
// Retrieve banding object from the data range.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const b = sheet.getDataRange().getBandings();
if (b.length == 0) {
console.log("Bandings are not used.");
return;
}
// Append the value.
sheet.appendRow(addValues);
// Expand the range of banding.
b[0].setRange(sheet.getDataRange());
}
When this script is run, the current banding is retrieved. And, after the value was appended, the banding is updated by including the appended row. In this sample, even when the multiple rows are appended, this script can be used.
Note:
From your question, I guessed that there is one banding in the data range in your sheet. Please be careful this.
References:
getBandings()
setRange(range)
Unfortunately the method appendRow() does not receive formatting settings as input, only an array of values.
However, here is a suggestion if you want to implement your own logic:
Sample code:
function applyColorLastRow() {
var ss = SpreadsheetApp.getActive(); //get active sheets file
var range = ss.getDataRange(); //get populated range, you may want to set a range manually if needed.
var lastRowNum = range.getLastRow(); //getting the last row index of the range.
var lastRowRange = ss.getRange(`${lastRowNum}:${lastRowNum}`); //narrowing the range (using A1 notation) to the last row only to apply color
var lastRowColor = lastRowRange.getCell(1,1).getBackgroundObject().asRgbColor().asHexString();
//Your row coloring logic here...
if (lastRowColor === '#ffffff'){ //toggling white/grey color as an example...
lastRowRange.setBackground('#cccccc'); //apply grey color to all cells in the last row range
} else {
lastRowRange.setBackground('#ffffff'); //apply white color to all cells in the last row range
};
}
Absolute noobie here, just trying to automate a process we currently do manually between google sheets.
I'd like to have a script attached to a button that does the following when pressed -
"lock" a vlookup or freeze a cell's contents. (I use a separate sheet of prices for materials that changes over time. When a quote gets accepted, I want to be able to "lock" the data that's already been pulled across from the other sheet, so the customer only pays what they've been quoted.
export the current sheet URL (or ID) to another sheet. I've got a "dashboard" sheet that we use as an overview of all the other sheets. Once the button is pressed I want to add the current sheet to the list of sheets we are monitoring on the dashboard sheet. Essentially I want to be able to extract the url of the sheet where we've just pressed the button, and add that url (or ID) to a list on another sheet.
Hope that makes sense! Any help is greatly appreciated.
This will get you started. The copyUrl function will paste the url to the first empty row in column B, you can change the column by changing the 2 on codeline 12.
function freeze(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const activeSheet = ss.getActiveSheet();
activeSheet.getDataRange().copyTo(activeSheet.getDataRange(),{contentsOnly:true});
}
function copyUrl(){
const targetSheetId = 'xxxxxx';
const targetSheetName = 'sheetname';
const currentUrl = SpreadsheetApp.getActiveSpreadsheet().getUrl();
const target = SpreadsheetApp.openById(targetSheetId).getSheetByName(targetSheetName);
target.getRange(target.getLastRow()+1,2).setValue(currentUrl);
}
References
copyTo(spreadsheet)
getLastRow()
Could someone help me with creating a script that does the following:
Function: Upon adding a new sheet to my already existing workbook, I would like it to copy Column "E" from Sheet 1 and (Paste Special > Conditional formatting only) to the newly introduced Sheet "X"
Where can I learn more on how to write code? I have never used Stackoverflow by the way someone just recommended me to come here. I believe I just answered my own question somehow on the post, which I am sure was wrong to do but I couldn't comment on an already existing answer without exceeding the limit.
// Adds custom menu
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('CustomMenu').addItem('Copy format', 'copyFormat') //Add function to menu.'GIVE NAME HERE', 'functionName'
.addToUi();
}
function copyFormat() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh1 = ss.getSheets()[0]; //Gets the first sheet of the workbook. Can use ss.getSheetByName('Name of sheet here'); If it is not the first sheet
var activeSh = ss.getActiveSheet(); //Get the active sheet, you should be on the sheet just added
var rowEnd = activeSh.getLastRow(); //Last row of active sheet
sh1.getRange("E1:E").copyFormatToRange(activeSh, 5, 5, 1, rowEnd); //Copy format, including conditional, to column E of active sheet
}
This just adds a button that allows you to select a cell and give it the same conditions has in the original sheet.
Example: Sheet 1: Column E1:E100 has a given condition.. which needs to apply in the exact same way to any new incoming sheets since they all come in the same format. Right now its at a point of which when a new sheet arrives in the workbook: I can enter the new sheet > Select the cell which requires the conditions > Select the custom menu > Cell gets conditioned. So the next step would be automate the process I just mentioned since there is several sheets added daily to the workbook.
I read Google Script: Conditionally copy rows from one spreadsheet to another and could not make it work for me.
I need a script that will allow me to do the quoted text below. Please feel free to edit my spreadsheet to make a complete working script. I will keep the spreadsheet publicly available for anyone to copy the script for their own use. I really know nothing about script writing so I need it all spelled out. Sorry, I'm such a noob with all this, but this will help me learn.
https://docs.google.com/spreadsheet/ccc?key=0AoJdwy8V1ldHdFA5M1M1Wlp1NHZhcmxJOUZKVEU4X3c&usp=sharing
If Column B on sheet "All_Mileage" says "John" then I want that row to
be copy and pasted into Sheet "John" starting on row 3 and following.
If Column B on sheet "All_Mileage" says "Adam" then I want that row to
be copy and pasted into Sheet "Adam" starting on row 3 and following.
If Column B on sheet "All_Mileage" says "Mike" then I want that row to
be copy and pasted into Sheet "Mike" starting on row 3 and following.
I saw other scripts on here, but I couldn't get them to work. Like I said I'm greener than a sapling when it come to code.
Thanks a ton!
C.Lang is right, this is not a place to get readymade scripts ... but since this question is so common and has been aswered so often it took me a few minutes to write and test... so there it is :
var ss=SpreadsheetApp.getActiveSpreadsheet();// some global variables
var master = ss.getSheetByName('All_Mileage');
var colWidth = master.getMaxColumns();
function copyRowsOnCondition() {
var data = master.getDataRange().getValues();
for(n=2;n<data.length;++n){
if(data[n][1].length<16){ // if not pre-filled with your text
Logger.log(data[n][1])
var dest = ss.getSheetByName(data[n][1].toString().replace(/ /g,''));//remove any spaces that could be included in the name so the name = sheetName for sure
var destRange = dest.getRange(dest.getLastRow()+1,1);// the place to write
master.getRange(n+1,1,1,colWidth).copyTo(destRange);the copy itself value & format
}
}// loop
}
EDIT : since I used the name value in MasterSheet to find destination sheet I thought it might be usefull to handle the case where the destination sheet doen't exist by creating it using the same rule, ie. name = sheetName...
The other issue was that there was no way to know which rows had been already copied... so I made a version that handles all that, copying only the rows that are manually selected (even in only a single column) and change the background color to tell that these rows have been processed. I also added a menu for a minimal comfort ;-)
(how to keep busy on a cold sunday afternoon ;-)
var ss=SpreadsheetApp.getActiveSpreadsheet();
var master = ss.getSheetByName('All_Mileage');
var colWidth = master.getLastColumn();// last used col in masterSheet
var sheets = ss.getSheets();// number of sheets
function onOpen() {
var menuEntries = [ {name: "Copy selected Rows to sheets", functionName: "copyRowsOnConditionV2"},
];
ss.addMenu("Copy functions",menuEntries);// custom menu
}
function copyRowsOnConditionV2() {
var sheetNames = [];// array of existing sheet names
var sheets = ss.getSheets();// number of sheets
for(s=0;s<sheets.length;++s){sheetNames.push(sheets[s].getName())};
ss.getActiveSelection().setBackground('#ffffbb');
var selectedfirstRow = ss.getActiveSelection().getRowIndex();
var selectedHeigth = ss.getActiveSelection().getHeight()
var selectedFullRange = master.getRange(selectedfirstRow,1,selectedHeigth,colWidth);
var data = selectedFullRange.getValues();
for(n=0;n<data.length;++n){
if(data[n][1].length<16){
if(sheetNames.toString().match(data[n][1].toString().replace(/ /g,''))!=data[n][1].toString().replace(/ /g,'')){// if no sheet exist with this name
var newSheet = ss.insertSheet(data[n][1].toString().replace(/ /g,''),ss.getSheets().length);// then create it
master.getRange(1,1,2,colWidth).copyTo(newSheet.getRange(1,1));// and copy the headers on 2 first rows, then continue as usual
newSheet.getRange(1,1).setValue('Gas Mileage Log - '+data[n][1].toString().replace(/ /g,''));// set name in header
SpreadsheetApp.flush();
var sheets = ss.getSheets();// number of sheets
var sheetNames = [];// update array of existing sheet names
for(s=1;s<sheets.length;++s){sheetNames.push(sheets[s].getName())};
Logger.log(sheetNames)
};
var dest = ss.getSheetByName(data[n][1].toString().replace(/ /g,''));//find the destination sheet
Logger.log(data[n][1].toString().replace(/ /g,''))
var destRange = dest.getRange(dest.getLastRow()+1,1);// define range
master.getRange(selectedfirstRow+n,1,1,colWidth).copyTo(destRange);// and make copy below last row
}
}
}
Illustration below :