質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

3036閲覧

GAS スプレッドシート の指定列重複項目を日付の昇降順を参照に削除したいです

nezumimuzen

総合スコア19

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/05/26 07:50

下記参照シートのように、メールアドレスの重複を日付が過去のものから削除するプログラムを組みたいのですが私の組んだコードでは正しく動作しません。
メール重複と日付から参照するようにするにはどう良いかわからず質問をさせていただきました。
環境としましてはスプレッドシート内 の[test]というシート上で動作をさせています。

[参照シート]
|名前|メールアドレス|電話番号|日付
|:--|:--:|--:|
|あ|abcde@abcd.com|09000000000|2020/05/25
|い|fghi@klm.com|09012345678|2020/05/25
|う|nopq@rst.com|09010111213|2020/05/25
|あ|abcde@abcd.com|09014151617|2020/05/26
|い|fghi@klm.com|09000000000|2020/05/26
|え|abcde@abcd.com|09000000000|2020/05/26

[希望の処理完了後]
|名前|メールアドレス|電話番号|日付
|:--|:--:|--:|
|う|nopq@rst.com|09010111213|2020/05/25
|い|fghi@klm.com|09000000000|2020/05/26
|え|abcde@abcd.com|09000000000|2020/05/26

[実際の処理完了後]
|名前|メールアドレス|電話番号|日付
|:--|:--:|--:|
|あ|abcde@abcd.com|09000000000|2020/05/25
|あ|abcde@abcd.com|09014151617|2020/05/26

Google

1 2function removeDuplicates(){ 3 var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 4 5 var objSheet = objSpreadsheet.getSheetByName("test");  6 var sheet = SpreadsheetApp.setActiveSheet(objSheet); 7 sheet.getRange("A:D").sort({column: 4, ascending: false}).removeDuplicates([1]); 8}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

複雑に考え過ぎだと思います。これだけで十分なはずです。

JavaScript

