Como leer una hoja de calculo con Google Apps Scripts


Artículo perteneciente a la introducción de Google Apps Script
Artículo referente a como usar Google Apps Script en spreadsheets

Una de las aplicaciones más usuales (y útiles) de GAS es poder obtener información de una hoja de cálculo que tengamos compartida en Drive.

Hay dos maneras de obtener la información de una hoja de cálculo de Drive:

- Leyendo casilla a casilla: Útil si hay poca información, extremadamente lento si hay mucha.
- Leyendo fila a fila : Bastante más rápido cuando el volumen de información es elevado dado que se hacen menos accesos a disco.

Dado que para mi la mejor manera de aprender es mediante los ejemplos, no os explicaré como se lee un fichero, os adjunto dos códigos muy sencillos e intentad entenderlo vosotros. Ambos hacen lo mismo, recogen todos los datos de una hoja de calculo y lo ponen dentro de un string (sin sentido por separado, pero con bastante utilidad si esta funcionalidad la tenemos en un código más grande).

Probad a copiar este código y ejecutar las funciones Lento y Rapido.

function onOpen() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [
    { name : "Lento",  functionName : "Lento"},
    { name : "Rapido",  functionName : "Rapido"}
 
  ];
  spreadsheet.addMenu("Lord Pakus Scripts", entries);
};

function Lento()
{
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var rows = sheet.getDataRange();
  var numCols = rows.getNumColumns();
  var numRows = rows.getNumRows();
  var string ="";

  for (var i = 0 ; i < numRows; ++i )
    for(var j = 0 ; j < numCols ; j++)
      string += sheet.getRange(i+1, j+1).getValue() + " ";
}


function Rapido()
{
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadsheet.getActiveSheet();
    var rows = sheet.getDataRange();
    var values = rows.getValues();
    var numCols = rows.getNumColumns();
    var numRows = rows.getNumRows();
    var string ="";
 
    for(var i = 0 ;i < numRows ; ++i)
    {
      var row = values[i];
      for(var j = 0 ; j < numCols ; ++j)
      {
        string += row[j] + " ";
      }
    }
}

Cuánto más rápido? Cuánto más lento? Una forma fácil de verlo es mediante la opción de Ver->Transcripción de la Ejecución, que no hace más que un log de las cosas más importante de la ejecución y al final de todo dice cuanto ha tardado la última ejecución

Transcripción de ejecución

Probad ambas funciones y mirad sus trazas de ejecución. Veréis que la función lenta tarda más y genera logs más extensos ( dado que tiene que hacer mas accesos a fichero ) mientras que la rápida hace un log mucho más discreto y los tiempos de ejecución son brutalmente mejores. Depende del tamaño de los datos que tengamos en esa hoja de cálculo, del número de filas y de columnas y de como están dispuestas, pero para tamaños medios-grandes de información podríamos hablar de mejores de rendimiento de x10 o x15, así que vale la pena que os acostumbréis desde el principio a leer ficheros de forma óptima.

Para cualquier duda ya sabéis que estoy a vuestra disposición.

Nos vemos

NOTA: Si te ha gustado este tutorial tal vez también te interese el tutorial sobre las diferentes maneras de obtener una fila de un spreadsheet con Google Apps Script

