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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

5162閲覧

GASで列の複数の値を分割して特定の位置にセットしたい

Yohei04

総合スコア24

Google Apps Script

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/06/17 11:44

前提・実現したいこと

こんにちは、はじめての質問になります。

GASにて列に格納された配列を分割したあとにその値と他の列を参照して決まった位置に決まった値をセットするというコードを書きたいのですがやり方がわからず困っています。
具体的にはD列に日付とその日の値段が配列の形で格納されており、この値段部分を第一行の日付を参照した場所(画像の赤枠の部分)にセットしたいです。

画像の様に関数では実現できたのですが、これだと応用が利かずGASで実現したいと思っております。
ちなみに第二行に[]で囲まれた日付がありますが、元々の文字列が[]で囲まれているため無理やり付け足しただけで、できれば一行目の様に普通の日付を参照したいと思っております。
画像は途中で切れていますが日付は6/11-7/10までになります。

イメージ説明

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

D列の配列がsplitにて分割できない。※そもそもsplitでいいのかも怪しいです。 列を参照して特定の位置にセットする方法がわからない。 引用ページ:[リンク内容](https://vba-gas.info/gas-split2) 引用ページ:[リンク内容](https://qiita.com/sha9sa9/items/8d10f550c673336ba1f4)

該当のソースコード

GAS

1function myFunction() { 2var ss = SpreadsheetApp.getActiveSpreadsheet(); //アクティブなスプレッドシートを取得 3var sh = ss.getSheetByName('ダブル'); //アクティブなスプレッドシートのアクティブシートを取得 4var last_row=sh.getLastRow(); //シートの最終行を取得 5var last_column=sh.getLastColumn(); //シートの最終列を取得 6 7var rows = sh.getRange(3,4,last_row,1).getValues(); //複数の値を取得 8var ary = sh.getRange("D5").getValue(); //特定の値を取得 9var columns = sh.getRange(2,5,1,last_column); 10var columnsValues = columns.getValues(); 11 12 var items=[rows] 13 14 items.forEach(function( value ) { 15 Logger.log(value); 16 }); 17 18 ary.split(' ').forEach( function( values ) { 19 20 Logger.log(values); 21 22 }); 23 24 25var count = ary.length; //配列変数aryの配列数を調べる 26var num=columns.getNumColumns(); 27 28 for (var i = 0; i < count/2; i++) { 29 30sh.getRange(12, 9+i).setValue(ary[2*i+1]); //配列変数aryの値段部分だけを取り出す 31 32 } 33} 34

試したこと

変数aryの様に一つのセルを取得した場合、splitで分割できたのですが、rowsの様に列全体で取得するとsplitで分割するとエラーがでてしまいこれがどうしても解決できませんでした。
いろいろ調べてforEach関数なども使ってみたのですがやはりうまくいきませんでした。
2次元配列を1次元配列にしてループで回したりするのでしょうか?

また値のセットの仕方も簡単な物や参照しない方法でならできたのですが今回の自分のやりたいことはやり方がわかりませんでした。

GASどころかプログラミング自体全くの素人の為、コードもいろいろ試した跡が残ってしまっていてかなり見にくいかもしれません。大変申し訳ありません。。

お手数ですがご回答いただければ幸いです。

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

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

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

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

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

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

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

papinianus

2019/06/17 22:28

一行目は日付があらかじめ埋まっているということでしょうか?
Yohei04

2019/06/17 23:40

ご返信ありがとうございます。 その通りです。日付とD列はあらかじめ関数にて入れております。
guest

回答1

0

ベストアンサー

思いつきで書いたので、もっといいやり方があるはず。

第二行に[]で囲まれた日付

これはない想定(2行目からデータ群)でくんでます。

行数DEFGHIJ
1連泊情報2019-06-112019-06-122019-06-132019-06-142019-06-152019-06-16
2[2019-06-06] [\1,000]
3[2019-06-05] [\2,000] [2019-06-06] [\2,100] [2019-06-07] [\2,200]
4[2019-06-09] [\3,000] [2019-06-10] [\3,100] [2019-06-11] [\3,200]
5[2019-06-10] [\4,000] [2019-06-11] [\4,100] [2019-06-12] [\4,200]
6[2019-06-12] [\5,000]
7[2019-06-12] [\6,000] [2019-06-13] [\6,100] [2019-06-14] [\6,200]
8[2019-06-15] [\7,000] [2019-06-16] [\7,100] [2019-06-17] [\7,200]
9[2019-06-16] [\8,000] [2019-06-17] [\8,100] [2019-06-18] [\8,200]
10[2019-06-17] [\9,000] [2019-06-18] [\9,100] [2019-06-19] [\9,200]
11[2019-06-17] [\10,000]

途中日付計算が面倒でMomentを使いました。
このらへんを参考にどうぞ。
https://tonari-it.com/gas-moment-js-moment/
https://qiita.com/osakanafish/items/5ef636bbcb2c3ef94953

GAS

1function q195471() { 2 const DataSeparater = '|'; 3 const KvSeparater = ':'; 4 5 const sheet = SpreadsheetApp.getActiveSheet(); 6 const data = sheet.getDataRange().getValues(); 7 8 // 連泊情報を整理 9 const info = data.map(function(row) { 10 // D列の値を取得してオブジェクト化 11 const obj = {}; 12 row[3].replace(/] [\/g, KvSeparater) 13 .replace(/] [/g, DataSeparater) 14 .replace(/[/g,'') 15 .replace(/]/g,'') 16 .split(DataSeparater) 17 .forEach(function(pair) { 18 const kv = pair.split(KvSeparater); 19 obj[kv[0]] = kv[1]; 20 }) 21 return obj; 22 }); 23 24 const dataSet = []; 25 26 // データを作成 27 for (var i = 1; i < info.length; i++) { 28 var dataSetRow = []; 29 for (var j = 4; j < data[0].length; j++) { 30 dataSetRow.push(info[i][Moment.moment(data[0][j]).format('YYYY-MM-DD')] || ''); 31 } 32 dataSet.push(dataSetRow); 33 } 34 35 sheet.getRange(2, 5, dataSet.length, dataSet[0].length).setValues(dataSet); 36}

#コメントに対する追記

どうして'|'や':'でreplaceしているのか

確かに無駄にわかりにくくしてるかも。
下記のほうがシンプルですね。

const info = data.map(function(row) { // D列の値を取得してオブジェクト化 const obj = {}; const pairs = row[3].replace(/^[/,'') .replace(/]$/,'') .replace(/\/g,'') .split('] ['); for(var i = 0; i < pairs.length; i++) { obj[pairs[i++]] = pairs[i]; } return obj; });

投稿2019/06/18 02:05

編集2019/06/19 08:49
macaron_xxx

総合スコア3191

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

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

Yohei04

2019/06/18 03:53

ご回答ありがとうございます。 早速実行してみましたが赤枠が全て空になってしまうだけでした。 第二行がない想定(2行目からデータ群)でくんでます。ということですが、E2以降の列を空にすれば良いということでしょうか? それかもしかしたら、連泊情報の全ての[]ごとに半角スペースが入っているからかもしれません。 お伝えしておらずすみません。。 ↓こうなっています [2019-06-05] [\6,445] [2019-06-06] [\5,858] [2019-06-07] [\5,858] [2019-06-08] [\7,030] [2019-06-09] [\6,445] [2019-06-10] [\6,445]
macaron_xxx

2019/06/18 04:09

コードみたらたしかに半角スペースでsplitしてありましたね。すみません。 コード修正しました。
Yohei04

2019/06/18 09:05

ご返信ありがとうございます。 今やってみましたらうまくできました!!ありがとうございます!! ただコードを見る限りわからないところだらけでもっと勉強しないといけないなというのを痛感しております。 // 連泊情報を整理 も // データを作成 も何が起きてるのかさっぱりです。。 GASだとあまり記事がないのでJavaScriptを勉強してみます。 本当に助かりました。ありがとうございました。
macaron_xxx

2019/06/19 01:04

そうですね。 GASはほとんどJavaScript(バージョンが古いですが)なので、そちらを勉強されるとよいです。 実際、今回のコードも最初のシート・データ取得部分と最後のデータセット部分以外は全てただのJavaScriptです。 不明点があれば、回答しますので、おっしゃってください。
Yohei04

2019/06/19 05:47

ご返信ありがとうございます。 やはりそうなんですね。JavaScript勉強してみます。 不明点はどうして'|'や':'でreplaceしているのか、obj[kv[0]] = kv[1];とはどういう状態なのか(配列の中に配列が入っている状態?等見たことがありませんでした)、他にも多々ありすぎてまだ質問もできないというのが正直なところです。 いろいろググってみてどうしても分からなければ質問させてください。それがmacaron_xxxさんの時間も取らせませんし自分のためにもなる気がします。 逆にGAS,JavaScriptはこれを見るといいよというようなサイトなどありますでしょうか? やはりまずはprogate,ドットインストールあたりでしょうか? 昨日SamuraiBlogというのを見つけて参考になりそうだったので読んでいます。 よろしくお願い致します。
macaron_xxx

2019/06/19 09:02

replaceの部分はわかりにくかったので、シンプルな記述に変えたものを追記しました。 あと、SamuraiBlogは嘘も多いので、参考にするのはほどほどに。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問