1function myFunction() { 2 const file = SpreadsheetApp.getActiveSpreadsheet(); 3 const sheet = file.getSheetByName("シート1"); 4 5 const lastRow = sheet.getLastRow(); 6 const lastCol = sheet.getLastColumn(); 7 //ヘッダーを除いたデータ範囲を取得 8 const range = sheet.getRange(2, 1, lastRow - 1, lastCol); 9 //ヘッダーを除いたデータ行を2次元配列として取得 10 const data = range.getValues(); 11 12 //メアドのリスト 13 const emails = data.map((rowData) => rowData[1]); 14 15 //末尾から同じメアドを探して見つかった最初のインデックスと同じインデックスの行のみフィルタ 16 const result = data.filter( 17 (rowData, index, array) => index === emails.lastIndexOf(rowData[1]) 18 ); 19 20 //シートクリアしてから貼り付け 21 range.clear(); 22 sheet.getRange(2, 1, result.length, lastCol).setValues(result); 23} 24

投稿2020/05/26 20:21

draq

総合スコア2577

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ソートを掛けて重複を弾くというやり方が思いつかず、ガッツリコードを書いてしまいました。
あまりきれいなコードではないので、参考程度にしていただければ幸いです。。

js

1class Teratail265015 { 2 constructor() { 3 this.NAME = 0; 4 this.EMAIL = 1; 5 this.TEL = 2; 6 this.DATE = 3; 7 } 8 9 uniq() { 10 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 11 const sheet = spreadsheet.getSheetByName('test'); 12 const range = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()); 13 const sheetValues = range.getValues(); 14 15 const uniqData = []; 16 for (let i = 0; i < sheetValues.length; i++) { 17 const row = sheetValues[i]; 18 19 const name = row[this.NAME]; 20 const email = row[this.EMAIL]; 21 const tel = row[this.TEL]; 22 const date = row[this.DATE]; 23 24 let found = false; 25 for (let j = 0; j < uniqData.length; j++) { 26 const datum = uniqData[j]; 27 28 const uniqDataMs = +(new Date(datum[3])); 29 const dateMs = +(new Date(date)); 30 31 if (datum[1] === email) { 32 found = true; 33 if(uniqDataMs <= dateMs) { 34 // 入れ替え 35 uniqData.splice(j, 1); 36 uniqData.push([name, email, tel, date]); 37 } 38 break; 39 } 40 } 41 42 if (!found) { 43 uniqData.push([name, email, tel, date]); 44 } 45 } 46 47 // データ埋め 48 for (let i = uniqData.length; i < sheetValues.length; i++) { 49 uniqData.push([null, null, null, null]); 50 } 51 52 // データ反映 53 range.setValues(uniqData); 54 } 55} 56 57// 呼び出し部 58function myFunction() { 59 (new Teratail265015()).uniq(); 60}

投稿2020/05/26 10:29

nawada

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nezumimuzen

2020/05/26 16:34 編集

nawadaさん、回答ありがとうございます! 書いていただいたコードでtestは正常に動きました! しかし、今回testで4項目だったものを13項目で実装しようとしており、いただいたコードをもとに試しに5項目(下記コード)で実行したところ正常に動いたのですが13項目で動かしたところ「Exception: データの列数が範囲の列数と一致しません。データは 13 列ですが、範囲は 5.列です。(行 73、ファイル「コード」)」とエラーが発生してしまいます。 下記に13項目のコードも記載していますためお手数ですが間違いをお教えいただければ幸いです。 何卒よろしくお願い申し上げます。 5項目コード class Teratail265015 { constructor() { this.NAME = 0; this.EMAIL = 1; this.TEL = 2; this.DATE = 3; this.MAILMAGA= 4; } uniq() { const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadsheet.getSheetByName('test'); const range = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()); const sheetValues = range.getValues(); const uniqData = []; for (let i = 0; i < sheetValues.length; i++) { const row = sheetValues[i]; const name = row[this.NAME]; const email = row[this.EMAIL]; const tel = row[this.TEL]; const date = row[this.DATE]; const mailmaga = row[this.MAILMAGA]; let found = false; for (let j = 0; j < uniqData.length; j++) { const datum = uniqData[j]; const uniqDataMs = +(new Date(datum[3])); const dateMs = +(new Date(date)); if (datum[1] === email) { found = true; if(uniqDataMs <= dateMs) { // 入れ替え uniqData.splice(j, 1); uniqData.push([name, email, tel, date, mailmaga]); } break; } } if (!found) { uniqData.push([name, email, tel, date, mailmaga]); } } // データ埋め for (let i = uniqData.length; i < sheetValues.length; i++) { uniqData.push([null, null, null, null, null]); } // データ反映 range.setValues(uniqData); } } // 呼び出し部 function myFunction() { (new Teratail265015()).uniq(); } 13項目(エラーが発生) class Teratail265015 { constructor() { this.MAILMAGA = 0; this.GENDER = 1; this.EMAIL = 2; this.NAME = 3; this.KANA = 4; this.TEL = 5; this.TRACK = 6; this.TRACK0 = 7; this.TRACK1 = 8; this.TRACK2 = 9; this.BIRTH = 10; this.BIKO = 11; this.DATE = 12; } uniq() { const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadsheet.getSheetByName('test'); const range = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()); const sheetValues = range.getValues(); const uniqData = []; for (let i = 0; i < sheetValues.length; i++) { const row = sheetValues[i]; const mailmaga = row[this.MAILMAGA]; const gender = row[this.GENDER]; const email = row[this.EMAIL]; const name = row[this.NAME]; const kana = row[this.KANA]; const tel = row[this.TEL]; const track = row[this.TRACK]; const track0 = row[this.TRACK0]; const track1 = row[this.TRACK1]; const track2 = row[this.TRACK2]; const birth = row[this.BIRTH]; const biko = row[this.BIKO]; const date = row[this.DATE]; let found = false; for (let j = 0; j < uniqData.length; j++) { const datum = uniqData[j]; const uniqDataMs = +(new Date(datum[12])); const dateMs = +(new Date(date)); if (datum[2] === email) { found = true; if(uniqDataMs <= dateMs) { // 入れ替え uniqData.splice(j, 2); uniqData.push([mailmaga, gender, email, name, kana, tel, track, track0, track1, track2, birth, biko, date]); } break; } } if (!found) { uniqData.push([mailmaga, gender, email, name, kana, tel, track, track0, track1, track2, birth, biko, date]); } } // データ埋め for (let i = uniqData.length; i < sheetValues.length; i++) { uniqData.push([null, null, null, null, null, null, null, null, null, null, null, null, null]); } // データ反映 range.setValues(uniqData); } } // 呼び出し部 function myFunction() { (new Teratail265015()).uniq(); }
nawada

2020/05/27 02:09

(draqさんが僕のより確実に見やすい・効率のいいコードを書いてくれていますので、そちらを使用されたほうが良いかと思います。) エラーの内容は「書き込み先の列数が足りないよ。」という内容です。 おそらくtestシートに5列しかないのだと思いますので、testシートのデータを確認してみてください。
nezumimuzen

2020/05/27 07:40

testシートのデータを確認したところnawadaさんのおっしゃる通りシートに問題があり、そちらを直したら正常に動作しました! 丁寧にお教えいただき誠にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問