I have a script that works like copy paste with Index Match
of entry
and database
sheet. It works perfectly if entrysheet C7:I7
has text value but not work when its date 14.11.2024
has tried the Utilities.formatDate
but not help.
What the script do
Check if an value in row 4 already appears in "database"
if yes, then update the value in Column B
if no, then append the row 4 and row 7 values to "database"
Can someone tell me where I'm making a mistake?
function CopyEntry2Db() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var entrySheet = ss.getSheetByName("entry")
var dbSheet = ss.getSheetByName("database")
// get Entry sheet row 4 and 7 and flatten to 1D arrays
var entryRow4 = entrySheet.getRange("C7:I7").getDisplayValues().flat()
//var entryRow4 = Utilities.formatDate(entryRow, "GMT+1", "dd/MM/yyyy");
var entryRow7 = entrySheet.getRange("C4:I4").getValues().flat()
// Logger.log(entryRow4) // DEBUG
// Logger.log(entryRow7) // DEBUG
// get database sheet columns A and B
var dbSheetLR = dbSheet.getLastRow()
// Logger.log("DEBUG: Last row of data on database = "+dbSheetLR+", so number of rows of data exlcuding header = "+(+dbSheetLR-1))
var dbColAValues = dbSheet.getRange(2,1,dbSheetLR-1,1).getValues().flat()
// Logger.log(dbColAValues) // DEBUG
var dbColBValues = dbSheet.getRange(2,2,dbSheetLR-1,1).getValues().flat()
// Logger.log(dbColBValues) // DEBUG
// create a temporary array to hold values to add to database
var tempArray = []
// loop though the row4 entry values to find a match on db column A
// if indexOf return value = -1, then no match, so add entry value to db
// if indexOf returns value <. -1, then value is array index
for (var i=0;i<entryRow4.length;i++){
var idxMatch = dbColAValues.indexOf(entryRow4[i]);
//Logger.log("DEBUG: The entry value = "+entryRow4[i]+", index match = "+idxMatch)
if (idxMatch == -1 ){
// no match, so add entry values to tempArray
tempArray.push([entryRow4[i],entryRow7[i]])
}else{
// Logger.log("matches value = the index = "+idxMatch+""+", Column A = "+entryRow4[i]+", new value = "+entryRow7[i])
// match, so update dbColB value
dbColBValues[i] = entryRow7[i]
}
}
// Logger.log(tempArray) // DEBUG
// Logger.log(dbColBValues) // DEBUG
// convert dbColBValues to 2d array
var nArr = [];
while(dbColBValues.length > 0) {
nArr.push(dbColBValues.splice(0,1));
}
// Logger.log("DEBUG: the Column B range = "+dbSheet.getRange(2,2,nArr.length,1).getA1Notation())
// update dbColBValues
dbSheet.getRange(2,2,nArr.length,1).setValues(nArr)
// copy new entry values to database Sheet
// Logger.log("the target range = "+dbSheet.getRange(dbSheetLR+1,1,tempArray.length,2).getA1Notation())
dbSheet.getRange(dbSheetLR+1,1,tempArray.length,2).setValues(tempArray)
}
Considering that your date values have a uniform format, the primary issue with your code is that you are using a getDisplayValues()
to turn the values in a string on the line:
var entryRow4 = entrySheet.getRange("C7:I7").getDisplayValues().flat()
To an object using the getValues()
on the line:
var dbColAValues = dbSheet.getRange(2,1,dbSheetLR-1,1).getValues().flat()
which causes a major issue with finding its exact values, for easier identification of its comparison, they must be in the same format.
Here's the complete modified code:
function CopyEntry2Db() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var entrySheet = ss.getSheetByName("entry")
var dbSheet = ss.getSheetByName("database")
var entryRow4 = entrySheet.getRange("C7:I7").getDisplayValues().flat()
var entryRow7 = entrySheet.getRange("C4:I4").getValues().flat()
var dbSheetLR = dbSheet.getLastRow()
var dbColAValues = dbSheet.getRange(2,1,dbSheetLR-1,1).getDisplayValues().flat()
var dbColBValues = dbSheet.getRange(2,2,dbSheetLR-1,1).getValues().flat()
var tempArray = []
for (var i=0;i<entryRow4.length;i++){
var idxMatch = dbColAValues.indexOf(entryRow4[i]);
if (idxMatch == -1 ){
tempArray.push([entryRow4[i],entryRow7[i]])
}else{
dbColBValues[idxMatch] = entryRow7[i]
}
}
var nArr = [];
while(dbColBValues.length > 0) {
nArr.push(dbColBValues.splice(0,1));
}
dbSheet.getRange(2,2,nArr.length,1).setValues(nArr)
dbSheet.getRange(dbSheetLR+1,1,tempArray.length,2).setValues(tempArray)
}
I also have seen some issues with the indexing on the else
statement instead of [i]
I replace it with the variable [idxMatch]
Sample Output:
References: