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

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

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

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

Q&A

解決済

1回答

896閲覧

GASの検索条件に該当するものを別シートに書き写したい

ai39

総合スコア7

Google Apps Script

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

0グッド

0クリップ

投稿2023/01/02 12:58

前提

GASで、検索条件に該当するものを別シートに書き写すスクリプトを書いています

実現したいこと

①シート2のG列と、シート1のA列(管理Key)、もしくはC列(ID)にある単語が一致していた場合、
シート1のB列(名称)をシート2のA列に書き写したいです
イメージ説明

発生している問題・エラーメッセージ

だいたいは実現しているんですが、
配列にある要素を上限として、シート2のA列が埋められないです。

上記画像でいうと、シート1にある2行目~10行目までの要素9個分までは、
シート2のA9までは記載ができるのですが、A10以降は埋めることができません。

該当のソースコード

function Keysheet() { // 対象のスプレッドシートを指定 var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('シート2'); //コピー先のスプレッドシートID(CopyDB) var SS_CopyFrom = SpreadsheetApp.openById("URL"); var copydb_sheet = SS_CopyFrom.getSheetByName('シート1'); var lastRow = copydb_sheet.getLastRow() var matchArray = []; //一致する値を格納する配列 //B,一致する値を配列に格納 for (var i = 1; i <= lastRow; i++) { var kanrikey = copydb_sheet.getRange("A" + i).getValue(); var idkey = copydb_sheet.getRange("C" + i).getValue(); var name = sheet.getRange("G" + i).getValue(); if (name === kanrikey || name === idkey) { var listEach = copydb_sheet.getRange("B" + i).getValues(); matchArray.push(listEach); // 最終行に追加したい // var data3 = sheet.getRange("G2:G").getValues(); // var lastRow2 = data3.filter(String).length; //C,シートに一致したデータを入力 var matchArrayLen = matchArray.length; for (var y = 2,i = 1; i < matchArrayLen; y++,i++) { //試したがだめでした。 //for (var y = 2,i = 1; i < matchArrayLen; y++,i++) { sheet.getRange(y, 1).setValue(matchArray[i]); } } } }

試したこと

配列の個数が上限になっているので、最終行までを上限にして試したのですが、うまく動きません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

YAmaGNZ

2023/01/02 22:15 編集

なぜ条件にあっているものを見つけるループの中に条件に合ったものが格納されている配列を書き出すループがあるのでしょうか? また、外側のループで使用しているiが内側のループでも使用されていますが、iの値がどのように変化しているのか確認されたのでしょうか?
guest

回答1

0

ベストアンサー

不具合の原因

  • シート1の行数分の新規配列を生成して、シート2に書き込もうとしている。
    • 実際には、シート2の行数分の配列を生成しなければならない。
  • (不具合の原因ではありませんが)1セルずつ照合しているので、GASの処理に時間がかかる。
    • 一括で取得・照合したほうが処理が速いです。今のコードでは行数が例えば100行、1000行と増えると、非常に直間がかかってしまいます。

コード例

あまり精査していないので、もう少しスマートな方法があるかもしれませんが…。
とりあえず処理が速く、正常に動作するコードです↓

イメージ説明
イメージ説明

javascript

1function writeKeys() { 2 const START_ROW = 2; 3 4 // シート2 5 const ss = SpreadsheetApp.getActiveSpreadsheet(); 6 const sheet = ss.getSheetByName('シート2'); // 名称を書き込むシートを取得 7 const adminKeysToCheck = sheet.getRange(START_ROW, 7, sheet.getLastRow() - START_ROW + 1, 1).getValues().flat(); // 確認するkeyを取得 8 // [ 'a6', 'a1', 'c2', 'c10', 'c5', '', 'b0' ] 9 10 // シート1 11 const dbSs = SpreadsheetApp.openById('****ID****'); 12 const dbSheet = dbSs.getSheetByName('シート1'); // key・名称・IDが載っているシートを取得 13 const dbRecords = dbSheet.getRange(START_ROW, 1, dbSheet.getLastRow() - START_ROW + 1, dbSheet.getLastColumn()).getValues(); // 値を全て取得 14 // [ [ 'a1', '名称1', 'c1' ], [ 'a2', '名称2', 'c2' ], [ 'a3', '名称3', 'c3' ], [ 'a4', '名称4', 'c4' ], [ 'a5', '名称5', 'c5' ] ] 15 16 const namesToWrite = adminKeysToCheck.map(key => { 17 const arr = dbRecords.filter(r => r.includes(key)).flat(); // シート2のkeyが存在するシート1の行(配列)を抜き出す 18 // 例: [] or [ 'a1', '名称1', 'c1' ] 19 return arr ? [arr[1]] : ['']; // 抜き出した配列が存在する場合は「名称」を、存在しない場合は空の配列を、namesToWriteの要素とする 20 }); 21 // [ [ undefined ], [ '名称1' ], [ '名称2' ], [ undefined ], [ '名称5' ], [ undefined ], [ undefined ] ] 22 23 sheet.getRange(START_ROW, 1, sheet.getLastRow() - START_ROW + 1, 1).setValues(namesToWrite); // シート2に書き込む 24}

投稿2023/01/03 01:51

編集2023/01/03 01:54
Cocode

総合スコア2314

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

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

ai39

2023/01/03 04:13

無事動かすことができました! いただいたコードで知らないものもあったので、調べながら勉強します! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問