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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

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

Q&A

解決済

3回答

7630閲覧

GASで重複していないデータを抽出したいです

ishikoro.1234

総合スコア14

Google Apps Script

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

0グッド

1クリップ

投稿2019/05/28 03:50

編集2019/05/28 03:57

前提・実現したいこと

業務上、シート数の多いスプレッドシートにて翻訳する必要がございまして、仕事の効率化を捗るためにGASを勉強しています。
今回はシートごとに効率よく用語集の作成するために、GASを使ってスプレッドシート内の全てのシートを対象として、シートにあるデータの中に重複していないデータのみ抽出し、新しい行を追加して、重複していないデータを記入したいです。
プログラミングの初心者で、ネットで似たようなコードを検索してアレンジしていますが、どこから間違っているのかが分からなくて、ご教授頂ければ幸いです。

発生している問題・エラーメッセージ

重複していないデータの抽出まではできましたが、なぜか配列をオブジェクトに変換できないとエラーがでました。
また、アクテイブシートを対象にし、重複したデータを取得できていますが、シートごとを対象にコードを書き換えてましたら、
「TypeError: (class)@2e5cac0fは関数ではなくオブジェクトです」と表示されました。

該当のソースコード

Google

1//var ss = SpreadsheetApp.getActiveSpreadsheet(); 2//var sheet = ss.getActiveSheet(); 3 4function readData() { 5 var column = 1, //対象列の指定 6 lastRow = sheet.getLastRow(), //最終列を取得 7 columnRange = sheet.getRange(1,column,lastRow,2),  //範囲を取得 8 rangeArray = columnRange.getValues();  //データを取得 9 rangeArray = [].concat.apply([],rangeArray); 10 Logger.log(rangeArray); 11 return rangeArray; 12} 13 14function findUnique(data) { 15 var sortedData = data.slice().sort(); //データ配列をソート 16 var unique = []; 17 //var setCol = sheet.getLastColumn() + 1; //データのある最終行を取得して、新しい行を追加する際に使う予定です 18 19 for (var i = 0; i <= sortedData.length -1; i++) { 20 21 if (sortedData[i + 1] != sortedData[i]) {  //重複していない文字を抽出 22 unique.push(sortedData[i]); 23} 24 } 25sheet.getRange(1,3).setValues(unique); 26} 27 28function main () { 29 var SSLink = SpreadsheetApp.openById('対象スプレッドシートID'); 30 var sheet = SSLink.getSheets(); 31 var data = sheet.forEach(readData()); 32 var Unique = sheet.forEach(findUnique(data)); 33 //var data = readData(); アクテイブシートを対象にした場合に使っていました 34 //var Unique = findUnique(data); 35 36}

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

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

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

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

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

guest

回答3

0

仕様面での回答となります。

  • 単語帳となる(ブック→)シートを作る
  • 拾うのは単に文章ブックでユニークであることを越えて、単語帳と照らしあわせて考える
  • 単語帳はソートする(あー、でも漢語はうまくソートできないか)

動作検証するつもりなし

javascript

1function q191750() { 2 const dicSheetName = "glossary" 3 const dicSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(dicSheetName) 4 const dicEntries = dicSheet.getDataRange().map(pickFirstOfArray); 5 const pickSpreadSheetId = "sheetid" 6 SpreadsheetApp.openById(pickSpreadSheetId).getSheets() 7 .map(function(e) { return e.getDataRange().map(pickFirstOfArray) }) 8 .reduce(function(a,c){ return a.concat(c)},[]) 9 .filter(function(e,i,a){ return a.indexOf(e) === i}) 10 .filter(function(e){ return dicEntries.indexOf(e) === -1 }) 11 .forEach(function(e) { dicSheet.appendRow([e]) }) 12 dicSheet.getDataRange().sort(1) 13} 14function pickFirstOfArray(e) { 15 return e[0] 16}

投稿2019/05/28 14:51

papinianus

総合スコア12705

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

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

macaron_xxx

2019/05/28 23:55

変数名はdicなのにシート名はglossaryで少し笑いましたw
ishikoro.1234

2019/05/29 02:54

いつもお忙しい中、お時間を割ってご教授くださり、誠にありがとうございます。 上記のコードを参考しながら、自分なりに研究して参ります。
guest

0

ベストアンサー

回答:

「TypeError: (class)@2e5cac0fは関数ではなくオブジェクトです」と表示されました。

呼出関数の引数に対して関数を渡さなければならない時にオブジェクトとなりえる要素を渡し実行しているためです。

そもそも、ご提示いただきましたソースコードをそのままGASで実行しましても関数「readData」内の[sheet.getLastRow()]の呼び出しでエラーとなり、ご質問頂いているエラーは発生しえません。

また、ご質問頂きましたのうち

シートにあるデータの中に重複していないデータのみ抽出し、

とありますが、この点「データ」とは何でしょうか?スプレッドシートの各シートごとの各セル内の入力された文字という意味合いでしょうか?

ご質問頂く場合、ご質問者様が認識なさっていることを具体的に細かくご提示いただきたく存じます。

ソースコードにつきましては間違っている部分が仰る通り初歩的な部分が多いですので、根本的にjavascriptの「文法」「戻り値」「関数」など基礎から学ぶべきかと存じます。

