0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Microsoft LearnのOffice Script(CSV→Excel変換)を理解する

Last updated at Posted at 2025-12-29

はじめに

本記事は以下記事で使用したOffice Scriptを学習する記事です。

上記の記事では、Microsoft Learnのサンプルコードを使用しています。
CSVをExcelに変換するサンプルコードを学習したいと思います。

サンプルコード

CSVデータ分解(行単位)

CSVデータを一行ずつ分解して配列rowsに格納する処理です。

  csv = csv.replace(/\r/g, "");
  let rows = csv.split("\n");

改行がCRLF(\r\n)LF(\n)の2パターンあるので、先にReplace関数でCR(\r)を除去してから、LF(\n)で分割して配列rowsに行を格納しています。

replace関数の引数「/\r/g」のgは、TypeScriptの正規表現で、gを付ければ最後まで検索、付けなければ最初の1つだけを検索します。

正規表現

CSV の1行をセル単位に切り出すための正規表現です。

  const csvMatchRegex = /(?:,|\n|^)("(?:(?:"")*[^"]*)*"|[^",\n]*|(?:\n|$))/g

カンマ区切りでセルに書き込む値を抽出しますが、クォート付き、クォート無しなど考慮するため以下の正規表現が使われています。

正規表現 意味 備考
(?:,|\n|^) カンマ「,」改行「\n」「先頭文字」のいずれかを検出 Bob,25,Osakaの場合、→Bob(先頭)→25(カンマ)→Osaka(カンマ) ?:は非キャプチャグループ
("(?:(?:"")*[^"]*)*" クォート付きフィールドを抽出 "Tokyo, Japan","He said ""Hello"""の場合、→Tokyo, Japan→He said ""Hello"" *は0回以上の繰り返し、""はダブルクォート。^"は否定のためダブルクォート以外
[^",\n]* クォート無しフィールドを抽出 Tokyo, Japan,He said Helloの場合→ Tokyo→Japan→He said Hello ダブルクォート、カンマ、改行以外の文字を0回以上抽出
(?:\n|$)) 「改行または文字列の末尾を抽出 - \nは改行、$は最後の文字

繰返し処理(CSVデータ行単位)

CSVデータを1行ずつ処理します

rows.forEach((value, index) => { });

forEachで配列rows(CSVデータの行格納)の各要素(各行)に対して1回ずつ実行します。
value(第1引数)には、CSVデータ1行分の内容が、index(第2引数)にはカウンタが入っています。

空行判定

CSVデータ1行分が空行かどうかを判定して、空行の場合はスキップします。

 if (value.length > 0) { ... }

セルを抽出

CSVデータ1行分から正規表現「csvMatchRegex」でセルに格納する文字列を取得して配列rowに格納します 。

 let row = value.match(csvMatchRegex);

先頭空文字判定

行の最初がカンマから始まっている場合、最初のフィールドは空になるので配列の先頭に""を追加します。

if (row[0].charAt(0) === ',') {
    row.unshift("");
}

unshift関数は配列の先頭に要素を追加する関数です。

セル内容整形

先頭にカンマがあれば除去、先頭と末尾の両方ともダブルクォーテーションがある場合は除去します。

row.forEach((cell, index) => {
    cell = cell.indexOf(",") === 0 ? cell.substring(1) : cell;
    row[index] = cell.indexOf("\"") === 0 && cell.lastIndexOf("\"") === cell.length - 1 ? cell.substring(1, cell.length - 1) : cell;
});

三項演算子条件式 ? 真の場合の値 : 偽の場合の値; を使用

コード 意味
cell = cell.indexOf(",") === 0 ? cell.substring(1) : cell; 文字列の先頭がカンマか判定。先頭がカンマなら除去、そうでなければセル内容を設定
row[index] = cell.indexOf("\"") === 0 && cell.lastIndexOf("\"") === cell.length - 1 ? cell.substring(1, cell.length - 1) : cell; 先頭と末尾がダブルクォーテーションか判定。両側がダブルクォーテーションであればクォートを除去、そうでなければセル内容を設定。

行書込み

1行分のデータを2次元配列にして、Excelの該当行に書込みます。

let data: string[][] = [];
data.push(row);

let range = sheet.getRangeByIndexes(index, 0, 1, data[0].length);
range.setValues(data);

setValues関数が行と列の2次元配列を受け取るため、string[][]としています。
push関数は配列の末尾に要素を追加します。
getRangeByIndexesはIndex(第1引数)には書込む開始行、0(第2引数)は開始列、1(第3引数)は行数、data[0].lengthは列数になります。

学習した所感

CSVはPower Queryで扱う場合はそうでもないかもしれませんが、Office Scriptで扱う場合は処理が複雑のように感じました。
forEachは配列を処理する方法として抑えたいと思います。
今度は、JSON→Excelファイルに変換するOffice Scriptを書いてみたいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?