二重ループで指定した範囲の表を処理する
function 表ループして新規シートに貼付け() {
var 行;
var 列;
var 番号;
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getDataRange();
var values = range.getValues();
var LastRow1 = sheet.getRange(sheet.getLastRow(), 2).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
var LastCol1 = sheet.getRange(2, sheet.getLastColumn()).getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn();
var newSheet = SpreadsheetApp.getActive().insertSheet(sheet.getName() + "_" + Utilities.formatDate(new Date(), "JST", "h時mm分ss秒"));
newSheet.getRange(1, 1, 1, 4).setValues([["項目名1", "項目名2", "項目名3", "項目名4"]]);
var target = newSheet;
var previousSheet = SpreadsheetApp.getActive().getSheetByName(sheet.getName());
番号 = 2;
for (行 = 2; 行 <= LastRow1; 行++) {
for (列 = 2; 列 <= LastCol1; 列++) {
if (values[行 - 1][列 - 1] != "") {
previousSheet.getRange(行, 1).copyTo(target.getRange(番号, 1));
previousSheet.getRange(行, 2).copyTo(target.getRange(番号, 2));
previousSheet.getRange(1, 列).copyTo(target.getRange(番号, 3));
previousSheet.getRange(行, 列).copyTo(target.getRange(番号, 4));
番号++;
}
Utilities.sleep(0);
}
}
newSheet.activate();
SpreadsheetApp.getActive().getSheetByName(sheet.getName()).activate();
SpreadsheetApp.getUi().alert("完了");
}
解説
- 関数の名前を定義しています。ここでは「表ループして新規シートに貼付け」という名前になっています。
function 表ループして新規シートに貼付け() {
- 変数「行」「列」「番号」を定義しています。
var 行;
var 列;
var 番号;
- 変数「sheet」にアクティブなシートを代入しています。
var sheet = SpreadsheetApp.getActiveSheet();
- 変数「range」にシートのデータを取得し、変数「values」にその値を代入しています。
var range = sheet.getDataRange();
var values = range.getValues();
- 変数「LastRow1」にデータがある最後の行を代入し、「LastCol1」にデータがある最後の列を代入しています。
var LastRow1 = sheet.getRange(sheet.getLastRow(), 2).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
var LastCol1 = sheet.getRange(2, sheet.getLastColumn()).getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn();
- 変数「newSheet」に、アクティブなスプレッドシートに、現在のシートの名前に現在時刻を付けた名前の新しいシートを挿入しています。
var newSheet = SpreadsheetApp.getActive().insertSheet(sheet.getName() + "_" + Utilities.formatDate(new Date(), "JST", "h時mm分ss秒"));
- 新しいシートの1行目に、4つの列の項目名を設定しています。
newSheet.getRange(1, 1, 1, 4).setValues([["項目名1", "項目名2", "項目名3", "項目名4"]]);
- 変数「target」に新しいシートを代入し、「previousSheet」に元のシートを代入しています
var target = newSheet;
var previousSheet = SpreadsheetApp.getActive().getSheetByName(sheet.getName());
- forループを使用して、元のシートの各行と各列を反復処理します。各セルの値が空でない場合、元のシートの現在の行、2番目の列、現在の列、各セルの値を新しいシートの行、2番目の列、3番目の列、4番目の列にコピーしています。
番号 = 2;
for (行 = 2; 行 <= LastRow1; 行++) {
for (列 = 2; 列 <= LastCol1; 列++) {
if (values[行 - 1][列 - 1] != "") {
previousSheet.getRange(行, 1).copyTo(target.getRange(番号, 1));
previousSheet.getRange(行, 2).copyTo(target.getRange(番号, 2));
previousSheet.getRange(1, 列).copyTo(target.getRange(番号, 3));
previousSheet.getRange(行, 列).copyTo(target.getRange(番号, 4));
番号++;
}
Utilities.sleep(0);
}
}
- 後に、新しいシートと元のシートの両方をアクティブにし、完了メッセージを表示しています。
補足
- 変数の定義
- 行、列、番号:for ループのインデックス変数
- sheet:現在アクティブなシートを取得
- range:現在アクティブなシートの範囲を取得
- values:現在アクティブなシートの値を 2 次元配列に格納
- LastRow1:現在アクティブなシートの最終行を取得
- LastCol1:現在アクティブなシートの最終列を取得
- newSheet:現在アクティブなスプレッドシートに新しいシートを挿入して、そのシートを取得
- target:貼り付け先のシートを newSheet に設定
- previousSheet:元のシートを取得して、後でアクティブにするために保存
- 新しいシートに項目名を挿入する
- 新しいシートの A1:D1 に、項目名を持つ 1 行を挿入
- データをループ処理して新しいシートに貼り付ける
- 行と列のループで、元のシートの値を確認
- もし値が空でなければ、元のシートから必要なセルをコピーして、新しいシートに貼り付ける
- 番号をインクリメントして、貼り付け先の行番号を更新する
- GAS の DoEvents に相当する sleep() メソッドで、処理の実行を一時停止する
- 元のシートと新しいシートをアクティブにする
- 処理の完了をアラートで表示する
エクセルVBAとGASの違い
VBA 版と比較して、スプレッドシートのデータを扱うためのオブジェクトやメソッドが異なることがわかります。例えば、Excel VBA では、セルの値を直接取得することができますが、GAS では、まず範囲を取得してから値を取得する必要があります。また、シートを選択して操作するのではなく、シートのオブジェクトを取得してから操作する必要があります。
コメント