Automatizar informes tipo docs con AppScript / AppSheet / Google Drive y Spreadhseets

0

 




Introducción: ¿Por qué automatizar sus informes?

¿Se encuentra usted inmerso en un ciclo interminable de replicación y transposición manual de datos, trasladando información valiosa de sus diversas aplicaciones a plantillas estáticas de Word o Excel de forma recurrente? 

¿Detecta una fuga significativa de su tiempo, dedicando incontables horas cada semana a la tediosa y repetitiva elaboración de informes detallados, actas de reuniones o facturas que, con la tecnología adecuada, podrían ser generadas de manera completamente automática y eficiente? Si estas preguntas resuenan con su experiencia diaria y su respuesta es un rotundo afirmativo, entonces el presente blog ha sido meticulosamente concebido y diseñado pensando exclusivamente en usted, ofreciéndole soluciones prácticas y estrategias innovadoras para transformar su operativa y liberar su potencial productivo.

Considere la posibilidad de disponer de una aplicación en AppSheet donde se registran sus transacciones de venta, inspecciones o cualquier otro tipo de datos, y que, mediante una simple pulsación de un botón, se genere un documento PDF de carácter profesional, con un formato impecable y listo para su envío o archivo. Una perspectiva ciertamente atractiva, ¿no es así?

A lo largo de esta guía, le conduciremos de manera metódica, paso a paso, a través del proceso de integración de la funcionalidad de AppSheet con la flexibilidad de Google Docs y la potencia de Google Apps Script. No se requiere ser un programador experto. Si usted posee conocimientos en el uso de AppSheet y Google Sheets, se encuentra plenamente capacitado para iniciar este proceso.


Al finalizar la lectura de este Ebook, usted estará en capacidad de:

  • Diseñar una plantilla de informe en Google Docs.

  • Elaborar un script básico para poblar dicha plantilla con datos.

  • Implementar su script para facilitar la comunicación con AppSheet.

  • Configurar un botón en su aplicación de AppSheet para generar un PDF con un solo clic

Capítulo 1: El Ecosistema de Trabajo


Previo a la escritura de cualquier línea de código, resulta fundamental comprender las cuatro herramientas que se emplearán y cómo interactúan entre sí.

AppSheet

Constituye nuestra interfaz de usuario. Es aquí donde los usuarios ingresan los datos (por ejemplo, los detalles de una venta) y donde se ubicará el botón "Generar Informe".

Google Sheets (Hoja de Cálculo)

Es nuestra base de datos. Todos los datos ingresados en AppSheet se almacenan en este medio. Nuestro script extraerá la información de esta hoja.

Google Docs (Documento)

En este entorno crearemos nuestra plantilla. Será un documento estándar con marcadores de posición específicos (ej. <<nombre_cliente>>) que nuestro script reemplazará con los datos reales.

Google Apps Script

Este componente actúa como el cerebro 🧠 del sistema. Es un lenguaje de programación basado en JavaScript que reside dentro del ecosistema de Google. Nuestro script funcionará como un "robot" que:

  • Recibe una instrucción desde AppSheet (a través de un botón).

  • Accede a la hoja de Google Sheets para recuperar la información pertinente.

  • Crea una copia de la plantilla de Google Docs.

  • Puebla la copia con la información obtenida.

  • Convierte el documento a formato PDF y lo almacena en Google Drive.

El flujo es directo: AppSheet imparte una orden al Script, el Script interactúa con Sheets y Docs, y finalmente produce un archivo PDF

Capítulo 2: La Base de Todo


Procedamos a la preparación de nuestro entorno. Para nuestro ejemplo, desarrollaremos un generador de "Recibos de Venta".

Paso 1: La Hoja de Cálculo (Google Sheets)


  1. Cree una nueva Hoja de Cálculo en Google Sheets.

  2. Asígnele el nombre "RegistroVentas".

  3. Cree una hoja denominada "Ventas" con las siguientes columnas:

    • idVenta: ¡Esta columna es de suma importancia! Debe contener un identificador único para cada venta. En AppSheet, es posible generar este valor automáticamente empleando la función UNIQUEID().

    • Fecha: La fecha correspondiente a la venta tipo DATE().

    • Cliente: El nombre del cliente tipo TEXT.

    • Producto: El nombre del producto vendido, tipo TEXT.

    • Cantidad: El número de unidades vendidas, tipo NUMBER().

    • Precio_Unitario: El precio por unidad, tipo PRICE().

    • Total: El importe total de la venta (Cantidad * Precio_Unitario).

