Solo comencé a usar Apps Script durante unos meses y, por lo general, puedo averiguar por qué me da mensajes de error. Pero este último me tiene completamente perplejo y no puedo encontrar a nadie que haya preguntado algo similar aquí.
Tengo un código muy simple que recupera datos de una hoja de cálculo, los recorre para eliminar algunos valores antes de volver a pegarlos en otra hoja. Sin embargo, el bucle sigue arrojando el error "Error de tipo: no se puede leer la propiedad '0' de indefinido".
Después de investigar un poco, creo que encontré el problema: la matriz que extraje de la hoja tiene 3 filas menos de lo que debería ser.
Entonces var refArray = sheet.getRange("F5:F").getValues(); tiene la longitud 65 a pesar de que hay 68 filas en la hoja.
Pero lo que realmente me desconcierta es que cuando ejecuto var len = refArray.length , ¡devuelve 68! Entonces, a falta de una mejor jerga, esto confunde mi ciclo ya que no puede encontrar los últimos 3 elementos y obtengo el error anterior (al menos eso es lo que pienso).
Intenté extraer los datos usando var refArray = sheet.getRange(1,6,sheet.getMaxRows(),1) pero esto también salta las últimas 3 filas. No hay ninguna razón en particular por la que omitiría estas filas y, a veces, solo omite 2, por lo que no creo que el problema se encuentre dentro de mis datos...
Puedo compartir una maqueta de mi hoja y secuencia de comandos si ayuda, ¡no tengo idea de por qué está haciendo esto o cómo solucionarlo!
Gracias ya a todos.
EDITAR
Es posible que haya estado ladrando al árbol equivocado, ya que solo intenté replicar el problema en otra hoja y la matriz parecía haberse extraído correctamente, pero luego apareció el error nuevamente cuando comenzó a repetirse. Como dije, solo estoy incursionando en Apps Script, por lo que mis bucles son muy básicos. Solo agregaré la secuencia completa a continuación y veré si alguien puede detectar el error:
var s = SpreadsheetApp.getActive(); var sheet = s.getSheetByName("Sheet1"); var sheet2 = s.getSheetByName("Sheet2"); function test() { // get archive Array var archiveArray = sheet2.getRange("A3:A").getValues(); console.log("Array Check: "+archiveArray[0][0]); // get ref Array to loop through var refArray = sheet.getRange("F2:F").getValues(); console.log("Array Check: "+refArray[0][0]); // length 29 var len = refArray.length; console.log(len); // length 29 for ( var l = len - 1; l > 0; l--){ for( var a = 0; a < archiveArray.length; a++) { if ( archiveArray[a][0] == refArray[l][0] ) { refArray.splice(l,1); // remove all duplicates } } } console.log("New array:"+refArray);Propondría usar el método array.includes() y crear una nueva matriz en lugar de cambiar una existente:
Con un bucle:
var archiveArray = ['a', 'b', 'c', 'd']; var refArray = ['a', 'b', 'e', 'f']; var new_refArray = []; for (var val of refArray) { if (!archiveArray.includes(val)) new_refArray.push(val) } console.log(new_refArray); // output [ 'e', 'f' ]O con un filtro:
var archiveArray = ['a', 'b', 'c', 'd']; var refArray = ['a', 'b', 'e', 'f']; var new_refArray = refArray.filter(val => !archiveArray.includes(val)); console.log(new_refArray); // output [ 'e', 'f' ]El código final puede ser así:
var s = SpreadsheetApp.getActive(); var sheet = s.getSheetByName("Sheet1"); var sheet2 = s.getSheetByName("Sheet2"); function test() { var archiveArray = sheet2.getRange("A3:A").getValues() .flat().filter(String); // convert 2D into 1D and remove empty elements var refArray = sheet.getRange("F2:F").getValues() .flat().filter(String); // convert 2D into 1D and remove empty elements var new_refArray = refArray.filter(val => !archiveArray.includes(val)); console.log(new_refArray); }Nota: si desea volver a pegar la matriz de resultados en la hoja, debe ser una matriz 2D. Puede convertir la matriz plana en una matriz 2D de esta manera:
new_refArray = new_refArray.map(x => [x]); // [a,b,c] --> [[a],[b],[c]]