GASを利用し、簡易な顧客の管理システムを作成しています。
【今から作成したいもの】
スプレッドシート内にGASを利用して検索・登録用のシートを設置して
問い合わせいただいた内容や顧客情報を検索・登録できるようにしたいです。
①検索機能
登録・検索シートから「名前」「電話番号」などを入力した際に
顧客情報から一致する情報を書き出す。
②登録機能
登録・検索シートに情報を入力することで
顧客情報の一番下へ反映される。
(情報が重複する場合わかるようにできればと考えています。)
GASを利用してメール内容の取得などコードを組んでいたのですが、知識不足な点が多くお力添えいただきたいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/07 01:11
回答3件
0
ベストアンサー
質問がうまく伝わらなかったみたいですみません。
少なくともこれまでに与えられた状況からはフィルタ一択です。
フィルタ(エクセルのフィルタのイメージで語ってるのでもしかしたら合ってないかもですが)で、絞り込みが多段階にできる機能が存在するのになぜ中途半端な劣化コピーのコードを書かなければならないのか分かりません。
まあ、自己満足な例を考えてみたんで、(将来の訪問者さんの)参考までに。
こういうデータを用意しました。
で、こういう結果をだしたいと思います。
枠線とか引いてないですが2行目が検索です。結果は5行目以下に出てきます。
質問のような検索窓を作ると、全部の項目で検索したくなるのが人情。
複数項目がからむとandとかorとかのインターフェイスと制御はなかなかに直感的でなくて分かりにくいので、類似度の高いものから(類似度0を除き)リストアップして表示することにしました。
コードはこんな感じ
javascript
1function filterSimilarity() { 2 const dataSheetName = '顧客情報'; 3 const editingSheetName = '登録・検索'; 4 const activeSheet = SpreadsheetApp.getActiveSheet(); 5 if(activeSheet.getName() !== editingSheetName) return; 6 activeSheet.getRange(5,1,Math.max(1, activeSheet.getLastRow() - 5), 7).clear(); 7 const key = activeSheet.getRange(2,1,1,7).getValues()[0]; 8 const data = SpreadsheetApp.getActive().getSheetByName(dataSheetName).getDataRange().getValues(); 9 const similars = data.map(function(e){ return e.concat([calcScore(key,e)]); }).filter(function(e){ return e[e.length - 1] > 0}); 10 if(similars.length < 1) return; 11 similars.sort(function(a,b){ return b[a.length - 1] - a[a.length - 1];}); 12 activeSheet.getRange(5,1,similars.length,similars[0].length).setValues(similars); 13} 14 15function calcScore(key, haystack) { 16 const len = Math.min(key.length, haystack.length); 17 var sum = 0; 18 for(var i = 0; i < len; i++) { 19 if(key[i] === "") continue; 20 if(key[i] === haystack[i]) { sum++; continue;} 21 if(haystack[i].toString().indexOf(key[i].toString()) !== -1) { sum += (key[i].toString().length / haystack[i].toString().length); continue; } 22 } 23 return sum; 24}
calcScore
が雑すぎて実用に耐えないとは思いますが、逆に言えばここの評価関数だけ必要に応じて直せば(例えば日付は無視するとか、フリガナや名前は完全一致にするとか、前方一致にするとか、全角半角をちゃんと考慮するとか)実用できるんじゃないかと思います。このところは要件が明確になっていれば実装は難しくないですが、なんでもかんでも考えつくすっていうのは無理があるところなので、このレベルになってしまいます。
実際のところ、質問の例だと日付の完全一致で探すパターンがあり得るっぽいので、1日に複数の取引先を登録しちゃうだけで、質問のような美しい見た目のマスにはうめられない(同日登録された一部の取引先は日付検索ができない)ことになって破綻するのが目に見えているので、それにくらべりゃだいぶマシかと思います。
投稿2019/05/07 16:03
編集2019/05/08 06:03総合スコア12705
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
以前、Vlookupみたいなのを作る演習を勝手にやってみたときのサンプルがあるので、共有します。
checkdata:検索のためのキーワード
sheetname:検索用リストのあるシート名
targetcolumn:リスト上の検索ワード格納列数
getcolumn:リスト上の取り出したい情報の格納列数
です。
GAS
1/*最もシンプルな発想での記述*/ 2 3function mylookup1(checkdata,sheetname,targetcolumn,getcolumn) { 4 var ss = SpreadsheetApp.getActiveSpreadsheet(); 5 var sh = ss.getSheetByName(sheetname); 6 7 var lastrow = sh.getLastRow(); 8 9 for(var i = 1;i<=lastrow;i++){ 10 var data = sh.getRange(i,targetcolumn).getValue(); 11 if(data == checkdata){ 12 var anser = sh.getRange(i,getcolumn).getValue(); 13 return anser; 14 break; 15 }else{} 16 } 17} 18 19//**************************************************************************************************************** 20/*データを配列でまとめて取得して処理する記述*/ 21 22function mylookup2(checkdata,sheetname,targetcolumn,getcolumn) { 23 var ss = SpreadsheetApp.getActiveSpreadsheet(); 24 var sh = ss.getSheetByName(sheetname); 25 26 var datarange = sh.getDataRange().getValues(); 27 28 for(var i = 0;i<datarange.length;i++){ 29 var data = datarange[i][targetcolumn-1]; 30 if(data == checkdata){ 31 var anser = datarange[i][getcolumn-1]; 32 return anser; 33 break; 34 }else{} 35 } 36} 37 38//**************************************************************************************************************** 39/*データを配列でまとめて取得してindexOfを活用して処理する記述*/ 40 41function mylookup3(checkdata,sheetname,targetcolumn,getcolumn) { 42 var ss = SpreadsheetApp.getActiveSpreadsheet(); 43 var sh = ss.getSheetByName(sheetname); 44 45 var datarange = sh.getDataRange().getValues(); 46 var lastrow = sh.getLastRow(); 47 var dataarry = sh.getRange(1,targetcolumn,lastrow,1).getValues(); 48 var data =Array.prototype.concat.apply([], dataarry); 49 50 var Rownumber = data.indexOf(checkdata); 51 if(Rownumber<=-1){}else{ 52 var anser = datarange[Rownumber][getcolumn-1]; 53 return anser; 54 } 55} 56
投稿2019/05/07 06:09
総合スコア640
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
GoogleスプレッドシートにはVLOOKUP関数が存在します。
https://support.google.com/docs/answer/3093318
データの登録(追加)はコチラをご参照下さい。
https://www.atmarkit.co.jp/ait/articles/1706/09/news018.html
投稿2019/05/05 09:58
編集2019/05/05 10:02総合スコア2937
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。