Paso 2: La Aplicación (AppSheet)

  1. Acceda a AppSheet y cree una nueva aplicación a partir de su hoja "RegistroVentas".

  2. AppSheet generará automáticamente una vista para el registro de nuevas ventas. ¡Excelente! Asegúrese de que la columna idVenta posea como valor inicial (Initial value) la fórmula UNIQUEID().

Paso 3: La Plantilla (Google Docs)

  1. Cree un nuevo Documento de Google. Nómbrelo "Plantilla de Recibo".

  2. Diseñe un recibo sencillo. En los lugares donde desee insertar datos de su hoja de cálculo, utilice un marcador de posición con doble llave: <<nombre_de_la_columna>>.

Ejemplo de Plantilla:Recibo de Venta


Número de Recibo: <<idVenta>>

Fecha: <<Fecha>>

Cliente: <<Cliente>>


Detalle:

Producto

Cantidad

Precio Unit.

Total

<<Producto>>

<<Cantidad>>

<<Precio_Unitario>>

<<Total>>

¡Gracias por su compra!


¡Importante! Conserve el ID de su Hoja de Cálculo y el ID de su Plantilla. Los encontrará en la URL.

  • Hoja de Cálculo: [https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)ESTE_ES_EL_ID/edit

  • Documento (Plantilla): [https://docs.google.com/document/d/](https://docs.google.com/document/d/)ESTE_ES_EL_ID/edit

Capítulo 3: El Cerebro de la Operación

¡Ha llegado el momento de programar! No se alarme, procederemos línea por línea.

  1. Abra Script home https://script.google.com/home/

  1. Elija o de clic en Nuevo proyecto

Paso 1: Configuración Inicial

Elimine el código predeterminado y pegue el siguiente. Sustituya los IDs por los que ha guardado previamente.

// --- 1. CONFIGURACIÓN ---

const SPREADSHEET_ID = "ID_DE_TU_HOJA_DE_CÁLCULO";

const TEMPLATE_ID = "ID_DE_TU_PLANTILLA_DE_DOCS";

const DESTINATION_FOLDER_ID = "ID_DE_LA_CARPETA_DE_DRIVE_DONDE_GUARDAR";


/**

 * Esta es la función principal. Se ejecuta cada vez que AppSheet la llama.

 */

function doGet(e) {

  // El resto del código irá aquí...

}

Paso 2: El Punto de Partida - Recibiendo la Orden desde AppSheet

Nuestro script necesita "despertar" y saber para qué venta debe generar un recibo. AAquí es donde la función doGet(e) entra en juego.

  • doGet(e) es una función especial en Apps Script que se ejecuta cada vez que alguien visita la URL de nuestra aplicación web (generada al desplegar el script).

  • El parámetro e es un objeto que contiene toda la información de la solicitud, incluyendo los parámetros de la URL.

  • AppSheet llamará a una URL como: .../exec?idVenta=78f41187.

  • Nuestro código extrae ese valor con e.parameter.idVenta.

JavaScript

function doGet(e) {

  // Obtiene el idVenta de la URL

  const idVenta = e.parameter.idVenta;


  // Si no nos envían un idVenta, detenemos el proceso.

  if (!idVenta) {

    return ContentService.createTextOutput("Error: Falta el parámetro idVenta.");

  }


  // ... el resto del código se ejecuta aquí ...

}

Paso 3: Buscando la aguja en el pajar - Lectura de datos en Google Sheets

Con el idVenta en mano, ahora debemos buscar toda la información relacionada con esa venta en nuestra hoja de cálculo.

  1. Conexión: Abrimos la hoja de cálculo usando su ID: SpreadsheetApp.openById(spreadsheetId).

  2. Acceso a los Datos: Obtenemos todos los datos de la hoja "registro" en un formato de array (una matriz de filas y columnas): sheet.getDataRange().getValues().

  3. La Búsqueda: Recorremos este array con un bucle for, fila por fila, comparando el idVenta de cada fila con el que recibimos de AppSheet.

  4. Captura: Cuando encontramos la primera coincidencia, guardamos toda esa fila de datos en la variable ventaData y extraemos la información principal como el cliente y la fecha.

JavaScript

// Obtiene los datos de la hoja de cálculo

const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName("registro");

const data = sheet.getDataRange().getValues();


// Busca la venta por idVenta

let ventaData = null;

for (let i = 1; i < data.length; i++) { // Empezamos en 1 para saltar los encabezados

  if (data[i][0] == idVenta) {

    ventaData = data[i];

    break; // Encontramos lo que necesitábamos, salimos del bucle.

  }

}

Paso 4: Organizando la Información - Preparando los Datos para el Recibo

No todos los datos se usan tal como vienen. La fecha necesita formato y, lo más importante, debemos construir la tabla de detalles.

  1. Datos Simples: Extraemos el nombre del cliente y formateamos la fecha a un formato legible (toLocaleDateString()).

  2. Construcción de la Tabla:

    • Creamos un array vacío llamado tablaDetalle.

    • La primera fila de este array serán los encabezados: ["Producto", "Cantidad", "Precio Unitario", "Total"].

    • Recorremos nuevamente todos los datos de la hoja, pero esta vez, en lugar de detenernos, recopilamos todas las filas que coincidan con el idVenta. Esto es clave para ventas con múltiples productos.

    • Por cada producto encontrado, añadimos una nueva fila al array tablaDetalle.

JavaScript

// Prepara los datos para la tabla de detalle

const tablaDetalle = [];

tablaDetalle.push(["Producto", "Cantidad", "Precio Unitario", "Total"]); // Encabezados


// Busca TODAS las filas para la misma venta

for (let i = 1; i < data.length; i++) {

  if (data[i][0] == idVenta) {

    let producto = data[i][3];

    let cantidad = data[i][4];

    // ... y así con el resto de columnas

    tablaDetalle.push([producto, cantidad, precioUnitario, total]);

  }

}

Paso 5: La Magia de la Creación - Generando el Documento de Google

Este es el corazón del proceso. Transformamos nuestra plantilla en un documento finalizado.

  1. Copia de Seguridad: ¡Nunca trabajamos sobre la plantilla original! Primero, creamos una copia en nuestra carpeta de destino: templateFile.makeCopy(...).

  2. Edición: Abrimos este nuevo documento para poder editarlo: DocumentApp.openById(...).

  3. Reemplazos Simples: Usamos la función body.replaceText() para buscar nuestros marcadores (<<Cliente>>, <<Fecha>>) y reemplazarlos con los datos que obtuvimos en el paso anterior.

  4. Reemplazo de la Tabla (El Truco Maestro):

    • Buscamos la ubicación del marcador <<tablaDetalle>>.

    • Obtenemos el párrafo que lo contiene y averiguamos su posición (índice) dentro del documento.

    • Usando el cuerpo principal del documento (body), insertamos nuestra tabla (tablaDetalle) justo en esa posición: body.insertTable(index, tablaDetalle).

    • Finalmente, eliminamos el párrafo original que contenía el marcador <<tablaDetalle>> para limpiar el documento.

JavaScript

// Reemplaza el marcador de la tabla

const rangeElement = body.findText("<<tablaDetalle>>");

if (rangeElement) {

  const placeholderParagraph = rangeElement.getElement().getParent();

  const index = body.getChildIndex(placeholderParagraph);

  body.insertTable(index, tablaDetalle);

  placeholderParagraph.removeFromParent();

}

Paso 6: El Toque Final - Creando y Guardando el PDF

Un documento de Google es útil, pero un PDF es universal y más profesional para compartir.

  1. Guardar y Cerrar: Es una buena práctica guardar los cambios en el documento de Google: newDoc.saveAndClose().

  2. Conversión: Obtenemos el contenido del Google Doc como un "Blob" (un objeto que representa datos de archivo) y lo convertimos al formato PDF: newDocFile.getBlob().getAs('application/pdf').

  3. Creación del Archivo: Con este Blob de PDF, creamos un nuevo archivo físico en nuestra carpeta de destino: folder.createFile(pdfBlob).


Capítulo 4: Abriendo la Puerta al Mundo

Nuestro script se encuentra listo, pero actualmente, su estado es análogo al de un teléfono sin línea. Nadie puede invocarlo. Procederemos a su "implementación" para asignarle una URL pública que AppSheet podrá utilizar.

  1. En el editor de Apps Script, haga clic en el botón azul "Implementar" (Deploy).

  2. Seleccione "Nueva implementación" (New deployment).

  3. Haga clic en el icono de engranaje ⚙️ junto a "Seleccionar tipo" y elija "Aplicación web" (Web app).

  4. Configure lo siguiente:

    • Descripción: Generador de Recibos

    • Ejecutar como: Yo (tu.correo@ejemplo.com)

    • Quién tiene acceso: Cualquier usuario (Anyone). Este ajuste es crítico para asegurar el acceso de AppSheet sin inconvenientes.

  5. Haga clic en "Implementar".

  6. ¡IMPORTANTE! Google solicitará la autorización de permisos. Acepte todas las solicitudes.

  7. Al finalizar, se le proporcionará una URL de la aplicación web. ¡Cópiela y guárdela! Esta será la dirección de nuestro "robot".

Pro-Tip: Cada vez que realice modificaciones en su código, deberá volver a implementarlo. Diríjase a Implementar > Administrar implementaciones, seleccione su implementación, haga clic en el lápiz (Editar) y elija "Nueva versión".



Capítulo 5: El Botón Mágico

Regresemos a AppSheet para el paso final.

  1. En el editor de AppSheet, acceda a la pestaña Actions.

  2. Cree una nueva acción (+ New Action).

  3. Configúrela de la siguiente manera:

    • For a record of this table: Ventas.

    • Action name: Generar Recibo PDF.

    • Do this: External: go to a website.

    • Target: Aquí es donde se produce la parte fundamental. Pegue la siguiente fórmula, sustituyendo la URL por la que copió en el paso anterior.

  4. CONCATENATE(

  5.   "URL_DE_TU_SCRIPT_AQUI",

  6.   "?id_venta=", ENCODEURL([ID_Venta])

  7. )

  8. ¿Cuál es la función de esta fórmula?

    • CONCATENATE enlaza varios segmentos de texto.

    • Inicialmente, inserta la URL de su script.

    • Posteriormente, agrega ?id_venta= para indicar al script el parámetro que se le está enviando.

    • Finalmente, ENCODEURL([ID_Venta]) toma el ID de la fila actual en AppSheet y lo formatea de manera segura para su inclusión en una URL.

  9. Appearance: Seleccione un icono adecuado (como un icono de PDF o de impresión).

  10. Prominence: Opte por Display prominently para que el botón sea visible y claro.

  11. ¡Guarde su aplicación de AppSheet!

¡Listo! Abra su aplicación, diríjase al detalle de cualquier venta y observará su nuevo botón. Pulse y compruebe cómo se abre una nueva pestaña que, tras unos instantes, le mostrará una respuesta de éxito y habrá generado el PDF en su carpeta de Google Drive.





Capítulo 6: Llevándolo al Siguiente Nivel

Lo que hemos desarrollado representa únicamente el inicio. A continuación, se presentan algunas sugerencias para optimizar sus informes:

  • Tablas con Múltiples Filas: Si maneja datos relacionados (por ejemplo, una venta con varios productos), puede implementar un bucle en su script para construir tablas más elaboradas.

  • Inserción de Imágenes: Es posible añadir un marcador <<foto_producto>> y utilizar body.insertImage() para incorporar fotografías de manera dinámica.

  • Lógica Condicional: Emplee sentencias if/else en su script para adaptar el contenido del informe. Por ejemplo, para añadir un sello de "PAGADO" si una columna de estado así lo indica.

  • Envío por Correo Electrónico: En lugar de simplemente guardar el PDF, puede utilizar GmailApp.sendEmail() para enviarlo automáticamente al cliente.


Conclusión


¡Ha alcanzado su objetivo! Ha establecido un vínculo entre su aplicación de AppSheet y sus documentos de Google, creando un sistema de informes automatizado y de índole profesional. Ahora puede:


✅ Preparar su entorno de datos.

✅ Diseñar plantillas dinámicas.

✅ Desarrollar y comprender un Google Apps Script.

✅ Implementarlo como una aplicación web.

✅ Conectar todos los elementos mediante un botón simple en AppSheet.


Este conocimiento es sumamente valioso. Ahora puede aplicar esta misma lógica para la creación de una amplia gama de documentos: certificados, actas de inspección, contratos, cotizaciones y mucho más.


El universo de la automatización está a su alcance.¡Continúe experimentando y construyendo!


Si deseas un aplicativo más complejo, no dudes en hacérmelo saber escribiendo al correo jaisizqu87@gmail.com.


Estaré compartiendo videos tutoriales con aplicativos más avanzados en mi canal de miembros; si deseas colaborar y verlos, puedes inscribirte en el siguiente link: https://www.youtube.com/channel/UCxlnUaYjaS4lKd8nQL-lqXQ/join

Las insignias doradas son las que tendrán los aplicativos más complejos:


Apéndice: Código completo del proyecto


A continuación, se presenta el código completo del script para su copia y pegado. Recuerde sustituir los IDs al inicio.


function doGet(e) {

 // IDs de tus archivos y carpeta

 const spreadsheetId = "";

 const templateId = "";

 const folderId = "";


 // Obtiene el idVenta de la URL

 const idVenta = e.parameter.idVenta;


 if (!idVenta) {

   return ContentService.createTextOutput("Error: Falta el parámetro idVenta.");

 }


 // Obtiene los datos de la hoja de cálculo

 const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName("registro");

 const data = sheet.getDataRange().getValues();


 // Busca la venta por idVenta

 let ventaData = null;

 for (let i = 1; i < data.length; i++) {

   if (data[i][0] == idVenta) {

     ventaData = data[i];

     break;

   }

 }


 if (!ventaData) {

   return ContentService.createTextOutput("Error: Venta no encontrada para el ID: " + idVenta);

 }


 // Extrae los datos de la venta

 const fecha = new Date(ventaData[1]).toLocaleDateString();

 const cliente = ventaData[2];


 // Prepara los datos para la tabla de detalle

 const tablaDetalle = [];

 tablaDetalle.push(["Producto", "Cantidad", "Precio Unitario", "Total"]); // Encabezados de la tabla


 // Busca todas las filas para la misma venta

 for (let i = 1; i < data.length; i++) {

   if (data[i][0] == idVenta) {

     let producto = data[i][3];

     let cantidad = data[i][4];

     let precioUnitario = data[i][5];

     let total = data[i][6];

     tablaDetalle.push([producto, cantidad, precioUnitario, total]);

   }

 }



 // Crea el documento a partir de la plantilla

 const folder = DriveApp.getFolderById(folderId);

 const templateFile = DriveApp.getFileById(templateId);

 const newDocFile = templateFile.makeCopy(`Recibo - ${cliente} - ${fecha}`, folder);

 const newDoc = DocumentApp.openById(newDocFile.getId());

 const body = newDoc.getBody();


 // Reemplaza los marcadores de texto

 body.replaceText("<<Cliente>>", cliente);

 body.replaceText("<<Fecha>>", fecha);


 // --- SECCIÓN CORREGIDA ---

 // Reemplaza el marcador de la tabla

 const rangeElement = body.findText("<<tablaDetalle>>");

 if (rangeElement) {

   const placeholderParagraph = rangeElement.getElement().getParent();

   const index = body.getChildIndex(placeholderParagraph);

  

   // Inserta la tabla en el cuerpo del documento en la posición del párrafo

   const table = body.insertTable(index, tablaDetalle);

  

   // Opcional: dar estilo a la tabla

   table.setBorderColor("#000000");

   table.getRow(0).editAsText().setBold(true); // Poner encabezados en negrita

  

   // Elimina el párrafo que contenía el marcador <<tablaDetalle>>

   placeholderParagraph.removeFromParent();

 }

 // --- FIN DE LA SECCIÓN CORREGIDA ---


 newDoc.saveAndClose();


 // Crea el PDF

 const pdfBlob = newDocFile.getBlob().getAs('application/pdf');

 const pdfFile = folder.createFile(pdfBlob);

 pdfFile.setName(`Recibo - ${cliente} - ${fecha}.pdf`);



 return ContentService.createTextOutput(`Documento y PDF generados para la venta ${idVenta}.`);



Tal vez te interesen estas entradas

No hay comentarios