Loop function from a certain row till the last row - google-apps-script

I have a list of urls in column A, and I'm copying and pasting formulas from a row that contains the formulas (Template row) against the URLs to extract data.
The code then does a SpreadsheetApp.flush(); and then copies the the results from that particular row and pastes it as values onto the same row.
The code I've put together to do this is as follows.
function scraper(){
copypasteFormulas();
copypasteResultValues();
}
function copypasteFormulas() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var sourceRange = sheet.getRange('B2:T2'); //Copy formulas from template row
var sourceFormulas = sourceRange.getFormulasR1C1();
var targetRange = sheet.getRange('B5:T5'); //Paste formulas
targetRange.setFormulasR1C1(sourceFormulas);
}
function copypasteResultValues() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
SpreadsheetApp.flush(); //Delay between paste of formula and copypaste of values onto it's self
var copyFromRange = 'Sheet1!B5:T5'; // Copies result range
var copyToRangeStart = 'Sheet1!B5'; // Pastes results into itself as values
var source = sheet.getRange(copyFromRange);
source.copyTo(sheet.getRange(copyToRangeStart), {contentsOnly: true});
}
However I'd like for this to loop through every row till the last row and start again from B5:T5 to the end of the rows.
For example the following stays constant since thats where the formulas are copied from.
var sourceRange = sheet.getRange('B2:T2'); //Copy formulas from template row
var sourceFormulas = sourceRange.getFormulasR1C1();
The rest needs to change as each row gets filled in
var targetRange = sheet.getRange('B5:T5'); //Paste formulas
targetRange.setFormulasR1C1(sourceFormulas);
var copyFromRange = 'Scraper!B5:T5'; // Copies result range
var copyToRangeStart = 'Scraper!B5'; // Pastes results into itself as values
I'm not sure how to do this.
****** UPDATE ******
I managed to put together the following code to loop through from a certain row to the last row.
function iterativeCopyPaste() {
// Get array of values in the search Range
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Scraper");
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(2,2, lastRow-1, lastColumn-1);
var rangeValues = searchRange.getValues(); // Loop through array and if condition met, add relevant
var sourceRange = sheet.getRange(2,2,1,19); //Copy formulas from template row
var sourceFormulas = sourceRange.getFormulasR1C1();
// Copy paste formulas and copy paste result to values iteration
for ( j = 5 ; j < lastRow - 1; j++){
var i = 2;
if(rangeValues[j][i] === ""){
var targetRange = sheet.getRange(j, i, 1, 19); //row range to which the formulas are pasted
targetRange.setFormulasR1C1(sourceFormulas);
SpreadsheetApp.flush();
};
var source = sheet.getRange(j, i, 1, 19); // result range to copy
SpreadsheetApp.flush();
source.copyTo(sheet.getRange(j, i, 1, 19), {contentsOnly: true}); // Pastes results into itself as values
SpreadsheetApp.flush();
};
};
However it stops two rows before the last row, so I had to add two dummy rows at the end of the list on column A so the urls get looped through.
The formulas that get copied into the rows use importxml to extract data and sometimes they get stuck on "Loading", one of the formulas I use as follows.
=if(iserror(IMPORTXML($A2,"//h1[contains(#class,'ch-title')]")),"Loading",IMPORTXML($A2,"//h1[contains(#class,'ch-title')]"))
Is there any way that the iteration only goes ahead only if none of the cells in sheet.getRange(j, i, 1, 19) show as loading.
EDIT: It appears that if I use a
SpreadsheetApp.flush();
Utilities.sleep(100000);
under //row range to which the formulas are pasted it appears to slowly go through all the URLs loading up all the data and then copying and pasting on itself as values. So far it seems to work well.

