僕も、hope_mucciさんの意見に賛同します。
項目が一つ増えたとか、部署も表示したいとか要望が増えたり、エラーで動かなくなったとkimizoさんに連絡がきて、なんだかんだと改修の仕事を振られます。
やるとしたらこんな感じかなと思います。
極力わかりやすい関数にしてますので、ちょっと長くなってます。
この内容で難しいと感じるようでしたら、編集や修正は難しいのでピポットテーブルをおすすめします!
gas
1function myfunc(){
2var ss = SpreadsheetApp.openById('***'); //スプレッドシートの指定
3var sheet = ss.getSheetByName('***'); //シートの指定
4var values = sheet.getDataRange().getValues(); //集計したいデータを全取得
5
6
7//結果を入れる連想配列
8var results = {}
9
10//取得した全データを集計
11values.forEach(e =>{
12
13 //タイトル行は無視
14 if(e[0]!="出動日"){
15
16 var date = e[0] //出勤日
17 var name = e[1] //担当者名
18 var content = e[2] //作業内容
19
20
21 //結果に担当者の配列を確認 あれば出動日の回数を追加
22 if(!results[name]){
23 results[name] ={attendance:0}
24 }else{
25 results[name]["attendance"] +=1
26 }
27
28
29 //担当者配列の中に作業内容の値があるか確認 あれば回数を追加
30 if(!results[name][content]){
31 results[name][content] = 1
32 }else{
33 results[name][content] += 1
34 }
35 }
36 })
37
38 var setValues = []
39 var maxColumn = 0
40
41 //setValuesで貼り付ける際に2次元配列の長さが一致しないと貼れないので連想配列の最大の長さを調べる
42 Object.keys(results).forEach(e=>{
43 if(maxColumn < Object.keys(results[e]).length+1){
44 maxColumn = Object.keys(results[e]).length+1
45 }
46 })
47
48 for(var key in results){
49 //名前と出動回数を配列に入れる
50 var item = [[key],["出動日 "+results[key]["attendance"]+"回"]]
51
52 //連想配列の中のスタッフごとの値を連想配列から配列へ変更
53 for(var content in results[key]){
54 if(content != "attendance"){
55 item.push([content+": "+ results[key][content]+"回"])
56 }
57 }
58
59 //setValuesで貼り付ける際に2次元配列の長さが一致しないと貼れないのでここで調整
60 var counter = maxColumn - item.length
61 for(var i = 1; i <=counter;i++ ){
62 item.push("")
63 }
64
65 setValues.push(item)
66 }
67
68
69 var setSheet = ss.getSheetByName('***'); //貼り付け先のシートの指定
70
71 //貼り付け先シートのクリア
72 setSheet.clear();
73 //貼り付け
74 setSheet.getRange(1,1,setValues.length,maxColumn).setValues(setValues)
75
76}
77