ラベル AppScript の投稿を表示しています。 すべての投稿を表示
ラベル AppScript の投稿を表示しています。 すべての投稿を表示

2024年11月29日金曜日

GoogleSpreadSheetで月ごとに色を分ける方法

GoogleSpreadSheetで月ごとに色を分ける方法

概要

特定のカラムで日時を管理している場合に月ごとにセルの色を変更する方法を紹介します
条件付き書式ではできないので GoogleAppScript を使います

環境

  • GoogleSpreadSheet (2024/11/29時点)
  • GoogleAppScript (2024/11/29時点)

特定の色に変更する方法

事前に30色分(30ヶ月分)用意しています
何度実行しても同じ色になるようにしています

B2 カラムで日時を管理している想定です
B2 カラムの1行目はヘッダで2行目から日時データの想定です
B2 カラムの日時はフォーマットが Date になっていることが条件です

function colorRowsByMonth() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const lastRow = sheet.getLastRow(); // シート内の最終行を取得
  const range = sheet.getRange(2, 2, lastRow - 1, 1); // B列の2行目から最終行まで取得
  const values = range.getValues(); // データを2次元配列で取得
  const colors = {}; // 月ごとの色を保持するオブジェクト
  const colorPalette = getLargeFixedColorPalette(); // 固定された30色の薄い色パレット
  let paletteIndex = 0;

  for (let i = 0; i < values.length; i++) { // ヘッダーをスキップ
    const date = values[i][0]; // 日時が入力されているカラム (A列の場合)
    if (date instanceof Date) { // 日付形式か確認
      const monthKey = Utilities.formatDate(date, Session.getScriptTimeZone(), "yyyy/MM");
      // 月ごとの色を設定(未登録なら新しい色を割り当て)
      if (!colors[monthKey]) {
        colors[monthKey] = colorPalette[paletteIndex % colorPalette.length];
        paletteIndex++;
      }
      // B2から下に行の背景色を設定
      sheet.getRange(i + 2, 2, 1, 1).setBackground(colors[monthKey]);
    }
  }
}

// 固定された30個の薄い色のパレットを生成する関数
function getLargeFixedColorPalette() {
  return [
    "#FFCCCC", "#FFEECC", "#FFFFCC", "#CCFFCC", "#CCE5FF",
    "#CCCCFF", "#FFCCE5", "#FFE4B5", "#D8BFD8", "#B0E0E6",
    "#F0E68C", "#E6E6FA", "#F5DEB3", "#FFDAB9", "#F0FFF0",
    "#FFF0F5", "#FFFACD", "#E0FFFF", "#FAFAD2", "#D3D3D3",
    "#FFC0CB", "#B0C4DE", "#ADD8E6", "#DDA0DD", "#D9F2E6",
    "#F2E2D2", "#F5F5DC", "#FBE5D6", "#EBF4FA", "#FAEBD7"
  ];
}

月分だけ色を用意する方法

例えば 2024/01 と 2025/01 は同じセルの色にしたい場合などはこちらを使います
こちらの方法は12色準備すれば OK なので色の追加などは不要です

function colorRowsByMonth() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const lastRow = sheet.getLastRow(); // シート内の最終行を取得
  const range = sheet.getRange(2, 2, lastRow - 1, 1); // B列の2行目から最終行まで取得
  const values = range.getValues(); // データを2次元配列で取得
  const monthColors = getMonthColors(); // 月ごとの色を取得

  for (let i = 0; i < values.length; i++) { // ヘッダーをスキップ
    const date = values[i][0]; // 日時が入力されているカラム (A列の場合)
    if (date instanceof Date) { // 日付形式か確認
      const month = date.getMonth(); // 月を取得(0: 1月, 11: 12月)
      const color = monthColors[month]; // 月に対応する色を取得
      // B2から下に行の背景色を設定
      sheet.getRange(i + 2, 2, 1, 1).setBackground(color);
    }
  }
}

