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

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

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

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

Q&A

解決済

1回答

1407閲覧

GAS 転記元のデータを条件付きで転記先のデータに反映したい

退会済みユーザー

退会済みユーザー

総合スコア0

Google Apps Script

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

0グッド

1クリップ

投稿2023/07/26 06:13

編集2023/07/26 06:20

GASまったくの初心者です。
いろんなサイトを確認していますが、応用できず質問させていただきます。

下記の条件で、転記元から転記先のシートの最終列にコピーできるようにしたいです。

①転記元のE列が「確定」になっていること
②転記元のG列(番号)と転記先のF列を比較し、同じ番号があれば無視
⑤同じ番号がない場合、転記先の最終列(A列以降)に転記元のデータB列~I列、M列をコピー
(下記の表の場合黄色い部分)

イメージ説明

イメージ説明

こちらの回答が似ているかと思いますが、自分のやりたいことにうまく当てはめることができません。
https://teratail.com/questions/m9951yjox94ueq

よろしくお願いいたします。

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

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

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

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

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

YAmaGNZ

2023/07/26 07:58

質問者さんはどこまでのことが出来ていてどこが出来ないのでしょうか?
退会済みユーザー

退会済みユーザー

2023/07/27 03:44

ほんとうに初心者なので変数とは…引数とは… のレベルでした… わかりづらく申し訳ございませんでした。 ありがとうございました。
guest

回答1

0

ベストアンサー

例えば次のようなスクリプトでしょうか。(修正案の再修正をアップしました。)
当初の例で画像シートの行、列、配列のインデックスを数値のまま(いわゆるマジックナンバーのまま)使っていました。
また、転記する列がM列以降となっていたので、N列以降は転記しないように改めました。
行、列を指定する変数名が多くなりました。(→変数の扱いを再修正しました。)

JavaScript