71 comentarios:

  1. Hola,
    tengo una cosa que realizar y no se como realizarla, te explico,
    por un lado mediante php obtengo los del formulario de contacto y guardo los datos del usuario en un sheet. por otro lado en google adwords cada 7 días o cada día realizare un reporte de click_performance_report, y lo metere en un sheet. Lo que quiero hacer es lo siguiente:

    Antes de volcar todo el reporte a la hoja de datos lo que quiero hacer es buscar el gclid del reporte buscarlo por el sheet del usuario que obtengo el gclid también, si el gclid del reporte es igual al gclid del cliente añado a esa fila los valores del reporte correspondiente al gclid del reporte, y así succesivamente.

    No se si me he explicado, no se como realizar la lectura de un cambo de un sheet y compararlo con otro campo de otro sheet y añadir los valores.

    Espero que puedas ayudarme.

    PD:gran aporte pero como ejecutas las funciones?

    Saludos

    ResponderEliminar
    Respuestas
    1. Desconozco lo que es el gclid así que no te puedo ayudar mucho, si me lo explicas intentaré echarte un cable.
      Las funciones se pueden ejecutar desde la ventana de código. Tal vez este link te pueda ayudar: http://googleappscriptsweb.blogspot.com.es/2015/02/hola-mundo-google-apps-script.html

      Eliminar
  2. Cómo podría crear un fomulario de consulta usando Google Script

    Estimado, tengo una planilla sheets con las notas de mis alumnos:
    Id-Apellido-Nombre-Nota 1-Nota 2 - Nota 3- Promedio Final

    Quisiera crear un scritp público para que los padres de los alumnos, a través de un Id puedan consultar las calificaciones de sus hijos.
    No soy programador (es obvio) solo quiero mejorar la comunicación con las familias (los alumnos, no siempre cuentan la verdad de las calificaciones a sus padres)

    Desde ya muchas gracias.

    ResponderEliminar
    Respuestas
    1. Lo mejor que puedes hacer es una web en la que se pueda ingresar el id (o bien poner el id como parametro de la url) .

      Con ese id puedes filtrar la información que necesitas y generar una pequeña web enseñando esa información.

      Aquí te dejo unos links:
      http://googleappscriptsweb.blogspot.com/2015/03/como-crear-una-web-dinamica-con-google.html

      http://googleappscriptsweb.blogspot.com/2017/07/como-leer-parametros-de-la-url-con.html

      Si no has programado nunca puede ser complicado. Dime si te sirven los links

      Nos vemos

      Eliminar
  3. Muchas Gracias LordPakus por responder. He probado con la web dinámica y obtuve la 1° Columna de Id
    Luego probe con la lectura de parámetros de la url, pero no logré hacerla funcionar. No comprendo donde está el parámetro que debo cambiar.
    De todas formas te agradezco mucho. Saludos cordiales
    Augusto

    ResponderEliminar
    Respuestas
    1. Hola Augusto,

      Es que lo que quieres hacer no es fácil y es complicado explicarlo por aquí.

      Si tienes dudas puntuales hazmelas llegar en los comentarios ( con código a ser posible) y te las intento responder.

      Suerte

      Eliminar
  4. Podría ponerme en contacto a través de un email privado para que me realices un presupuesto de la aplicación? mi correo es augustoburgos@gmail.com

    ResponderEliminar
  5. Hola
    Entiendo que éstos scripts son para documentos activos.
    Como puedo hacer para de una doc.activo activar otro documento, modificarlo y volver al anterior
    Hice lo siguientes:
    ....
    function Leo_documento(wID)
    {
    var sheet = SpreadsheetApp.open(wID)
    }
    No funciona y no sé como hacerlo
    Gracias

    ResponderEliminar
    Respuestas
    1. Tendrias que vigilar el tema permisos.

      SpreadsheetApp.open te abrirá el spreadsheet que tu le pases
      Tienes tres variantes para el open:
      SpreadsheetApp.open(file)
      SpreadsheetApp.openById(id)
      SpreadsheetApp.openByUrl(url)

      Una vez tengas el spreadsheet tendrás que seleccionar el sheet que tu quieras.

      Espero que esto te sirva, dimelo sino.

      Nos vemos

      Eliminar
    2. Gracias LordPakus
      Los permisos están ok ya que estoy accediendo
      Hice lo siguiente:
      function Leo_PLANILLAdeCOMISION(ID_COMISION)
      {
      Logger.log("1")
      pp = SpreadsheetApp.openById(ID_COMISION)
      Logger.log("2")
      ...
      para ver si iba ejecutando los pasos, pero
      muestra el 1 y no me muestra el 2 por lo
      que deduzco que no lo hizo.
      No entiendo muy bien porque.
      Gracias otra vez

      Eliminar
  6. prueba con punto y coma al final de las lineas y var en la definición de las variables
    Logger.log("1");
    var pp = SpreadsheetApp.openById(ID_COMISION);
    Logger.log("2");

    El id tiene formato de numeros y letras. Es la parte final de la url.

    Ya me diras como te va

    Nos vemos

    ResponderEliminar
  7. Otra vez gracias por molestarte. Hice pruebas con las 3 opciones.
    La única que pude hacer funcionar es con openByUrl.
    Entonces:
    1) A que se refiere cuando dice openById(id) y que open(file)?
    2) Como hago para visualizar la 1º hoja del documento?
    Gracias
    function PRUEBA_1()
    {
    var ID_COMISION = ("https://docs.google.com/spreadsheets/d/1CrlfxcV-zb4SJjLMIPmtGfV5BFXsLPqaKkXiZBI8M_8/edit#gid=0");
    Logger.log("1");
    var pp = SpreadsheetApp.openByUrl(ID_COMISION);
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadsheet.getActiveSheet()

    Logger.log("2");
    }

    ResponderEliminar
  8. En este caso concreto el id seria "1CrlfxcV-zb4SJjLMIPmtGfV5BFXsLPqaKkXiZBI8M_8", por lo que el openById con este string deberia funcionarte también.

    El open(file) funciona con un objeto de tipo file (el que puedes obtener de DriveApp por ejemplo)

    Son diferentes maneras de hacer lo mismo, como Google Apps Script está montado en módulos a veces es más fácil tener acceso de una manera u otra.

    En cuanto a la visualizacion, que quieres decir? que se marque como activa la primera hoja?
    En principio si pillas un rango cualquiera (getRange("A1") por ejemplo) y le haces un setActive deberias tener suficiente.

    Ya me contaras

    ResponderEliminar
  9. Hola LORDPAKUS
    FUNCIONA PERFECTO SI LO HAGO EJECUTANDO EL Código.gs
    COMO VERÁS PUSE UNA FUNCIÓN QUE SE EJECUTA AL REALIZAR UN CAMBIO.
    BUENO, EN ESE CASO SE CORTA DESPUES EL Logger 2
    LO QUE SIGNIFICA QUE
    var pp = SpreadsheetApp.openById(ID_COMISION);
    NO LA RECONOCE.
    ¿ALGUNA RESPUESTA?
    Y TAMBIÉN LE PUSE
    sheet.showSheet() (AUNQUE LA ANULÉ PORQUE SE CORTA)
    LA IDEA ERA VER EL DOCUMENTO
    GRACIAS...TE DEBO UN ASADO
    ------------------------------------------------

    function onEdit(e)
    {
    PRUEBA_1()
    }

    function PRUEBA_1()
    {
    Logger.log("1");
    var ID_COMISION = ("1CrlfxcV-zb4SJjLMIPmtGfV5BFXsLPqaKkXiZBI8M_8");
    Logger.log("2");
    var pp = SpreadsheetApp.openById(ID_COMISION);
    Logger.log("3");
    var sheet = pp.getActiveSheet();
    Logger.log("4");
    // sheet.showSheet()
    var wDato_1 = sheet.getRange("H9").getValue();
    var wDato_2 = sheet.getRange("C14").getValue();
    Logger.log("wDato_1: " + wDato_1);
    Logger.log("wDato_2: " + wDato_2);
    }

    ResponderEliminar
  10. Vale, ya veo tu problema.

    Estas abriendo otro documento desde el onEdit, eso está totalmente prohibido.

    Es por un tema de permisos, lo que quieres no se puede hacer.

    Es por ello que te da problemas en el open.

    Ya me explicaras como te va

    ResponderEliminar
  11. SI, CLARO.
    SE TRATA DE UNA ACTUALIZACIÓN.
    EN UN EXCEL GRABAN LOS DATOS QUE LUEGO ACTUALIZAN
    LOS DOCUMENTOS.
    ENTONCES, ME DECIS QUE ES 'IMPOSIBLE' POR UN TEMA
    DE PERMISOS.
    PERO PORQUE PUEDO HACERLO DESDE DE EL Código.gs?
    Y...COMO HAGO PARA VISUALIZARLO?
    GRACIAS

    ResponderEliminar
    Respuestas
    1. Ufff... fácil no es.

      La mejor manera es que cada cierto tiempo vayas copiando el contenido del fichero en tu spreadsheet (con un trigger de tiempo): http://googleappscriptsweb.blogspot.com/2015/11/como-ejecutar-automaticamente-scripts.html

      Esto es por que los chronotriggers no tiene problemas de permisos y pueden acceder a donde quieres.

      Despues en el onEdit de tu spreadsheet deberias acceder a la copia que tienes en tu mismo spreadsheet.

      No es fácil, la verdad, pero me ha tocado hacerlo más de una vez

      Nos vemos

      Eliminar
  12. Como verás soy muy nuevo en todo esto pero VOY APRENDIENDO...GRACIAS A VOS.
    Otra cosa que no logro encontrar es como continuar una linea abajo. En otros
    lenguajes lo hacía con & _ pero acá no pude encontrarlo.

    ResponderEliminar
    Respuestas
    1. No te acabo de entender... linea abajo....

      Si estas imprimiendo texto con un '/n', es esto?

      Eliminar
  13. Hola LORDPAKUS, recién veo que sos español. El asado entonces cuando vengas x Bs.As. y mirá que ahora es como 'oro en polvo'
    Sabés que desde el Código.gs puede actualizar un documento en otra carpeta.
    Sólo no puedo hacerlo llamandolo desde una funcion dentro el onEdit(e).
    Muy bien no entiendo porque aparentemente nada tiene que ver con los permisos.
    ME SOBREPASA
    Gracias

    ResponderEliminar
    Respuestas
    1. Si, soy del otro lado del charco , lo del asado si no es por amazon lo veo complicado :D

      Exacto, desde cualquier sitio puedes modificar cualquier cosa, pero desde el onEdit todo queda restringido al mismo documento.

      Piensalo de otra manera, una persona que edite un documento no está aceptando nada de permisos de ejecucion, así que no puede hacer según que.

      Sino, seria un peligro que cualquier persona que editara se le permitiera acceder a cualquier sitio sin aceptar permisos de ejecución.

      Tranquilo, que a todos nos a sobrepasado, hasta que no lo ves, cuesta de entender.

      Paciencia

      Eliminar
  14. REGIO. Gracias. Como uds.dice 'vale'....recién cuando pusiste eso me di cuenta...que pavo soy

    ResponderEliminar
    Respuestas
    1. jajaja, poca importancia tendrá de donde venimos o adonde vamos.

      Me alegra que vayas aprendiendo con este blog

      Nos vemos

      Eliminar
  15. Hola LORDPAKUS.
    Puedo hacerte mas preguntas?

    ResponderEliminar
  16. VALE
    1) Estoy viendo la función onEdit(e)
    Esta se ejecuta una vez cambiado el valor de la celda en una Hoja de Cálculo.
    Como logro obtener el dato (wDato) al posicionar el cursor en una celda
    (wRo,wCo)
    Lo que en otros lenguajes podria ser getFocus
    2) Esta ya te la hice y recién veo tu respuesta: como continuar la linea
    en el Codigo.gs
    3) Como agregar otro arghivo .gs
    4) Si puedo colocar en ese nuevos archivo funciones que serán llamadas
    desde el .gs
    Gracias
    En serio te debo un montón
    Sos de gran ayuda

    ResponderEliminar
    Respuestas
    1. REGIO :)

      1. Respuesta rápida. No puedes. La única manera de hacer algo parecido seria montando una web que mostrará el contenido del spreadsheet y entonces pillar el focus con javascript. Realmente, ahora mismo, te veo algo lejos de conseguirlo.
      2. No puedes.(lo siento :))
      3. Archivo, nuevo, gs
      4. Sip. Puedes tener 800 mil ficheros ( por decir algo), pero da igual, todo es accesible desde todos sitios. Solo es un tema organizativo tuyo.

      Para eso estamos (el asado cabe en sobre de correos? :) )

      Nos vemos

      Eliminar
  17. JA...sabés cuanto es la inflación acá? va un 57% y sigue subiendo
    Se va todo a la merda. Se pudrió todo.
    Los medicamentos es imposible comprar. La leche (y mirá que en otra
    época la mandabamos a España) NO EXISTE en las góndolas.
    Todo mal.
    Que le vamos a hacer.
    Pero te la debo.
    Acabo de mandár un msje a amigos que tengo en las prov.
    de Chaco y COrrientes (que están inundadas) para si necesitan
    puedo hacerme cargo de un par de niños hasta superar
    esta crisis. Pero no sigo porque me están cayendo las
    lagrimas. Nunca vivimos algo parecido.
    Realmente es una desgracia haber ido al fondo.
    No sigo porque realmente me siento mal.

    ResponderEliminar
    Respuestas
    1. Dioses, sabía que el tema estaba mal pero no que estuviera tan mal.

      En mi experiencia todo acaba pasando ( lo bueno y lo malo) , paciencia y fuerza.

      Eliminar
  18. Pero no me dijiste como pongo otro fichero (uno aunque sea)
    Con esto (aprendiendo) me saco un poco de éste desastre.

    ResponderEliminar
    Respuestas
    1. No te entiendo, si que te lo he dicho. Archivo > Nuevo > Archivo de secuencia de comandos.

      Mejor así?

      Eliminar
  19. No lo ví. Gracias
    Si...estamos realmente mal. Muy pero muy mal
    Acá muchos creian que pidiendo prestamo ibamos a salir adelante.
    y no se dan cuenta que de la única manera es creando trabajo.
    Cuando piden plata, A ALGUIEN SE LE PEGA...después se van y
    te dejan el agujero. Y...los MACRI SON LA MAFIA.
    Pero esto es hablar de política y este no es el lugar
    Otra vez gracias, e igual tenés un asadito en tu haber.
    JC

    ResponderEliminar
  20. Hola LordPakus. Otra vez preguntando.
    Sigo consistiendo una Spreadsheet con muchos datos.
    Todo va funcionando; pero noto que se queda sin memoria.
    Es posible? Donde puedo leer algo sobre como liberar memoria
    Gracias LordPakus
    Noticias sobre Argentina: seguimos cayendo. Es impresionante

    ResponderEliminar
    Respuestas
    1. Liberar memoria?

      "noto que se queda sin memoria": Como?

      El procesador que mueve el script esta en un servidor de google, no corre en tu PC. Hasta donde yo se no hay manera de liberar memoria por que ya lo hace el mismo lenguaje cuando una variable ya no es necesaria.

      Truco? Funciones pequeñas y reaprovechar el código todo lo posible. Con esto le daras margen al sistema para ir limpiando lo que ya no se use.

      De todas maneras, lo más normal es que tengas problemas de tiempo de ejecución ( que nada tiene que ver con la memoria ), y ahi si que hay trucos para hacer que vaya más rapido, pero milagros pocos.

      Ya me explicaras

      Eliminar
    2. Estoy definiendo las variables al principio; entonces debo definirlas a medida que las uso?

      Eliminar
    3. continuación del anterior....
      es decir en cada script

      Eliminar
    4. Mi consejo es que lo separes todo en funciones pequeñas.
      Y si, desdeluego las funciones deberian contener solo las variables que usen.
      Como consejo general intenta siempre que haya el mínimo de distancia entre la declaracion de una variable y su uso.

      Reducir el scope de las variables ayuda siempre a tener el código más limpio y a usar el mínimo de memoria.

      Eliminar
  21. Saludos estoy buscando la mejor práctica para manejar datos de diferrdife tablas que se relacionen entre sí hasta ahora sí tengo una tabla que a su vez se relaciona con otra obtengo la data y la cargo en un array que luego combino en otro para obtener los datos relacionados que necesito pero me es un poco confuso manejar el código o hacer algún cambio, sabes si hay una forma mejor?

    ResponderEliminar
    Respuestas
    1. Asi sin más, es complejo aconsejarte pero yo me inclinaria por el hecho de usar objetos.

      Cuando las cosas se complican utilizar un array de objects (new Object()) e ir insertando los datos procesados en cada object acostumbra a ayudar.

      Si te hace falta más ayuda dilo

      Nos vemos

      Eliminar
    2. Hola por el momento resolvi con los arrays, cargando la data una sola vez al iniciar el sistema y llamando al array cargado cada vez que fuera necesario. me puedes pasar donde puedo encontrar mas informacion de los object? no he trabajado con ellos aun.

      Eliminar
    3. Basicamente lo de los objects es lo siguiente:
      var user = new Object();
      user.edad = 54;
      user.nombre = "James";

      Cuando tienes una variable declarada como object puedes ponerle los miembros que tu quieras.

      Acostumbra a ser una buena opción para organizar la información

      Ya me explicarás como te va

      Eliminar
  22. Hola
    Puedo tener algo así como una Biblioteca de Clases?
    Lo que quiero es tener un Script Externo (que pueda modificar ya que lo estoy probando) y llamarlo desde un Spreadsheet?
    Gracias

    ResponderEliminar
  23. Si se puede hacer.

    Google Apps Script te permite usar librerias. En este link podrás aprender más sobre el tema : https://developers.google.com/apps-script/guides/libraries

    Espero que te sirva

    Nos vemos!

    ResponderEliminar
  24. Buen día, podría ayudarme con un script que me permita crear Folders y SubFolders usando información de una hoja de cálculo. Las dependencias parentales se definen en una hoja de Google Sheets. Si la carpeta ya existe, no crear, si el nombre es ha cambiado, entonces renombrar (esto sucederá si se ejecuta de nuevo el script y han habido cambios en la información del sheet).

    Que todo se construya en el Google Drive a partir de FolderParent_Name y FolderParent_ID.
    La tercera columna es el nombre del folder que se creará, definido por NewFolder_Name.
    La cuarta columna NewFolder_ID se llena automáticamente con el ID de cada folder creado.
    Las columnas que se manejan en excel son:
    FolderParent_Name, FolderParent_ID, NewFolder_Name, NewFolder_ID

    ResponderEliminar
    Respuestas
    1. Hola Marvin,

      Te he resuelto la duda en este post: https://googleappscriptsweb.blogspot.com/2015/10/como-crear-ficheros-y-carpetas-con.html

      Eliminar
  25. hola nesecito ayuda por favor urgente, no puedo hacer que la secuencia de comandos de google funcione coorectamente, lo que quiero hacer es que los datos que resiva de un formulario google los grabe en su exel y la secuencia de comandos los lea y lo publique en mi blog de blogger por favr ayúdenme, gracias

    este es mi cod

    https://drive.google.com/file/d/18tqRf5LW7R4ApFAPG68pnau5RuufOHIh/view?usp=sharing

    ResponderEliminar
  26. Hola
    ¡...NO ENTIENDO QUE SUCEDE...!
    Tengo 2 archivos de secuencia de comando (.gs)
    1) PRINCIPAL.gs
    2) GESTION_CARPETAS.gs
    En GESTION_CARPETAS.gs lo que hago es buscar la
    carpeta "IMAGENES" en la carpeta "PRUEBAs"
    Si la encuentra hago un return Encontro
    Puse distintos Logger para ver que sucedía y:
    A) SI EJECUTO desde el mismo GESTION_CARPETAS.gs
    todo funciona bien
    pero...
    B) Si EJECUTO desde el PRINCIPAL (eliminando var wCONVENIO = "IMAGENES" en
    GESTION _CARPETAS-gs) se corta en Logger.log(“1”),
    como si DriveApp.getFoldersByName fuera inválido

    ¡...NO ENTIENDO QUE SUCEDE...!
    ___________________________________________________________
    PRINCIPAL.gs
    ...
    // Ubica la carpeta del "IMAGENES" en la carpeta "PRUEBAs"
    wBUSQUEDA = "IMAGENES"
    wEncontro = getTheFiles(wBUSQUEDA )
    Logger.log("wEncontro: " + wEncontro)
    ...
    ___________________________________________________________

    GESTION_CARPETAS.gs
    function getTheFiles(wCONVENIO)
    {

    var wCONVENIO = "IMAGENES"
    Logger.log("1")
    var folder_Sel = DriveApp.getFoldersByName("PRUEBAs");
    Logger.log("2")
    var folder = folder_Sel.next();
    Logger.log("3")
    var item = folder.getFolders();
    Logger.log("4")
    var i = 1
    var wSe = ""
    while(item.hasNext())
    {
    var wItem = item.next();
    var wName = wItem.getName();
    wSe = wSe + wName + "|"
    i++
    }
    Logger.log("wSe: " + wSe)
    var wArray = wSe.split("|")

    var Encontro = "NO"
    for( var wx = 0 ; wx < i; wx ++ )
    {
    if (wArray[wx] == wCONVENIO)
    {
    Encontro = "SI"
    break;
    }
    }
    Logger.log("Encontro: " + Encontro)
    return Encontro;

    }

    ResponderEliminar
  27. Buenas,

    Cosillas que he visto ( no estoy seguro de que sea tu problema)
    1. Ponle punto y coma al final de todas las lineas.
    2. La carpeta se llama PRUEBAs o PRUEBAS ?

    Ya me diras si te va mejor

    Nos vemos

    ResponderEliminar
  28. Hola
    Con punto y coma funciona igual: no funciona
    y si se llama PRUEBAs (con minúscula al final)
    Pero es la misma función, sólo que cuando lo
    ejecuto desde el principal le paso un parámetro wCONVENIO
    y cuando ejecuto directamente desde GESTION_CARPETAS.gs
    fuerzo wCONVENIO
    Gracias por tu pronta respuesta

    ResponderEliminar
    Respuestas
    1. He copypasteado tu codigo y lo he ejecutado de las dos maneras. Me funciona perfectamente.

      No tiene ninguna logica lo que te esta pasando.

      Desde donde lo estás ejecutando? Todo parece que el problema lo tienes fuera de ese código.

      Siento no ser de más ayuda

      Eliminar
  29. No entiendo la pregunta ¿Desde donde lo estás ejecutando?

    ResponderEliminar
  30. Respuestas
    1. No, me refiero a si es una función que la ejecutas con un boton en el spreadsheet, desde la ventana de código con un trigger de tiempo, etc...

      Eliminar
  31. Tengo una Spreadsheet con varias pestañas. En una de ellas tengo una casilla de verificación que desencadena distintas funciones. Una de ella, si todo fue correcto desencadena la función getTheFiles(wCONVENIO) con el parámetro wCONVENIO. No entiendo x que ejecutando getTheFiles funciona y desde la otra función se cancela ¿?

    ResponderEliminar
  32. Ambas funciones estan en 2 archivos de secuencia de comando (.gs) diferentes: PRINCIPAL.gs y GESTION_CARPETAS.gs. Eso me lo enseñastes hace un tiempo pero no le veo el problema. Copié toda la funcion getTheFiles dentro del PRINCIPAL y tambien se cortó ¿?

    ResponderEliminar
  33. A vos te funcionó ¿verdad? porque así debería ser ¿?

    ResponderEliminar
  34. Como el último Logger que se muestra es "1" pienso que dá un error al leer: DriveApp.getFoldersByName("PRUEBAs"); ¿puede ser que falte algo?. Es raro poque si lo ejecuto directo funciona bien.

    ResponderEliminar
    Respuestas
    1. Sinceramente ni idea. A mi tu codigo me funciona, es muy raro que no te funcione,

      Para mirarmelo más en detalle deberiamos mirarlo a un nivel más profesional.

      Si quieres podemos ponernos en contacto en Fiverr. Tienes el link en la columna de la derecha.

      Nos vemos

      Eliminar
  35. A...lo ví...SI CLARO, COMO NO? Gracias

    ResponderEliminar
  36. Buenas tardes (y Feliz Navidad!!)
    Estoy intentando recorrer todas las hojas de mi libro, y capturar los valores de una columna, para luego compararlos con la hoja 'resumen'.
    function Hojas()
    {
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

    var sheets = spreadsheet.getSheets();

    var out = new Array();

    for ( var s = 2 ; s < sheets.length - 1 ; s++)
    {
    out.push(sheets[s].getName());
    }
    return out;
    }

    Mi problema es que no sé como recorrer ahora esas hojas que tengo recogidas

    function onOpen() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();

    var hs = ss.getActiveSheet(); /*la hoja activa -->Resumen */

    var sheets = ss.getSheets(); /*todas las hojas de mi libro */

    var numRows = hs.getMaxRows();

    var numColumns = hs.getMaxColumns();

    matriz = Hojas();
    for (var j=0 ; j<10; j++)
    {
    var saux = matriz[j];

    sauxr = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().setName(saux);
    }

    esto me dice que ya tengo una hoja creada con el mismo nombre, es como si me la creara otra vez...

    ResponderEliminar
    Respuestas
    1. Buenas ( Feliz Navidad )

      Creo que te has liado con el setName.

      sauxr = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().setName(saux);

      Esto lo que hace es que pilla el nombre de todas las hojas y una por una lo va seteando como nombre de la hoja activa.

      Evidentemente se queja que los nombres estan repetidos.

      Creo que lo que quieres seria algo de este estilo:
      var matriz = Hojas();
      for (var j=0 ; j<matriz.length; j++)
      {
      var sauxr = SpreadsheetApp.getSheetByName(matriz[j]);
      //sauxr es una de las hojas
      }

      Aunque también te diria que si lo que quieres es recorrer todas las hojas, tal vez lo más fácil seria:
      var sheets = SpreadsheetApp.getSheets();
      for(var j = 0 ; j < sheets.length ; j++)
      {
      var sauxr = sheets[j];
      }

      Ya me diras si te ha ayudado o te he liado más. Vigila que no he probado el código. Deberia funcionarte pero espero no haber hecho ningun fallo por ir rapido.

      Nos vemos!

      Eliminar
  37. Estimado, si aún estas atendiendo este blog quisiera consultarte algo sobre un appscript que ya tengo pero quisiera mejorarlo, espero su respuesta un saludo.

    ResponderEliminar
    Respuestas
    1. Por motivos personales no estoy en el mundo del freelancing, y llevo unos dias liado y no he podido responder los mensajes pero si, estoy por aqui. Dime que necesitas e intentaré echarte un cable

      Eliminar
  38. Hola, quiero leer datos de una planilla de cálculo y volcar algunos de ellos en otra. No encuentro un ejemplo. Me ayudarías?

    ResponderEliminar
    Respuestas
    1. Te serviria este ejemplo? https://www.tutorialesgoogleappscripts.com/2022/03/como-copiar-datos-de-una-hoja-otra-con-google-scripts.html

      Nos vemos

      Eliminar

Tal vez te interese