GASでシートかドキュメントのIDを指定して文章校正する方法

GASでシートかドキュメントを文章校正

Googleスプレッドシート、Googleドキュメント、Googleスライドを使用していると特定の間違った用語が含まえていないかチェックしたいことがある。

例: クスリマス => クリスマス

Google Apps Script (以下GAS) を使用すればGoogleスプレッドシートやGoogleドキュメントに間違った用語が含まれている箇所を簡単に検出することができる。

正誤チェックシートを作成する

まずGoogleスプレッドシートで正誤シートを作成する。

今回は「クスリマス => クリスマス」「コロナ渦 => コロナ禍」を検出できるものをサンプルとして作成する。

シンプルにA列に誤、B列に正を下図のように記載する。

シート名はcheckにしています。

GASはこのチェックシートに含めるのでまずツール => スクリプトエディタを開く。

スクリプトエディタを開いたら以下のスクリプトを貼り付けて保存して実行してください。

function getCheckData() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = ss.getSheetByName('check')
  const range = sheet.getRange(2, 1, sheet.getLastRow() - 1, 2)
  const arr = []
  for (let row = 1; row <= range.getNumRows(); row++) {
    const x = range.getCell(row, 1).getValue()
    const o = range.getCell(row, 2).getValue()
    arr.push({x, o})
  }
  return arr
}

Logger.log(getCheckData())
// => [{x=クスリマス, o=クリスマス}, {o=コロナ禍, x=コロナ渦}]

シートかドキュメントのIDから情報取得

GoogleスプレッドシートやGoogleドキュメントにはIDが付いている。

URLの/d/のうしろの太字の部分がIDに該当します。

https://docs.google.com/spreadsheets/d/1X9Gn8L0PCI8XejyYruu2w77X-ouW2778UhC7TbLwFYc/

この部分をDriveApp.getFileById()で取得すればいろいろな情報が取得できる。

function getFileData() {
  const file = DriveApp.getFileById('1X9Gn8L0PCI8XejyYruu2w77X-ouW2778UhC7TbLwFYc')
  console.log(file.getName()) // ファイル名
  console.log(file.getUrl()) // ファイルのURL
  console.log(file.getLastUpdated()) // ファイル更新日
  console.log(file.getDateCreated()) // ファイル作成日
  console.log(file.getMimeType()) // ファイルのMimeタイプ
}

コードにIDを記載して実行するのは手間なのでul.prompt()で取得するようにする。

function getFileData() {
  const ui = SpreadsheetApp.getUi()
  const res = ui.prompt('IDを入力してください。', '', ui.ButtonSet.OK_CANCEL)
  const fileId = res.getResponseText()
  const file = DriveApp.getFileById(fileId)
  console.log(file.getName()) // ファイル名
}

正規表現でURLからもIDを取得

IDではなくURLを貼り付けてIDを取得したい場合は/^https:/.test(text)で判定してURLならmatchで抽出する。

function getFileId() {
  const ui = SpreadsheetApp.getUi()
  const res = ui.prompt('IDを入力してください。', '', ui.ButtonSet.OK_CANCEL)
  const text = res.getResponseText()
  const fileId = /^https:/.test(text) ? text.match(/\/d\/([^/]+)\//)[1] : text
  console.log(fileId)
}

スプレッドシートかドキュメントか判定

ファイルのMimeタイプを使用すればGoogleスプレッドシート、ドキュメント、スライドなどを判定できる。

この3つはテキストの取得方法が異なるので必ず判定する必要がある。

if (file.getMimeType() === 'application/vnd.google-apps.spreadsheet') {
  getGsheetText(fileId, sheetResult)
} else if (file.getMimeType() === 'application/vnd.google-apps.document') {
  getGdocText(fileId, sheetResult)
} else if (file.getMimeType() === 'application/vnd.google-apps.presentation') {
  getGslideText(fileId, sheetResult)
}

gsheetのテキストの取得方法

gsheetの場合はアクティブのシートだけの場合はgetActiveSheet()で取得できるが…

function getGsheetText() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = ss.getActiveSheet()
  const range = sheet.getDataRange()
  console.log(range.getValues())
}

gsheetはgdocと異なりシートで複数に別れていることがある。

そのため複数のシートのテキストを取得する場合はgetSheetsで複数取得してforEachで取得する。

