Copy specific Columns data from Last Row and paste to another sheet - google-apps-script

I was trying to copy/fetch data from specific columns of the last row from my "Total" sheet, and pass those to another sheet named "vnSheet". The code below which i found earlier works fine. But, it copies all the row & column data from the mother sheet, which I don't want to happen.
function copySheet() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Total");
var destSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("vnSheet");
var columns_to_be_copied = ['A', 'B', 'D', 'F'];
var columns_to_be_pasted = ['A', 'B', 'D', 'F'];
for (column in columns_to_be_copied) {
var copy_range_string = columns_to_be_copied[column] + ':' + columns_to_be_copied[column];
var paste_range_string = columns_to_be_pasted[column] + ':' + columns_to_be_pasted[column];
var source = sourceSheet.getRange(copy_range_string);
var destination = destSheet.getRange(paste_range_string);
source.copyTo(destination, {contentsOnly:true});
}
}
Here, I want to Copy 'A', 'B', 'D', 'F'(except 'C' & 'E' ) column data only from Last row of "Total" and paste those data into the same columns of the "vnSheet" but in the Last row. I searched almost all over the internet and found no solution of my problem, all I found was similar to the code above.
As I'm new to this, my coding experience is limited but I'm a gd learner :) Any help to solve that problem will be greatly appreciated.
Thank you.

So there are a few things
You currently are not getting the last row, as far as I can tell
You currently have duplicate variables to hold the same array
You currently are copying an entire row, which is not what you want
Assuming there are already values in columns C and E in your Target Sheet there are a few ways to approach a solution:
You get the existing values from Target Sheet and then overwrite the columns you want to overwrite, then you update the entire row using one array
You only overwrite the particular cells you want to update, leaving the rest as is
Option 1 above will be quicker, but we are speaking fractions of a second.
Therefore I recommend option 2, as it does not touch an existing row with field you don't want to change.
My proposal is here:
function copyHandler(){
const activeSheet = SpreadsheetApp.getActive()
var sourceSheet = activeSheet.getSheetByName("Total");
const sourceLastRowNum = sourceSheet.getLastRow()
var destSheet = activeSheet.getSheetByName("vnSheet");
const destLastRowNum = destSheet.getLastRow() + 1
const lastRow = sourceSheet.getRange(sourceLastRowNum, 1, 1, 6).getValues()[0]
lastRow.forEach( (value, index) => {
// Skip column C and column E
if( index == 2 || index == 4) return
destSheet.getRange(destLastRowNum, index+1).setValue(value)
})
}

Use sourceSheet.getLastRow() before the for loop to get the row number of the last row in your "Total" sheet, then add this value after each column letters.
Let's say that you assign the result of the above to a lastRow, then you can use this variable this way:
var copy_range_string = columns_to_be_copied[column] + lastRow + ':' + columns_to_be_copied[column] + lastRow;
NOTE:
You might find helpful to read https://developers.google.com/apps-script/guides/support/best-practices. This article suggest to avoid doing calls to Google Apps Script classes as they are slow. One way to reduce the number of calls do achieve the result that you are looking is by using getRangeList at it allows to get multiple ranges at once. Another way is by using the Advanced Sheets Service as it allow to do batch updates.

Related

Script to VLOOKUP Summary Column From Multiple Tabs Pull Data wrt Value From Each Tab