1function myFunction() { 2 const fr = { //転記元データ 3 rowBegin: 5, //開始行:5行目 4 colBegin: 2, //開始列:B列 5 colEnd: 13, //最終列:M列(この列以降は不要:N列~) 6 colStatus: 5, //ステータスの列:E列 7 colNumber: 7, //番号の列:G列 8 colFillerBegin: 10, //不要な列の開始列:J列 9 colFillerEnd: 12, //不要な列の終了列:L列 10 }; 11 const to = { //転記先データ 12 rowBegin: 4, //開始列:4行目 13 colBegin: 1, //開始列:A列 14 colNumber: 6, //番号の列:F列 15 }; 16 const ss = SpreadsheetApp.getActiveSpreadsheet(); 17 fr.sheet = ss.getSheetByName(FROM_NAME);//← FROM_NAMEを実際の 'シート名' で書換 18 to.sheet = ss.getSheetByName(TO_NAME);//同上 19 //転記元データを二次元配列として取得 20 let fromValues = fr.sheet.getRange(fr.rowBegin, fr.colBegin, fr.sheet.getLastRow() - fr.rowBegin + 1, fr.colEnd - fr.colBegin + 1).getValues(); 21 //確定となっている要素を抽出 22 fromValues = fromValues.filter(v => v[fr.colStatus - fr.colBegin] == '確定'); 23 //転記先の番号の列を一元配列として取得 24 const toValues = to.sheet.getRange(to.rowBegin, to.colNumber, to.sheet.getLastRow() - to.rowBegin + 1, 1).getValues().flat(); 25 //番号が一致している要素を除く 26 if (fromValues.length > 0) { 27 fromValues = fromValues.filter(f => toValues.every(t => t != f[fr.colNumber - fr.colBegin])); 28 } 29 if (fromValues.length > 0) { 30 //不要な列の要素を除く 31 fromValues.forEach(f => f.splice(fr.colFillerBegin - fr.colBegin, fr.colFillerEnd - fr.colFillerBegin + 1)); 32 //転記先シートの最終行の後に追記 33 to.sheet.getRange(to.sheet.getLastRow() + 1, 1, fromValues.length, fromValues[0].length).setValues(fromValues); 34 } 35}

(当初の提案:N列以降も転記される)

JavaScript

1function myFunction() { 2 const ss = SpreadsheetApp.getActiveSpreadsheet(); 3 const shFrom = ss.getSheetByName(FROM_NAME); 4 const shTo = ss.getSheetByName(TO_NAME); 5 //転記元データを二次元配列として取得 6 let vFrom = shFrom.getRange(5, 2, shFrom.getLastRow() - 5 + 1, shFrom.getLastColumn() - 2 + 1).getValues(); 7 //確定となっている要素を抽出 8 vFrom = vFrom.filter(v => v[3] == '確定'); 9 //転記先の番号の列を一元配列として取得 10 const vTo = shTo.getRange(4, 6, shTo.getLastRow() - 4 + 1, 1).getValues().flat(); 11 //番号が一致している要素を除く 12 if (vFrom.length > 0) { 13 vFrom = vFrom.filter(f => vTo.every(t => t != f[5])); 14 } 15 if (vFrom.length > 0) { 16 //不要な列の要素を除く 17 vFrom.forEach(f => f.splice(8, 3)); 18 //転記先シートの最終行の後に追記 19 shTo.getRange(shTo.getLastRow() + 1, 1, vFrom.length, vFrom[0].length).setValues(vFrom); 20 } 21}

投稿2023/07/26 08:26

編集2023/07/27 03:37
YellowGreen

総合スコア868

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

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

YellowGreen

2023/07/27 03:38

コメント欄の列名表記を何度か修正したので最後のものをご利用ください。 コードは変わっていません。
退会済みユーザー

退会済みユーザー

2023/07/27 03:42

まさに!!N列以降もコピーされてしまうので、試行錯誤しているところでした・・・・ 正常に動きました。ほんとにすごいです。尊敬します。 GASのやり方をサイトでみながらここ数日頭が痛くなりながら考えていましたが、 私だけだったら1ヶ月考えてもできなかったでしょう… 本当に助かりました。 本当にありがとうございました。
退会済みユーザー

退会済みユーザー

2023/07/27 05:21 編集

解決後にすみません。 転記先のA4以降の行が空白の場合、エラーが出てしまいます。 おそらく何も入っていないってことはないと思うので大丈夫だとは思うのですが、 もしお時間があればで大丈夫ですのでご回答いただけますと幸いです。 また入れていただいたコメントもとてもわかりやすく、私でもアレンジして使うことができました。 ありがとうございます!!
YellowGreen

2023/07/27 08:14

エラーの内容をそのままコピペできますでしょうか?
YellowGreen

2023/07/27 08:36

Exception: The number of rows in the range must be at least 1. というエラーでしょうか。 そうであれば、 //転記先の番号の列を一元配列として取得 const toValues = to.sheet.getRange(to.rowBegin, to.colNumber, to.sheet.getLastRow() - to.rowBegin + 1, 1).getValues().flat(); を //転記先の番号の列を一元配列として取得 let toValues = [];//空の配列を用意 if (to.sheet.getLastRow() >= to.rowBegin) { toValues = to.sheet.getRange(to.rowBegin, to.colNumber, to.sheet.getLastRow() - to.rowBegin + 1, 1).getValues().flat(); } に変更してみてください。 let toValues = []; で最初に空の配列を用意して 転記先にデータがあるときだけtoValuesに値を取得するようにします。 let で配列 toValues を宣言するので、if 文の中のコードは const をつけません。
YellowGreen

2023/07/27 08:55

上の修正をせずに、 転記先toのrowBeginを3に設定するという手もあります。 番号が見出しと一致することはありませんので。
退会済みユーザー

退会済みユーザー

2023/07/28 00:24 編集

ご回答ありがとうございます!! エラーの内容を記載しておらずすみませんでした。 YellowGreenさんが仰っているのと同じエラーとなります。 >転記先toのrowBeginを3に設定する こちらで解決できました! 今回初めてこのような場所に質問させていただきドキドキしておりましたが 親切で丁寧な回答をいただいて本当に嬉しく思います。 ありがとうございました!!
YellowGreen

2023/07/28 00:49

お役に立って良かったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問