どうも。つじけ(tsujikenzo)です。今日は単発で「処理済みレコードにStarを付けよう」をお届けします。
この記事は、#Effective GoogleAppsScriptタグがついております。
今日のアジェンダ
- 処理済みレコードとは
- 2次元配列の処理
- オブジェクト化した処理
処理済みレコードとは
レコードとは
みなさん、スプレッドシートとGASを連携して、請求書を作成したり、メッセージを送信していると思います。 データベースを学んでいるかたにはおなじみだと思いますが、この、1行の1データを「レコード」と呼びます。
処理はレコード単位で行います。
物理削除と論理削除
処理が終わったレコードの扱い方は、さまざまな方法があります。
- マウス操作で削除する
- GASでデータを削除する
これは、実際にレコードを削除してしまう手法で、「物理削除」 と呼ばれます。
一方で、「レコードは存在するんだけど、データ的に削除する」という手法があります。「削除されたかどうか」とという列を、スプレッドシートに追加します。
セルには「TRUE」か「FALSE」のどちらかを入力して、レコードが存在するかを論理的にします。このような手法を 「論理削除」 と言います。
処理として負担が少なく、管理しやすいのが、論理削除で、さまざまな応用ができます。
処理済み列
以前「Gmail処理にStar機能を使おう」という記事で、処理済みGmailにStarを付ける流れをご紹介しました。
スプレッドシートも同様に、処理済みの列を作成し、任意の文字を入力することで、処理済み判定ができます。(わたしは★を使うのが好きです)
この処理を、GASで書いてみましょう。
2次元配列による処理
スプレッドシートは、引き続き、このような構成になっています。
やりたい処理は、以下です。
- 処理済み列に★がついているか判定
- ついていなければ、「メモ」をコンソールログに出力する
- 処理済み列に★をつける
まずは、初級編です。
getDataRange()メソッドで、シート全体の値を変数に格納します。
const sheet = SpreadsheetApp.getActiveSheet();
const values = sheet.getDataRange().getValues();
見出し行(1行目)を取り除きます。
values.shift();
for of文を使って、valuesのvalue(1レコードずつ)を処理します。今回は、D列(インデックス3)をコンソールログ出力します。
for (const value of values) {
console.log(value[3]);
}
このままだと、すべてのD列が出力されてしまうので、事前処理として、A列(インデックス0)が★のときはcontinue(Skipする処理)させます。
for (const value of values) {
if (value[0] === "★") continue;
console.log(value[3]);
}
処理が終わったら、A列にStarを入力したいので、entries()メソッドをつかって、values[i][0]にアクセスします。(少し理解に時間がかかるポイントです)
for (const [i,value] of values.entries()) {
if (value[0] === "★") continue;
console.log(value[3]);
values[i][0] = "★";
}
最後にvaluesをsetValues()します。(見出し行を除いていますので、2行目から開始です)
sheet.getRange(2, 1, values.length, values[0].length).setValues(values);
実行してみると、コンソールログが出力されます。
スプレッドシートのA列にもStarが入力されています。
オブジェクト化した処理
続いて、中級編です。スプレッドシートの構造も少しだけ複雑にします。
やりたい処理は、以下です。
- 処理済み列に★がないレコードを抽出する
- 営業部のレコードのみを抽出する
- 「未処理」「営業部」の「メモ」をコンソールログに出力する
- 処理済み列に★をつける
見出し行を除くレコードを変数に格納します。
const sheet = SpreadsheetApp.getActiveSheet();
const [header, ...records] = sheet.getDataRange().getValues();
オブジェクト(連想配列型)に変換します。
const keyValueArray = records.map(record => {
const obj = {};
header.map((key, index) => obj[key] = record[index]);
return obj;
});
スター無しのレコードのみを抽出します。
const withoutStarRecords = keyValueArray.filter(record => record['処理済み'] !== '★');
営業部のレコードのみを抽出します。
const eigyobuRecords = withoutStarRecords.filter(record => record['部署'] === '営業部');
ログ出力します。
for (const record of eigyobuRecords) {
console.log(record['メモ']);
}
スター処理をします。
eigyobuRecords.forEach(record => {
record['処理済み'] = '★';
return record;
});
オブジェクトを2次元配列に戻します。
const newRrecords = keyValueArray.map(record => Object.values(record));
最後にsetValues()します。
sheet.getRange(2, 1, newRrecords.length, newRrecords[0].length).setValues(newRrecords);
実行すると、ログ出力されます。
処理済みレコードに、Starが入力されます。
まとめ
以上で、「処理済みレコードにStarを付けよう」をお届けしました。
参照渡しを理解すると、何を変数に格納し、格納しないかの区別がつくと思います。
中級の場合、各メソッドの戻り値が、新しい配列を生成するのか、というのもポイントです。
ぜひ活用してみてください。
GitHubリポジトリ
この記事のコード全文は、GitHubにUPしています。