Excel Officeスクリプト 複数セルをまとめて取得・設定する方法(getValues/setValuesで高速化)

2025年12月17日

アニメ調のブログヘッダー画像。中央のPCモニターにはExcel画面と共に「Office Script」「複数セルをまとめて」という文字が表示されている。左側にはたった1つのキューブを持って困惑している猫(単一セル処理の非効率さ)、右側には大量のキューブが入った箱を抱えて自信たっぷりに微笑む女性(一括処理の効率性)が描かれ、スクリプトによる業務効率化を表現している。

はじめに

Officeスクリプトで多くのセルを処理していると、「なんだか動作が遅い」と感じることはありませんか。その原因は、セルへの読み書きを「1つずつ」行っていることにある場合が多いです。

本記事では、データを「まとめて取得」し「まとめて書き出す」ことで、処理速度を向上させる方法を解説します。複数のセルを一括で扱うgetValuessetValuesを使いこなせるようになれば、日常業務の効率化に大きく貢献できます。

もし、1つのセルを扱う基本操作の情報が必要な場合は、先に以下の記事をご覧ください。

概要解説動画

※要約を抜粋した動画(朗読版)です。声優・井上喜久子さんの声を元にしたAI音声(桜乃そら)を使用しており、ラジオのように聞きやすく、優しい声で聞き流せます。

なぜ「1セルずつのループ処理」は遅いのか

Officeスクリプトはクラウド上で動作しており、スクリプトとExcelの間で通信が発生しています。この仕組みを理解すると、処理速度の問題がなぜ起きるのかが見えてきます。

例えば、setValueを100回実行すると、100回分の通信が発生します。これは郵便物を1通ずつポストに投函しに行くようなものです。1通出すたびに往復の時間がかかるため、まとめて持っていく場合に比べて大幅に時間がかかります。

実行時間のかかるスクリプトの例:

この「まとめて持っていく」方法が、今回紹介するgetValuessetValues(複数形のs付き)です。これらを使えば、データの取得も書き込みも1回の通信で完了できるため、処理時間を大幅に短縮できます。

複数セルの値を取得する(getValues)

複数セルの値をまとめて取得するには、getValues()メソッドを使用します。単一セル用のgetValue()との違いは、最後に「s」が付いている点です。

構文

range.getValues()

2次元配列という形式

getValues()で取得したデータは「2次元配列」という形式で変数に格納されます。2次元配列と聞くと難しそうに感じるかもしれませんが、Excelの「行」と「列」をそのまま表現したデータ構造だと考えると理解しやすいです。

Excelでは、セルは縦方向(行)と横方向(列)で整理されています。2次元配列もこれと同じ構造を持っています。

コード例

function main(workbook: ExcelScript.Workbook) {
    // A1:C3の範囲の値を取得
    let values = workbook.getWorksheet("Sheet1").getRange("A1:C3").getValues();
    
    // 取得したデータにアクセス
    console.log(values[0][0]); // A1の値
    console.log(values[0][1]); // B1の値
    console.log(values[1][0]); // A2の値
    console.log(values[2][2]); // C3の値
}

実行結果の例:

インデックスの対応関係

配列のインデックス(添え字)は「0」から始まる点に注意が必要です。以下に、Excelのセル位置と配列インデックスの対応関係を示します。

セル位置配列での指定
A1values[0][0]
B1values[0][1]
C1values[0][2]
A2values[1][0]
A3values[2][0]

1つ目の数字が「行番号 - 1」、2つ目の数字が「列番号 - 1」と覚えておくと便利です。

複数セルに値を設定する(setValues)

複数セルに値をまとめて設定するには、setValues()メソッドを使用します。作成・加工した配列データを、指定した範囲に一気に書き込むことができます。

構文

range.setValues(配列データ)

重要なルール:範囲と配列サイズの一致

setValues()を使う際に最も重要なのは、書き込む範囲(Range)と配列のサイズ(行数・列数)を一致させることです。例えば、3行2列の範囲に書き込むなら、配列も3行2列のデータを用意する必要があります。

コード例

function main(workbook: ExcelScript.Workbook) {
    // 書き込むデータを2次元配列で用意
    let data: (string | number)[][] = [
        ["りんご", 100],
        ["みかん", 80],
        ["ぶどう", 200]
    ];
    
    // A1:B3の範囲にデータを一括書き込み
    workbook.getWorksheet("Sheet1").getRange("A1:B3").setValues(data);
}

上記の例では、3行2列の配列を用意し、A1からB3の範囲(同じく3行2列)に書き込んでいます。

実行結果の例:

データを加工して転記するサンプル

ここでは、実務でよくあるシナリオを例に、getValuessetValuesを組み合わせた活用方法を紹介します。

シナリオ

A列に商品の単価、B列に販売個数が入力されています。この2つの値を掛け合わせて、売上金額をC列に一括で書き込みます。

実行前のデータ(例)

※解説をシンプルにするため、今回は見出し行(ヘッダー)を作らず、1行目からデータを入力しています。

