実現したいこと
Googleスプレッドシートのシート1に複数の時系列グラフがある。Google Apps Script(GAS)でシート2に直近1時間分のグラフを描かせたい。
シート1の単数グラフの直近一時間のグラフをシート2に描かせるScriptは人に書いて貰って問題なく動くので、これを改造して、複数のグラフを描かせたい。
前提
シート1のA列に時間、B列、C列、D列、E列にデータが入っている。データはGASで行末に十秒に一度追加される。
問題なく動くシート1の単数のグラフの直近一時間のデータをシート2にグラフで書かせる為のGASは以下の通りである。
1// 既存のグラフのデータ範囲を更新 2function updateChartRange() { 3 // 初期設定 4 const ss = SpreadsheetApp.getActiveSpreadsheet(); 5 const sheet1 = ss.getSheetByName('シート1'); 6 const sheet2 = ss.getSheetByName('シート2'); 7 8 // シート1の最終行を取得し、その60秒×60分÷10秒(1時間)分の360行を遡った行番号を取得 9 const lastRow = sheet1.getLastRow(); // 最終行 10 const firstRow = lastRow <= 360 ? 1 : lastRow - 360; // 1時間前の行(1時間経過していないなら最初の行) 11 12 // A列の遡った行からB列の最終行までのセル範囲を取得 13 const rangeAdd = sheet1.getRange('A' + firstRow + ':B' + lastRow); 14 15 // シート2の既存のグラフを取得 16 // ※ グラフは1つしかないが、配列で取得されるので1番目[0] 17 let chart = sheet2.getCharts()[0]; 18 19 // 既存のグラフをベースとするグラフ作成ツールを取得 20 const chartBuilder = chart.modify(); 21 22 // グラフ作成ツールからデータのセル範囲を全て取得 23 // ※ 実際には、セル範囲は1つしかないが配列で取得される 24 const ranges = chartBuilder.getRanges(); 25 26 // グラフ作成ツールにより、 27 // 設定されているセル範囲を削除し、 28 // 新たなセル範囲を追加してからグラフを生成 29 chart = chartBuilder 30 .removeRange(ranges[0]) // 取得したセル範囲の配列の最初のセル範囲[0]を削除 31 .addRange(rangeAdd) // 前もって取得しておいたセル範囲を追加 32 .build(); // 変更を反映したグラフを生成 33 34 // 生成したグラフで既存のグラフを更新 35 sheet2.updateChart(chart); 36} 37 38// ファイルを開いたときにメニューを追加 39function onOpen() { 40 SpreadsheetApp.getUi() 41 .createMenu('グラフ') 42 .addItem('更新', 'updateChartRange') 43 .addToUi(); 44}
これを改造して、複数のグラフに対応させたい。
試したこと
以下の通り、レンジ指定を変えてA列とB列だけでなく、A列とC列、A列とD列、A列とE列のグラフに拡張しようとスクリプトを改造した。
1 2function updateChartRange() { 3const ss = SpreadsheetApp.getActiveSpreadsheet(); 4const sheet1 = ss.getSheetByName('シート1'); 5const sheet2 = ss.getSheetByName('シート2'); 6const lastRow = sheet1.getLastRow(); 7const firstRow = lastRow <= 360 ? 1 : lastRow - 360; 8const range0Add = sheet1.getRange('A' + firstRow + ':B' + lastRow); 9const range1Add = sheet1.getRange('A' + firstRow + ':A' + lastRow + ',' + 'C' + firstRow + ':C' + lastRow ); 10const range2Add = sheet1.getRange('A' + firstRow + ':A' + lastRow + ',' + 'D' + firstRow + ':D' + lastRow ); 11const range3Add = sheet1.getRange('A' + firstRow + ':A' + lastRow + ',' + 'E' + firstRow + ':E' + lastRow ); 12 13let chart0 = sheet2.getCharts()[0]; 14let chart1 = sheet2.getCharts()[1]; 15let chart2 = sheet2.getCharts()[2]; 16let chart3 = sheet2.getCharts()[3]; 17 18const chartBuilder0 = chart0.modify(); 19const chartBuilder1 = chart1.modify(); 20const chartBuilder2 = chart2.modify(); 21const chartBuilder3 = chart3.modify(); 22 23const ranges0 = chartBuilder0.getRanges(); 24const ranges1 = chartBuilder1.getRanges(); 25const ranges2 = chartBuilder2.getRanges(); 26const ranges3 = chartBuilder3.getRanges(); 27 28chart0 = chartBuilder0 29chart1 = chartBuilder1 30chart2 = chartBuilder2 31chart3 = chartBuilder3 32 33.removeRange(ranges0[0]) 34.removeRange(ranges1[0]) 35.removeRange(ranges2[0]) 36.removeRange(ranges3[0]) 37 38.addRange(range0Add) 39.addRange(range1Add) 40.addRange(range2Add) 41.addRange(range3Add) 42 43.build(); 44sheet2.updateChart(chart0); 45sheet2.updateChart(chart1); 46sheet2.updateChart(chart2); 47sheet2.updateChart(chart3); 48 49} 50// ファイルを開いたときにメニューを追加 51function onOpen() { 52 SpreadsheetApp.getUi() 53 .createMenu('グラフ') 54 .addItem('更新', 'updateChartRange') 55 .addToUi(); 56}
上のスクリプトでは、sheet1.getRangeで('A' + firstRow + ':B' + lastRow);
として、もし現在のデータ数が660個だとすると、グラフの範囲(A300:B660)を指定している。C列のデータ範囲が'シート1'!A300:A360,'シート1'!C300:C360なので、指定にsheet1.getRange('A' + firstRow + ':A' + lastRow + ',' + 'C' + firstRow + ':C' + lastRow )としてみたが、こういう使い方は Range not foundといわれるので書式が良くないらしい。
他にもBuild周りでちゃんと動かない気がする。
どうやったら、複数のグラフでシート2にグラフを書かせることが出来るでしょうか?
よろしくお願いします。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/01/15 13:16