This code I am using is only allowing me to past the range of the source range at the end of the string not after the uniqueString. Is there a way I can paste the source range after the unique string in the target range ?
function copyData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("Sheet110");
var sourceRange = sourceSheet.getRange("A3:A8");
var targetRange = sourceSheet.getRange("B3:B8");
var uniqueString = "Critical dates meeting comments:\n";
var sourceValues = sourceRange.getValues();
var targetValues = targetRange.getValues();
for (var i = 0; i < sourceValues.length; i++){
targetValues[i][0] = targetValues[i][0] + sourceValues[i][0];
}
targetRange.setValues(targetValues);
}
Test
Sheet link "Test" above. I want to transfer the strings from column A to Column B and paste them after this unique string "Critical dates meeting comments:".
Currently the code pastes the string at the end of the cell as you will notice "Feb'23..." comments where it is located.
The result I want is:
"Critical dates meeting comments:
Feb'23 Decision forthcoming ------ the string is from cell A3
Dec'22 intention to renew
etc,,"
Related
I'm breaking my head here trying to figure it out a way to achieve this in a simples way.
I got working a code that copies a range from a sheet and paste in another at the last row.
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Review");
var pasteSheet = ss.getSheetByName("Log");
// get source range
var source = copySheet.getRange(3,2,15,5);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,3,15,5);
// copy values to destination range
source.copyTo(destination, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
The problem is, at the destination sheet, I still have columns A and B empty. By each row in the source (varies from time to time) copied, I need to place at column A todays date and column B the text "Review".
Like: Date (column A) | Revview (column B) | Pasted Data from Source (column C and other)
Do I need to write a completely new code to check for empty or can I implement both solutions into this code?
The code should fill the two cells before your data. It also caters for the setup where you have three areas in the same sheet.
Each copyInfoXd_button function will be assigned to your button image.
function copyInfo1d_button() {
copyInfo(2, "B1:B");
}
function copyInfo7d_button() {
copyInfo(9, "I1:I");
}
function copyInfo30d_button() {
copyInfo(16, "P1:P");
}
function copyInfo(startingCol, subjectCol)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Review");
var pasteSheet = ss.getSheetByName("Log");
const sourceCols = 4; //actual number of columns to copy, not including the empty column H
const destCols = 6; //actual number of columns to write to, from DATE to OBS
//find the last row from a colum
var avals = copySheet.getRange(subjectCol).getValues();
var lastRow = avals.filter(String).length;
var rowsToCopy = lastRow - 2; //skip the first 2 rows as they are headers
// get source range
var source = copySheet.getRange(3,startingCol,rowsToCopy,sourceCols); // row, column, number of rows and number of columns
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,rowsToCopy,destCols);
var data = [];
var sourceValues = source.getValues();
//construct new data for the destination range
for (var row in sourceValues) {
var destRow = [Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), 'MMMM dd, yyyy'), 'Review'];
destRow = destRow.concat(sourceValues[row]);
data.push(destRow);
}
destination.setValues(data);
}
I made it! I'm so proud! Thank you all for the help!
I'm beginning to do stuff like this!
After the Charles answer I looked for a way to add to each row. However, I know the code might not be too elegant, and I couldn't figured it out a way of doing using script itself, so I added a helper cell inside the sheet in H1 and H2.
Here's the solution:
function copyInfo24() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Review");
var pasteSheet = ss.getSheetByName("Log");
// get source range
var source = copySheet.getRange(4,2,99,5);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,3,99,5);
// copy values to destination range
source.copyTo(destination, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
// Sets date at Column A and "Review" at Column B.
var data = [];
for(var i =0; i < copySheet.getRange("H1").getValue(); i++) {
data.push([Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), 'MMMM dd, yyyy'), 'Review']);
}
reviewRange = pasteSheet.getRange(pasteSheet.getLastRow()-copySheet.getRange("H2").getValue(), 1, copySheet.getRange("H1").getValue(), 2)
reviewRange.setValues(data); //set the date and 'Review' data
}
We use google sheets for our invoice system. Once we pull the order, we fill in the invoice and anything that we do not have we backorder. We type BO in column I. In excel, we used a button that we could click to copy those cells to our 2nd sheet. We need cells A & B to copy to sheet 2 (which is an exact copy of sheet 1) if column I says BO. Here's what I have so far. This almost works... It deletes everything above the rows with data though and copies the data even if column I doesn't have BO.
I need it to just copy Column A & B if column I says BO to sheet 2 (which is a duplicated of sheet 1) I'm sure there's a simple way, but I can't seem to figure it out.
function Backorder() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Carolina Fireworks Order Form");
var columnToSearch = 9; // I column
Logger.log(sheet.getLastRow());
var range =sheet.getRange(1,columnToSearch,sheet.getLastRow(),columnToSearch);
var destination = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Back Order");
var values = range.getValues();
//Destination
var numberOfColumns = 12;
var numberOfRows = 223 ;
var startColumn = 1;
var startRow = 12;
// equivalent to destination.getRange('A1:L223');
var destinationRange= destination.getRange(startRow, startColumn,numberOfRows,numberOfColumns);
var count = '0';
for(var i=0;i<values.length;i++){
Logger.log("i is now: " +i);
Logger.log("Current row value: " +values[i][0])
if(values[i][0] == 'BO'){
Logger.log("*** Value found in column: " +values[i][0] +"**** \n Count: " +i);
count++;
var rangeToCopy = sheet.getRange(i, 1,numberOfRows,numberOfColumns);
rangeToCopy.copyTo(destinationRange);
}
}
}
SOLUTION
**Updated **
The updated script below will loop through the sourceSheet on every row and it specifically checks if every row on column I says "BO".
If there's a match on that specific row of column I, the row # from the loop will be added to rangeToCopy variable (e.g. range "A(row #):B(row #)" in A1 notation). Then, the rangeToCopy will be copied to the destination in the same exact range of rangeToCopy, given that the destination is the same exact copy of sourceSheet.
function backOrder(){
var sheet = SpreadsheetApp.getActive();
var sourceSheet = sheet.getSheetByName("Carolina Fireworks Order Form");
var destination = sheet.getSheetByName("Back Order");
var lastRow = sourceSheet.getDataRange().getLastRow();
//LOOP THROUGH SOURCE SHEET
for(var row=1; row<=lastRow; row++){
//CHECK FOR "BO" ON EVERY ROWS OF COL I ON SOURCESHEET
if(sourceSheet.getRange(row,9).getValue() == "BO"){
Logger.log("CELL I"+row+" has \"BO\""+"\n=================\n"+"RANGE TO COPY:\n"+ "\"A"+row+":B"+row+"\"");
var rangeToCopy = "A"+row+":B"+row;
sourceSheet.getRange(rangeToCopy).copyTo(destination.getRange(rangeToCopy));
sourceSheet.getRange(row,9).setValue("- BO").setHorizontalAlignment("right");
}
}
}
RESULT
Sample filled out Carolina Fireworks Order Form sheet:
The Back Order sheet after running the script:
Execution logs result for review:
Trying to copy a range (L2:L9) to another spreadsheet based on a data validation selection (ID #) in a specific cell (G11) on the source spreadsheet.
The ID#s are all in alphanumeric order on the target spreadsheet along row 5, so all I need is to get the column number that corresponds to the choice made in the data validation field.
Before I had to convert the ID#s to Alphanumeric values, I simply had numeric values and the script worked fine. Now I'm having trouble converting the script to work with this modification.
function Submit() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // ss = source spreadsheet
var source_sheet = ss.getActiveSheet();
if (source_sheet.getName() == "Pre-Season CC") {
var SRange = source_sheet.getRange('L2:L9');
var A1Range = SRange.getA1Notation();
var SData = SRange.getValues();
var target = SpreadsheetApp.openById('1MpKdxFyBrVQT3EumePQvtCZpgzcDW5xlYe4B1DKZCA8');
var target_sheet = target.getSheetByName('Pre-Season');
var idNumber = source_sheet.getRange('Pre-Season CC!G11').getValue();
for (var i = 0; i < idNumber.length; i++) {
for (var j = 0; j < idNumber.length;j++){
if (target_sheet[4][j] == idNumber){
Logger.log((j+1))
return j+1;
target_sheet.getRange('B6:B13').offset(0,valueA1 = ss.getRange('Pre-Season!G11').getValue(idNumber)+1).setValues(SData);
}
}
}
}
At that point, I need the data copied from source spreadsheet onto the target spreadsheet in it's designated column, according to the ID#. Please help!
Try below code.
function Submit() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // ss = source spreadsheet
var source_sheet = ss.getActiveSheet();
if (source_sheet.getName() == 'Pre-Season CC') {
// source sheet items
var SData = source_sheet.getRange('L2:L9').getValues();
var idNumber = source_sheet.getRange('Pre-Season CC!G11').getValue();
// target sheet items
var targetSS = SpreadsheetApp.openById('1MpKdxFyBrVQT3EumePQvtCZpgzcDW5xlYe4B1DKZCA8');
var target_sheet = targetSS.getSheetByName('Pre-Season');
// 5 = row where IDs are
var TData = target_sheet.getRange(5, 1, 1, target_sheet.getLastColumn()).getValues()[0];
// column index of #ID in target sheet
var colIndex = TData.indexOf(idNumber) + 1;
// write data in that column, rows from 6 to 13
target_sheet.getRange(6, colIndex, SData.length, 1).setValues(SData);
}
}
My 1st question in Stack Overflow.
I have a Google Spreadsheet with 4 individual sheets.
Sheet1 is responses from GForm. Sheet2,3,4 have same data but in 3 languages English, Tamil, Hindi and named English, Tamil, Hindi.
At present the Script takes cell value date from Sheet1, matches the data in the language Tamil sheet, mail merges with the correct language Tamil GDoc and emails it.
Now, I cannot figure out how to make the Script pick a different language Gsheet, one of the 3, depending upon the evalues4 from Form input, which is a Radio Button.
Can someone help me to figure it out?
Select appropriate language
Gsheet using ss.getSheetByName and
GDoc using DriveApp.getFileById
based on Form response evalues4.
Here is the code and which works fine, if I input just one language by name/sheetID/DocID.
//Get information from the form and set as variables
function onFormSubmit(e)
{
var Time = e.values[0];
var email = e.values[1];
var fog = e.values[2];
var mog = e.values[3];
var lang = e.values[4];
var do_date = e.values[5];
//Match chosen date from data sheet & get Row Number
function findInColumn() {
var data = do_date;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Tamil");
var range = sheet1.getRange(1,1,sheet1.getLastRow(),1);
var values= range.getValues();
var row = 0;
while ( values[row] && values[row][0] !== data ) {
row++;
}
if (values[row][0] === data)
return row+1;
else
return -1;
}
//Use above Row number to load in Range, get values, assign to variable cells
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet3 = ss.getSheetByName("Tamil");
// Get range of cells in All columns and All rows with entries
var dataRange = sheet3.getRange(findInColumn(), 1, 1, sheet3.getLastColumn());
// Get entries for each row in the Range.
var data = dataRange.getValues();
// Set each value to a unique variable
for (i in data) {
var cell = data[i];
// Get document template, copy it as a new doc with Name and email, and save the id
var copyId = DriveApp.getFileById("1Nxxxxxxxxxxxxxx2k")
Sorry, completely forgot that I had asked the question here. I solved it the same weekend, by using the If - else [Note: Instead of var ss I used var ssn, and instead of var sheet3 I used var tocopyID in the rewrite]
//Use above Row number to load in Range, get values, assign to variable cells
var ss = SpreadsheetApp.getActiveSpreadsheet();
if (lang === "Tamil"){
var ssn = ss.getSheetByName("Tamil");
var tocopyId = DriveApp.getFileById("1NxxxxTamil");
}
else if (lang === "Hindi"){
var ssn = ss.getSheetByName("Hindi");
var tocopyId = DriveApp.getFileById("Hindi");
}
else if (lang === "English"){
var ssn = ss.getSheetByName("English");
var tocopyId = DriveApp.getFileById("1NxxxxEnglish");
}
You could use you lang variable to get the correct sheet, since they've got the same name. Like :
var sheet1 = ss.getSheetByName(lang); // where lang = "Tamil" for example
For using the correct template, you can store the id of your template with the Properties like:
var templateId = PropertiesService.getScriptProperties().getProperty(lang); // where lang = "Tamil" for example
var copyId = DriveApp.getFileById(templateId);
Where you have properties set with the language name you want. You can set them with code :
PropertiesService.getScriptProperties().setProperty('Tamil', '1Nxxxxxxxxxxxxxx2k');
I'm trying to move a row of data from one sheet to another in the same spreadsheet based on a value of today's date.
In column "A", I have a date. I want to move the row if the date entered in column "A" is older than today's date. (it's a flight schedule for aircraft and I want to move flights that have already occured onto a sheet called "Past Flights".) The name of the active sheet is "Flight Schedule".
After the row is moved, I want it to delete off the "Flight Schedule" sheet. I know where to add scripts, but have no idea how to make this happen.
Here is what I have tried. I think on line "If (data.link >1..." data.link isn't the right one to use. But I can't find something for indicating older than todays date.
function approveRequests() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
sheet = ss.getActiveSheet(),
sheetName = sheet.getName(),
data = sheet.getDataRange().getValues();
if (sheetName == "Flight Shedule") {
var range = sheet.getActiveRange(),
startRow = range.getRowIndex(),
numRows = range.getNumRows(),
numCols = range.getNumColumns()
if (numCols == 9) {
if (data.length > 1) {
var values = range.getValues(),
nextSheet = ss.getSheetByName("Past Flight"),
lastRow = nextSheet.getLastRow();
nextSheet.getRange(lastRow+1,1,numRows,3).setValues(values);
sheet.deleteRows(startRow,numRows);
}
}
}
}
Any help would be huge!
Thanks!
Ok, I will go in with some general tips based on your current code first.
In your function you do a sheet = ss.getActiveSheet() which is redundant because you already have SpreadsheetApp.getActiveSpreadsheet().Also I would recommend to avoid this
var ss = SpreadsheetApp.getActiveSpreadsheet()
sheet = ss.getActiveSheet(),
sheetName = sheet.getName(),
data = sheet.getDataRange().getValues();
in favour of this:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetName = sheet.getName();
var data = sheet.getDataRange().getValues();
which is much more easy to read and change without making mistakes.
data.length has nothing to do with current date, it will simply be the length of the array. So if you select 1 row of data, it will be 1, if you select 2 rows it will be 2 etc. .getValues() will return an array where data[row][col]. What you are looking for is getting the value of the flight time, converting it into a date object (not a google specific thing, just general javascript). Then use var now = new Date() and compare the two.
I would also recommend to re-think your if statements. There are a lot of better ways to grab the row data than selecting the row manually and then running the function. You can save a lot of lines of code should you decide to actually make this run automatically, because as it is, it will run only when called manually.
This sample is working:
function approveRequests() {
// Initialising
var ss = SpreadsheetApp.getActiveSpreadsheet();
var scheduleSheet = ss.getSheetByName("Flight Shedule");
var pastSheet = ss.getSheetByName("Past Flight");
var lastColumn = scheduleSheet.getLastColumn();
// Check all values from your "Flight Schedule" sheet
for(var i = scheduleSheet.getLastRow(); i > 0; i--){
// Check if the value is a valid date
var dateCell = scheduleSheet.getRange(i, 1).getValue();
if(isValidDate(dateCell)){
var today = new Date();
var test = new Date(dateCell);
// If the value is a valid date and is a past date, we remove it from the sheet to paste on the other sheet
if(test < today){
var rangeToMove = scheduleSheet.getRange(i, 1, 1, scheduleSheet.getLastColumn()).getValues();
pastSheet.getRange(pastSheet.getLastRow() + 1, 1, 1, scheduleSheet.getLastColumn()).setValues(rangeToMove);
scheduleSheet.deleteRow(i);
}
}
}
}
// Check is a valid date
function isValidDate(value) {
var dateWrapper = new Date(value);
return !isNaN(dateWrapper.getDate());
}
So yes, It's not the optimized solution (cause of the use of several sheet.getRange() method), but it's working and allowing to have a clear code.