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

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

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

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

1531閲覧

一次元配列から二次元配列へ変換したのち、シートにデータを貼り付けたい。

退会済みユーザー

退会済みユーザー

総合スコア0

Google Apps Script

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2023/07/21 02:10

実現したいこと

for文で作った一次元配列のデータを二次元配列に変換し、シートの指定カ所に一気に貼り付けたいです。

前提

GoogleスプレッドシートのGASで一覧表のようなものを作っています。
C列・D列のデータを二次元配列として取得し、for文で加工して1つの文字列として一次元配列に作り直し、B列に一気に入れる、という作業をしたいです。

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

Exception: The parameters (number[]) don't match the method signature for SpreadsheetApp.Range.setValues.

該当のソースコード

GAS

1let njigenText = [ichijigenText]; 2sheet.getRange(2,2,njigenText.length,1).setValues(njigenText);

試したこと

C列・D列のデータを取得することは出来て、文字列の加工もできました。
文字列で一次元配列を作ることも出来ました。
ネットで調べたところ、一次元配列ではsetValuesは使えない、とのことでした。

なので、
let njigenText = [ichijigenText];
で二次元化してみました。

しかし、
sheet.getRange(2,2,njigenText.length,1).setValues(njigenText);
で貼り付けられず、エラーが出てしまいます。