function getGsheetText() {
  const ui = SpreadsheetApp.getUi()
  const res = ui.prompt('IDを入力してください。', '', ui.ButtonSet.OK_CANCEL)
  const fileId = res.getResponseText()
  const file = SpreadsheetApp.openById(fileId)
  const sheets= file.getSheets()
  sheets.forEach(sheet => {
    const range = sheet.getDataRange()
    console.log(range.getValues())
  })
}

gdocのテキストの取得方法

gdocの場合はDocumentApp.openById()でidからファイルを取得してfile.getBody().asText().getText()でテキストを取得する。

function getGdocText() {
  const ui = SpreadsheetApp.getUi()
  const res = ui.prompt('IDを入力してください。', '', ui.ButtonSet.OK_CANCEL)
  const fileId = res.getResponseText()
  const file = DocumentApp.openById(fileId)
  const text = file.getBody().asText().getText()
  console.log(text)
}

gslideのテキストの取得方法

gslideの場合はSlidesApp.openById()でidからファイルを取得してfile.getSlidesで各スライドを取得してforEachで個別のスライドからgetText().asString()でテキストを取得する。

function getGslideText() {
  const ui = SpreadsheetApp.getUi()
  const res = ui.prompt('IDを入力してください。', '', ui.ButtonSet.OK_CANCEL)
  const fileId = res.getResponseText()
  const file = SlidesApp.openById(fileId)
  const slides = file.getSlides()
  const textArr = []
  slides.forEach(slide => {
    slide.getShapes().forEach(shape => {
      textArr.push(shape.getText().asString())
    })
  })
  console.log(textArr)
}

gsheet, gdoc, gslideを判定して取得

ui.promptで取得したidからgsheet, gdoc, gslideの判定できるので、以下のように個別の関数を作成して条件分岐すればそれぞれのファイルのテキストを取得できるようになる。

テキストを取得してcheckシート内のテキストと一致したらresultシートに該当するテキストを追加する。

function getGsheetText(fileId, sheetResult) {
  const file = SpreadsheetApp.openById(fileId)
  const sheets= file.getSheets()
  const checkData = getCheckData()
  const result = []
  sheets.forEach(sheet => {
    const range = sheet.getDataRange()
    range.getValues().forEach((v, i) => {
      checkData.forEach(check => {
        if (~v.indexOf(check.x)) {
          const row = i + 1
          const col = v.indexOf(check.x) + 1
          result.push([
            sheet.getSheetName(),
            sheet.getRange(row, col).getA1Notation(),
            check.x,
            check.o
          ])
        }
      })
    })
  })
  if (result.length) {
    sheetResult.getRange(2, 1, result.length, 4).setValues(result)
  }
}

function getGdocText(fileId, sheetResult) {
  const checkData = getCheckData()
  const file = DocumentApp.openById(fileId)
  const text = file.getBody().asText().getText()
  const textArr = text.split('\n').filter(v => v !== '')
  const result = []
  textArr.forEach((v, i) => {
    checkData.forEach(check => {
      if (~v.indexOf(check.x)) {
        result.push([file.getName(), i, check.x, check.o])
      }
    });
  })
  if (result.length) {
    sheetResult.getRange(2, 1, result.length, 4).setValues(result)
  }
}

function getGslideText(fileId, sheetResult) {
  const checkData = getCheckData()
  const file = SlidesApp.openById(fileId)
  const slides = file.getSlides()
  const textArr = []
  const result = []
  slides.forEach(slide => {
    slide.getShapes().forEach(shape => {
      textArr.push(shape.getText().asString())
    })
  })
  textArr.forEach((v, i) => {
    checkData.forEach(check => {
      if (~v.indexOf(check.x)) {
        result.push([file.getName(), i, check.x, check.o])
      }
    })
  })
  if (result.length) {
    sheetResult.getRange(2, 1, result.length, 4).setValues(result)
  }
}