This is the final code I put together that works for what I wanted.
And set a time trigger to run every 30 minutes incase there is a timeout.
function iterativeCopyPaste() {
// Get array of values in the search Range
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Scraper");
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(2,2, lastRow-1, lastColumn-1);
var rangeValues = searchRange.getValues(); // Loop through array and if condition met, add relevant
var sourceRange = sheet.getRange(2,2,1,10); //Copy formulas from template row
var sourceFormulas = sourceRange.getFormulasR1C1();
var counter = 0;
// Copy paste formulas and copy paste result to values iteration
for ( j = 5 ; j < lastRow - 1; j++){
var i = 2;
counter++;
var targetRange = sheet.getRange(j, i, 1, 10); //row range to which the formulas are pasted
if(targetRange.isBlank()){
//var targetRange = sheet.getRange(j, i, 1, 10); //row range to which the formulas are pasted
targetRange.setFormulasR1C1(sourceFormulas);
SpreadsheetApp.flush();
Utilities.sleep(100000); // Delay before the copy and paste of result values
};
var source = sheet.getRange(j, i, 1, 19); // result range to copy
SpreadsheetApp.flush();
source.copyTo(sheet.getRange(j, i, 1, 19), {contentsOnly: true}); // Pastes results into itself as values
SpreadsheetApp.flush();
if (counter === 4) { // Delay after every 5 rows
Utilities.sleep(240000);
SpreadsheetApp.flush();
counter = 0;
};
};
};

Related

Google Apps Scripts send 2 form input to 2 difference column but in same Row

Hello there actually im new using this Apps scripts and trying to build something that can be achieve with spreadsheet. The problem is when i submit new data to a second form the output is below the new data.,
here the code:
Code.gs
function processForm(input1, input2, input3) {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("B4:D4");
range.setValues([[input1, input2, input3]]);
var values = range.getValues();
var lastRow = sheet.getLastRow();
var nextRow = lastRow + 1;
sheet.insertRowAfter(lastRow);
sheet.getRange(nextRow, range.getColumn(), 1, 3).setValues([[input1, input2, input3]]);
return true;
}
function processForm1(input4, input5, input6) {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("G4:I4");
range.setValues([[input4, input5, input6]]);
var values = range.getValues();
var lastRow = sheet.getLastRow();
var nextRow = lastRow + 1;
sheet.insertRowAfter(lastRow);
sheet.getRange(nextRow, 7, 1, 3).setValues([[input4, input5, input6]]);
return true;
}
i have try many option but still cant figure it out.,
the row is still follow the lastrow of processform.
refer the image what im trying to achieve
How about modifying your script using this sample script?
Modified script:
// Ref: https://stackoverflow.com/a/44563639
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
function processForm(input1, input2, input3) {
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.get1stNonEmptyRowFromBottom(2) + 1; // Last row of column "B".
// sheet.insertRowAfter(row); // If you want to use this line, please enable this.
sheet.getRange(row, 2, 1, 3).setValues([[input1, input2, input3]]);
return true;
}
function processForm1(input4, input5, input6) {
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.get1stNonEmptyRowFromBottom(7) + 1; // Last row of column "G".
// sheet.insertRowAfter(row); // If you want to use this line, please enable this.
sheet.getRange(row, 7, 1, 3).setValues([[input4, input5, input6]]);
return true;
}
By this modification, at processForm, the values are put to the next row of the last row of column "B". At processForm1, the values are put to the next row of the last row of column "G".
Reference:
Related thread.
Determining the last row in a single column

Google Script to Delete a Range of Empty Rows

