【GAS】スプレッドシートからスライド作成②

GAS

こんにちは!ウメハラ(plumfield56)です。

前回は欲しいフォーマットをコピーし、スライドをリストとして保管して文字列の置換を行いました。

今回は1ページにグループ化されたオブジェクトが存在し、グループ内のオブジェクト内容を変更したいケースです。

Groupオブジェクトの取得

まずは下記のコードでGroupオブジェクトを取得していきたいと思います。

function myFunction() {

  const slideId = 'id';
  const slides = SlidesApp.openById(slideId).getSlides();

  const slidesObj = {slide: slides[1], groups: [], index: 0}


  //スプレッドシート操作
  const sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const values = sht.getDataRange().getValues();
  const header = values.splice(0, 1).flat();

  const length = sht.getRange('B2:B').getValues().flat().filter(val => val).length;
  let needpage = Math.ceil(length / 6);

  // Groupオブジェクトをリストに追加
  while(needpage) {
    slidesObj['groups'].push(slidesObj['slide'].getGroups());

    needpage --;
    if(needpage) {
      const duplicateSlide = slidesObj['slide'].duplicate();
      slidesObj['slide'] = duplicateSlide;
    }
  }
  slidesObj['groups'] = slidesObj['groups'].flat();
  
  console.log(slidesObj);
}
/*
{ slide: {},
  groups: [ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} ],
  index: 0 }
*/
}

今回のケースだと1ページの6のグループが存在し、スプレッドシートの行数が7行なので1ページ分コピーされ、その全てのGroupオブジェクト(12個)がslidesObjのgroupsに入った状態となりました。

このままでも良いのですが、使用しない要素を削除する処理を加えます。

function myFunction() {

  const slideId = 'id';
  const slides = SlidesApp.openById(slideId).getSlides();

  const slidesObj = {slide: slides[1], groups: [], index: 0}

  //スプレッドシート操作
  const sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const values = sht.getDataRange().getValues();
  const header = values.splice(0, 1).flat();

  const length = sht.getRange('B2:B').getValues().flat().filter(val => val).length;
  let needpage = Math.ceil(length / 6);

  // Groupオブジェクトをリストに追加
  while(needpage) {
    slidesObj['groups'].push(slidesObj['slide'].getGroups());

    needpage --;
    if(needpage) {
      const duplicateSlide = slidesObj['slide'].duplicate();
      slidesObj['slide'] = duplicateSlide;
    }
  }
  slidesObj['groups'] = slidesObj['groups'].flat();
  slidesObj['groups'].splice(length).forEach(elem => elem.remove());
  

  console.log(slidesObj);
}
/*
{ slide: {},
  groups: [ {}, {}, {}, {}, {}, {}, {} ],
  count: 0,
  index: 0 }
*/
}

処理の途中でlengthという変数でスプレッドシートに入っている行数を把握できているので、リストの8つ目以降をspliceメソッドで取り出しつつ、removeで削除する処理を加えています。

保守性を高くするための処理

ここで今後の処理に必要なオブジェクトをもう1つ作成したいと思います。
前提として項目名とスライドのテキストの内容が同じになっています。
ただし、スプレッドシートの方で情報を整理する際に列順が変わったり、列追加されたりするケースが考えられるので、そういう場合でも変更無しで動くようにしたいと思います。

追加するコードは冒頭で作成しているheaderの変数を使用してどの項目がどのインデックスかがわかるようにします。

function myFunction() {

  const slideId = '1ffmPzWi-RzRGM-30KdQ27KXt0ymxbGMG50qD8iMNwrs';
  const slides = SlidesApp.openById(slideId).getSlides();

  const slidesObj = {slide: slides[1], groups: [], index: 0}


  //スプレッドシート操作
  const sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const values = sht.getDataRange().getValues();
  const header = values.splice(0, 1).flat();

  const headerObj = {};
  header.forEach((val, index) => headerObj[val] = index);

  console.log(headerObj);
 //{ 'フォーマット': 0, '名前': 1, '年齢': 2, '好きなもの': 3 }
  return;
}

これを追加してスプレッドシート情報を順番にスライドに反映させる際に名前の置換であればhearderObj[‘名前’]で列方向のインデックスを指定可能になりました。

Groupの子要素の取得

Groupの中の要素を取得するためにgetChildrenを使用します。

子要素の取得

Groupオブジェクト.getChildren()

これでGroup内の全てのオブジェクトが取得可能です。

function myFunction() {

  const slideId = '1ffmPzWi-RzRGM-30KdQ27KXt0ymxbGMG50qD8iMNwrs';
  const slides = SlidesApp.openById(slideId).getSlides();

  const slidesObj = {slide: slides[1], groups: [], index: 0}


  //スプレッドシート操作
  const sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const values = sht.getDataRange().getValues();
  const header = values.splice(0, 1).flat();

  const headerObj = {};
  header.forEach((val, index) => headerObj[val] = index);


  const length = sht.getRange('B2:B').getValues().flat().filter(val => val).length;
  let needpage = Math.ceil(length / 6);

  // Groupオブジェクトをリストに追加
  while(needpage) {
    slidesObj['groups'].push(slidesObj['slide'].getGroups());

    needpage --;
    if(needpage) {
      const duplicateSlide = slidesObj['slide'].duplicate();
      slidesObj['slide'] = duplicateSlide;
    }
  }
  slidesObj['groups'] = slidesObj['groups'].flat();
  slidesObj['groups'].splice(length).forEach(elem => elem.remove());
  

  // スプレッドシートのオブジェクト作成とスライド複製
  for(const row of values) {
    if(row) {
      const index = slidesObj['index'];
      const elems = slidesObj['groups'][index].getChildren();
      for(const elem of elems) {
        if(elem.getPageElementType().toString() === 'SHAPE') {
          const textRange = elem.asShape().getText();
          const text = textRange.asString().replace('\n', '');
          textRange.replaceAllText(text, row[headerObj[text]]);

        }
      }

      slidesObj['index'] ++;
    }
  }
}

このコードでなくてももっと簡単に動かせますが、汎用性が高いコードを目指しているうちにこの形になりました。

コメント

タイトルとURLをコピーしました