質問: sh.getRange(LastRow,2); Logger.log(LastRow_Range) LastRow_Range.setFormula("=INDIRECT(\"コメント入力用シート!\"&\"R\"&(ROW()+1)/2&\"C\"&column(B$181), FALSE)"); } ```
回答: まず、あまり手を入れない最低限の変更でループするように↓のように書き換えさせていただきました(もしdiffツールが使えるようなら差分を見てください) こうすることで、例えばスクリプトエディタ画面のメニューの実行→関数の実行からzenbuを選択すれば、コメントの成形シートがまるっと書き換わるはずです(もちろん、コメント入力用シートに空行があっても) ``` function zenbu(){ var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメントの成形"); Logger.log(sh); sh.clear(); // var LastRow = sh.getLastRow(); // Logger.log(LastRow); // var rng = sh.getRange(LastRow,1).getValue(); // Logger.log(rng); // var rng2 = sh.getRange(LastRow,2).getValue(); // Logger.log(rng2); sample_Range_merge(); sample_Range_Formula1(); sample_Range_Formula2(); } function sample_Range_merge(){ var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメントの成形"); var shref = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメント入力用シート"); var LastRow = shref.getLastRow(); Logger.log(LastRow); for(var i = 0; i <= LastRow; i++) { var rng = sh.getRange(i*2+1,2,2); var rng2 = sh.getRange(i*2+1,1,2); // Logger.log(rng); rng.merge(); rng2.merge(); } } // 日付の入力(INDIRECT) function sample_Range_Formula1(){ var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメントの成形"); var shref = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメント入力用シート"); var LastRow = shref.getLastRow(); Logger.log(LastRow); for(var i = 1; i <= LastRow; i++) { // var LastRow_Value = sh.getRange(i,1).getValue(); // Logger.log(LastRow_Value); var LastRow_Range2 = sh.getRange(i*2 + 1,1); // Logger.log(LastRow_Range2) LastRow_Range2.setFormula("=INDIRECT(\"コメント入力用シート!\"&\"R\"&(ROW()+1)/2&\"C\"&column(A$181), FALSE)"); } } // 数式の入力 function sample_Range_Formula2(){ var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメントの成形"); var shref = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("コメント入力用シート"); var LastRow = shref.getLastRow(); Logger.log(LastRow); for(var i = 1; i <= LastRow; i++) { // var LastRow_Value = sh.getRange(i,1).getValue(); // Logger.log(LastRow_Value); var LastRow_Range = sh.getRange(i*2+1,2); Logger.log(LastRow_Range) LastRow_Range.setFormula("=INDIRECT(\"コメント入力用シート!\"&\"R\"&(ROW()+1)/2&\"C\"&column(B$181), FALSE)"); } } ``` ただ、こうなってくると、どういうタイミングでどれくらいの分量のデータを編集するのか、という問題が起こります。 試していただくと分かると思うのですが、上記のスクリプトは(処理内容から考えると)実行に時間がかかりすぎます。コメント入力用シートの行数次第では途中でタイムアウトするかもしれません。 もし、コメント入力用シートが、「データ量が多い」けれども「一行ずつ記入される」(まとめて何行もコピペすることはなく、頻度は多くても一度に一行しか入らない)とか、編集トリガで入力と成形シートが同時並行的にメンテされる、という状況で利用されるものであれば、私が書き換えた方法ではタイムアウトしてデータがおかしくなる危険があります。なので、あえてループにせず、一行ずつ追加する方法(あなた様がもともと書いておられた方法)が適当になる場合もあるかと思いました。 そうではなくて、例えば「データ量は一定量を越えない」(月ごとにファイルもしくはシートが分けられる運用)であるとか「一日一回整理すればよい」(一回の実行に数秒~十数秒待てる)のであれば、ループによる方法も適当かもしれません。 また、関数を動かす方法も、編集をきっかけにするのか、時間なのか、ボタンを配置してそれを押すのか、などどういうタイミングで成形をしたいか、によっても解決方法は異なります。 (もちろん、ループの方法を最適化してもっと早くやるように書くことはできます。ただ、改変可能な、つまり理解可能な方法を提示しようとしています) > > そもそも、今回の私のやりたいことは、手動でやればよいことで、 > > GASを使って実現することが難しいことなのかもしれません...。 > > こう思わせる回答をしてしまったことは、大変に遺憾です。 > > しかし、(手間を減らそうという着想を持てる)あなたのような方がこのような単純作業をするのは勿体ないですし、また今のところGASでやりにくいというよりも、要件が明らかになっていないように思います。 > > > もし前回のif文を取る、あるいは今回のループが目的を達しないのであれば、「何をきっかけに」「どれくらいの量のコメントを」「どれくらいの頻度で」「一回あたりどれくらいの時間をかけて」処理するものなのかが想像できるような実際の使い方をご提示いただければと思います。