I need to use a button to delete empty rows in the range A1:A25 on Sheet1 in google sheets. Column A will be the reference column for empty cells. I cannot seem to find a simple answer on how to define the Range for the deletion of empty rows. I do not want it to delete empty rows below row 25.
// Deletes any row whose first column is blank
// WARNING: Assumes any valid row has data in column 1
function deleteBlankRows() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getSheetByName("Sheet1");
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
for (var i = lastRow; i > 0; i--) {
var range = sheet.getRange(i,1);
var data = range.getValue();
if (data == '') {
sheet.deleteRow(i);
}
}
}
I believe your goal is as follows.
You want to delete rows when the column "A" is empty.
As a condition, you don't want to delete rows after row 25.
When your script is modified, how about the following modification?
From:
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
To:
var lastRow = 25;
In this modification, when the column "A" of row 25 is empty, that row is deleted. When you want to leave row 25, please modify it to var lastRow = 26;.
Note:
In your script, when deleteRow() is run in the loop, when the process time is long, how about the folloging modified script? This modified script deletes the rows with the empty of column "A" before the row 25. If you want to leave row 25, please modify var v1 = values.splice(0, 25); to var v1 = values.splice(0, 26);.
function deleteBlankRows() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getSheetByName("Sheet1");
var range = sheet.getDataRange();
var values = range.getValues();
var v1 = values.splice(0, 25);
var res = [...v1.filter(([a]) => a.toString() != ""), ...values];
range.clearContent();
sheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}
In this case, when you want to delete rows after row 25, please modify var res = [...v1.filter(([a]) => a.toString() != ""), ...values]; to var res = [...v1, ...values.filter(([a]) => a.toString() != "")];.
Added:
From your following reply,
The change to last row worked great. I, however, now need to stop the deletion at row 11. The code I have deletes all the way to row 1 (I know that is what is in my original post). Things changed in the last few minutes.
When you want to delete rows from 11 to 25 and when you want to modify your script, how about the following modification?
From:
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
for (var i = lastRow; i > 0; i--) {
To:
var lastRow = 25;
for (var i = lastRow; i >= 11; i--) {
In this modification, the rows are deleted from 11 to 25.
If you will use my 2nd modification, how about the following modification?
function deleteBlankRows() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getSheetByName("Sheet1");
var range = sheet.getDataRange();
var values = range.getValues();
var v2 = values.splice(0, 25);
var v1 = v2.splice(0, 10);
var res = [...v1, ...v2.filter(([a]) => a.toString() != ""), ...values];
range.clearContent();
sheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}

COPYING DATA FROM ONE SPREADSHEET TO ANOTHER

I have three source files - Alpha, Beta, Kappa. They have same headers and basically, I just want them all consolidated in one file on a weekly basis. I started with Kappa and somehow it works - it creates a new spreadsheet and copies info from the Kappa file and paste it to the newly created spreadsheet as values.
Now I tried, adding the Alpha file to the same spreadsheet, just below the info that I copied from the Kappa file using the getLastRow function. I got an error saying that source range and target range must be on the same spreadsheet.
function RawExtractCopy() {
var version = 'ver. 4.01'
var ssnew = SpreadsheetApp.create('V5 Raw Extract '+ version ); //create a spreadsheet
var ssnewsheet = ssnew.getSheetByName('Sheet1'); //get the sheet named Sheet1
ssnewsheet.insertRows(1,30000); //inserting more rows
ssnewsheet.setName('V5 Raw Extract'); //rename the sheet name of the newly created spreadsheet
var ssKappa = SpreadsheetApp.getActiveSpreadsheet(); //opens source file
var targetss = ssnew; //define created ss as the target ss
var srcSheetKappa = ssKappa.getSheetByName('KAPPA'); //get source sheet name
var targetSheet = targetss.getSheetByName('V5 Raw Extract'); //defining target sheet
var srcRangeKappa = srcSheetKappa.getRange("A1:AM30000"); //get source data
var destRangeKappa = targetss.getRange("A1"); //define target
var values = srcRangeKappa.getValues(); //line 18 to 21 is just to match source sheet and target sheet
var bGcolors = srcRangeKappa.getBackgrounds();
var colors = srcRangeKappa.getFontColors();
var fontSizes = srcRangeKappa.getFontSizes();
destRangeKappa.setValues(values);
destRangeKappa.setBackgrounds(bGcolors);
destRangeKappa.setFontColors(colors);
destRangeKappa.setFontSizes(fontSizes);
srcRangeKappa.copyTo(destRangeKappa, {contentsOnly: true});
var ssAlpha = SpreadsheetApp.openById("1gIs4vCdcGG79poDujz9t8Fq7_BWlaEiMrYUH9DTxVHs").activate();
var srcSheetAlpha = ssAlpha.getSheetByName('V5 ALPHA');
var srcRangeAlpha = srcSheetAlpha.getRange("A2:AM30000");
var destRangeAlpha = targetSheet.getRange(targetSheet.getLastRow()+1,1);
var valuesAlpha = srcRangeAlpha.getValues();
var bGcolorsAlpha = srcRangeAlpha.getBackgrounds();
var colorsAlpha = srcRangeAlpha.getFontColors();
var fontSizesAlpha = srcRangeAlpha.getFontSizes();
destRangeAlpha.setValues(values);
destRangeAlpha.setBackgrounds(bGcolors);
destRangeAlpha.setFontColors(colors);
destRangeAlpha.setFontSizes(fontSizes);
srcRangeKappa.copyTo(destRangeAlpha, {contentsOnly: true});
}
The thing, it still copies the data from Kappa but did not push through with Beta. Can someone please be kind to tell what I am missing here?
The OP's goal is to make a duplicate of three sheets in three separate spreadsheets; Alpha, Beta and Kappa. The OP's code works for Kappa, but not Alpha or Beta.
Why does this code work and the OP code doesn't
Well, the OP code does work, but the OP fudges by specifying a fixed range (30000 rows long and about 40 column wide). This works for the first sheet, but not so easily for the second and third sheets. The following code differs in two major respects from the OP code:
the data ranges in Alpha, Beta, Kappa and "Raw Extract" are evaluated using getLastRow and getLastColumn. So the source range and the target range will match each other. In addition, data from the second and third sheets is easily appended one row below the preceding last row.
the copyTo code is changed to copy the whole sheet rather than a range. The reason for this is the the preceding four commands setValues(values), setBackgrounds(bGcolors), setFontColors(colors), and setFontSizes(fontSizes) have already copied the data range to "Raw Extract".
function so_55448299() {
var version = 'ver. 4.01'
var ssnew = SpreadsheetApp.create('V5 Raw Extract ' + version); //create a spreadsheet
var ssnewsheet = ssnew.getSheetByName('Sheet1'); //get the sheet named Sheet1
ssnewsheet.setName('V5 Raw Extract'); //rename the sheet name of the newly created spreadsheet
// copy Kappa and data
var ssKappa = SpreadsheetApp.getActiveSpreadsheet(); //opens source file
var targetss = ssnew; //define created ss as the target ss
var srcSheetKappa = ssKappa.getSheetByName('KAPPA'); //get source sheet name
var targetSheet = targetss.getSheetByName('V5 Raw Extract'); //defining target sheet
// get the last row and column of the source sheet
var kappaLastRow = srcSheetKappa.getLastRow();
var kappaLastCol = srcSheetKappa.getLastColumn();
//Logger.log("DEBUG: Kappa Last row = "+kappaLastRow+", Last column = "+kappaLastCol);//DEBUG
// declare the source and target ranges
var srcRangeKappa = srcSheetKappa.getRange(1, 1, kappaLastRow, kappaLastCol); //get source data
var destRangeKappa = targetSheet.getRange(1, 1, kappaLastRow, kappaLastCol); //define target
// get values and other data
var values = srcRangeKappa.getValues(); //line 18 to 21 is just to match source sheet and target sheet
var bGcolors = srcRangeKappa.getBackgrounds();
var colors = srcRangeKappa.getFontColors();
var fontSizes = srcRangeKappa.getFontSizes();
// set values and other data
destRangeKappa.setValues(values);
destRangeKappa.setBackgrounds(bGcolors);
destRangeKappa.setFontColors(colors);
destRangeKappa.setFontSizes(fontSizes);
// duplicate the entire sheet
srcSheetKappa.copyTo(targetss);
// end copy Kappa and data
// start copy Alpha and data
var ssAlpha = SpreadsheetApp.openById("<insert code here>");
var srcSheetAlpha = ssAlpha.getSheetByName('V5 ALPHA');
// get the last row and column of the source sheet
var alphaLastRow = srcSheetAlpha.getLastRow();
var alphaLastCol = srcSheetAlpha.getLastColumn();
//Logger.log("DEBUG: Alpha Last row = "+alphaLastRow+", Alpha Last Column = "+alphaLastCol);//DEBUG
// get the last row and column of the target sheet
var rawLastRow = targetSheet.getLastRow();
var rawLastCol = targetSheet.getLastColumn();
Logger.log("DEBUG: Target Last row = " + rawLastRow + ", Target Last Column = " + rawLastCol); //DEBUG
// declare the source and target ranges
var srcRangeAlpha = srcSheetAlpha.getRange(2, 1, alphaLastRow - 1, alphaLastCol);
var destRangeAlpha = targetSheet.getRange(rawLastRow + 1, 1, alphaLastRow - 1, alphaLastCol);
//Logger.log("DEBUG:destRangeAlpha = "+destRangeAlpha.getA1Notation());//DEBUG
// get values and other data
var values = srcRangeAlpha.getValues();
var bGcolors = srcRangeAlpha.getBackgrounds();
var colors = srcRangeAlpha.getFontColors();
var fontSizes = srcRangeAlpha.getFontSizes();
// set values and other data
destRangeAlpha.setValues(values);
destRangeAlpha.setBackgrounds(bGcolors);
destRangeAlpha.setFontColors(colors);
destRangeAlpha.setFontSizes(fontSizes);
// duplicate the entire sheet
srcSheetAlpha.copyTo(targetss);
// end copy Alpha and data
// start copy Beta and data
var ssBeta = SpreadsheetApp.openById("<insert code here>");
var srcSheetBeta = ssBeta.getSheetByName('V5 BETA');
// get the last row and column of the source sheet
var betaLastRow = srcSheetBeta.getLastRow();
var betaLastCol = srcSheetBeta.getLastColumn();
//Logger.log("DEBUG: Beta Last row = "+betaLastRow+", Beta Last Column = "+betaLastCol);//DEBUG
// get the last row and column of the target sheet
var rawLastRow = targetSheet.getLastRow();
var rawLastCol = targetSheet.getLastColumn();
//Logger.log("DEBUG: Target Last row = "+rawLastRow+", Target Last Column = "+rawLastCol);//DEBUG
// declare the source and target ranges
var srcRangeBeta = srcSheetBeta.getRange(2, 1, betaLastRow - 1, betaLastCol);
var destRangeBeta = targetSheet.getRange(rawLastRow + 1, 1, betaLastRow - 1, betaLastCol);
//Logger.log("DEBUG:destRangeBeta = "+destRangeBeta.getA1Notation());//DEBUG
// get values and other data
var values = srcRangeBeta.getValues();
var bGcolors = srcRangeBeta.getBackgrounds();
var colors = srcRangeBeta.getFontColors();
var fontSizes = srcRangeBeta.getFontSizes();
// set values and other data
destRangeBeta.setValues(values);
destRangeBeta.setBackgrounds(bGcolors);
destRangeBeta.setFontColors(colors);
destRangeBeta.setFontSizes(fontSizes);
// duplicate the entire sheet
srcSheetBeta.copyTo(targetss);
// end copy Beta and data
}
UPDATE - One Small Function
#tehhowch rightly observes that a more appropriate way to manage this process would be one small function called with a few parameters from a driver function. This is something that I had in mind at the time but (for better or worse) I felt that the long-hand approach would enable the OP to better understand how the code varied from their own. However, this variation seeks to fulfil tehhowch's observation. I have left in the Logger statements for the benefit of the OP (which explains the extraordinary length of the code
function so_55448299_04() {
//Note#1: this function assumes that it is located in the "Kappa" sheet
//Note#2: the spreadsheet ID for Alpha and Beta cannot be assigned to a variable. they must be entered longhand BEFORE this function is processed.
//Note#3: the target sheet names are also entered longhand. BUT the number of sheets is described in the variable "usersheets"
// user defined variables
var targetVn = 'ver. 4.01';
var targetName = 'V5 Raw Extract';
var usersheets = 3;
// create the targetspreadsheet and starting sheet
var targetss = SpreadsheetApp.create(targetName + " " + targetVn);
var targetSheet = targetss.getSheetByName('Sheet1');
targetSheet.setName(targetName);
//loop through the usersheets
for (var i = 0; i < usersheets; i++) {
// if i==0, then process this sheet - KAPPA
if (i == 0) {
//Logger.log("DEBUG: This is KAPPA");//DEBUG
var srcss = SpreadsheetApp.getActiveSpreadsheet();
//Logger.log("DEBUG: this spreadsheet is "+srcss.getName());//DEBUG
// startrow is 1 in order to include headers
var startrow = 1;
var srcSheet = srcss.getSheetByName("v5 KAPPA");
}
// if i=1, then process Alpha
else if (i == 1) {
//Logger.log("DEBUG: This is ALPHA");//DEBUG
var srcss = SpreadsheetApp.openById("<Insert code>");
//Logger.log("DEBUG: this spreadsheet is "+srcss.getName());//DEBUG
// startrow is 2 in iorder to avoid duplicating headers
var startrow = 2;
var srcSheet = srcss.getSheetByName("v5 ALPHA");
}
// if i=2, then process Beta
else if (i == 2) {
//Logger.log("DEBUG: This is BETA");//DEBUG
var srcss = SpreadsheetApp.openById("<Insert code>");
//Logger.log("DEBUG: this spreadsheet is "+srcss.getName());//DEBUG
// startrow is 2 in iorder to avoid duplicating headers
var startrow = 2;
var srcSheet = srcss.getSheetByName(usersheets[i]);
}
// run the subroutine to copy and paste data
// Logger.log("DEBUG: srcSheet: "+srcSheet.getName()+", targetSheet: "+targetSheet.getName()+", startrow: "+startrow+", targetss: "+targetss.getName());//DEBUG
var getresult = getData04(srcSheet, targetSheet, startrow, targetss);
}
}
function getData04(srcSheet, targetSheet, startrow, targetss) {
//get the source sheet - last row and column
var srcLastRow = srcSheet.getLastRow();
var srcLastCol = srcSheet.getLastColumn();
//Logger.log("DEBUG: Source Last row = "+srcLastRow+", Last column = "+srcLastCol);//DEBUG
// get the target sheet - last row and column
var targetLastRow = targetSheet.getLastRow();
var targetLastCol = targetSheet.getLastColumn();
//Logger.log("DEBUG: Target Last row = "+targetLastRow+", Target Last Column = "+targetLastCol);//DEBUG
// declare the source and target ranges
if (startrow == 1) {
var srcRange = srcSheet.getRange(startrow, 1, srcLastRow, srcLastCol);
var targetRange = targetSheet.getRange(startrow, 1, srcLastRow, srcLastCol);
} else {
var srcRange = srcSheet.getRange(startrow, 1, srcLastRow - 1, srcLastCol);
var targetRange = targetSheet.getRange(targetLastRow + 1, 1, srcLastRow - 1, srcLastCol);
}
//Logger.log("DEBUG: srcRange = "+srcRange.getA1Notation()+", target range = "+targetRange.getA1Notation());//DEBUG
// get source values and other data
var values = srcRange.getValues();
var bGcolors = srcRange.getBackgrounds();
var colors = srcRange.getFontColors();
var fontSizes = srcRange.getFontSizes();
// set values and other data
targetRange.setValues(values);
targetRange.setBackgrounds(bGcolors);
targetRange.setFontColors(colors);
targetRange.setFontSizes(fontSizes);
// duplicate the entire sheet
srcSheet.copyTo(targetss);
var result = "Successful";
return result;
}

How do you use a cell value to find the matching sheet name?

I am trying to find a way to copy information from one sheet to another. I know how to find the information from the sheet to copy from, but I'm having trouble finding the sheet to copy to. I want to copy to a sheet based off of a value in my original sheet.
I have a list of names in column C, ex. John, Mark, and Will that starts in row 40. I would like to then copy John's row of information to the sheet titled "John", and Mark's information to a sheet titled "Mark", etc. so that each person's information is summarized on their own sheet. I am having trouble using the value found in column C (the person's name), and then using that value to find a sheet with the coordinating name.
function CopyInfo() {
var CopyFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Summary");
var ColumntoSearch = 3;
var LastRow = CopyFrom.getLastRow();
//Gets column to search for names to compare
var Range = CopyFrom.getRange(40, ColumntoSearch, LastRow, 1);
var Values = Range.getValues();
//Sets the amount of data to copy over
var NumberofColumns = 11;
var NumberofRows = 1;
//Compares all the names in the Summary sheet
var d=0;
for(var i=0;i<Values.length;i++) {
var Name = CopyFrom.getRange(i-d+40, 3);
var CopyTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(Name);
if(Name == ????????){
var RangetoCopy=CopyFrom.getRange(i-d+40,1,NumberofRows,NumberofColumns);
var DestRange=CopyTo.getRange(CopyTo.getLastRow()+1,1,NumberofRows,NumberofColumns);
RangetoCopy.copyTo(DestRange);
d++;
}
}
}
You want to copy the values from Summary sheet to each sheet with the sheet name retrieved from the column "C" in Summary sheet.
There are values for copying in the column "A:K".
For example, when the row 45 of Summary sheet has the values of a45, b45, c45, d45, e45, f45, g45, h45, i45, j45, k45, the values are copied to just below the last row of the sheet name of c45.
If my understanding is correct, how about this modification? I think your script is almost correct. So I modified your script a little.
Modified script:
function CopyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Added
var CopyFrom = ss.getSheetByName("Summary"); // Modified
var ColumntoSearch = 3;
var LastRow = CopyFrom.getLastRow();
//Gets column to search for names to compare
var Range = CopyFrom.getRange(40, ColumntoSearch, LastRow, 1);
var Values = Range.getValues();
//Sets the amount of data to copy over
var NumberofColumns = 11;
var NumberofRows = 1;
//Compares all the names in the Summary sheet
// var d=0; // Removed
for (var i = 0; i < Values.length; i++) {
var Name = Values[i][0]; // Modified
var CopyTo = ss.getSheetByName(Name); // Modified
if (Name) { // Modified
if (!CopyTo) CopyTo = ss.insertSheet(Name); // Added
var RangetoCopy = CopyFrom.getRange(i + 40, 1, NumberofRows, NumberofColumns); // Modified
var DestRange = CopyTo.getRange(CopyTo.getLastRow() + 1, 1, NumberofRows, NumberofColumns);
RangetoCopy.copyTo(DestRange);
// d++; // Removed
}
}
}
Note:
In this modified script, if the sheet name is not found, new sheet of the sheet name is inserted. If you don't want to insert new sheet, please replace if(!CopyTo) CopyTo = ss.insertSheet(Name) to the following script.
if (CopyTo) {
var RangetoCopy = CopyFrom.getRange(i + 40, 1, NumberofRows, NumberofColumns);
var DestRange = CopyTo.getRange(CopyTo.getLastRow() + 1, 1, NumberofRows, NumberofColumns);
RangetoCopy.copyTo(DestRange);
}
If I misunderstood your question and this was not the result you want, I apologize.

