2018年4月6日

Googleスプレッドシート 選択範囲を回転させる


Google Apps Script を使ってスプレッドシートに処理を加える方法をメモメモ…



最近はよくGoogleスプレッドシートをいじっています。データの計算・解析だけでなく、ToDoリストの管理やゲームのステージ作成など幅広く利用できるので便利ですね!さて、スプレッドシートを使っていて「選択した範囲のセルを90°回転させたい」と思う場面がちょこちょこあったので、手軽に操作ができるようGoogle Apps Script (GAS)で実装してみました。

セルの並びを回転させた~い!

単に「選択範囲の行と列を入れ替えたい」場合には、対象の範囲をコピーしたあと 右クリック > 特殊貼り付け > 転置して貼り付け を実行すればいいのですが、回転となると手動でやるにはちょっとメンドくさそうだったのでスクリプトに頼ることにしました。もしかしたらもっと簡単な方法があるかもしれませんが、まあGASの練習も兼ねてということで…。

シートにスクリプトを追加する

まずは使用中のスプレッドシートにスクリプトを追加します。画面上部の「ツール」から「スクリプト エディタ」を選択しましょう。


これで新しくプロジェクトが作成され、使用中のスプレッドシートに紐づけされます。プロジェクト名やスクリプト名は適当で構いません。あとは実際にスクリプトの中身を書いていけば、シート内から関数を使うことができるようになります。

スクリプトを書く

とりあえずコードはこんな感じ。onOpen()関数とrotateActiveRange()関数を作成しました。

// メニューを追加する
function onOpen()
{
  var ui = SpreadsheetApp.getUi();  
  var menu = ui.createMenu('スクリプト');  
  menu.addItem('選択範囲を右に90°回転', 'rotateActiveRange');  
  menu.addToUi();
}

// 選択範囲を時計回りに回転させる
function rotateActiveRange()
{
  // 現在開いているシートと選択中のセルを取得する
  var sheet = SpreadsheetApp.getActiveSheet();
  var activeRange = SpreadsheetApp.getActiveRange();
  
  // 選択範囲の値を取得する
  var originalValues = activeRange.getValues();
  var pivotRow = activeRange.getRow();
  var pivotColumn = activeRange.getColumn();
  var height = activeRange.getHeight();
  var width = activeRange.getWidth();
  
  // 選択中のセルは一旦クリアしておく
  activeRange.clearContent();
  
  // 結果を入れる配列を作成する
  var resultValues = [];
  for(var i = 0; i < width; i++){ resultValues[i] = []; }
  
  // それぞれの値を回転後の位置に移動させる
  for(var r = 0; r < height; r++)
  {
    for(var c = 0; c < width; c++)
    {
      var value = originalValues[r][c];
      var newRow = c;
      var newColumn = height - r - 1;
      resultValues[newRow][newColumn] = value;
    }
  }
  
  // まとめてシートに書き込む
  sheet.getRange(pivotRow, pivotColumn, width, height).setValues(resultValues);
}

onOpen()は「トリガー」と呼ばれる特殊な関数です。onOpenという名前の関数はユーザーがスプレッドシートを開いたときに自動的に実行されます。ここでスプレッドシートのUIに項目を追加しておくと、メニュー操作でrotateActiveRange()関数を呼び出せるようになります。

メニューから実行できるようになる

  var sheet = SpreadsheetApp.getActiveSheet();
  var activeRange = SpreadsheetApp.getActiveRange();

現在使用中のシートや現在選択中のセルといった情報は SpreadsheetApp から簡単に取得できます。また、たとえば SpreadsheetApp.getActive().getSheetByName('NAME') のように指定した名前のシートを取得したり SpreadsheetApp.openByUrl('https://...') のようにURLからファイルを開くことも可能です。

  activeRange.clearContent();

セルの入力内容を消去するにはclearContent()を使います。似た関数でclear()というものもありますが、これだと書式も含めてすべて消去されてしまうので注意しましょう。

あとは、公式のリファレンスがかなり丁寧なので、取得したい情報や実行したい基本操作がある場合にはそれを見れば大体解決します。たとえば「選択範囲の横幅(列数)が知りたい!」というときはRangeクラスのページを見るとgetWidth()という関数が見つかるのでそれを利用すればOK。「現在のシートから特定の位置のセルを取得したい!」という場合ならSheetクラスのページを見ればgetRange(row, column)などの関数が見つかります。参照しているオブジェクトがSpreadsheet(スプレッドシートファイル)なのかSheet(シート)なのかRange(選択範囲)なのかだけはきちんと把握しておきましょう。

ちなみに…37行目と38行目を以下のように書きかえれば左(反時計回り)に回転するようになります。

  var newRow = width - c - 1;
  var newColumn = r;

スクリプトを実行する

では、いよいよ実行です!

まずさきほどのスクリプトを忘れず保存しておきます。保存するにはフロッピーディスクのマークを押すかショートカットキー(Ctrl + S)を入力しましょう。

次に、最初に開いていたスプレッドシートを開きなおします(リロードでもOK)。スクリプト内のonOpen()関数はファイルを開いた時点で呼び出されるので、ファイルを読み込みなおさないと反映されないのです。ファイルを開きなおして数秒待つと上部のメニューの右端(ヘルプの横)に「スクリプト」という項目が表示されます。表示されない場合はミスっているのでスクリプトにおかしいところがないかもう一度チェックしてください。

あとはその「スクリプト」から「選択範囲を右に90°回転」をクリックすれば処理が実行されるのですが…

なんか怖いメッセージが出た

たいていこうなります。

これは悪質なスクリプトを実行させないようにするGoogle側のセキュリティ対策の一環です。信頼のおけないスクリプトを呼び出すにはユーザーによる承認が必要になります。正直、自分の書いたコードなんだから承認もへったくれもない気がしますが、まあ用心するに越したことはないのでそこはよしとしましょう…。

画面の指示に従い「続行」をクリックし、自分のアカウントを選択。もしここで「このアプリは確認されていません」という画面になったら左下の「詳細」をクリックし、その後「XXX(安全ではないページ)に移動」を選択します。「安全なページに戻る」を押すと何もせず戻ってしまうので注意しましょう。


さらに確認画面が出るので「許可」ボタンを押せば完了です。…ただし、実はこの方法で許可をしてしまうとGoogleからセキュリティ上の警告を受けてしまいます。一応それを回避することも可能なのですが…長くなるので別の投稿にまとめました


何はともあれこれでGoogle Apps Scriptを使いスプレッドシートに自作の処理を追加できるようになりました!あらためて適当な範囲を選択したあと「スクリプト」→「選択範囲を右に90°回転」をクリックしてみましょう。セルの中身が移動したら成功です。


今回作成したスクリプトでは、選択した範囲の開始位置を起点として縦と横のセル数が入れ替わります。シートの行数/列数を超えた場合は自動で追加してくれるようです。また、移動するのは値だけで書式は元のセルに固定されたままです。回転の起点となる位置を変更したい場合や書式も含めて移動させたい場合は適宜コードを修正してくださいね。ではでは!

0 件のコメント:

コメントを投稿