A列(単価)B列(個数)C列(売上)
50010(空欄)
8005(空欄)
12003(空欄)

コード

※注意:範囲の指定について このサンプルコードは、「1行目からデータが始まっている(見出し行がない)」という前提で書かれています。 もし、実務で見出し行がある表を扱う場合は、getRange("A2:B4") のように、見出しを除いたデータ範囲を指定してください。見出しを含めてしまうと、文字と数値を掛け算しようとしてエラー(NaN)になります。

function main(workbook: ExcelScript.Workbook) {
    // 対象シートを取得
    let sheet = workbook.getWorksheet("Sheet1");
    
    // A1:B3の範囲から単価と個数を取得
    let inputData = sheet.getRange("A1:B3").getValues();
    
    // 計算結果を格納する配列を用意
    let outputData: number[][] = [];
    
    // 各行の売上を計算
    for (let i = 0; i < inputData.length; i++) {
        let price = inputData[i][0] as number;  // 単価
        let quantity = inputData[i][1] as number;  // 個数
        let sales = price * quantity;  // 売上を計算
        
        // 結果を配列に追加(1列分なので要素は1つ)
        outputData.push([sales]);
    }
    
    // C1:C3の範囲に計算結果を一括書き込み
    sheet.getRange("C1:C3").setValues(outputData);
}

実行後のデータ

A列(単価)B列(個数)C列(売上)
500105000
80054000
120033600

このように、データの取得から加工、書き込みまでの一連の流れを、最小限の通信回数で実現できます。

配列データの処理にはループ(繰り返し)を使います。ループの書き方については以下の記事で解説しています。

よくあるエラー:範囲のサイズ不一致

setValuesを使用していて、「引数が無効です(The argument is invalid)」などのエラーが表示されることがあります。最も多い原因は、書き込み先の範囲と配列のサイズが一致していないことです。

エラーが発生する例

function main(workbook: ExcelScript.Workbook) {
    // 5行分の範囲を指定
    let range = workbook.getWorksheet("Sheet1").getRange("A1:A5");
    
    // 3行分のデータしか用意していない
    let data = [[100], [200], [300]];
    
    // エラー発生:範囲は5行、データは3行で不一致
    range.setValues(data);
}

エラー発生の例:

対処法

この問題を解決する方法は主に2つあります。

方法1:データに合わせて範囲を動的に指定する

function main(workbook: ExcelScript.Workbook) {
    let sheet = workbook.getWorksheet("Sheet1");
    let data = [[100], [200], [300]];
    
    // データの行数を取得
    let rowCount = data.length;
    
    // データの行数に合わせて範囲を指定
    let range = sheet.getRange(`A1:A${rowCount}`);
    range.setValues(data);
}

方法2:範囲に合わせてデータの数を調整する

あらかじめ書き込み先の範囲が決まっている場合は、データの方を範囲に合わせて調整します。足りない分は空文字や0で埋めるなどの処理を入れることで対応できます。

まとめ

本記事では、Officeスクリプトで複数セルをまとめて取得・設定する方法を解説しました。

要点を整理すると、1つずつセルにアクセスすると通信回数が増えて処理が遅くなるため、getValuessetValuesを使って一括処理を行うことで高速化が実現できます。取得したデータは2次元配列として扱い、インデックスは0から始まる点に注意が必要です。また、setValuesでは範囲と配列のサイズを一致させる必要があります。

データ量が多い業務では、この一括処理のテクニックは必須といえます。「通信回数を減らす」という意識を持つことが、Officeスクリプトを使いこなす上での重要なポイントです。

他にもOfficeスクリプトの便利なテクニックをまとめています。

🚀 Excel自動化を「点」から「線」へ。体系的に学びたい方へ

本記事で解説したテクニックは、日々の業務を効率化する大きな一歩です。

しかし、実務で直面する複雑な課題を解決するためには、基礎から体系的に知識を身につけることが最短ルートになります。

「ネットの情報だけでは限界を感じる」「もっと自由自在にツールを作れるようになりたい」

そうお考えのあなたにおすすめしたいのが、Officeスクリプトを網羅的に学べるこちらの電子書籍です。

『ビジネスパーソンのためのOfficeスクリプト入門:Excel作業の自動化とデータ処理【2025年7月大幅改訂版】』

この書籍は、忙しいビジネスパーソンが最短でOfficeスクリプトを習得できるよう設計されています。

本書のここがポイント!

  • 🔰 プログラミング知識ゼロでも大丈夫! 専門用語を避け、初心者目線でやさしく解説。「VBAは難しかった…」という方でも安心してスタートできます。
  • 🔄 VBA経験者はスムーズに移行! VBAとの違いを比較しながら解説しているので、今ある知識を無駄なく活かせます。
  • 【2025年7月大幅改訂】最新トレンドを完全網羅! 話題の生成AIを活用してコード作成を強力に支援する方法を新設。さらに、Power Automateと連携した高度な自動化シナリオも大幅に拡充されています。

「脱・手作業」を実現し、ワンランク上の業務効率化を目指すための必携書です。ぜひ手に取ってみてください。