ただ、これでは不親切すぎますので、ユニークな文字列の抽出までのソース例(※)添付しておきます。
それ以降の挿入処理などはお調べつつ実装ください。
※あまりに大きいファイルは負荷がかかりますので、その辺りは自己責任でお願いいたします。

javascript

1 2 /** 3 * 引数で指定したSheetの、targetColumnで指定された列 および 全文字列要素を取得する 4 * @param {Sheet}sheet データを取得するSheetオブジェクト 5 * @param {number|undefined}targetColumn 指定する範囲の列番号 6 * @param {number|undefined}targetLow 範囲の行数 7 * @return {[].<String>} 当該のSheetで取得した文字列を格納したリスト 8 */ 9 function getSheetValues(sheet , targetColumn , targetLow) { 10 // targetColumn が無い場合 1 列をしてい 11 if(!targetColumn)targetColumn = 1; 12 // targetLow が無い場合 最終行を指定 13 if(!targetLow)targetLow =sheet.getLastRow(); 14 // 今回指定した範囲のRangeデータを取得 15 const columnRange = sheet.getRange(1,targetColumn,targetLow,2);  //範囲を取得 16 // Rangeデータ内に含まれる全Valueを取得し、1つの配列要素に変換 17 const rangeValueDataMultipleList =[].concat.apply([], columnRange.getValues()); 18 return rangeValueDataMultipleList; 19 } 20 21 /** 22 * rangeValueDataMultipleList に含まれる文字列をユニークKeyとしたオブジェクトを取得する 23 * @param {[].<String>} rangeValueDataMultipleList 24 * @return {{}} ユニークな文字列をKey,Valueをtrueとしたオブジェクト 25 */ 26 function findUniqueDataObject(rangeValueDataMultipleList) { 27 const tempUniqueDataObject = {}; 28 const uniqueDataObject = {}; 29 // rangeValueDataMultipleListの各要素に含まれる文字列をKey、Valueをtrueとして uniqueDataObject オブジェクトに格納 30 // オブジェクトに格納することで重複要素を 31 const FIND =true; 32 rangeValueDataMultipleList.forEach(function(str){ 33 // 既に重複している為,当該要素を削除 34 if(tempUniqueDataObject[str] === FIND){ 35 delete uniqueDataObject[str]; 36 }else{ 37 tempUniqueDataObject [str] = FIND; 38 uniqueDataObject[str] = FIND; 39 } 40 }); 41 return uniqueDataObject ; 42 } 43 44 45 /** 46 * lastUniqueDataObjectに新しくユニークと判定した uniqueDataObjectの内容を追加する 47 * @param {{}}lastUniqueDataObject 48 * @param {{}}uniqueDataObject 49 */ 50 function margeUniqueObjectData(lastUniqueDataObject , uniqueDataObject){ 51 const FIND =true; 52 if(uniqueDataObject) 53 for(var key in uniqueDataObject){ 54 // 既に要素があったら削除 55 if(lastUniqueDataObject[key]){ 56 delete lastUniqueDataObject[key] 57 }else{ 58 lastUniqueDataObject[key] = FIND; 59 } 60 } 61 } 62 63 64 /** 65 * オブジェクトのKeyとなったデータを配列データとして変換する 66 * @param convertObject 67 * @return {Array} 68 */ 69 function objectKeyToArray(convertObject){ 70 var convertedKeyArray = []; 71 if(convertObject){ 72 convertedKeyArray =Object.keys(convertObject); 73 } 74 return convertedKeyArray; 75 } 76 77 function main () { 78 const TARGET_SHEET_ID = "スプレッドシートID"; 79 const SSLink = SpreadsheetApp.openById(TARGET_SHEET_ID); 80 const sheets = SSLink.getSheets(); 81 const uniqueDataObject = {}; 82 sheets.forEach(function(sheetObject){ 83 const rengeList = getSheetValues(sheetObject); 84 margeUniqueObjectData(uniqueDataObject , findUniqueDataObject(rengeList)); 85 }); 86 Logger.log(uniqueDataObject); 87 const convertedKeyArray = objectKeyToArray(uniqueDataObject); 88 Logger.log(convertedKeyArray); 89 }

投稿2019/05/28 06:15

kanimaru

総合スコア1013

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

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

ishikoro.1234

2019/05/29 04:20

お忙しい中、ご教授及びアドバイスをくださり、誠にありがとうございます。 「シートにあるデータ」の文章につきまして、説明不足で申し訳ございません、文字となります。 また、ユニークな文字列の抽出までのソース例を添付してくださり、誠にありがとうございます。 挿入処理につきまして、また可能であれば、重複していた場合も、一回のみその文字を記録するようにしたいので、自分なりに勉強して参ります。
guest

0

あんまりちゃんとコードを読んでないんですが
少なくとも

GAS

1function readData(sheet) { // 引数にsheetが必要 2 3/* 略 */ 4 5function main () { 6 var SSLink = SpreadsheetApp.openById('対象スプレッドシートID'); 7 var sheets = SSLink.getSheets(); // 複数だから変数名を変更 8 9 sheets.forEach(function(sheet) { 10 findUnique(readData(sheet)); // findUniqueとreadDataは同じSheetに対する処理(?)だから同じループ内 11 }); 12} 13

投稿2019/05/28 05:51

macaron_xxx

総合スコア3191

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問