【GAS】スプレッドシートにGmailからスクレイピング~重複しないようにする~【第8回】
前回はスプレッドシートにとりあえず書き込んでみました。今回は、重複しないように書き込めるようにしたいと思います。
目次
- 【GAS】スプレッドシートにGmailからスクレイピング~メールを検索して件名を表示~【第1回】
- 【GAS】スプレッドシートにGmailからスクレイピング~本文からデータを抜き出して表示~【第2回】
- 【GAS】スプレッドシートにGmailからスクレイピング~抜き出したデータの整理と関数化~【第3回】
- 【GAS】スプレッドシートにGmailからスクレイピング~日付データと配列化とソート~【第4回】
- 【GAS】スプレッドシートにGmailからスクレイピング~GmailIDと各データ取得~【第5回】
- 【GAS】スプレッドシートにGmailからスクレイピング~スプレッドシートの用意~【第6回】
- 【GAS】スプレッドシートにGmailからスクレイピング~スプレッドシートへの書き込み~【第7回】
- 【GAS】スプレッドシートにGmailからスクレイピング~重複しないようにする~【第8回】
- 【GAS】スプレッドシートにGmailからスクレイピング~GASでセルに関数を入れる~【第9回】
- 【GAS】スプレッドシートにGmailからスクレイピング~トリガー設定~【第10回】
今回やること
Gmail IDで重複しているかどうかをチェックしてから書き込みを行います。そのためには、Gmail IDの列データと、そこにデータが含まれているかどうかをチェックする必要があります。
.getRange(行番号、列番号、行数、列数).getValues()
.getRangeは前回も使いましたが、今回は範囲を指定して使います。列数は省略すると1列になります。範囲で取得する場合は、getvaluesとする必要があります。二次元配列で取得されます。
const range = st.getRange(7,28,st.getLastRow()-6).getValues();
配列.flat()
flat()メソッドは、サブ配列の要素を指定した深さで結合して新しい配列を生成します。深さを指定する時は.flat(2)のように使います。
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]
配列.includes()
includes()メソッドは、特定の要素が配列内に含まれているかどうかをtrue、falseで返します。
const array1 = [1, 2, 3];
console.log(array1.includes(2));
// expected output: true
配列に含まれているかテスト
上記の3つを使って、配列を取得して値が含まれているかテストします。g_idには実際に含まれていたGmail IDから値を持ってきました。
GAS
const range = st.getRange(7,28,st.getLastRow()-6).getValues();
const g_id = '1819d502ef867706';
console.log(range.flat().includes(g_id));
実行結果
「true」が返されました。
continue
continue文は「true」の時、現在のループの反復処理中の文の実行を終了して、次の反復処理でループの実行を続けます。
let text = '';
for (let i = 0; i < 10; i++) {
if (i === 3) {
continue;
}
text = text + i;
}
console.log(text);
// expected output: "012456789"
先ほどのflatと組み合わせると、true(Gmail IDが重複)の時に、現在のループ処理を終了してくれるので、ifと組み合わせることでスプレッドシートに書き込まれなくなります。
GAS全体
function myFunction() {
const query ='さんの脳トレ記録をお届けします。';
const start = 0;
const max = 10;
const threads = GmailApp.search(query,start,max);
const st = SpreadsheetApp.openById('Gmail ID').getSheetByName('シート1');
const st2 = SpreadsheetApp.openById('Gmail ID').getSheetByName('シート2');
const fetchData = (str ,pre ,suf) =>{
const reg = new RegExp(pre + '.*?' + suf,'g');
const preg = new RegExp(pre,'g');
const sreg = new RegExp(suf,'g');
var data = str.match(reg);
var data1 = null;
if(data !== null){
data1 = data[0].replace(preg,'').replace(sreg,'');
}
return data1;
};
const fetchData1 = (str ,pre ,suf) =>{
const reg = new RegExp(pre + '*?' + suf,'g');
const preg = new RegExp(pre,'g');
const sreg = new RegExp(suf,'g');
var data = str.match(reg);
var data1 = null;
if(data !== null){
data1 = data[0].replace(preg,'').replace(sreg,'');
}
return data1;
};
const moment = (str1) =>{
const minute = str1.replace('分',':').replace('秒','.');
return minute;
};
var date10 = [['日付','経過日数','脳年齢','抑制力','処理速度','短期記憶','計算100','人数数え','ID']];
var calc1001 = null;
var people1 = null;
var calc250 = null;
var double_task1 = null;
var kanji1 = null;
var last_photo1 = null;
var finger_calc1 = null;
var finger_exe1 = null;
for(const thread of threads){
const messages = GmailApp.getMessagesForThread(thread);
for(const message of messages){
const plainBody = message.getPlainBody();
const id = message.getId();
const continuity = fetchData(plainBody,'脳トレ\\s','日目');
const date = fetchData(plainBody,'日目\\s','(');
const ba = fetchData(plainBody,'今回:脳年齢\\s','才');
const ba_suppression =fetchData(plainBody,'・抑制力\\s','才');
const ba_process = fetchData(plainBody,'・処理速度\\s','才');
const ba_memory = fetchData(plainBody,'・短期記憶\\s','才');
const calc100 = fetchData(plainBody,'計算100\\s・','(');
const calc25 = fetchData(plainBody,'計算25\\s・','(');
const ns_read =fetchData(plainBody,'新聞音読\\s・','音');
const song_perf = fetchData(plainBody,'名曲演奏\\s・','点(');
const people = fetchData(plainBody,'人数数え\\s・','/6問');
const kanji = fetchData(plainBody,'漢字合成\\s・','(')
const last_photo = fetchData(plainBody,'直前写真\\s・','(');
const ins_memory = fetchData(plainBody,'瞬間記憶\\s・','個(');
const finger_calc = fetchData(plainBody,'指計算\\s・','(');
const finger_exe = fetchData(plainBody,'指体操\\s・','(');
const double_task = fetchData(plainBody,'二重課題\\s・','(');
const sudoku_class = fetchData(plainBody,'数独(',')');
const sudoku_art = fetchData(plainBody,'・','問クリア');
const anecdote = fetchData1(plainBody,'川島教授の脳の小話\\s[\\s\\S]','\\s\\s\\s\\s')
if(calc25 !== null){
calc250 = moment(calc25);
}
else{calc250=null;}
if(calc100 !== null){
calc1001 = moment(calc100);
}
else{calc1001 = null;}
if(people !== null){
people1 = moment(people);
}
else{people1 = null;}
if(kanji !== null){
kanji1 = moment(kanji);
}
else{kanji1 = null;}
if(last_photo !== null){
last_photo1 = moment(last_photo);
}
else{last_photo1 = null;}
if(finger_calc !== null){
finger_calc1 = moment(finger_calc);
}
else{finger_calc1 = null;}
if(finger_exe !== null){
finger_exe1 = moment(finger_exe);
}
else{finger_exe1 = null;}
if(double_task !== null){
double_task1 = moment(double_task);
}
else{double_task1=null;}
date10.push([date,continuity,ba,ba_suppression,ba_process,ba_memory,calc1001,calc250,ns_read,song_perf,people1,kanji1,last_photo1,ins_memory,finger_calc1,finger_exe1,double_task1,sudoku_class,sudoku_art,id,anecdote]);
}
}
date10.sort(function(a,b){
return new Date(a[0]) - new Date(b[0]);
});
console.log(date10);
var j = date10.push();
console.log(j);
const hasId = id =>{
const range = st.getRange(7,28,st.getLastRow()-6).getValues();
return range.flat().includes(id);
}
for(let k=1;k<j;k++){
const lastrow = st.getLastRow()+1;
if(hasId(date10[k][19])) continue;
//日付
st.getRange(lastrow,1).setValue(date10[k][0]);
//経過日数
st.getRange(lastrow,2).setValue(date10[k][1]);
//脳年齢
st.getRange(lastrow,4).setValue(date10[k][2]);
//脳年齢-抑制力-処理速度-短期記憶
st.getRange(lastrow,5).setValue(date10[k][3]);
st.getRange(lastrow,6).setValue(date10[k][4]);
st.getRange(lastrow,7).setValue(date10[k][5]);
//トレーニング結果-計算100-計算25-新聞音読-名曲演奏
st.getRange(lastrow,9).setValue(date10[k][6]);
st.getRange(lastrow,11).setValue(date10[k][7]);
st.getRange(lastrow,12).setValue(date10[k][8]);
st.getRange(lastrow,13).setValue(date10[k][9]);
//トレーニング-人数数え-漢字合成-直前写真-瞬間記憶
st.getRange(lastrow,14).setValue(date10[k][10]);
st.getRange(lastrow,16).setValue(date10[k][11]);
st.getRange(lastrow,18).setValue(date10[k][12]);
st.getRange(lastrow,20).setValue(date10[k][13]);
//トレーニング-指計算-指体操-二重課題-数独級-数独数-GmailID
st.getRange(lastrow,21).setValue(date10[k][14]);
st.getRange(lastrow,23).setValue(date10[k][15]);
st.getRange(lastrow,25).setValue(date10[k][16]);
st.getRange(lastrow,26).setValue(date10[k][17]);
st.getRange(lastrow,27).setValue(date10[k][18]);
st.getRange(lastrow,28).setValue(date10[k][19]);
const lastrow1 = st2.getLastRow()+1;
st2.getRange(lastrow1,1).setValue(date10[k][20])
}
}
実行結果
実行後のGmail IDと日付を切り出してみました。Gmail IDが重複して書き込まれないようになっていることがわかります。
最後に
今回は、Gmail IDを使ってメールが重複して書き込まれないようにしました。
次回は、もうひとつの問題点のあらかじめ数式をいれてしまうとうまく動かなくなってしまうことについて対策します。
ディスカッション
コメント一覧
まだ、コメントがありません