function getFileText() {
  const ui = SpreadsheetApp.getUi()
  const res = ui.prompt('IDを入力してください。', '', ui.ButtonSet.OK_CANCEL)
  const text = res.getResponseText()
  const fileId = /^https:/.test(text) ? text.match(/\/d\/([^/]+)\//)[1] : text
  const file = DriveApp.getFileById(fileId)
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const sheetResult = ss.getSheetByName('result')
  sheetResult.getRange(2, 1, sheetResult.getLastRow(), 4).clear()

  if (file.getMimeType() === 'application/vnd.google-apps.spreadsheet') {
    getGsheetText(fileId, sheetResult)
  } else if (file.getMimeType() === 'application/vnd.google-apps.document') {
    getGdocText(fileId, sheetResult)
  } else if (file.getMimeType() === 'application/vnd.google-apps.presentation') {
    getGslideText(fileId, sheetResult)
  }
}

一致したらresultシートに書き出す

checkシートに一致したテキストは一致したものをresultシートに一覧で書き出しておくと何が検出されたのかがわかりやすくなる。

作成したサンプルのコードではresultの配列にシート名(ファイル名)、該当のテキストがある場所、誤、正の情報を格納している。

result.push([
  sheet.getSheetName(),
  sheet.getRange(row, col).getA1Notation(),
  check.x,
  check.o
])

GoogleドキュメントとスライドはスプレッドシートのようにA2のように場所を指定できないため、配列の場所を入れている。

result.push([file.getName(), i, check.x, check.o])

実行しやすいようヘルプ右に追加

このGASで実行するのはgetFileTextという関数だけだが、スクリプトエディタから実行するのは手間なのでcreateMenuでメニューのヘルプ右に追加してgetFileText()を実行できるようにしておくと良いだろう。

function onOpen() {
  const ui = SpreadsheetApp.getUi()
  const menu = ui.createMenu('チェック')
  menu.addItem('実行', 'getFileText')
  menu.addToUi()
}
GASでシートかドキュメントのIDを指定して文章校正する方法

最後にGASを圧縮する

GASは圧縮したほうが処理速度が早くなるのでClosure CompilerでコンパイルしたものをApps Scriptのコード.gsに貼り付けて利用する。

ここまで読んでよく理解できなかった人でもGoogleスプレッドシートを作成してcheckシートとresultシートを作成して「ツール => スクリプトエディタ」に以下のコードを保存すれば「チェック => 実行」から使用可能ですので試してみてください。

function onOpen(){var a=SpreadsheetApp.getUi().createMenu("\u30c1\u30a7\u30c3\u30af");a.addItem("\u5b9f\u884c","getFileText");a.addToUi()}function getCheckData(){var a=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("check");a=a.getRange(2,1,a.getLastRow()-1,2);for(var c=[],b=1;b<=a.getNumRows();b++){var f=a.getCell(b,1).getValue(),d=a.getCell(b,2).getValue();c.push({x:f,o:d})}return c}
function getFileId(){var a=SpreadsheetApp.getUi();a=a.prompt("ID\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002","",a.ButtonSet.OK_CANCEL).getResponseText();a=/^https:/.test(a)?a.match(/\/d\/([^/]+)\//)[1]:a;console.log(a)}
function getGsheetText(a,c){var b=SpreadsheetApp.openById(a).getSheets(),f=getCheckData(),d=[];b.forEach(function(e){e.getDataRange().getValues().forEach(function(h,g){f.forEach(function(k){if(~h.indexOf(k.x)){var l=g+1,m=h.indexOf(k.x)+1;d.push([e.getSheetName(),e.getRange(l,m).getA1Notation(),k.x,k.o])}})})});c.getRange(2,1,d.length,4).setValues(d)}
function getGdocText(a,c){var b=getCheckData(),f=DocumentApp.openById(a),d=[];f.getBody().asText().getText().split("\n").filter(function(e){return""!==e}).forEach(function(e,h){b.forEach(function(g){~e.indexOf(g.x)&&d.push([f.getName(),h,g.x,g.o])})});c.getRange(2,1,d.length,4).setValues(d)}
function getGslideText(a,c){var b=getCheckData(),f=SlidesApp.openById(a),d=[],e=[];f.getSlides().forEach(function(h){h.getShapes().forEach(function(g){d.push(g.getText().asString())})});d.forEach(function(h,g){b.forEach(function(k){~h.indexOf(k.x)&&e.push([f.getName(),g,k.x,k.o])})});c.getRange(2,1,e.length,4).setValues(e)}
function getFileText(){var a=SpreadsheetApp.getUi();a=a.prompt("ID\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002","",a.ButtonSet.OK_CANCEL).getResponseText();a=/^https:/.test(a)?a.match(/\/d\/([^/]+)\//)[1]:a;var c=DriveApp.getFileById(a),b=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("result");b.getRange(2,1,b.getLastRow(),4).clear();"application/vnd.google-apps.spreadsheet"===c.getMimeType()?getGsheetText(a,b):"application/vnd.google-apps.document"===c.getMimeType()?getGdocText(a,
b):"application/vnd.google-apps.presentation"===c.getMimeType()&&getGslideText(a,b)};

正誤チェックシート

gsheet sample

gdoc sample

gslide sample