#実現したいこと
いつもお世話になっております。
https://teratail.com/questions/196217#reply-290859
https://teratail.com/questions/196919
以前質問させていただいた二つの質問でHTMLのフォームからスプレットシート(シート1)に値を入れるときに値が0の場合シートに格納しないことができて、シート1の指定した箇所の値をコピーして、値が入っている時といない時でそれぞれ別の値を別のシート(シート2)の同じ個所にどちらかが入るような所まで教えていただきました。
今回はそれの続きでシート1に値が入っていない場合、J列をシート2に格納する所は同じで、シートに値が入っていた場合K列を代入するところまでは同じなのですが、代入する前にシート2の最終行に行を追加してJ列の値と日付(L列)を指定した箇所に追加してからその下の行にK列の値と日付を追加したいです
##発生している問題・エラーメッセージ
メソッド insertRowBefore() が見つかりません。
insertRowBefore()の()に適当な値を入れると下のメッセージが表示される
Array を Object[][] に変換できません。
## 概要のソースコード
【コードgs】
function copylist() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var ss_copyFrom = ss.getSheetByName("シート1"); var copyValue = ss_copyFrom.getRange("L2:L299").getValues();//コピー元のシートの中のセルを指定 var copyValue2 = ss_copyFrom.getRange("J2:K299").getValues();//コピー元のシートの中のセルを指定 var setData = copyValue2.map(function(row) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var ss_copyFrom = ss.getSheetByName("シート1"); var copyValue3 =ss_copyFrom.getRange("J2:J299").getValues(); var ss_copyTo = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); var sheet_copyTo = ss_copyTo.getSheetByName('シート2'); if(row[1]!== ""){ sheet_copyTo.insertRowBefore(); sheet_copyTo.getRange("I3:I300").setValues(copyValue3); sheet_copyTo.getRange("O3:O300").setValues(copyValue3); return [row[1] === "" ? row[0] : row[1]]; } }); var ss_copyTo = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); var sheet_copyTo = ss_copyTo.getSheetByName('シート2');//コピー先のスプレットシートの中のシート名 sheet_copyTo.getRange("I3:I300").setValues(setData); sheet_copyTo.getRange("O3:O300").setValues(setData); sheet_copyTo.getRange("D3:D300").setValues(copyValue); }
## 試したこと
if(row[1]!== ""){ sheet_copyTo.insertRowBefore(); sheet_copyTo.getRange("I3:I300").setValues(copyValue3); sheet_copyTo.getRange("O3:O300").setValues(copyValue3); return [row[1] === "" ? row[0] : row[1]]; }
row[1]の中身がK列であると思ったので!==で空白でなければといった感じのif文を作り、insertRowBeforeで指定した行(K列)が入る前に新しい行を挿入して、J列をgetValuesで手に入れてきてから、setValuesで値を入れるような処理を考えたつもりでしたが動かなくて手詰まりになってしまったので、問題点等のご指摘をお願いします。
## 図表
やりたいこととしてはこのような感じにしたいと考えています
## 追記
macaron_xxx様の回答・追記を受けて自分なりの解釈と疑問点を追記させていただきます
function q197326() { //コピー元のスプレットシートを取得する var ss = SpreadsheetApp.getActiveSpreadsheet(); var ss_copyFrom = ss.getSheetByName("シート1"); var fromData = ss_copyFrom .getDataRange().getValues(); // データは全部取る //コピー先のスプレットシートを取得する var ss_copyTo = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); var sheet_copyTo = ss_copyTo.getSheetByName('シート2'); //コピー先のスプレットシートの中のシート名 var toData = sheet_copyTo.getDataRange().getValues(); // データは全部取る
この部分は理解できました
var tmpRow = (function(baseArr) { var arr = []; for (var i = 3; i < 15; i++) { arr.push(baseArr[i]); } return arr; })(toData[1]);
tmprowを元の配列としてarrに空の配列を与えて、3列目(差額支払い日)から15列になるまで繰り返し処理を行ってbaseArr(基準の配列?)に配列を加える
その後returnでarrに返してtoDateに収納する
テンプレートになるという表現がとても分かりやすかったです
var setData = fromData.reduce(function(acc, cur, idx, arr) { if(idx !== 0) { var row1 = tmpRow.concat(); row1[0] = cur[11]; row1[5] = cur[9]; row1[6] = arr[0][9]; row1[11] = cur[9]; acc.push(row1);
acc(アキュムレーター)状態を保持するための引数? cur(現在値)idx(現在のインデックス)シートの行
arr(配列)上の行で作ったシート2のテンプレの配列
row1=tmpRowの部分に以下の配列を連結する
row1[0] = cur[11]; シート2の差額支払い日とシート1の支払日
row1[5] = cur[9]; シート2の仮払い金とシート1の支払金
row1[6] = arr[0][9]; この部分がいまいち理解できませんでした
row1[11] = cur[9]; シート2の仮払い金とシート1の支払金
acc.push(row1); 最新の配列(コピー先のデータ)に上の行でrow1に加えた情報を追加する
if(cur[10] !== "") { var row2 = tmpRow.concat(); row2[0] = cur[11]; row2[5] = cur[10]; row2[6] = arr[0][10]; row2[11] = cur[10]; acc.push(row2); } } return acc; }, []);
シート1の差額の部分が空白でないならば変数row2を追加する
row2の部分は上の値が違うだけなので省略
return acc; if分で追加した要素を最新の配列コピー先のデータにreturnで戻す
[]が初期値なのは空の配列だからということであっているでしょうか?
sheet_copyTo.getRange(sheet_copyTo.getLastRow() + 1, 4, setData.length, setData[0].length).setValues(setData); }
だいたいは理解できたのですが
setData.lengthは貼り付ける行数
setData[0].lengthは貼り付ける列数になるの部分がいまいち理解できていないです・・・
## わからない部分
1 今回使っているreduce関数と前回使っていただいたmap関数は役割的にかなり近いものがあると調べてみて感じたのですが今回reduce関数を使用した理由等があればお聞きしたいです
2 row1[6] = arr[0][9]; この部分がいまいち理解できませんでした
この部分はどのような役割を果たしているのでしょうか?
3 etData.lengthは貼り付ける行数
setData[0].lengthは貼り付ける列数になる理由・・・
追記 SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')の文字列リテラルを閉じました

回答1件
あなたの回答
tips
プレビュー