https://i.stack.imgur.com/7VAJk.png
Quiero copiar datos de la hoja "dB" A5:A29 y pegarlos en la columna correcta. así que uso el script para encontrar la columna correcta.
allí el rango B2: CX2 tiene un valor de 0 (no correcto) o 1 (correcto), así que uso 'para' y 'si' ¡PERO! Es demasiado retraso!! uso console.time() y obtengo 25909ms (valor timecheck2) !!!
por favor, ayúdame.....
aquí está mi código
function save(){ var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('dB'); console.time("timecheck1"); //find last row var copyrangeO = sheet.getRange(5,1,25,1).getValues(); var lastrowO = copyrangeO.filter(String).length; var copyrange = sheet.getRange(5,1,lastrowO,1); console.timeEnd("timecheck1"); //my dB data start "B2". var cv = 1; //find correct value(1). B2 ~ CX2 (#100) console.time("timecheck2"); for (var i=2; i<101;i++){ if(sheet.getRange(2,i).getValue()===1){ cv = i; } } console.timeEnd("timecheck2"); //if data isn't correct, cv===1. so error msg print. console.time("timecheck3"); if(cv ===1){ Browser.msgBox("ERROR") }else { //data copy and paste. var columnToCheck = sheet.getRange(4,cv,1000).getValues(); var lastrow = getLastRowSpecial(columnToCheck); var pasterange = sheet.getRange(lastrow+4,cv); copyrange.copyTo(pasterange, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); Browser.msgBox(lastrowO + " saved!"); } console.timeEnd("timecheck3"); }La función pasará la mayor parte de su tiempo en el bucle for porque repite la llamada Range.getValue() muchas veces. Puede acelerar un poco las cosas obteniendo todos los valores con una llamada a Range.getValues() , como esta:
let cv = 1; console.time("timecheck2"); sheet.getRange('B2:B100').getValues().flat() .some((value, index) => (cv = 2 + index) && value === 1); console.timeEnd("timecheck2"); Tenga en cuenta que esta no es la forma más limpia de encontrar cv , pero debería ayudar a ilustrar por qué tiene un problema de rendimiento. Es posible que desee hacer una reescritura completa del código, utilizando el estilo declarativo en lugar del imperativo.
Si entiendo su situación correctamente, desea encontrar la celda en B2:CX2 en la que el valor es 1 , pero el script está tardando demasiado en hacerlo.
El problema aquí es que está utilizando getRange y getValue en un bucle ( sheet.getRange(2,i).getValue()===1 ). Esto aumenta considerablemente la cantidad de llamadas al servicio Hojas de cálculo, lo que ralentiza su secuencia de comandos, como puede ver en Minimizar llamadas a otros servicios .
En ese caso, te sugiero hacer lo siguiente:
1 .Para hacer eso, reemplace esto:
var cv = 1; //find correct value(1). B2 ~ CX2 (#100) console.time("timecheck2"); for (var i=2; i<101;i++){ if(sheet.getRange(2,i).getValue()===1){ cv = i; } }Con este:
var ROW_INDEX = 2; var FIRST_COLUMN = 2; // Column B var LAST_COLUMN = 102; // Column CX var columnValues = sheet.getRange(ROW_INDEX, FIRST_COLUMN, 1, LAST_COLUMN-FIRST_COLUMN+1).getValues()[0]; var cv = columnValues.findIndex(columnValue => columnValue === 1) + FIRST_COLUMN; Si no hay ninguna celda en el rango con el valor 1 , findIndex devuelve -1 que, sumado a FIRST_COLUMN , da como resultado 1 . Eso es apropiado para su script actual, pero no funcionará si FIRST_COLUMN deja de ser 2 , así que tenga cuidado con esto (cambie la condición if(cv ===1){ a algo menos estricto, o no asigne el resultado valor a cv si findIndex devuelve -1 ).
Prueba esto:
No sé lo que está haciendo en el guardado porque no proporcionó el código de la función auxiliar.
function save(){ var ss = SpreadsheetApp.getActiveSpreadsheet(); var sh = ss.getSheetByName('dB'); var vs0 = sh.getRange(5,1,25,1).getValues(); var lr0 = vs0.filter(String).length; var crg = sh.getRange(5,1,lr0,1); var cv = 1; const vs1 = sh.getRange(2,2,1,99).getValues().forEach((c,i) => { if(c == 1)cv = i + 2 }) if(cv == 1){ Browser.msgBox("ERROR") }else { var vs2 = sh.getRange(4,cv,1000).getValues(); var lastrow = getLastRowSpecial(vs2); var drg = sh.getRange(lastrow+4,cv); crg.copyTo(drg, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); Browser.msgBox(lr0 + " saved!"); } }