0

Problem

I am working with a Google Sheet, and trying to output data to a Google Doc (without having the manually code it line by line, which I am currently doing).

The Source: 2(or 3) Columns, and dynamic Rows (based on check boxes). Whittling the array down to the dynamic rows is already done:

ARRAY = [
  [HEADER TITLEA, CONTENTA],
  [HEADER TITLE2, CONTENTA2], 
  [HEADER TITLEA3, CONTENTA3]
]

ARRAY = [
  [HEADER TITLEA, CONTENTA, CONTENTB],
  [HEADER TITLE2, CONTENTA2, CONTENTB],
  [HEADER TITLEA3, CONTENTA3, CONTENTB]
]

Final Format:

text
Header TitleA

Static: ContentA 

Header TitleA2

Static: ContentA2

and so forth.


OR (w/ 3)

text
Header TitleA

Static: ContentA

Static2: ContentB

I know I can run a loop and get a very basic output, but I have no idea how to manipulate each of the inner array items to get my desired output. My current Loop is:

for (row = 0; row < newA.length; row++) {
   for (col = 0; col < 3; col++) {
     Logger.log(newA[row][col]);
   }
}

which returns:

text  
HEADERA

CONTENTA

CONTENTB

But, I want to loop through each inner array and manipulate them individually for an output (not sure if that is even the right words).

My current output (doing it manually):

  var htmlTitleProp = sh.getRange('A3').getValue();
  var htmlTitleHeaderO = body.appendParagraph(htmlTitleProp);
  htmlTitleHeaderO.setHeading(DocumentApp.ParagraphHeading.HEADING4);

  var htmlTitleCurrent = sh.getRange('B3').getValue();
  var htmlTitleRecommended = sh.getRange('C3').getValue();

  var htmlTitleCurrentO = body.appendParagraph(htmlTitleRecommended);

  //description
  var htmlDescriptionProp = sh.getRange('A4').getValue();
  var htmlDescriptionHeaderO = body.appendParagraph(htmlDescriptionProp); 
  htmlDescriptionHeaderO.setHeading(DocumentApp.ParagraphHeading.HEADING4);

  var htmlDescriptionCurrent = sh.getRange('B4').getValue();
  var htmlDescriptionRecommended = sh.getRange('C4').getValue();

  var htmlDescriptionCurrentO = body.appendParagraph(htmlDescriptionRecommended);

Basically, looking on how to automate the body.appendParagraph based on my source array file.

How do I solve this problem?

With tehhowch providing some insights, below was the function I used to solve my problem (w/ 3 columns):

newA.forEach(function (row) {
    var heading = row.shift();
    if (heading) {
      body.appendParagraph(heading).setHeading(DocumentApp.ParagraphHeading.HEADING4);
        if (row[0]) {
         body.appendParagraph( "Current: \n" + row[0] + "\n");
        }   
        if (row[1]) {
         body.appendParagraph( "Recommended: \n" + row[1]);  
        }  
    }
  });
AndrewB
  • 13
  • 2

1 Answers1

0

Assuming you have the data laid out such that column A is document headings, and columns B:... are content under that heading, you want to run two forEach loops using the contents of the array.

function foo() {
  const doc = DocumentApp.getActive();
  const source = get2DArraySomehow();

  const body = doc.getBody();
  source.forEach(function (row) {
    var heading = row.shift();
    if (heading) {
      body.appendParagraph(heading).setHeading(...);
      row.forEach(function (text) {
        if (text) {
          body.appendParagraph(text);
        }
      });
    }
  });
  ...
}

The result of most Document Service methods is chainable, so you could apply additional styling as required.

The above should work for an arbitrary number of columns of text per heading, not just 2 or 3, e.g. a suitable get2DArraySomehow definition could be:

function get2DArraySomehow() {
  const wb = SpreadsheetApp.openById("some id");
  const datasheet = wb.getSheetByName("some name");
  const data = datasheet.getDataRange().getValues();
  data.shift(); // remove row 1, i.e. it is assumed to be a header row
  return data;
}

Refs

tehhowch
  • 9,645
  • 4
  • 24
  • 42
  • Thank You! You got me 90% of the way there. I ended up not needing two loops, which I was certain I needed. Added my final function above. – AndrewB Mar 20 '19 at 16:43