Google Apps Script, parte 8: Eliminar filas en una hoja de cálculos

Hola a todas y todos, finalizamos este ABM con la parte que nos faltaba, que es la de eliminar una fila.

Método deleteRow()

Para eliminar una fila no tenemos más que hacer que:

ws.deleteRow(numero_de_fila);

Siguiendo con el ejemplo que estábamos viendo, podemos reutilizar la función que habíamos creado en GAS en la publicación pasada:

function getFilaPorId(p_id){
    
  let menu = getMenu();
  
  let ides = menu.map(function(e){
    return e[0];
  });
    
  let fila = ides.indexOf(p_id);
  
  if(fila > -1){
    fila += 2;
  }
  
  return fila;  
  
}

La que nos devolvía el número de fila que le correspondía a un id del ítem del menú. Así que sólo nos resta, una vez obtenido el número de fila, usar el método deleteRow() para eliminar la misma.

Vamos al código GAS y agregamos la siguiente función:

function deleteItemMenu(p_item){
  
  let ws = SS.getSheetByName("Menu");
  
  let fila = getFilaPorId(p_item.ID);
  
  if(fila > -1){
    ws.deleteRow(fila);
    return true;
  }else{
    return false;
  }
  
}

Luego vamos al frontend y agregamos el método al código VUE:

deleteItemMenu: function(p_item){
                    let that = this;
                    if(confirm("Está segura/o que desea eliminar este ítem?")){
                       google.script.run.withSuccessHandler(function(){
                           alert("El registro se ha eliminado del menú.");
                           that.getMenu();
                       }).deleteItemMenu(p_item);
                    }
}

Y en el HTML:

<button type="button" class="btn btn-danger" v-on:click="deleteItemMenu(item)"> Eliminar </button>

Finalmente el código GAS quedará del siguiente modo:

const SS = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/[ID-DE-TU-HOJA-DE-CALCULOS]/edit#gid=0");

function doGet() {
  let layout = HtmlService.createTemplateFromFile("layout");
  return layout.evaluate();
}

function getCategorias(){
  
  let ws = SS.getSheetByName("Categorias");
  
  let data = ws.getRange(
    2, 
    1, 
    ws.getLastRow() - 1, 
    1
  ).getValues();
      
  return data;
  
}

function addItemMenu(p_item){
  
  let ws = SS.getSheetByName("Menu");
  
  let date = new Date();
  
  ws.appendRow([
	getIdDinamico(),
    p_item.nombre,
    p_item.descripcion,
    p_item.categoria,
    date,
    date
  ]);
  
}

function updateItemMenu(p_item){
  
  let ws = SS.getSheetByName("Menu");
  
  let fila = getFilaPorId(p_item.ID);
  
  if(fila > -1){
    ws.getRange(fila, 2).setValue(p_item.nombre);
    ws.getRange(fila, 3).setValue(p_item.descripcion);
    ws.getRange(fila, 4).setValue(p_item.categoria);
    return true;
  }else{
    return false;
  }
  
}

function deleteItemMenu(p_item){
  
  let ws = SS.getSheetByName("Menu");
  
  let fila = getFilaPorId(p_item.ID);
  
  if(fila > -1){
    ws.deleteRow(fila);
    return true;
  }else{
    return false;
  }
  
}
    
function getIdDinamico(){
        
    return new Date().getTime() + '-' + (Math.floor(Math.random() * 100) + 1);
    
}

function getMenu(){
  
  let ws = SS.getSheetByName("Menu");
  
  let data = ws.getRange(
    2, 
    1,
    ws.getLastRow() - 1, 
    4
  ).getValues();
      
  return data;
    
}

function getMenuFiltrado(p_texto_busqueda){
  
  let menu = getMenu();
  let menu_filtrado = [];
  
  for(let i = 0; i < menu.length; i++){
    if(buscarEnTexto(menu[i][1], p_texto_busqueda) || buscarEnTexto(menu[i][2], p_texto_busqueda) || buscarEnTexto(menu[i][3], p_texto_busqueda)){
      menu_filtrado.push(menu[i]);
    }
  }
    
  return menu_filtrado;
  
}

function buscarEnTexto(p_texto, p_texto_busqueda){
  return p_texto.toLowerCase().indexOf(p_texto_busqueda.toLowerCase()) > -1;
}

function getFilaPorId(p_id){
    
  let menu = getMenu();
  
  let ides = menu.map(function(e){
    return e[0];
  });
    
  let fila = ides.indexOf(p_id);
  
  if(fila > -1){
    fila += 2;
  }
  
  return fila;  
  
}

