Excel VBAユーザー向け Google Apps Script(スプレッドシート)構文比較
Excel VBAに慣れている人が、Googleスプレッドシートを Google Apps Script(GAS)で操作するときに迷いやすい構文を比較します。
VBAとGASは似た作業ができますが、オブジェクト名・範囲指定・配列の扱いがかなり違います。
まず対応関係をざっくり見る
| やりたいこと | Excel VBA | GAS |
|---|---|---|
| アプリ全体 | Application |
SpreadsheetApp |
| ブック / ファイル | Workbook |
Spreadsheet |
| シート | Worksheet |
Sheet |
| セル範囲 | Range |
Range |
| セルの値 | .Value |
.getValue() / .setValue()
|
| 複数セルの値 | .Value |
.getValues() / .setValues()
|
| 最終行 | .Cells(.Rows.Count, 1).End(xlUp).Row |
sheet.getLastRow() |
| 最終列 | .Cells(1, .Columns.Count).End(xlToLeft).Column |
sheet.getLastColumn() |
GASでは、値を取得するメソッドは get...()、値を設定するメソッドは set...() という名前が多いです。
ブック・スプレッドシートを取得する
VBA
Dim wb As Workbook
Set wb = ThisWorkbook
GAS
const ss = SpreadsheetApp.getActiveSpreadsheet();
別ファイルをIDで開く場合です。
const ss = SpreadsheetApp.openById('スプレッドシートID');
シートを取得する
VBA
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
GAS
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
アクティブシートを取得する場合です。
const sheet = SpreadsheetApp.getActiveSheet();
セルを指定する
VBA
Worksheets("Sheet1").Range("A1").Value = "test"
Worksheets("Sheet1").Cells(1, 1).Value = "test"
GAS
const sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange('A1').setValue('test');
sheet.getRange(1, 1).setValue('test');
GASの getRange(row, column) は、行・列ともに1始まりです。
セルの値を取得する
VBA
Dim value As Variant
value = Worksheets("Sheet1").Range("A1").Value
GAS
const value = sheet.getRange('A1').getValue();
セルへ値を入れる
VBA
Worksheets("Sheet1").Range("A1").Value = "完了"
GAS
sheet.getRange('A1').setValue('完了');
複数セルの値をまとめて取得する
VBA
Dim values As Variant
values = Worksheets("Sheet1").Range("A1:C3").Value
GAS
const values = sheet.getRange('A1:C3').getValues();
GASの getValues() は2次元配列を返します。配列の添字は0始まりです。
const values = sheet.getRange('A1:C3').getValues();
console.log(values[0][0]); // A1
console.log(values[1][2]); // C2
ここが混乱しやすいところです。
-
getRange(1, 1)の座標は1始まり -
values[0][0]の配列は0始まり
複数セルへまとめて書き込む
VBA
Worksheets("Sheet1").Range("A1:B2").Value = Array( _
Array("品番", "数量"), _
Array("A001", 10) _
)
VBAでは2次元配列を作る書き方に少しクセがあります。
GAS
const values = [
['品番', '数量'],
['A001', 10],
];
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
GASの setValues() は、書き込み先の範囲サイズと配列サイズが一致している必要があります。
最終行を取得する
VBA
Dim lastRow As Long
With Worksheets("Sheet1")
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
GAS
const lastRow = sheet.getLastRow();
注意点として、getLastRow() はシート全体でデータが入っている最後の行を返します。特定列だけを基準にしたい場合は、自分で列データを見る必要があります。
const values = sheet.getRange('A:A').getValues();
let lastRow = 0;
for (let i = values.length - 1; i >= 0; i--) {
if (values[i][0] !== '') {
lastRow = i + 1;
break;
}
}
最終列を取得する
VBA
Dim lastCol As Long
With Worksheets("Sheet1")
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
GAS
const lastColumn = sheet.getLastColumn();
行・列を追加する
VBA
Worksheets("Sheet1").Rows(2).Insert
Worksheets("Sheet1").Columns(3).Insert
GAS
sheet.insertRowBefore(2);
sheet.insertColumnBefore(3);
末尾に行を追加する場合です。
sheet.appendRow(['A001', '標準ねじ', 10]);
行・列を削除する
VBA
Worksheets("Sheet1").Rows(2).Delete
Worksheets("Sheet1").Columns(3).Delete
GAS
sheet.deleteRow(2);
sheet.deleteColumn(3);
シートを追加する
VBA
Worksheets.Add.Name = "出力"
GAS
const ss = SpreadsheetApp.getActiveSpreadsheet();
ss.insertSheet('出力');
シートを削除する
VBA
Application.DisplayAlerts = False
Worksheets("出力").Delete
Application.DisplayAlerts = True
GAS
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('出力');
if (sheet) {
ss.deleteSheet(sheet);
}
セルの背景色を変える
VBA
Worksheets("Sheet1").Range("A1").Interior.Color = vbYellow
GAS
sheet.getRange('A1').setBackground('yellow');
複数セルにまとめて設定する場合です。
sheet.getRange('A1:C3').setBackground('#fff2cc');
文字色・太字を設定する
VBA
With Worksheets("Sheet1").Range("A1")
.Font.Bold = True
.Font.Color = vbRed
End With
GAS
sheet.getRange('A1')
.setFontWeight('bold')
.setFontColor('red');
GASの多くの set...() メソッドは、戻り値として Range を返すため、続けて書けるものがあります。
フィルターを作る
VBA
Worksheets("Sheet1").Range("A1:C10").AutoFilter Field:=1, Criteria1:="A001"
GAS
const range = sheet.getRange('A1:C10');
range.createFilter();
range.getFilter().setColumnFilterCriteria(
1,
SpreadsheetApp.newFilterCriteria()
.whenTextEqualTo('A001')
.build()
);
GASのフィルター操作は、VBAより少し書く量が多くなります。
ループ処理
VBA
Dim i As Long
For i = 2 To 10
Worksheets("Sheet1").Cells(i, 1).Value = "OK"
Next i
GAS
for (let i = 2; i <= 10; i++) {
sheet.getRange(i, 1).setValue('OK');
}
ただし、GASではセルを1つずつ読み書きすると遅くなりやすいです。できるだけ getValues() / setValues() でまとめて処理します。
const range = sheet.getRange('A2:A10');
const values = range.getValues();
const newValues = values.map(() => ['OK']);
range.setValues(newValues);
VBAとGASで特に違うところ
1. アクティブシート依存を避ける
VBAでは Range("A1") や Cells(1, 1) をオブジェクトなしで書くと、アクティブシート依存になります。
' 避けたい
Range("A1").Value = "test"
' 推奨
Worksheets("Sheet1").Range("A1").Value = "test"
GASでも getActiveSheet() は便利ですが、自動処理ではシート名で取るほうが安全です。
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
2. GASは権限承認が必要になる
GASでは、スプレッドシートやDrive、Gmailなどにアクセスする処理で権限承認が必要になります。
最初の実行時に承認画面が出ることがあります。
3. GASは実行時間の制限を意識する
GASはVBAと違って、実行時間やサービス呼び出し回数の制限を意識する必要があります。
大量データでは、セルを1つずつ処理するより、まとめて読み書きするのが基本です。
const values = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
// 配列上で加工する
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
4. Value と getValue() / setValue() の違い
VBAはプロパティに代入する書き方です。
Range("A1").Value = "test"
GASはメソッドを呼び出す書き方です。
sheet.getRange('A1').setValue('test');
まとめ
VBAからGASへ移るときは、まず次の対応だけ覚えると入りやすいです。
| VBA | GAS |
|---|---|
Workbook |
Spreadsheet |
Worksheet |
Sheet |
Range("A1").Value |
getRange('A1').getValue() |
Range("A1").Value = x |
getRange('A1').setValue(x) |
Range("A1:C3").Value |
getRange('A1:C3').getValues() |
.Cells(row, col) |
.getRange(row, col) |
VBAの感覚でGASを書くと、最初は少し冗長に感じます。
ただ、スプレッドシート・Drive・Gmail・フォームなどをつなげられるので、業務自動化の幅はかなり広がります。