I've a sheet where there are multiple tabs. I want to summarize first column and 11th column of all tabs.
I would like to merge the first column so there are only unique values. Then pull the data from first tab as 2nd column and second tab as 3rd column and so on. The sheet is here
What I've tried so far:
I have tried to use formula which is both manual and ever increasing. The tab name is "Desired".
For the first column I used query formula. I used only for two tabs since I've more tabs.
=UNIQUE(query({indirect(address(2,1,1,1,TEXT(B1,"ddmmmyyy"))&":A"),indirect(address(2,1,1,1,TEXT(C1,"ddmmmyyy"))&":A")},"Select Col1 where Col1 is not null"))
Then for each column I used vlookup
=VLOOKUP($A2,{indirect(address(2,1,1,1,TEXT(B$1,"ddmmmyyy"))&":A"),indirect(address(2,9,1,1,TEXT(B$1,"ddmmmyyy"))&":I")},2,0)
Update: I managed to solve the first part with the following code
function SUMMARIZE2() {
const ss = SpreadsheetApp.getActive();
const weekSheets = ss.getSheets().filter(sheet => sheet.getName().endsWith("2020"));
const summarySheet = ss.getSheetByName("Summary");
let weekData = weekSheets.map(weekSheet => {
return weekSheet.getRange(2, 1, weekSheet.getLastRow() - 1).getValues();
}).flat();
const getUnique_ = array2d => [...new Set(array2d.flat())];
uniqueValues = getUnique_(weekData).map(e => [e]);
var header = [["Company Name"]];
summarySheet.getRange("A1:A1").setValues(header);
summarySheet.getRange("A2:A"+(uniqueValues.length+1)).setValues(uniqueValues);
}
I appreciate the replies.
You could do the following:
Get the headers of the destination sheet, starting with Company Name and followed by the different sheet names.
Get the unique names of the companies (2D array with inner arrays having a single element - the company name).
Iterate through all sheets ending with 2020. For each sheet, follow steps 4-5.
Iterate through all rows in the sheet. For each row, look for the index of the company (column A) in the array of companies from step 2, using findIndex.
On the index found in 4, push the value from column 11 to the corresponding inner array (from step 2).
Concatenate the headers from 1 with the values from 4-5.
Since the different inner arrays have different lengths, find the array with maximum length and add elements to the others so that all inner arrays have the same length (that's necessary when using setValues).
Use setValues to write all your summarized values to your destination sheet.
Code snippet:
function summarizeAllData() {
const ss = SpreadsheetApp.getActive();
const weekSheets = ss.getSheets().filter(sheet => sheet.getName().endsWith("2020"));
const summarySheet = ss.getSheetByName("Summary");
const headers = ["Company Name"].concat(weekSheets.map(weekSheet => weekSheet.getName()));
let values = weekSheets.map(weekSheet => {
return weekSheet.getRange(2, 1, weekSheet.getLastRow() - 1).getValues();
}).flat();
values = [...new Set(values)];
weekSheets.forEach(weekSheet => {
const sheetValues = weekSheet.getRange(2, 1, weekSheet.getLastRow() - 1, 11).getValues();
sheetValues.forEach(row => {
const companyIndex = values.findIndex(company => company[0] === row[0]);
if (values[companyIndex]) values[companyIndex].push(row[10]);
});
});
values = [headers].concat(values);
const lengths = values.map(a=>a.length);
const maxLength = lengths[lengths.indexOf(Math.max(...lengths))];
values.forEach(row => {
for (let i = row.length; i < maxLength; i++) {
row.push("");
}
});
summarySheet.getRange(1,1,values.length,values[0].length).setValues(values);
}
Notes:
When I tried to copy all the data, I got an error saying that the resulting spreadsheet would reach the 5 million cell limit. Because of this, I created a new spreadsheet instead of writing to the Summary sheet: SpreadsheetApp.create("YOUR NEW SPREADSHEET").getSheets()[0].getRange(1,1,values.length,values[0].length).setValues(values);. Replace last line in the code with that if you get this error.
The sheet names are not sorted chronologically. Since the sheet names are not dates themselves, sorting them is not immediate, so I skipped that part (it's not an insurmountable difficulty, so if you have problems with this, I'd suggest posting another question).
There are sheets ("tabs") which have repeated company names, each with a different value in column 11. In cases like this, the script will retrieve the value corresponding to the first row that is found. Please be careful about this.

Exception: The starting row of the range is too small - Logs Numbers Why?

I have a basic script to take numbers from a sheet and use them to create a range, as well as using the last column function. I have had the error range is too small for the posting range.
When I log the output for both the column and row numbers these come out as expected!
I thought initially, it was because one was a last column pull and the other was pulling an integer from the cell in the sheets, as they were coming with decimal places, so I have overcome this with the conversion to number and then removing the decimals with the .tofixed() but this does not work either. Any ideas?
function weeklyData() {
var sourcess = SpreadsheetApp.openById('1B93Oq2s9Nou5hVgOb3y3t15t9xnqRMBnrYkAed-oxrE'); // key of source spreadsheet
var sourceSheet = sourcess.getSheetByName('Measures & Answers'); // source sheet name - change to your actual sheet name
var lr = Number(sourceSheet.getRange(2,3).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow()).toFixed(0);
for(var i=0;i<lr+1;i++){
var dataValue = sourceSheet.getRange(i+2,3).getValue(); //This weeks numbers to update into table
var rowdataRange = sourceSheet.getRange(i+2,4).getValue(); //The row that the data needs to be pasted
var rowformat = Number(rowdataRange);
var row = rowformat.toFixed(0);
var pasteSheet = sourcess.getSheetByName('WHERE DATA ENDS UP'); // Data is to be pasted - change to your actual sheet name
var pasteColumn = pasteSheet.getRange(12,12).getDataRegion(SpreadsheetApp.Dimension.COLUMNS).getLastColumn()+1;
var column = pasteColumn.toFixed(0); // Column that is free for this weeks data
var pasteRange = pasteSheet.getRange(row,column,1,1);
Logger.log(pasteRange);
// pasteRange.setValue(dataValue);
}};
Your script works fine for me. I suspect this is an example script you've adapted from somewhere and trying to apply it to your data structure?
The reason you are getting the error is probably because the data in column 4 of your source sheet is not of number format? Either change your data or change the following line to the column containing numeric values.
var rowdataRange = sourceSheet.getRange(i+2,4).getValue();
This script is poorly written for this particular use.
You might want to check your Spreadsheet since it has lots of random values at random ranges.
When you use the following command Logger.log(pasteSheet.getLastColumn()); the number returned is 3753: which means that that is the next available column at which your data will be pasted.
The error message you were getting is due to the fact that the range was incorrect and you were passing wrong values in order to access it, which was most likely because of the values mentioned above.
Moreover, after cleaning all the unnecessary data, you can make use of the below script.
Snippet
function weeklyData() {
var spreadsheet = SpreadsheetApp.openById("ID_OF_THE_SPREADSHEET");
var sourceSheet = spreadsheet.getSheetByName("Measures & Answers");
var pasteSheet = spreadsheet.getSheetByName("WHERE DATA ENDS UP");
var valsToCopy = sourceSheet.getRange(2, 3, sourceSheet.getLastRow(), 1).getValues();
var rowsAt = sourceSheet.getRange(2, 4, sourceSheet.getLastRow(), 1).getValues();
var column = pasteSheet.getRange(12,12).getDataRegion(SpreadsheetApp.Dimension.COLUMNS).getLastColumn()+1;
for (var i = 0; i < valsToCopy.length; i++)
if (rowsAt[i][0] != "")
pasteSheet.getRange(parseInt(rowsAt[i][0]), parseInt(column)).setValue(valsToCopy[i][0].toString());
}
Explanation
The above script gathers all the data that needs to be copied as well as the rows associated with it. In order to make sure you don't end up using inappropriate values for the ranges, an if condition has been placed to make sure the value is not empty.
Reference
Sheet Class Apps Script - getLastColumn();
Sheet Class Apps Script - getRange(row, column, numRows, numColumns);

Overwriting Google sheets (for form response) rows if duplicate entered

So, I've been trying to figure out how to stop the duplicate rows appearing in my google sheets response output from a google form. If found this link which sounds like it does exactly what I want (Form Google Script Prevent Duplicates), but cannot for the life of me work out how to edit the given answer to work on my sheet.
I have included a screenshot of my workbook to give an example of the structure of the data I'd like the edited code to run on, and also below is my attempt at making the code run correctly on my data structure.
My sheet structure that I'd like to run the code on. I want to use the email address as the 'unique' identifier, so any duplicate rows can be identified using that.
My attempt at adapting the code to work on the above data structure (I have absolutely no background with this scripting language, so please go easy on me if I've made a glaringly obvious error):
function updateExisting() {
var s = SpreadsheetApp.getActiveSheet(),
// s = ss.getSheetByName(''),
lastRow = s.getLastRow(),
lastValues = s.getRange('A'+lastRow+':C'+lastRow).getValues(),
name = lastValues[0][0],
allNames = s.getRange('B2:B').getValues(),
row, len;
// TRY AND FIND EXISTING NAME
for (row = 0, len = allNames.length; row < len - 1; row++)
if (allNames[row][0] == name) {
// OVERWRITE OLD DATA
s.getRange('A2').offset(0, 0, row,
lastValues.length).setValues([lastValues]);
// DELETE THE LAST ROW
s.deleteRow(lastRow);
break;}
}
Key words: duplicates, Google, spreadsheet, Sheets, Form, submission, edit, row, unique.
This code prevents duplicates in a Google Sheet when submitting a Google Form, by overwriting an existing row with the existing unique value, if one exists.
The code searches one column in a spreadsheet and looks for a match. I tried to make it generic so that the code doesn't need to be changed depending upon what column the unique identifier is in. You need to make a couple of settings in the "User Settings" section to make it work. But that is better than needing to rewrite the code.
function updateExisting(columnWithUniqueIdentifier,sheetTabName) {
var dataFromColumnToMatch,lastColumn,lastRow,rowWithExistingUniqueValue,rowOfDataJustSaved,
sh,ss,valueToSearchFor;
// USER SETTINGS - if the values where not passed in to the function
if (!columnWithUniqueIdentifier) {//If you are not passing in the column number
columnWithUniqueIdentifier = 2;//Hard code column number if you want
}
if (!sheetTabName) {//The sheet tab name was not passed in to the function
sheetTabName = "Put your Sheet tab name here";//Hard code if needed
}
//end of user settings
ss = SpreadsheetApp.getActiveSpreadsheet();//Get the active spreadsheet - this code must be in a project bound to spreadsheet
sh = ss.getSheetByName(sheetTabName);
lastRow = sh.getLastRow();
lastColumn = sh.getLastColumn();
//Logger.log('lastRow: ' + lastRow)
rowOfDataJustSaved = sh.getRange(lastRow, 1, 1, lastColumn).getValues();//Get the values that were just saved
valueToSearchFor = rowOfDataJustSaved[0][columnWithUniqueIdentifier-1];
//Logger.log('valueToSearchFor: ' + valueToSearchFor)
dataFromColumnToMatch = sh.getRange(1, columnWithUniqueIdentifier, lastRow-1, 1).getValues();
dataFromColumnToMatch = dataFromColumnToMatch.toString().split(",");
//Logger.log('dataFromColumnToMatch: ' + dataFromColumnToMatch)
rowWithExistingUniqueValue = dataFromColumnToMatch.indexOf(valueToSearchFor);
//Logger.log('rowWithExistingUniqueValue: ' + rowWithExistingUniqueValue)
if (rowWithExistingUniqueValue === -1) {//There is no existing data with the unique identifier
return;
}
sh.getRange(rowWithExistingUniqueValue + 1, 1, 1, rowOfDataJustSaved[0].length).setValues(rowOfDataJustSaved);
sh.deleteRow(lastRow);//delete the row that was at then end
}

Autofill google forms based on user input

Alright stack friends,
I'm working on my first projects using google scripts and it's been pretty fun so far. My project is to create a form for data entry that can either accept an ID number and fill in the rest of the fields, or let the user fill out the entire form. Basically my method to fill in the other fields is just to have a lookup table on the second sheet. When the user submits a form, the script runs, looks for the ID of the last row, scans the reference table for the ID, and then fills in the details.
I think the problem I'm having is the assumption that the data from the form is already in the sheet when the script runs. The problem I noticed is that the script sometimes fails to fill in the gaps. I tried creating form submissions in a loop with the same ID and they function somewhat erratically but it seems like the last sumbission always works which would make sense if the script executions are not matching up with the form submissions. Here's the script for reference:
function fillGaps() {
// First take in the appropriate spreadsheet objects and get the sheets from it
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheets()[0];
var refSheet = ss.getSheets()[1];
// Here's the last rows' index
var lastRow = sheet.getLastRow();
var lastRowRef = refSheet.getLastRow();
// now this is an array of values for the last row and the student ID entered
var response = sheet.getRange(lastRow, 1, 1, 7).getValues();
var enteredID = response[0][1];
// Next we're going to try to load up the lookup table and scan for the ID
var stuIDs = refSheet.getRange(2, 4, refSheet.getLastRow()).getValues();
var row = 0;
while(enteredID != stuIDs[row] && row <= lastRowRef){
row++;
}
// Okay at this point the row variable is actually -2 from what the sheet index
// is that I'm thinking of. This is because we didn't load the first row (names)
// and the way arrays are indexed starts with 0.
row++;
row++;
// now assuming that it found a match we'll fill in the values
if(row < refSheet.getLastRow()){
// Alright now we need to wrangle that row and format the data
var matchedRow = refSheet.getRange(row, 1, 1, 6).getValues();
// modify the response
var replacement = [response[0][0],enteredID, matchedRow[0][1],matchedRow[0][0],matchedRow[0][2],matchedRow[0][4],matchedRow[0][5]];
sheet.getRange(lastRow, 1, 1, 7).setValues([replacement]) ;
}
}
So I'm wondering:
Does this seem like the right diagnosis?
If so, what would be the best way to remedy? I thought of adding a little delay into the script as well as trying to capture the submissions timestamp (not sure how to do that)
Thank you much!
The following code gives a 2D array:
var stuIDs = refSheet.getRange(2, 4, refSheet.getLastRow()).getValues();
Also,refSheet.getLastRow gives the last row, lets say it is 10 in this case. The syntax for getRange is getRange(row, column, numRows) and the last argument is the number of rows, not the last column. So in the above code the selected range would be row 2 - 11 rather than 2- 10. Unless that is what you intended, modify the code like so:
var stuIDs = refSheet.getRange(2, 4, refSheet.getLastRow()-1).getValues();
To access the values in stuIDs you should use stuIDs[row][0] (2D array) to check for matching ID. Assuming your ID was to be matched was in column 1.
Secondly, in the loop you are using the following to check for the last index in array row <= lastRowRef which will cause it go out of range(because array starts at 0 and sheet row at 1) instead use this row < stuIDs.length
Finally, in case you don't find a match you will end up with the last row and your code will end you taking the last row as the matched index. This can be prevented by using a boolean variable to check for a match.
var foundId = false
var row = 0;
var i = 0;
for (i in stuIDs){
if(stuIDs[i][0] == enteredID)
foundID = true
break
}
}
row = i + 2
if (foundID){
var matchedRow = refSheet.getRange(row, 1, 1, 6).getValues();
// modify the response
var replacement = [response[0][0],enteredID, matchedRow[0][1],matchedRow[0][0],matchedRow[0][2],matchedRow[0][4],matchedRow[0][5]];
sheet.getRange(lastRow, 1, 1, 7).setValues([replacement]) ;
}
PS: You can also use event objects to get the values of response (eventObj.values). As mentioned here: https://developers.google.com/apps-script/guides/triggers/events
Hope that helps!

Copying Data Sheet1 to Sheet2 so you can sort & edit both sheets (google apps script?)

I am working in goggle sheets and think I need to use a google apps script to do what I want, but I am a psychologist at a non-profit University hospital trying to do some good and not a programmer (which probably shows) and I am desperately in need of help. I am trying to set up a series of spreadsheets to track participation in workshops for our treatment method.
1) I have a sheet “Participant_Registration” where basic information is entered
2) I want to transfer information from only the first four columns (A:D) of “Participant_Registration” to a second sheet “Learning_Sessions_Attendance”
3) I am also transferring the same information to a third sheet 'Consultation1_Attendance' – but I need to first filter and select only those people assigned to that group.
Here is a link to a copy of my spreadsheet.
https://docs.google.com/spreadsheets/d/17d0bT4LZOx5cyjSUHPRFgEZTz4y1yEL_tO3gtSJ4UJ8/edit?usp=sharing
More generically this is what I am trying to do. Is this possible in google app scripts? It seems it should be.
1) I have original data in sheet1
2) I want the first four columns (A:D) to transfer to sheet2 (it is fine if I need a trigger variable)
3) I want them to transfer in such a way that if you sort either sheet, the data are still fine (still linked to the right line).
4) Ideally if there is a change to the data in the source sheet (Sheet1) the same change will be made in Sheet2.
5) Ideally this would all happen automatically without human intervention through a script.
Any ideas?? I so need your help. I have been all over the forum, git hub, and done a ton of searches and tried following a lot of examples I saw but nothing works. I really need help.
Here are my sample scripts each with a problem:
//The following code copies a range from sheet1 to sheet2 as I wanted. A problem occurs if after if we copy the data from sheet1 we add data to other columns on sheet2. Later if we sort on some variable (which people are bound to do) if the function is deployed again it will overwrite data meaning the data from sheet1 are not connected to the right individual on sheet2
function CopyRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Participant_Registration");
var range = sheet.getRange("A14:D");
var values = range.getValues();
var target = ss.getSheetByName("Learning_Sessions_Attendance");
var target_range = target.getRange("A10:D");
range.copyTo(target_range);
}
So I tried again. This time I tried to just copy the last edited row from sheet1 to sheet2. This function does not appear to work for me.
function CopyRow2() {
// Get Spreadsheets
var source = SpreadsheetApp.openById("1egn6pnRd6mKMGuQxX_jtgwYDtkuMUv2QJItLdh7aIEs");
var target = SpreadsheetApp.openById("1egn6pnRd6mKMGuQxX_jtgwYDtkuMUv2QJItLdh7aIEs");
// Set Sheets
var source_sheet = source.getSheetByName("Participant_Registration");
var target_sheet = target.getSheetByName("Learning_Sessions_Attendance");
var rowIdx = source_sheet.getActiveRange().getRowIndex();
var rowValues = source_sheet.getRange(rowIdx,1,1,source_sheet.getLastRow()).getValues();
Logger.log(rowValues);
var destValues = [];
destValues.push(rowValues[0][0]);// copy data from col A to col A
destValues.push(rowValues[0][1]);//copy data from col B to col B
destValues.push(rowValues[0][2]);//copy data from col C to col C
destValues.push(rowValues[0][3]);//copy data from col D to col D
var dest=source.getSheets()[4];
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);//update destination sheet with selected values in the right order, the brackets are there to build the 2D array needed to write to a range
}
So I tried again and again. I have lots of examples but none seem to work.
Thanks so much.
Chandra
For that to happen automatically (one sheet's change updating another sheet), you will surely need an "event/trigger" to run a script whenever you change a cell. (that is the "onEdit()" function).
But since scripts are likely to fail sometimes (even when they are perfect, that's because of some Google issues), it's not guaranteed that the sheets will always contain the same data.
But, if I could suggest another way, do not let ID be optional. If that is a real ID (like the person ID card number), create another ID exclusively for working with the sheet.
I have edited your second sheet showing a suggestion of how to do it without using scripts. The only things you must be aware of are:
Do not create two people with the same ID.
You have to insert (only) the ID manually in the second sheet.
The VLOOKUP forumla will search for that ID in the first sheet and return the data in the same line. You can sort any sheet in whatever way you like. As long as you don't change people's IDs.
So, in sheet 2, use this in the First Name, Last Name and Email address:
=vlookup(A10,Participant_Registration!$A:$D,2,false)
=vlookup(A10,Participant_Registration!$A:$D,3,false)
=vlookup(A10,Participant_Registration!$A:$D,4,false)
Just extend this formula downwards
I hope this helps. I would avoid scripting for that at any cost. It would be my last resort. (Scripts also need to be changed if you want to rearrange your sheet, and if not, they might cause trouble, write over existing data...)
I also added a button (insert - drawing) and put a script in it (right button, click down arrow, "transfer? script" -- translated from Portuguese).
If you lock all four columns in sheet2 and lock the ID column in sheet 1, people will not be able to chang IDs and cause mess. They can edit people in sheet 1 and not change the formula in sheet2. Script is not affected by sorting or empty spaces (it adds the person in the first empty row it finds).
I added "named ranges" for the four column headers. (With named ranges, the script can refer to names instead of coordinates, which enables you to rearrange the sheet inserting and deleting columns, or moving them with CUT and paste - but the VLOOKUP formula will need manual update if you rearrange columns).
Here is the code: (it could get better if you manage to create dialog boxes and ask for the person's data inside that dialog, then you could lock everything - and you would need an edit button besides the add).
function AddPerson()
{
var S1Name = "Participant_Registration";
var S2Name = "Learning_Sessions_Attendance";
var ID1Name = "regID";
var ID2Name = "learnID";
//these vars are not used in this script
var FN1Name = "regFirstName";
var FN2Name = "learnFirstName";
var LN1Name = "regLastName";
var LN2Name = "learnLastName";
var Email1Name = "regEmail";
var Email2Name = "learnEmail";
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var Sheet1 = sSheet.getSheetByName(S1Name);
var Sheet2 = sSheet.getSheetByName(S2Name);
var ID1 = getRangeByName(sSheet, Sheet1.getName(), ID1Name);
var ID2 = getRangeByName(sSheet, Sheet2.getName(), ID2Name); Logger.log("ID2: " + ID2.getValue());
var Empty1 = getFirstEmpty(ID1);
var Empty2 = getFirstEmpty(ID2);
var Biggest1 = getBiggestID(ID1); Logger.log("Biggest 1: " + Biggest1);
var Biggest2 = getBiggestID(ID2); Logger.log("Biggest 2: " + Biggest2);
if (Biggest1 !== Biggest2)
Browser.msgBox("Warning: there are IDs in one sheet that are not in the other sheet");
var Biggest;
if (Biggest1 > Biggest2) Biggest = Biggest1;
else Biggest = Biggest2;
Biggest++;
Empty1.setValue(Biggest);
Empty2.setValue(Biggest);
}
function getFirstEmpty(Header)
{
while (Header.getValue() !== "")
{
Header = Header.offset(1,0);
}
return Header;
}
function getBiggestID(Header)
{
var Sheet = Header.getSheet();
var LastRow = Sheet.getLastRow();
var Values = Sheet.getRange(Header.getRow(), Header.getColumn(), LastRow - Header.getRow() + 1).getValues();
var len = Values.length;
var MaxID = 1;
for (var i = 0; i < len; i++)
{
var val = Number(Values[i]);
if (!isNaN(val) && val > MaxID)
MaxID = val;
}
return MaxID;
}
function getRangeByName(spreadSheet, sheetName, rangeName)
{
Logger.log("Trying range: " + "'" + sheetName + "'!" + rangeName);
return spreadSheet.getRangeByName("'" + sheetName + "'!" + rangeName);
}