Copying Rows of Data to Different Sheets

I am new to coding/JavaScript, so I apologize in advance if this question is (unintentionally) poorly phrased. I've been searching around and found some similar questions but nothing to solve my issue.
I have a scenario where I have a Workbook with one sheet called "Data" containing records and a column header. There is another sheet called "Template" containing a fixed template. I need to duplicate the Template for the number of records in Data (i.e. 5 records of Data will create 4 copies of the original Template). Next, I need to add the first record in Data to a specific cell range in the original Template, the second record in Data to the same specific cell range in the first Template copy, etc.
I've gotten my script to where I can duplicate the Template sheet and pull all the records into an array, but I haven't been able to figure out how to set the first record to the original Template, the second record to the second Template, etc. Any help is greatly appreciated!
function duplicate() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');
var startRow = 2; //first row
var lastRow = sheet.getLastRow();
var StartCol = 1
var LastCol = sheet.getLastColumn()
var numCol = sheet.getLastColumn();
var numRows = sheet.getLastRow(); // Number of rows to process
var dataRange = sheet.getRange(startRow, StartCol, numRows, numCol);
var data = dataRange.getValues();
//Duplicate Sheet based on # of Records
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Template");
for (i=1;i<numRows;++i) s.copyTo(ss).setName("Template "+i);
//A bad attempt at trying to add the records to each template copy
var nextSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Template "+i);
nextSheet.getRange(lastRow+1,1,numRows,numCol).setValues(data[0+1]);
}
'
If I understand correctly, you would like each data record[row] to have its own sheet, based on a Template, with the single record inserted into the same cell range for each record's individual sheet?
function duplicate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Data");
// Get the Template sheet
var template = ss.getSheetByName("Template");
var startRow = 2; //first row
var lastRow = sheet.getLastRow();
var StartCol = 1;
var LastCol = sheet.getLastColumn();
var numCol = sheet.getLastColumn();
var numRows = sheet.getLastRow(); // Number of rows to process
var dataRange = sheet.getRange(startRow, StartCol, numRows, numCol);
var data = dataRange.getValues();
// The constant single column range to insert the data record into
var data_insert_range = sheet.getRange("C14:C22").getA1Notation();
// For each data record create a new sheet based on the template
// and insert into a pre-set range
data.forEach(function (e,i) {
var nextSheet = ss.insertSheet("Template Copy " + i, {template: template});
// Map each col of the record into it's own row
var dataRowIntoCol = e.map(function (c) { return [c] });
// Insert record into the desired column
nextSheet.getRange(data_insert_range).setValues(dataRowIntoCol);
});
}
Instead of using the template to both copy from and overwriting data, I would suggest keeping the Template pure and create new sheets for writing data from it. If not, just place your copyTo() back in place of the insertSheet() and it will work that way as well
edit: Updated code to reflect clarified range/data information
I wasn't sure exactly what you wanted but I think this will give you a boost in a positive direction.
function duplicate() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sheet=ss.getSheetByName('Data');
var startRow = 2; //first row
var lastRow = sheet.getLastRow();
var StartCol = 1
var LastCol = sheet.getLastColumn()
var numCol = sheet.getLastColumn();
var numRows = sheet.getLastRow()-startRow+1; // Number of rows to process
var dataRange = sheet.getRange(startRow, StartCol, numRows, numCol);
var data = dataRange.getValues();
//Duplicate Sheet based on # of Records
var s = ss.getSheetByName("Template");
for (i=0;i<numRows;++i)
{
s.copyTo(ss).setName("Template " + Number(i+1));
s.getRange(startRow,startCol,numRows,numCol).setValues(data);
}
}