GAS実践ガイド
GAS×スプレッドシート実践【よく使うテクニック集】
GASとスプレッドシートを組み合わせれば、強力な業務ツールが作れます。この記事では、実務でよく使うテクニックを解説します。
データ操作の基本
効率的なデータ取得
JavaScript
// 悪い例:1セルずつ取得(遅い)
for (let i = 1; i <= 1000; i++) {
const value = sheet.getRange(i, 1).getValue();
}
// 良い例:一括取得(速い)
const data = sheet.getRange(1, 1, 1000, 1).getValues();
for (const row of data) {
const value = row[0];
}
効率的なデータ書き込み
JavaScript
// 悪い例:1セルずつ書き込み(遅い)
for (let i = 1; i <= 1000; i++) {
sheet.getRange(i, 1).setValue(i);
}
// 良い例:一括書き込み(速い)
const data = [];
for (let i = 1; i <= 1000; i++) {
data.push([i]);
}
sheet.getRange(1, 1, 1000, 1).setValues(data);
最終行・列の取得
JavaScript
function getLastRowCol() {
const sheet = SpreadsheetApp.getActiveSheet();
// 最終行(データがある最後の行)
const lastRow = sheet.getLastRow();
// 最終列
const lastCol = sheet.getLastColumn();
// A列の最終行(特定列)
const lastRowA = sheet.getRange("A:A")
.getValues()
.filter(row => row[0] !== "")
.length;
return { lastRow, lastCol, lastRowA };
}
検索・フィルタリング
値の検索
JavaScript
function findValue(searchValue) {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].length; j++) {
if (data[i][j] === searchValue) {
return { row: i + 1, col: j + 1 };
}
}
}
return null;
}
条件に合う行の抽出
JavaScript
function filterRows(columnIndex, condition) {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
const header = data[0];
// 条件に合う行を抽出
const filtered = data.slice(1).filter(row => {
return condition(row[columnIndex]);
});
// 結果を新しいシートに出力
const resultSheet = SpreadsheetApp.getActiveSpreadsheet()
.insertSheet("抽出結果");
resultSheet.appendRow(header);
filtered.forEach(row => resultSheet.appendRow(row));
return filtered.length;
}
// 使用例:B列が100以上の行を抽出
function extractHighValues() {
const count = filterRows(1, value => value >= 100);
Logger.log(`${count}件抽出しました`);
}
重複の検出
JavaScript
function findDuplicates(columnIndex) {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
const seen = new Map();
const duplicates = [];
for (let i = 1; i < data.length; i++) {
const value = data[i][columnIndex];
if (seen.has(value)) {
duplicates.push({
value: value,
rows: [seen.get(value), i + 1]
});
} else {
seen.set(value, i + 1);
}
}
return duplicates;
}
データの集計
グループ別集計
JavaScript
function groupSum() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
// A列でグループ化、B列を合計
const groups = {};
for (let i = 1; i < data.length; i++) {
const key = data[i][0];
const value = data[i][1];
if (!groups[key]) {
groups[key] = 0;
}
groups[key] += value;
}
// 結果を出力
const resultSheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName("集計") || SpreadsheetApp.getActiveSpreadsheet()
.insertSheet("集計");
resultSheet.clear();
resultSheet.appendRow(["グループ", "合計"]);
Object.entries(groups).forEach(([key, sum]) => {
resultSheet.appendRow([key, sum]);
});
}
ピボットテーブル的な集計
JavaScript
function pivotSummary() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
// 行: A列、列: B列、値: C列の合計
const pivot = {};
const colKeys = new Set();
for (let i = 1; i < data.length; i++) {
const rowKey = data[i][0];
const colKey = data[i][1];
const value = data[i][2];
if (!pivot[rowKey]) pivot[rowKey] = {};
if (!pivot[rowKey][colKey]) pivot[rowKey][colKey] = 0;
pivot[rowKey][colKey] += value;
colKeys.add(colKey);
}
// 出力
const colArray = Array.from(colKeys).sort();
const output = [["", ...colArray]];
Object.entries(pivot).forEach(([rowKey, cols]) => {
const row = [rowKey];
colArray.forEach(colKey => {
row.push(cols[colKey] || 0);
});
output.push(row);
});
const resultSheet = SpreadsheetApp.getActiveSpreadsheet()
.insertSheet("ピボット");
resultSheet.getRange(1, 1, output.length, output[0].length)
.setValues(output);
}
複数シートの操作
全シートのデータを統合
JavaScript
function mergeAllSheets() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
let mergedData = [];
let headerAdded = false;
sheets.forEach(sheet => {
if (sheet.getName() === "統合") return;
const data = sheet.getDataRange().getValues();
if (!headerAdded) {
mergedData.push(data[0]);
headerAdded = true;
}
// ヘッダー以外を追加
for (let i = 1; i < data.length; i++) {
mergedData.push(data[i]);
}
});
// 統合シートに出力
let mergedSheet = ss.getSheetByName("統合");
if (!mergedSheet) {
mergedSheet = ss.insertSheet("統合");
}
mergedSheet.clear();
mergedSheet.getRange(1, 1, mergedData.length, mergedData[0].length)
.setValues(mergedData);
}
シートのコピーと操作
JavaScript
function copyAndModifySheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sourceSheet = ss.getSheetByName("テンプレート");
// シートをコピー
const newSheet = sourceSheet.copyTo(ss);
newSheet.setName("新しいシート_" + new Date().getTime());
// コピーしたシートを編集
newSheet.getRange("A1").setValue("コピーしたシート");
return newSheet;
}
外部データとの連携
CSVのインポート
JavaScript
function importCsvFromDrive(fileId) {
const file = DriveApp.getFileById(fileId);
const content = file.getBlob().getDataAsString("UTF-8");
const data = Utilities.parseCsv(content);
const sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}
JSONデータの取得
JavaScript
function fetchJsonData() {
const url = "https://api.example.com/data";
const response = UrlFetchApp.fetch(url);
const json = JSON.parse(response.getContentText());
// スプレッドシートに出力
const sheet = SpreadsheetApp.getActiveSheet();
const headers = Object.keys(json[0]);
sheet.appendRow(headers);
json.forEach(item => {
const row = headers.map(h => item[h]);
sheet.appendRow(row);
});
}
実践的なツール例
在庫管理ツール
JavaScript
function updateStock(productId, quantity, type) {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName("在庫");
const data = sheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
if (data[i][0] === productId) {
const currentStock = data[i][2];
const newStock = type === "in"
? currentStock + quantity
: currentStock - quantity;
sheet.getRange(i + 1, 3).setValue(newStock);
// 履歴を記録
const historySheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName("履歴");
historySheet.appendRow([
new Date(),
productId,
type,
quantity,
newStock
]);
return newStock;
}
}
return null;
}
勤怠管理ツール
JavaScript
function recordAttendance(type) {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName("勤怠");
const today = new Date();
const dateStr = Utilities.formatDate(today, "JST", "yyyy/MM/dd");
const timeStr = Utilities.formatDate(today, "JST", "HH:mm");
const user = Session.getActiveUser().getEmail();
sheet.appendRow([dateStr, user, type, timeStr]);
}
function clockIn() {
recordAttendance("出勤");
SpreadsheetApp.getUi().alert("出勤を記録しました");
}
function clockOut() {
recordAttendance("退勤");
SpreadsheetApp.getUi().alert("退勤を記録しました");
}
まとめ
パフォーマンスのポイント
- データは一括で取得・書き込み
- ループ内でgetValue/setValueを避ける
- 配列で処理してからシートに反映
よく使うメソッド
JavaScript
// シート操作
sheet.getRange(row, col).getValue()
sheet.getRange(row, col, numRows, numCols).getValues()
sheet.appendRow([values])
sheet.getLastRow()
// 書式
range.setBackground(color)
range.setFontWeight("bold")
関連記事
