Background
This code is apart of a library I'm developing for my company. It takes in anywhere from 3 to 5 arguments. All of the code functions properly. To be more specific, a user has data on a spreadsheet that they want copied somewhere else. The first function takes the data the user wants copied and puts it somewhere else on the same sheet in a spreadsheet. The second function takes the data and pastes it on a different sheet within the same spreadsheet. The third and fourth functions are the ones that I expect to be used most often. They copy and paste data from one spreadsheet to another spreadsheet. They are the more complex of the methods within this function. The reason there are two of them is because the format of the range can either be in array or string format. For example: if you wanted to paste data from cell A1 to cell B1, you could set copyRange = 'A1'
or copyRange = [1,1,1,1]
, and then set pasteRange = 'B1'
or pasteRange = [1,1]
.
A caveat though is that if the copyRange
is in array format, pasteRange
must also be in array format, and vice-versa. Same if either was in string format.
Another caveat that may not have been obvious is that copyRange
has four indexes, whereas pasteRange
only has two. This is because the setValues()
function that GAS uses, the size of the data array being copied must be the same size as the data array being pasted to. To avoid user error that the data arrays are not the same size, the third and fourth indexes of the copyRange
array are used in place of pasteRange
's third and fourth indexes in the getRange()
function. For visualization, it looks like this:
ss.getRange(pasteRange[0], pasteRange[1], copyRange[2], copyRange[3]).setValues(ss.getRange(copyRange[0], copyRange[1], copyRange[2], copyRange[3]).getValues())
My Request
I've attempted using objects on my own to improve it, but have had trouble implementing them properly. The convention I've followed to improve my code was from this answer, but have been unsuccessful so far in implementing it in this function specifically. Any assistance is appreciated, thank you.
My Code
//Functions that copy and paste values
function copyPasteValues(){
var function1 = function(sheet, copyRange, pasteRange){
let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet)
if(Array.isArray(copyRange) && Array.isArray(pasteRange)){
ss.getRange(pasteRange[0], pasteRange[1], copyRange[2], copyRange[3]).setValues(ss.getRange(copyRange[0], copyRange[1], copyRange[2], copyRange[3]).getValues())
//Should there be a typeof check for string here? (Throwing more errors)
} else{
ss.getRange(copyRange).copyTo(ss.getRange(pasteRange))
}
}
var function2 = function(sourceSheet, targetSheet, copyRange, pasteRange){
let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sourceSheet)
let sa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheet)
if(Array.isArray(copyRange) && Array.isArray(pasteRange)){
sa.getRange(pasteRange[0], pasteRange[1], copyRange[2], copyRange[3]).setValues(ss.getRange(copyRange[0], copyRange[1], copyRange[2], copyRange[3]).getValues())
} else{
ss.getRange(copyRange).copyTo(sa.getRange(pasteRange))
}
}
var function3 = function(sourceSheet, targetSheet, spreadsheetID, copyRange, pasteRange){
//Pushing data to another spreadsheet and pasting it to another
try{
let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sourceSheet)
let sa = SpreadsheetApp.openById(spreadsheetID).getSheetByName(targetSheet)
ss.getRange(copyRange).setValues(sa.getRange(pasteRange).getValues())
//Pulling data from another spreadsheet and pasting it
} catch(e){
if(e instanceof Error){
let ss = SpreadsheetApp.openById(spreadsheetID).getSheetByName(sourceSheet)
let sa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheet)
ss.getRange(copyRange).setValues(sa.getRange(pasteRange).getValues())
} else{
throw e
}
}
}
var function4 = function(sourceSheet, targetSheet, spreadsheetID, copyRange, pasteRange){
//Pushing data from another spreadsheet and pasting it to another
try{
if(arrayCheck(copyRange, pasteRange)){
let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sourceSheet)
let sa = SpreadsheetApp.openById(spreadsheetID).getSheetByName(targetSheet)
sa.getRange(pasteRange[0], pasteRange[1], copyRange[2], copyRange[3]).setValues(ss.getRange(copyRange[0], copyRange[1], copyRange[2], copyRange[3]).getValues())
}
//Pulling data from another spreadsheet and pasting it to another
} catch(e){
if(e instanceof Error){
let ss = SpreadsheetApp.openById(spreadsheetID).getSheetByName(sourceSheet)
let sa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheet)
sa.getRange(pasteRange[0], pasteRange[1], copyRange[2], copyRange[3]).setValues(ss.getRange(copyRange[0], copyRange[1], copyRange[2], copyRange[3]).getValues())
} else{
throw e
}
}
}
try{
if(arguments.length === 3){
function1(arguments[0], arguments[1], arguments[2])
} else if(arguments.length === 4){
function2(arguments[0], arguments[1], arguments[2], arguments[3])
} else if(arguments.length === 5){
if(Array.isArray(arguments[3]) && Array.isArray(arguments[4])){
function4(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4])
} else{
function3(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4])
}
}
} catch(e){
Logger.log(e)
}
}
Other Relevant Functions
function arrayCheck(copyRange, pasteRange){
if(!Array.isArray(copyRange) || !Array.isArray(pasteRange)){
throw 'Ranges must be in array format'
} else{
return true
}
}
Updated Version (2/7/2023)
Here is an even more updated one that I feel is more legible and understandable, as the previous updated one was just brute forcing it based on argument length. Most of the checks are going to be used for error handling once I feel comfortable with where the program currently sits
function copyValues(){
try{
const options = {
copy: arguments[0],
paste: arguments[1],
source: arguments[2]
}
if(arguments.length >= 4){
options.target = arguments[3]
if(arguments.length >= 5){
options.ss_ID = arguments[4]
}
}
if(arrayCheck(options.copy, options.paste)){
switch(true){
case arguments.length === 3:
ss = spreadsheet.getSheetByName(options.source)
ss.getRange(options.paste[0], options.paste[1], options.copy[2], options.copy[3]).setValues(ss.getRange(options.copy[0], options.copy[1], options.copy[2], options.copy[3]).getValues())
break;
case arguments.length === 4:
arrayPaste(options.copy, options.paste, spreadsheet.getSheetByName(options.source), spreadsheet.getSheetByName(options.target))
break;
case arguments.length === 5:
let obj = spreadsheetCheck(options.source, options.target, options.ss_ID)
arrayPaste(options.copy, options.paste, obj.ss, obj.sa)
break;
}
} else if(stringCheck(options.copy, options.paste)){
switch(true){
case arguments.length === 3:
ss = spreadsheet.getSheetByName(options.source)
ss.getRange(options.paste).setValues(ss.getRange(options.copy).getValues())
break;
case arguments.length === 4:
stringPaste(options.copy, options.paste, spreadsheet.getSheetByName(options.source), spreadsheet.getSheetByName(options.target))
break;
case arguments.length === 5:
let obj = spreadsheetCheck(options.source, options.target, options.ss_ID)
stringPaste(options.copy, options.paste, obj.ss, obj.sa)
}
}
} catch(e){
Logger.log(e)
}
function spreadsheetCheck(source, target, ss_ID){
let ss, sa
switch(true){
case SpreadsheetApp.openById(ss_ID).getSheetByName(source) === null:
ss = spreadsheet.getSheetByName(source)
sa = SpreadsheetApp.openById(ss_ID).getSheetByName(target)
break;
case SpreadsheetApp.openById(ss_ID).getSheetByName(target) === null:
ss = SpreadsheetApp.openById(ss_ID).getSheetByName(source)
sa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(target)
break;
}
return {ss, sa}
}
function arrayPaste(copy, paste, ss, sa){
sa.getRange(paste[0], paste[1], copy[2], copy[3]).setValues(ss.getRange(copy[0], copy[1], copy[2], copy[3]).getValues())
}
function stringPaste(copy, paste, ss, sa){
sa.getRange(paste).setValues(ss.getRange(copy).getValues())
}
function arrayCheck(copy, paste){
if(Array.isArray(copy) && Array.isArray(paste)){
return true
} else{
return false
}
}
function stringCheck(copy, paste){
if(String(copy) === copy && String(paste) === paste){
return true
} else{
return false
}
}
}
function5()
andfunction6()
, yet those do not appear to be defined. Should those befunction3()
andfunction4()
? \$\endgroup\$