Search code examples
google-apps-scriptgoogle-docsdelete-row

Difficulties getting rows deleted from two different tables in Google Docs


I'm hoping that one of you would be willing to assist me. As will soon be painfully obvious, I am fairly new to Google Apps Script (and loops, for that matter, but I'm trying hard to learn). I hope my code will not make you cringe.

Basically in the sample document
(https://docs.google.com/document/d/1VPua9T1d9qQFMCuvTlIqnvmhhMoplimZar4oAemAGPM/edit?usp=sharing), I'd like to delete all lines that include staff member, Derek. From the logs it indicates that would be row 17 and 18 (in the second table that is titled "Schedule of the Week") and rows 25-29 (in the fourth table that starts with Agenda/Notes).

The code below will run fine and delete the rows I want if I run each of the loops individually (with the exception of throwing an error re: a child index that I just dismiss).

When I try to run them together, I get close but on the first table, one of the rows (in the top table) does not delete. I've tried running the 2nd loop first and that makes it worse. Any help you could provide would be more than appreciated.

function DeleteRows() {
var doc = DocumentApp.getActiveDocument()
var body = doc.getBody();
var tables = body.getTables();
var numRows = tables[1].getNumRows();
var numRows2 = tables[3].getNumRows();

   
var row;
var val;
  
 for(row = 0; row<numRows-1; row++) {
 val = tables[1].getCell(row, 1).getText 

 tables[1].getRow(16).removeFromParent();    
     
 var row2;
 var val2;
    
for(row2 = 0; row2<numRows2-1; row2++) {    
val2 = tables[3].getCell(row2, 1).getText();
tables[3].getRow(24).removeFromParent(); 
     
     

  Logger.log(numRows);
  }
 }
}

Solution

  • Basically, you can remove all table rows with 'Derek' this way:

    function DeleteRows() {
      var body = DocumentApp.getActiveDocument().getBody();
      var found_element = body.findText('Derek');
      while (found_element != null) {
        found_element.getElement().getParent().getParent().getParent().removeFromParent();
        found_element = body.findText('Derek', found_element)
      }
    }
    

    It just will finds every 'Derek' take its parent of parent of parent { table row : { table cell : { paragraph: { text } } } } and remove it.

    For your case it will work only partially since your tables have merged cells. If you want to find all the empty rows after 'Derek's rows and remove them as well it's need a more complicated solution.

    But I failed to understand your script. Why do you need the nested loop? And if you find for 'Derek' where is any condition in your code?

    Update

    To remove rows 17-18 from table 2 and 25-29 from table 4 you can use this function:

    function DeleteRows2() {
      var tables = DocumentApp.getActiveDocument().getBody().getTables();
      [17,18].reverse().forEach(n => tables[1].getRow(n-1).removeFromParent());
      [25,26,27,28,29].reverse().forEach(n => tables[3].getRow(n-1).removeFromParent());
    }