質問: 関数が少しわかる程度の初心者です。 どうか条件付の並べ替えについて教えてください。 ### 前提・実現したいこと スプレッドシートで案件の管理をしており、A列からBE列まで情報を記載してます。 案件によっては納期が変更になる事もあるのでその都度、メニューから並べ替えを選んで納期順にしています。 また、一時的に案件がストップしたものはA~Bセルをピンク色に塗りつぶし、最終行に手作業で並べ替えをしています。 私がやりたい事は、ボタンを押すと勝手に納期順に並べ替えをし、かつピンク色に塗りつぶした行は納期の日にち関係なく 最終行にもっていくという事を実現したいです。 【 例 】 A列:月 B列:納期 C列:案件名 D列:お客様名...等 ### 試した事、分からない事 自分で考えた結果 1 まずはピンク色の色コードを取得 ``` function getBackColor(){ var ss=SpreadsheetApp.getActiveSpreadsheet(); var sheet=ss.getSheets()[0]; var cell=sheet.getRange('A67') cell.setBackground('A67') Browser.msgBox("A67のカラーコードは「"+cell.getBackground()+"」"); } ``` 2 1で取得したコードは「#ffccff」だったので 「#ffccff」だったら最終行に並べ替え 「#ffccff」以外だったらB列の納期別に並べ替え という指示を書きたかったのですが、それをどのように書いていいのか分かりません。 ``` function sort(){ var ss=SpreadsheetApp.getActiveSpreadsheet(); var s=ss.getActiveSheet()[0]; var lastRow=ss.getLastRow(); var lastCol=ss.getLastColumn(); const color='#ffccff'; switch(color){ case '#ffccff: ```
回答: パターンA:そのまま実装すると =============== ``` function sort() { const sheet = SpreadsheetApp.getActiveSheet(); sheet.getDataRange().sort({column:2, ascending:true}]); const lastRow = sheet.getLastRow(); const pink = "#ffccff"; const rows = sheet.getRange(1,1,lastRow,1).getBackgrounds().map(function(e,i){ return {R:i+1, Col:e[0]}}).filter(function(e){ return e.Col == pink;}).map(function(e){return e.R}).reverse(); const pinks = rows.length; rows.forEach(function(r) { sheet.moveRows(sheet.getRange(r, 1, 1, 5), lastRow+1);}); sheet.getRange(lastRow - pinks + 1, pinks, 5).sort([{column:2, ascending:true}]); } ``` ~~ピンクのを後ろに下げたときに、その中でもソートがかかっていることにするのが厄介でした。~~ミュータブルなinsertPosをデクリメントしながらやれば、再ソートは不要でしたね。もう検証したくないので書き直しませんが。 必ずA列が着色されているとき、色をまとめてとることはできるので、ボトルネックになるのは、着色行を一つずつ移動させる部分です。着色行が十分に少なければ、実用できると思います。 パターンB:ソート可能なデータを付与できるとすると ========================= 推奨されているソート可能なデータを付与する例ですが、個人的にはチェックボックスをおすすめします。ワンクリックだし誤入力(全角半角)もない。 見た目はこう ![運用イメージ コードはこう ``` function onEdit(e) { const sheet = e.range.getSheet(); if(sheet.getName() !== "そのシートの名前") return; const c = e.range.getColumn(); if(c !== 1) { return; } const r = e.range.getRow(); const value = e.value; switch(value) { case "TRUE" : sheet.getRange(r, 2, 1, 2).setBackground("#ffccff"); break; case "FALSE" : default : sheet.getRange(r, 2, 1, 2).setBackground(null); break; } } function sortByCheck() { const sheet = SpreadsheetApp.getActiveSheet(); sheet.getDataRange().sort([{column:1, ascending:true}, {column:3, ascending:true}]); } ``` ~~こちらは、他人がチェックをつけたときに、コードで色がつくのかなーという疑問がありますが、個人的にG Suiteを持たなくなったので分かりません。~~ ~~(もし運用上可能なら、色のことは忘れて、チェックがあることを延期と思えばいいような)~~ →条件付き書式なんですね。それは思いつかなかった。条件付き書式だとしたら、onEditは不要です)