// 1月から12月までの固定色を返す関数
function getMonthColors() {
  return [
    "#FFCCCC", // 1月 - 薄い赤
    "#FFEECC", // 2月 - 薄いオレンジ
    "#FFFFCC", // 3月 - 薄い黄色
    "#CCFFCC", // 4月 - 薄い緑
    "#CCE5FF", // 5月 - 薄い青
    "#CCCCFF", // 6月 - 薄い紫
    "#FFCCE5", // 7月 - 薄いピンク
    "#FFE4B5", // 8月 - 薄いベージュ
    "#D8BFD8", // 9月 - 薄いモーブ
    "#B0E0E6", // 10月 - 薄い水色
    "#F0E68C", // 11月 - 薄いカーキ
    "#E6E6FA"  // 12月 - 薄いラベンダー
  ];
}

最後に

レコードが増えたら再度 GAS を実行する必要があるのが不便です
(条件付き書式でもできる方法があるのだろうか)

2024年4月28日日曜日

Apps Script で doGet を実装して http リクエストを受け取れるようにする

Apps Script で doGet を実装して http リクエストを受け取れるようにする

概要

Google Apps Script にはウェブアプリとしてデプロイできる機能がありこれを使うことで Apps Script の特定の関数を curl からコールできるようになります
今回はその方法を紹介します

環境

  • Google Apps Script (2024/04/22 時点)

doGet の実装

function doGet(e) {
  var params = JSON.stringify(e);
  return ContentService.createTextOutput(params).setMimeType(ContentService.MimeType.JSON);
}

アプリのデプロイ

curl で実行する場合には全公開する必要があります

ウェブアプリの URL が発行されるのでメモしておきます

動作確認

リダイレクトがあるので curl の場合は -L を付与します

  • curl -L "https://script.google.com/macros/s/xxxxxx/exec"
{"contextPath":"","parameter":{},"parameters":{},"contentLength":-1,"queryString":""}

クエリストリングも送れます

  • curl -L "https://script.google.com/macros/s/xxxxxx/exec?name=hawksnowlog"
{"contentLength":-1,"parameters":{"name":["hawksnowlog"]},"queryString":"name=hawksnowlog","parameter":{"name":"hawksnowlog"},"contextPath":""}

最後に

AppsScript で定義した関数を外部からコールできるようにしてみました
ショートカットにしておけばアクセスするだけで特定のデータを抽出したりできます

自分しかアクセスできないウェブアプリの場合はブラウザでしかアクセスできないので注意しましょう

参考サイト

2022年12月22日木曜日

Google App Script で使用している列の一覧を取得する方法

Google App Script で使用している列の一覧を取得する方法

概要

例えば A から AB まで列を広げている場合に A から AB までを持つ配列を取得する方法を紹介します

環境

  • Google App Script 2022/12/16 時点

サンプルコード

// 数字情報を列のアルファベットに変換するメソッド
function columnToLetter(column) {
  var temp, letter = '';
  while (column > 0)
  {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}

// 指定の配列を number 個ずつ分割するメソッド
function sliceByNumber(array, number) {
  const length = Math.ceil(array.length / number)
  return new Array(length).fill().map((_, i) =>
    array.slice(i * number, (i + 1) * number)
  )
}

// メイン
function main() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var activeCols = sliceByNumber([...Array(sheet.getLastColumn()).keys()].map(i => columnToLetter(i+1)), 3);
}

ちょっと解説

[...Array(sheet.getLastColumn()).keys()] で最初の列からアクティブになっている最後の列までの数字配列を取得します

その結果に対して map で columnToLetter を実行し数字 -> アルファベットの変換をしています
数字状態の配列は0から始まっているので1から始めるために+1しています (A列は1に割り当てているので)

あとは sliceByNumber で配列を更に3つずつに分割しています
分割が必要ない場合は sliceByNumber の実行は不要です

最後に

これでどんどん列が増えていっても自動で列情報を取得することができます