Y el HTML:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">    
    <title> Prueba de Google App Script </title>    
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <!-- Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  </head>
  <body>
    
    <div id="app" class="container">
        
        <h1> Menú </h1>
        
        <table class="table">
            <thead>
                <tr>
                    <th> Nombre </th>
                    <th> Descripción </th>
                    <th> Categoría </th>
                    <th> </th>
                </tr>
            </thead>
            <tbody>                                
                <tr>
                    <td>
                        <input type="text" class="form-control" placeholder="Ingrese el nombre" v-model="item_menu_temp.nombre" />
                    </td>
                    <td>
                        <input type="text" class="form-control" placeholder="Ingrese una descripción" v-model="item_menu_temp.descripcion" />
                    </td>
                    <td>
                        <select class="form-control" v-model="item_menu_temp.categoria">
                            <option value=""> Ingrese la categoría </option>
                            <option v-for="c in categorias" v-bind:value="c[0]"> {{ c[0] }} </option>
                        </select>
                    </td>
                    <td>
                        <button type="button" class="btn btn-primary" v-on:click="addItemMenu()" v-bind:disabled="!validarItemMenu(item_menu_temp)"> Agregar </button>
                    </td>
                </tr>
                <tr>
                    <td colspan="3">
                        <input type="text" class="form-control" placeholder="Buscar" v-model="texto_busqueda" />
                    </td>
                    <td>
                        <button type="button" class="btn btn-secondary" v-on:click="getMenuFiltrado()"> Buscar </button>
                        <button type="button" class="btn btn-secondary" v-on:click="getMenu()"> Traer todo </button>
                    </td>
                </tr>
                <tr v-for="item in menu">
                    <td>
                        <input type="text" class="form-control" placeholder="Ingrese el nombre" v-model="item.nombre" />
                    </td>
                    <td>
                        <input type="text" class="form-control" placeholder="Ingrese una descripción" v-model="item.descripcion" />
                    </td>
                    <td>
                        <select class="form-control" v-model="item.categoria">
                            <option value=""> Ingrese la categoría </option>
                            <option v-for="c in categorias" v-bind:value="c[0]"> {{ c[0] }} </option>
                        </select>
                    </td>
                    <td>
                        <button type="button" class="btn btn-primary" v-on:click="updateItemMenu(item)" v-bind:disabled="!validarItemMenu(item)"> Modificar </button>
                        <button type="button" class="btn btn-danger" v-on:click="deleteItemMenu(item)"> Eliminar </button>
                    </td>
                </tr>
            </tbody>
        </table>
        
    </div>
    
    <script>
        
        new Vue({
            el: '#app',            
            data: function(){
                return {
                    categorias: [],
                    item_menu_temp: {
                        nombre: '',
                        descripcion: '',
                        categoria: ''
                    },
                    menu: [],
                    texto_busqueda: ''
                }
            },
            created: function(){
                this.getCategorias();
            },
            methods: {
                getCategorias: function(){
                    let that = this;
                    google.script.run.withSuccessHandler(function(categorias){
                        that.categorias = categorias;
                    }).getCategorias();
                },
                addItemMenu: function(){
                    let that = this;
                    google.script.run.withSuccessHandler(function(){
                        alert("El registro se ha guardado en el menú.");
                        that.item_menu_temp.nombre = "";
                        that.item_menu_temp.descripcion = "";
                        that.item_menu_temp.categoria = "";
                    }).addItemMenu(that.item_menu_temp);
                },
                validarItemMenu: function(p_item){
                    return (
                        p_item.nombre.split(" ").join("") != "" &&
                        p_item.descripcion.split(" ").join("") != "" &&
                        p_item.categoria.split(" ").join("") != ""
                    );
                },
                getMenu: function(){
                    let that = this;
                    that.menu = [];
                    google.script.run.withSuccessHandler(function(menu){
                        that.menu = [];
                        for(let i = 0; i < menu.length; i++)
                        {
                            that.menu.push({
                                ID:  menu[i][0],
                                nombre: menu[i][1],
                                descripcion: menu[i][2],
                                categoria: menu[i][3]
                            });
                        }
                    }).getMenu();
                },
                getMenuFiltrado: function(){
                    let that = this;
                    that.menu = [];
                    google.script.run.withSuccessHandler(function(menu_filtrado){
                        that.menu = [];
                        if(menu_filtrado.length > 0){
                            for(let i = 0; i < menu_filtrado.length; i++)
                            {
                                that.menu.push({
                                    ID:  menu_filtrado[i][0],
                                    nombre: menu_filtrado[i][1],
                                    descripcion: menu_filtrado[i][2],
                                    categoria: menu_filtrado[i][3]
                                });
                            }
                         }else{
                             alert('La búsqueda no ha traído resultado');
                         }
                    }).getMenuFiltrado(that.texto_busqueda);
                },
                updateItemMenu: function(p_item){
                    google.script.run.withSuccessHandler(function(){
                        alert("El registro se ha guardado en el menú.");
                    }).updateItemMenu(p_item);
                },
                deleteItemMenu: function(p_item){
                    let that = this;
                    if(confirm("Está segura/o que desea eliminar este ítem?")){
                       google.script.run.withSuccessHandler(function(){
                           alert("El registro se ha eliminado del menú.");
                           that.getMenu();
                       }).deleteItemMenu(p_item);
                    }
                }
            }
        });   
        
    </script>
    
    
  </body>
</html>

Pueden ver el ejemplo completo desde el enlace a Github.

Anterior: Google Apps Script, parte 7: Modificar filas de una hoja de cálculos