njigenText が二次元配列化に失敗しているのかと思い、
Logger.log(njigenText [0][10]
等で見てみましたが、問題は無いようです。

引数等が間違っているのかと思い、getRangeの数字を調整したりしたのですが、どうにもうまくいきません。

今現在は、setValuesではなくsetValueで、for文で回して1つずつ配列をセルに書き込んでごまかしています。
しかし、今後データが増えることを考えると、for文は使いたくありません。

なにとぞお知恵を拝借できないでしょうか?
よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

既に回答が出ていますが、エラーになるのは修正方法が回答者様の想定と違っているからだと思います。
質問者様に修正後のスクリプトの全体を示していただければと思いますが。

例えば、このように全体をお示ししてみるとどうでしょうか。
※ 回答を修正して、もう一つの参考例を追記しました。

JavaScript

1function myFunction() { 2 const ss = SpreadsheetApp..getActiveSpreadsheet(); 3 const sheet = ss.getSheetByName('メインシート'); 4 //C,D列の値を取得 5 const values = sheet.getRange(1, 3, sheet.getLastRow(), 2).getValues(); 6 //データの見出し行(1行目)を削除 7 values.shift(); 8 //C,D列の値を★で結合した一次元配列に変換 9 const ichijigenText = values.map(v => v.join('★')); 10 console.log(ichijigenText); 11 //二次元配列に変換 12 const nijigenText = ichijigenText.map(v => [v]); 13 console.log(nijigenText); 14 //B列(2行目以降)に値を記入 15 if (nijigenText.length > 0) { 16 sheet.getRange(2, 2, nijigenText.length, 1).setValues(nijigenText); 17 } 18}

なお、今回は、
一次元配列と二次元配列の変換がご質問の主旨でしたので上のような例としてますが、
一次元配列は二次元配列への変換用に一時的に生成されているだけなので、
最初から列を結合した二次元配列を生成することもできますので参考まで。

JavaScript

1function myFunction() { 2 const ss = SpreadsheetApp.getActiveSpreadsheet(); 3 const sheet = ss.getSheetByName('メインシート'); 4 //C,D列を結合した二次元配列を生成 5 const nijigenText = sheet.getRange(2, 3, sheet.getLastRow() - 1, 2) 6 .getValues().map(v => [v.join('★')]); 7 //B列に値を記入 8 if (nijigenText.length > 0) { 9 sheet.getRange(2, 2, nijigenText.length, 1).setValues(nijigenText); 10 } 11}

投稿2023/07/21 05:23

編集2023/07/21 23:29
YellowGreen

総合スコア673

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

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

退会済みユーザー

退会済みユーザー

2023/07/21 05:58 編集

色々ご提示いただいて試してはいるのですが、何をしても「~is not a function」的なエラーが出てしまいます。 コードの流れ的には、これでほぼ揃っています(他に行見出しの設定などありますが割愛しました)。 改めて皆様のお知恵を拝借したいです。 let ss = SpreadsheetApp.getActiveSpreadsheet(); let mainSheet = SpreadsheetApp.getActiveSpreadsheet() .getSheetByName('メインシート); ss.setActiveSheet(mainSheet); let lastRow = mainSheet.getLastRow(); let nijigenDisplayValues = mainSheet.getRange(2,3,lastRow,2).getDisplayValues(); //文字列の加工 let i; let ichijigenText = {}; for(i=0; i<lastRow; i++){ ichijigenText[i] = nijigenDisplayValues[i][0] + '★' + nijigenDisplayValues[i][1]; } let nijigenText = [ichijigenText]; //現在はこの方法でごまかしていますが、本音は一発で貼れるsetValuesを使いたいです。 for(i=0;i<lastRow;i++){ mainSheet.getRange(i + 2, 2).setValue(nijigenText[0][i]); }
YAmaGNZ

2023/07/21 06:54

let ichijigenText = {}; こちらの定義でichijigenText は連想配列となっています。 let ichijigenText = []; for(i=0; i<lastRow; i++){ ichijigenText.push(nijigenDisplayValues[i][0] + '★' + nijigenDisplayValues[i][1]); } と配列として定義してください。
YellowGreen

2023/07/21 08:20

全体としてお示ししたスクリプトを質問者様にご提示いただいたスクリプトの動作にあわせてみました。
退会済みユーザー

退会済みユーザー

2023/07/21 08:25

ご回答いただきありがとうございます。 連想配列とは気が付きませんでした。皆様のご意見を伺っていて、GASを使うならJavaScriptもきちんと勉強しないとダメだと痛感しました。これから頑張ります。 さて、ご提示いただいた普通の配列の書き方をしたところ、無事動きました! let nijigenText = []; ichijigenText.forEach(value => nijigenText .push([value])); mainSheet.getRange(2,2,lastRow,1).setValues(nijigenText); これでOKでした。 forEachの部分が全然意味不明ですが、これから勉強してみます。 こんな小さな質問にお付き合いいただき、本当にありがとうございました。
YellowGreen

2023/07/21 08:30

解決に導いたのはYAmaGNZ様だと思いますので、ベストアンサーは辞退させていただければと思います。
退会済みユーザー

退会済みユーザー

2023/07/21 08:33

承知いたしました。 しかし、私としては皆様にベストアンサーを差し上げたい気持ちです。 今後勉強する方向性も含め、色々な気付きを得ることが出来、大変有意義でした。
退会済みユーザー

退会済みユーザー

2023/07/22 01:31

追記の参考例を拝見しました。 早速その通りに書いて動かしてみたのですが、無事動きました! ご提示いただいた書き方のほうがコードがスマートですね。アロー関数というのが初耳で、使うこと自体、全然思いも付きませんでした。mapというのも馴染みが無いです。 今ちょっと調べましたが、JavaScriptのほうで便利なメソッドがたくさんあるんですね。これはますますJavaScriptを勉強した方がいいと思いました。 発展編という感じに受け取りました、とても勉強になりました。 本当にありがとうございました。
YellowGreen

2023/07/22 02:00 編集

参考にしていただけてよかったです。 配列に対する様々なメソッドとアロー関数を組み合わせるとスッキリしたコードになるので、 for (let i = 0; i < values.length; i++) { for (let j = 0 ; j < values[0].length; j++) { ...values[i][j]...; } } などインデックスを利用した煩雑なコードを書くことが減りました。 繰り返し処理でインデックスを利用したい時は、 values.forEach((v, i) => ...); とすると i をインデックスとして使えます。
退会済みユーザー

退会済みユーザー

2023/07/22 04:30

こちらこそ、コードの書き方っていろいろあるんだな、ということを教えていただき、本当にありがたいです。 アロー関数はいきなりは使えなさそうです……何かサンプルを作って練習したほうが良さそうですね。 土日の楽しみが増えました。ありがとうございました。
guest

0

2次元配列をsetValuesで入力する場合、njigenText [0][10]で言う所の[0]が行で[10]が列として処理されるので縦一列の範囲に横一列のデータが入力出来ずにエラーになっています。
なので配列内の行と列を入れ替える必要があります。

let njigenText = [ichijigenText]; const transpose = a => a[0].map((_, c) => a.map(r => r[c])); njigenText = transpose(njigenText);

投稿2023/07/21 02:47

編集2023/07/21 02:50
bebebe_

総合スコア497

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

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

退会済みユーザー

退会済みユーザー

2023/07/21 03:05

ご回答いただきありがとうございます。 const transpose = a => a[0].map((_, c) => a.map(r => r[c])); njigenText = transpose(njigenText); この2行の部分で、 TypeError: a[0].map is not a function というエラーが出てしまいます。aやcなど、何も宣言せず使ってよろしいのでしょうか?
bebebe_

2023/07/21 06:40

let ichijigenText = {}; を let ichijigenText = []; にしてみてください
退会済みユーザー

退会済みユーザー

2023/07/21 08:30

ご指摘ありがとうございます。 その通りでした。連想配列は間違っていました。
guest

0

ベストアンサー

1列に入れるということは
[[項目1,項目2,項目3,項目4]]
といった配列ではなく
[[項目1],[項目2],[項目3],[項目4]]
という配列にしなくてはなりません。

なので下記のように2次元配列に変換することになります。

JavaScript

1let njigenText = []; 2ichijigenText.forEach(value => njigenText.push([value]));

動作するサンプルとしては下記のようになります。

JavaScript

1 let values = [["項目1","項目2"],["項目3","項目4"]]; 2 let ichijigenText = values.flat(); 3 Logger.log(ichijigenText); 4 5 let nijigenText = []; 6 ichijigenText.forEach(value => nijigenText .push([value])); 7 Logger.log(nijigenText ); 8

投稿2023/07/21 02:49

編集2023/07/21 03:33
YAmaGNZ

総合スコア10210

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

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

退会済みユーザー

退会済みユーザー

2023/07/21 03:01

ご回答いただきありがとうございます。 forEachの行で、 TypeError: ichijigenText.forEach is not a function というエラーが出てしまいます。valueはそのままvalueと書いてよろしいのでしょうか?
YAmaGNZ

2023/07/21 03:29

ichijigenTextは1次元の配列なのではないですか?
退会済みユーザー

退会済みユーザー

2023/07/21 03:56

度々申し訳ありません。2行目の let ichijigenText = values.flat(); の部分で TypeError: syuttaikinText.flat is not a function のエラーが出てしまいます。 ichijigenTextは一次元配列だと思います。 ichijigenText[0] や ichijigenText[1] でログが取れます。
YAmaGNZ

2023/07/21 05:12

syuttaikinTextというものが突然出てきましたが、どのように取得しているのですか? そのあたりの取得からスプレッドシートへのセットまでのソースは開示できないですか?
退会済みユーザー

退会済みユーザー

2023/07/21 08:31

ごめんなさい、突然出てきたものは業務用の変数名なのでスルーしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問