teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

つら

2019/10/30 07:09

投稿

papinianus
papinianus

スコア12705

answer CHANGED
@@ -1,33 +1,70 @@
1
- ## 推定するデータ
2
- こういうことだと考えました。行と列が正しく使えてないので間違っているかも
1
+ コード未検証。おそらくこういうことだと思う
3
2
 
3
+ ```javascript
4
+ function q219502() {
5
+ const spreadSheet = SpreadsheetApp.getActive();
6
+ const eventSheet = spreadSheet.getSheetByName('event');
7
+ const startOfDataRow = 2; //10/24 が C2 と仮定
8
+ const startOfDataCol = 3; //10/24 が C2 と仮定
9
+ const endRow = eventSheet.getLastRow();
10
+ const endCol = eventSheet.getLastColumn();
11
+ // 結合セルからデータをひろってくる
12
+ const allData = q180220_getMargedRangeValues(sheet, startOfDataRow, startOfDataCol, endRow, endCol);
13
+ // 曜日でフィルタ
14
+ const theDay = "木";
15
+ const indexOfTheDays = allData[1].reduce(function(a, c ,i) { return c === theDay ? a.concat([i]) : a;},[]);
16
+ // // 曜日行を消す
17
+ allData.splice(1,1);
18
+ // // 曜日を行方向にして、空白をスキップしたデータに作り直す(求める姿とは行と列が逆転している。
19
+ const summed = indexOfTheDays.map(function(p){ return allData.reduce(function(a,c,i){ return i === p && c !== "" ? a.concat([c]) : a ;},[]);});
20
+ const maxSize = summed.reduce(function(a,c){ return c.length > a ? c : a ;}, 0);
21
+ // // 行の長さを揃える
22
+ const fixed = summed.map(function(r){ return fillingArray(r, maxSize, "");} );
4
- |A|B|C|D|E|F|G|H|
23
+ // 行列転置
5
- |--|--|--|--|--|--|--|--|
24
+ const transposed = fixed[0].map(function(_, c) { return fixed.map(function(r) { return r[c];});});
6
- |?|01|月|?|?|イベ|イベ||
7
- |?|02|火|?|?|イベ|||
8
- |?|03|水|?|?|イベ|イベ|イベ|
25
+ spreadSheet.getSheetByName('test').getRange(1,1,transposed.length, transposed[0].length).setValues(transposed);
26
+ }
9
27
 
28
+ // getRangeと同じように 1-indexed で指定する
29
+ function q180220_getMargedRangeValues(sheet, startRow, startCol, endRow, endCol) {
30
+ const targetRange = sheet.getRange(startRow, startCol, endRow, endCol);
31
+ var ret = targetRange.getValues();
32
+ targetRange.getMergedRanges().forEach(function(rng) {
33
+ var startR = rng.getRow();
34
+ var startC = rng.getColumn();
35
+ var rngVal = rng.getValue();
36
+ var rngA1 = rng.getA1Notation();
37
+ var rowBoundary = startR + rng.getNumRows();
38
+ var colBoundary = startC + rng.getNumColumns();
39
+ for(var ri = startR; ri < rowBoundary ; ri++) {
40
+ var ri_a = ri - startRow;
41
+ if(ri_a < 0) { continue; }
42
+ if(ret.length <= ri_a) { break; }
43
+ for(var ci = startC; colBoundary; ci++) {
44
+ var ci_a = ci - startCol;
45
+ if(ci_a < 0) { continue; }
46
+ if(ret[ri_a].length <= ci_a) { break; }
47
+ ret[ri_a][ci_a] = rngVal;
48
+ }
49
+ }
50
+ });
10
- ## 推定する得たい結果
51
+ return ret;
52
+ }
11
53
 
12
- |A|B|C|D|
54
+ function fillingArray(array, len, fill) {
13
- |--|--|--|--|
55
+ var pseudo = [];
14
- |04|イベ|イベ||
56
+ for(var i = 0; i < len; i++) {
15
- |11|イベ|||
16
- |18|イベ|イベ|イベ|
57
+ pseudo.push(fill);
58
+ }
59
+ return array.concat(pseudo).slice(0, len);
60
+ }
61
+ ```
17
62
 
18
- ## コード
63
+ ### 将来参考に訪れたかたへ
19
- テストしてです多分こういうことかと考えます
64
+ あなたのデータを見直してください。
20
- 現状のコードについては行と列がどうあるべきか分からないので直しようがないです。行方向については、変数すらありません。
21
65
 
22
- ```javascript
23
- function q219502(){
24
- const dateCol = 2 - 1;//row は行、colは列。コメントを信じてcolと考える
25
- const dayCol = 3 - 1;//row は行、colは列。コメントを信じてcolと考える
26
- const eventsStartCol = 6 - 1;
66
+ 列方向に組まれたデータはハンドリングが大変です。
27
- const theDay = "木";
28
- const book = SpreadsheetApp.getActive();
67
+ データベースもGoogle Sheet(を加工するGoogle App Script)も行方向に1データです。
68
+
69
+ 表示に最適化されすぎたデータはプログラム処理に向きません。
29
- const events = book.getSheetByName('event').getDataRange().getValues().filter(function (r) { return r[dayCol] === theDay;});
70
+ データモデルと表示は分離して、結合列や背景色でデータを表現しないようにしましょう。プレゼンするときにだけ、整形しましょう。またプレゼンのために新たに作らなくても、google sheetやexcelでは他のシートを参照する機能があるので、データシートと連動する表示シートを作るのはさほど難しくないはずです。
30
- const dateAndEvents = events.map(function(e) { return e.slice(dateCol,dateCol + 1).concat(e.slice(eventsStartCol));});7
31
- book.getSheetByName('test').getRange(1,1,dateAndEvents,length, dateAndEvents[0].length).setValues(dateAndEvents);
32
- }
33
- ```