Translate

ラベル :IT の投稿を表示しています。 すべての投稿を表示
ラベル :IT の投稿を表示しています。 すべての投稿を表示
Post Date:2026年5月14日 

Googleスプレッドシートで見栄えのよい人口ピラミッドを作成する

Googleスプレッドシートで見栄えのよい人口ピラミッドを作成する

Googleスプレッドシートで人口ピラミッドグラフを作成するには、「年齢・男・女」の3列データを用意し、男性人口をマイナス値にして横棒グラフにする方法が簡単です。

今回は、男性人口をマイナス値にする方法ではなく、メインビジュアルのように中央へ年齢ラベルを配置した、少し見栄えのよい人口ピラミッドグラフを作成してみました。

備忘録として、作成手順を残しておきます。


人口データを取得する

人口データは、e-Stat(政府統計ポータルサイト)から取得しました。今回は、2024年10月1日現在の日本人人口を使います。取得したデータから、グラフ作成に必要な「年齢」「男性人口(千人)」「女性人口(千人)」を抜き出したものが下表です。

− 日本人人口(2024年10月1日現在) | e-Stat −
A B C
1 年齢 男(千人) 女(千人)
20歳356339
31歳378360
42歳400380
53歳414396
64歳418400
75歳436417
86歳459438
97歳471450
108歳493468
119歳505481
1210歳505480
1311歳517494
1412歳519496
1513歳534507
::::
9997歳2290
10098歳1466
10199歳844
102100歳以上1177

1歳区切りのデータをそのまま使うと、表もグラフもかなり縦長になります。そのため、ここからは下表の10歳区切りにしたデータでグラフを作成していきます。

− 日本人人口(2024年10月1日現在) | 年代別 −
A B C
1 年齢 男(千人) 女(千人)
2 0-9歳 4330 4129
3 10-19歳 5345 5085
4 20-29歳 5933 5664
5 30-39歳 6358 6107
6 40-49歳 8090 7823
7 50-59歳 9062 8886
8 60-69歳 7215 7435
9 70-79歳 7396 8593
10 80-89歳 3980 6061
11 90-99歳 729 1985
12 100歳以上 11 77

完成イメージのグラフに合わせて表を作成する

今回作成する人口ピラミッドは、「左余白・男性人口・ラベル・女性人口・右余白」の5つのパートに分けた、積み上げ横棒グラフとして作成します。

左右の余白と中央のラベル部分を加えることで、男女の人口を左右に分けて表示します。

Google Sheets で人口ピラミッド

「左余白」は上図の男性グラフの左側の空白部分になります。同様に「右余白」は、女性グラフの右側空白部分です。「ラベル」は中央の年齢が記されている部分です。

グラフがバランスよく表示されるように、「男性人口」+「左余白」=「女性人口」+「右余白」になるようにします。下表では、男女ともに合算値が何れも9,100になるようにしています。

なぜ、9,100としたのでしょうか?

今回のデータでは、男性人口と女性人口の最大値は 9,062 です。最大値は、次の数式で求められます。

=max(B2:C12)

左余白と右余白は、この最大値以上の基準値から、男性人口または女性人口を差し引いて作ります。今回は、9,062 より少し大きい 9,100 を基準値にしました。この値はグラフの見た目を確認しながら調整していきます。

「左余白」の B2 には次の数式を入れます。

=9100-C2

また、「右余白」の F2 には次の数式を入れます。

=9100-E2

最後に「ラベル」列の説明です。ここには、「0-9歳」から「100歳以上」までの年齢区分を表示するための幅を設定します。今回は仮に 1000 としていますが、この値はグラフを見ながら調整します。

元データに「左余白」「ラベル」「右余白」を追加したものが、グラフ作成用の表になります。

− 日本人人口(2024年10月1日現在) | 年代別 −
A B C D E F
1 年齢 左余白 男(千人) ラベル 女(千人) 右余白
20-9歳47704330100041294971
310-19歳37555345100050854015
420-29歳31675933100056643436
530-39歳27426358100061072993
640-49歳10108090100078231277
750-59歳38906210008886214
860-69歳18857215100074351665
970-79歳1704739610008593507
1080-89歳51203980100060613039
1190-99歳8371729100019857115
12100歳以上9089111000779023

積み上げ横棒グラフで完成イメージを確認する

表ができたら、まずは積み上げ横棒グラフを作成して、完成イメージを確認します。

Googleスプレッドシートのメニューから「挿入」>「グラフ」を選択します。グラフエディタが表示されたら、グラフの種類で「積み上げ横棒グラフ」を選びます。

Google Sheetsで人口ピラミッド

この時点では色合いなどはまだ整っていませんが、人口ピラミッドの大まかな形を確認できます。

次に、中央に表示する年齢ラベルの幅を確認します。

グラフエディタを開き、「設定」タブの「ラベル」から「ラベルを追加」を選択し、「年齢」をラベルとして追加します。

Google Sheetsで人口ピラミッド

ラベルの位置は、「カスタマイズ」タブの「系列」で「ラベル」を選択し、「データラベル」の「位置」を「中央」にします。

Google Sheetsで人口ピラミッド

最初はラベル列の値を 1000 にしていましたが、実際にグラフにすると中央のラベル部分が狭すぎました。そこで、ラベル列の値を 4000 に変更しました。

また、「左余白 + 男性人口」と「女性人口 + 右余白」の合計値も、9100 から 9200 に変更しています。

Google Sheetsで人口ピラミッド

ここまでで、人口ピラミッドの基本形ができました。次は、このグラフをベースに、色や余白、軸の表示などを整えていきます。


色を変える

次にグラフの色を変えていきます。

「カスタマイズ」タブの「系列」で「左余白」を選び、「塗りつぶしの不透明度」を「0%」にすると、「左余白」がグラフ上で見えなくなります。

Google Sheetsで人口ピラミッド

同じように、「ラベル」と「右余白」も「塗りつぶしの不透明度」を「0%」にします。

Google Sheetsで人口ピラミッド

続いて、「系列」で「男(千人)」を選択し、「塗りつぶしの色」を青系に変更します。さらに「データラベル」にチェックを入れ、ラベルの位置を「内側軸寄り」にします。これで、男性人口の人数が棒グラフ内に表示されます。

Google Sheetsで人口ピラミッド

同じように、「女(千人)」を選択して「塗りつぶしの色」を赤系にし、データラベルにチェックを入れます。

Google Sheetsで人口ピラミッド

これで、だいぶ人口ピラミッドらしい見た目になってきました。


軸ラベルとグリッド線を消す

次に、軸ラベルとグリッド線を非表示にして、グラフをすっきりさせます。

Googleスプレッドシートでは、軸ラベルを完全に非表示にできないため、背景と同じ白に変更して、見えないようにします。

まず、「カスタマイズ」タブの「縦軸」を開き、「テキストの色」を白に変更します。

Google Sheetsで人口ピラミッド

同じように、「横軸」でも「テキストの色」を白に変更します。

Google Sheetsで人口ピラミッド

続いて、グリッド線を消します。

「カスタマイズ」タブの「グリッドラインと目盛」を開き、「主要グリッド線」のチェックを外します。

Google Sheetsで人口ピラミッド

これで、軸ラベルとグリッド線が目立たなくなり、すっきりとした人口ピラミッドグラフになります。


縦軸のタイトルと凡例を削除する

仕上げに、縦軸のタイトルと凡例を削除します。

まず、グラフ内に表示されている縦軸のタイトル「年齢」をクリックして選択します。選択できたら、「Delete」キーまたは「Backspace」キーで削除します。

Google Sheetsで人口ピラミッド

同じように、凡例もクリックして選択し、「Delete」キーまたは「Backspace」キーで削除します。

Google Sheetsで人口ピラミッド

これで、グラフ内に不要な文字要素がなくなり、人口ピラミッドの形がより見やすくなります。


タイトルを変更して微調整

最後に、グラフのタイトルを変更します。

「カスタマイズ」タブの「グラフと軸のタイトル」を開き、「タイトルテキスト」にグラフのタイトルを入力します。必要に応じて、フォントサイズや文字色などのフォーマットも調整します。

Google Sheetsで人口ピラミッド

あとは、グラフの位置やサイズを調整し、全体の見栄えを整えれば完成です。

Google Sheetsで人口ピラミッド

Googleスプレッドシートでも、余白とラベルをうまく使うことで、見栄えを整えた人口ピラミッドグラフを作成できます。

こちらは、1歳区切りで作成した人口ピラミッドです。余白とラベルを加えた積み上げ横棒グラフとして作成しているため、横軸の目盛りをそのまま人数として読むことはできませんが、全体として棺桶型の人口ピラミッドになっていることがわかります。また、58歳付近には丙午による凹み、78〜79歳付近には終戦直後生まれの凹みも見られます。

Google Sheetsで人口ピラミッド
Post Date:2023年7月16日 

Goolge Colabでお手軽テキストマイニング(日本語前処理)

象と散歩:pythonで遊ぶ 

Google Colaboratory は、Google アカウントさえ持っていれば、Python を実行できる素晴らしい環境です。準備やインストールが不要で、手軽に Pythonプログラミングを楽しめます。

テキストデータの分析(アンケートのフリーコメントや問い合わせ内容など)も、Google Colaboratory の環境を使えば、手軽にPythonでテキストマイニングができます。

今回は、テキストの前処理に関する2つのステップについて説明します。

  1. テキストの読み込み テキストファイル、CSV、Excel ファイルなどに保存されたテキストデータを読み込む方法です
  2. 読み込んだテキストの正規化 テキストの表記の揺れを少なくして文章を分析しやすい形式に変換します

1. 対象ファイルを読み込む

3つの方法でテキストデータを読み込む方法について説明します。2番目と3番目の方法では、pandasパッケージを使用します。

  1. テキストファイルの読み込み テキストファイルの中にあるテキストデータを読み込む方法です。open()関数を使用してファイルを開き、ファイルの中身をテキストデータとして抽出します。
  2. CSVファイルの読み込み CSVファイルに格納されたテキストデータを読み込む方法です。pandasパッケージのread_csv()関数を使用します。この関数にはCSVファイルのパスを指定し、データをデータフレームとして読み込むことができます。
  3. Excelファイルの読み込み Excelファイルに格納されたテキストデータを読み込む方法です。pandasパッケージのread_excel()関数を使用します。この関数にはExcelファイルのパスを指定し、データをデータフレームとして読み込むことができます。

ファイルのアップロード

Google Colaboratory ではGoogleドライブをマウントして利用することもできますが、下例は、ファイルをセッションストレージ(セッションが接続されている間だけ使えるストレージ)の "/content/sample_data" にアップロードする方法です。

  1. Colabの左端にあるファイルアイコンをクリック(下図オレンジ枠)
  2. sample_dataフォルダを開く
  3. セッションストレージにアップロード(下図グリーン枠)

ドラッグアンドドロップでもアップロードできます。

Google Colaboratory:ファイルのアップロード

アップロードするsample.txtの内容は下記のようなものです。

<sample.txt>
甘くてフルーティーな味で最高
チョコレートとストロベリーの組み合わせが最高!
香りが良くて食べやすい!おすすめです。
子供たちも大喜びのおいしさ!リピート決定。
さわやかな酸味と濃厚なチョコのバランスが絶妙。

エンコーディング

テキストデータを読み込む際には、エンコード(Encoding)を指定する必要があります。エンコードは、テキストデータのバイト列(バイナリデータ)への変換方法や規則を指定するものです。日本語などの2バイト文字データを正しく扱うためには、適切なエンコードを指定する必要があります。

一般的なエンコーディングとしては、以下のようなものがあります。

  • UTF-8: 広く使用されるUnicodeエンコーディングで、多くのプラットフォームやシステムでサポートされています。MacやLinux環境でよく使われます。
  • Shift-JIS: 主にWindows環境で使われる日本語エンコーディングです。

下例は、/content/sample_data/にあるsample.txtを読み込むコードです。file_pathに読み込むテキストをフルパスで指定しています。パスは当該フォルダを右クリックして"パスをコピー"で取得できます。

Google Colaboratory:ファイルパスの取得

UTF-8のファイルを指定する場合です。変数 textに読み込んだ内容を格納します。

file_path = '/content/sample_data/sample.txt'
with open(file_path, 'r', encoding='utf-8') as file:
    text = file.read()

print(text)

Shift-JISの場合は下記のようになります。

file_path = '/content/sample_data/sample.txt'
with open(file_path, 'r', encoding='shift_jis') as file:
    text = file.read()

print(text)

print(tex)の結果です。

甘くてフルーティーな味で最高
チョコレートとストロベリーの組み合わせが最高!
香りが良くて食べやすい!おすすめです。
子供たちも大喜びのおいしさ!リピート決定。
さわやかな酸味と濃厚なチョコのバランスが絶妙。

エンコードがわからない場合

chardetは、Pythonで利用できるエンコーディング推定ライブラリです。テキストのエンコードがわからない場合は、chardetでエンコードを確認してファイルを読み込みます。

下例では、sample.txtを読み込んで何のエンコードかを調べた結果をfle_encordingに格納し、そのエンコーディングでファイルを再度読み込みます。

import chardet

# ファイルのエンコーディング情報を取得
file_path = '/content/sample_data/sample.txt'
with open(file_path, 'rb') as f:
    file_encording= chardet.detect(f.read())['encoding']

print(file_encording) #エンコード情報

# 取得したエンコーディング情報でファイルを読み込む
with open(file_path, 'r', encoding=file_encording) as f:
    text = f.read()

print(text)

CSVからの読み込み

CSV(カンマ区切り)の場合は、pandasのread_csv()関数を使って列名を指定してデータを読み込みます。

読み込むcsvは、1列目の列名が「no.」、2列目の列名が「回答」です。

<sample.csv>
no.,回答
1,甘くてフルーティーな味で最高
2,チョコレートとストロベリーの組み合わせが最高!
3,香りが良くて食べやすい!おすすめです。
4,子供たちも大喜びのおいしさ!リピート決定。
5,さわやかな酸味と濃厚なチョコのバランスが絶妙。

下例は、上記のCSVファイルのうち列名が「回答」となっている列を取得するコードです。改行区切りで変数 textに格納します。

import chardet
import pandas as pd

# ファイルのエンコーディング情報を取得
file_path = '/content/sample_data/sample.csv'
with open(file_path, 'rb') as f:
    file_encording= chardet.detect(f.read())['encoding']

# CSVファイルを読み込んでテキストデータを抽出
df = pd.read_csv(file_path, encoding=file_encording)
text = '\n'.join(df["回答"])  # 回答列名を適宜変更してください

print(text)

print(tex)の結果です。

甘くてフルーティーな味で最高
チョコレートとストロベリーの組み合わせが最高!
香りが良くて食べやすい!おすすめです。
子供たちも大喜びのおいしさ!リピート決定。
さわやかな酸味と濃厚なチョコのバランスが絶妙。

Excelから読み込む場合

Excelファイルから直接読み込むことも可能です。pandasのread_excel()関数を使います。シート名と列名の指定が必要です。

import chardet
import pandas as pd

# ファイルのエンコーディング情報を取得
file_path = '/content/sample_data/sample.xlsx'
with open(file_path, 'rb') as f:
    file_encording= chardet.detect(f.read())['encoding']

# Excelファイルを読み込んでテキストデータを抽出
sheet_name = 'シート1'  # 読み込むシートの名前を指定してください
df = pd.read_excel(file_path, sheet_name=sheet_name, encoding=file_encoding)
text = '\n'.join(df["回答"])  # 回答列名を適宜変更してください

print(text)

print(tex)の結果です。

甘くてフルーティーな味で最高
チョコレートとストロベリーの組み合わせが最高!
香りが良くて食べやすい!おすすめです。
子供たちも大喜びのおいしさ!リピート決定。
さわやかな酸味と濃厚なチョコのバランスが絶妙。

2. テキストファイルの正規化

読み込んだテキストの正規化(表記の揺れの是正)を行います。正規化=文字の統一化です。

NFKC(Normalization Form KC)は、Unicodeの正規化形式の一つであり、日本語のテキストに特に有用です。NFKC形式では、以下のような処理が行われます:

  • 半角カタカナ→全角カタカナ
  • 全角英数字記号の半角化
  • 互換性のある文字の置換(①→1, ㋿→令和)

もうひとつ日本語表記の揺れを補正するライブラリとしてneologdnがあります。mecab と neologdn辞書での形態素解析をする前の正規化(表記の揺れの是正)として推奨されていますが、それ以外のケースでも有用です。以下のような処理が行われます。

  • 半角カタカナ→全角カタカナ
  • 全角英数字記号の半角化
  • 連続した長音記号を削除
  • 文字と文字の間のスペースを削除

実際に2つの正規化処理でどのようにテキストが変換されるのかをみていきましょう。


NFKCで正規化

NFKCの特徴は、互換性のある文字の置換です。①、㋿、㌢ といった文字が、1、令和、センチなどに変換されます。

import unicodedata

text = "カタカナカタカナ ABCABC ! ! 123 123 ①テキスト マイニング わーーーい 1984〜2000 ㋿ ㌢"

normalized_text = unicodedata.normalize('NFKC', text)
print(normalized_text)

実行すると下記の結果が出力されます。

カタカナカタカナ ABCABC ! ! 123 123 1テキスト マイニング わーーーい 1984〜2000 令和 センチ

neologdnで正規化

neologdnを使うにはパッケージのインストールが必要です。neologdnでは、"テキスト マイニング"→"テキストマイニング"と文字間のスペースが削除されたり、連続する長音の削除、チルダの削除などが行われます。

!pip install neologdn

import neologdn

text = "カタカナカタカナ ABCABC ! ! 123 123 ①テキスト マイニング わーーーい 1984〜2000 ㋿ ㌢"
normalized_text = neologdn.normalize(text)

print(normalized_text)

実行すると下記の結果が出力されます。

カタカナカタカナABCABC ! ! 123 123 ①テキストマイニングわーい19842000 ㋿㌢

NFKCとneologdnでテキストを正規化する

NFKCとneologdnには同じ正規化処理もあれば異なる処理もあるので、二つを組み合わせて実施しましょう。NKFCで正規化をした結果をneologdnで正規化します。

!pip install neologdn

import unicodedata
import neologdn

text = "カタカナカタカナ ABCABC ! ! 123 123 ①テキスト マイニング わーーーい 1984〜2000 ㋿ ㌢"

normalized_text = neologdn.normalize(unicodedata.normalize('NFKC', text))

print(normalized_text)

実行すると下記の結果が出力されます。

カタカナカタカナABCABC ! ! 123 123 1テキストマイニングわーい19842000令和センチ

読み込んだテキストを正規化する

sample.txtは正規化しても結果は変わりませんが、テキストファイルを読み込んで正規化するプログラムの例が下記になります。

!pip install neologdn

import chardet
import unicodedata
import neologdn

# ファイルのエンコーディング情報を取得
file_path = '/content/sample_data/sample.txt'
with open(file_path, 'rb') as f:
    file_encording= chardet.detect(f.read())['encoding']

# 取得したエンコーディング情報でファイルを読み込む
with open(file_path, 'r', encoding=file_encording) as f:
    text = f.read()
    
# テキストの正規化
normalized_text = neologdn.normalize(unicodedata.normalize('NFKC', text))

print(normalized_text)

正規化されたテキスト文章が、変数 normalized_text に格納されます。

次回は、日本語の文章をテキストマイニングする前処理として重要な形態素解析(単語や文節で区切り、品詞等を判別する)について説明していきたいと思います。

Post Date:2023年3月26日 

Markdown(Typora)でMindmapを描く!

Typoraで描いたマインドマップ

Typoraは優れたMarkdownエディターで、Mac、Windows、Linuxで使えます。有料アプリですが、$14.99(約2,000円)を払う価値のあるMarkdownエディターです。

Mermaidは、Markdown形式のテキストで図を描くことができるオープンソースのJavaScriptツールですが、Typoraは、Mermaidの機能を組み込んでいるので、Mermaidのコードを書くと図形描画ができます。

Mermaidでは、シンプルなテキストを使って複雑なフローチャート、シーケンス図、ガントチャート、クラス図、そしてマインドマップなどを作成することができます。

マインドマップ自体が、階層構造になっているので、Mermaidでの構文もとても簡単です。


Mermaidを使ってマインドマップを作成する

```mermaidでMermaidのコードが書けるようになります。

```mermaid

最初の行にmindmapと書いて、次の行からがマインドマップの構文になります。

mindmap

マインドマップの各ノードを描く

マインドマップは中心のトピックから放射状にアイデアが階層構造で配置されている図です。Mermaid でマインドマップを描くときも、階層構造で記載するので。マインドマップをイメージしながら書くことができます。

下記はrootから3つのメインブランチ(a1, a2, a3)があるマインドマップの例です。階層構造で示せば下記のようになります。

  • Root
    • a1
    • a2
    • a3

mermaid でも同じようにRootから1階層下げてa1, b1, c1 と記載します。

mindmap
	root
		a1
		b1
		c1

下記のように描画されます。

Typoraでマインドマップ

次にa1の下にサブブランチを2つ、a2_1とa2_2を追加します。a1から1階層下げてa2_1, a2_2を記載します。

mindmap
	root
		a1
			a2_1
			a2_2
		b1
		c1

下記のように描画されます。

Typoraでマインドマップ

上記のマインドマップに、a2_1の下にサブブランチ、a3を追加します。

mindmap
	root
		a1
			a2_1
				a3
			a2_2
		b1
		c1

下記のように描写されますが、root --> a1 --> a2_1 --> a3 と階層が下がるとブランチが段々と細くなっていきます。

Typoraでマインドマップ

各ノードの形を変える

各ノードに使える形状には、

  • cloud(雲吹き出し)
    ) ( で括る
  • bang(爆弾吹き出し)
    )) (( で括る
  • circle(円形)
    (( ))で括る
  • round square(角丸四角形)
    ( )で括る
  • square(四角形 )
    [ ] で括る
  • default(デフォルト)

の6種類がありますが、デフォルトは何も指定しない場合です。<br/>は改行です。

mindmap
	)cloud<br/>雲吹き出し(
	))bang<br>星吹き出し((
	((Circle<br>円形))
	(rounded square<br>角丸四角形)
	[square<br>四角形]
	default shap<br>デフォルト

描画すると下記のようになります。squareとdefaulとの違いはよく見るとデフォルトは下に線が入っています。

Typoraでマインドマップ(Shape)

アイコンを使う

ノードの中にアイコンを記載することもできます。Font Awesomrのアイコンが使用でき、class名を指定します。

Font Awesomr のアイコン

Font Awesomrのclass名は、Font Awesome4.7フォント一覧で調べられます。

アイコンを記載したノードの下に同じ階層で

::icon(fa class名)

という形式で指定します。

a1に音符、b1に封筒、c1にユーザのアイコンをそれぞれ指定する場合には下記のように記載します。

mindmap
	)Root(
		music
		::icon(fa fa-music)
		envelope
		::icon(fa fa-envelope-o)
		user
		::icon(fa fa-user)

こんな感じです。Font Awesomrのclass名で記載するので少々面倒ですが、アイコンを使うとマインドマップらしくなります。

Typoraでマインドマップ(Icon)

色の指定と配置はできない

ブランチの色を変更することはできません。またブランチの配置を変更することもできません。しかし、マインドマップ描画ソフトを使わなくてもMarkdownでマインドマップが簡単に描けるのは便利です。


円グラフを書く(おまけ)

最後に Mermaid を使った円グラフの描き方です。こちらも簡単に描けます。

```mermaid コードを記載します。

  • 1行目:pie円グラフの宣言
  • 2行目:titletitleの後が円グラフの表題
  • 3行目以降:円グラフの要素
    ”グラフの項目名”:比率

下記がサンプルコードです。

pie
	title pie chart
	"50%" : 50
	"30%" : 30
	"20%" : 20

下記が、Mermaidで描いた円グラフになります。

Mermaid で描いた円グラフ

bar chart(棒グラフ)もMermaidで描けるともっと便利になるのですが、、、。

Post Date:2022年8月13日 

GASで複数のPDFを結合する

ゾウでもわかる Google Apps Script

Google Apps Script で複数のPDFを結合できないかと探していたら、officeの杜 | PDFを結合するという記事がありました。

officeの杜で共有されているこちらのコード にある mergePdfs() を活用させていただきました。元ネタは、stack overflowにある Merge Multiple PDF's into one PDF です。


結合できるPDFファイル

stack overflowのコメントにPDFのバージョンが1.5以上である場合には大きな修正が必要(結合できない)と記載されていますが、Googleの機能(印刷)やChromeの印刷でPDFにしたPDFはマージ可能でした。

対象 PDFバージョン マージ可否
Googleドキュメント 1.4
Googleプレゼンテーション 1.7
Googleスプレットシート 1.7
Google Chrome 1.4
Office 365 1.7

PDFのバージョンはAdobe Acrobat Readerで確認できます。

下記は、Googleドキュメントの印刷からPDFを保存した場合です。バージョンは1.4となっています。

Googleスプレッドシート、プレゼンテーションは、バージョンが1.7と表示されますが、

前述したように問題なく結合することができます。

Office 365でPDFに変換したファイルは結合できませんでしたが、Googleを中心としたサービスを利用しているのであれば問題なさそうです。


mergePdfs()関数を使う

mergePdfs()関数の説明と引数をみると

mergePdfs(directory, name, pdf1, pdf2, pdf3, ....)
drirectory PDFが格納されているディレクトリID
name 結合したPDFのファイル名
pdf1, ... 結合するPDFファイル

結合するPDFファイルは2つ以上複数指定できますが、引数でファイル名をひとつづつ指定するのは煩わしい。

ということで、フォルダーにあるPDFをリスト(配列に格納)して引数として渡せるように変更してみました。

またPDFファイルの結合順番はファイル名で昇順にソートした順番にします。ファイル名の先頭に数字を入れておけば番号順で結合されます。

例えば、ファイル名を

0.test.pdf
1.test.pdf
2.test.pdf

としておけば、0.test、1.test、2.testの順番で結合されます。


mergePDFs()関数の修正

先ずは、office杜のこちらのリンクからmergePdfs()のプログラムを取得してください。

修正箇所は3箇所です。

12行目

関数の引数をファイル名から、配列を1つ渡すように変更します。

修正前:
function mergePdfs(directory, name, pdf1, pdf2, opt_pdf3) {
修正後:
function mergePdfs(directory, name, pdfList {
21行目

関数の引数ループで取得しているところを、引数に格納されているファイル数分(配列の長さ分)で処理するように変更します。

修正前:
for (var argumentIndex = 2; argumentIndex < arguments.length; argumentIndex++) {
修正後:
for (var i=0; i<pdfList.length; i++) {
23行目

マージするPDFのファイルサイズ取得を引数の配列からに変更します。

修正前:
var bytes = arguments[argumentIndex].getBlob().getBytes()
修正後:
var bytes = pdfList[i].getBlob().getBytes()

また、475行目移行はPDFを分割する関数のコードになっていますので削除してしまっても問題ありません。


mergePDFs()関数を呼び出す

次は、修正したmergePDFs()関数を呼び出すプログラムになります。指定したフォルダIDにあるPDFファイルを配列(pdfList)に格納して、ファイル名順にソートしてから mergePDFsに引き渡します。

<フォルダID>にはGoogleドライブのフォルダIDを、<ファイル名>には結合して作成するファイル名にしてください。

フォルダIDは、フォルダを開いたときのURL、https://drive.google.com/drive/folders/XXXXX XXXX部分になります。

function merge(srcFolderId, fileName){
  var srcFolderId = '<フォルダID>' //フォルダ ID
  var fileName = '<ファイル名>' //結合後のファイル名

  //フォルダ内のファイルを取得
  var srcFolder = DriveApp.getFolderById(srcFolderId)
  var srcFiles = srcFolder.getFiles()

  //PDFファイルだけを配列に格納
  var pdfList = []
  while(srcFiles.hasNext()) {
    var srcFile = srcFiles.next()
    if (srcFile.getMimeType()==='application/pdf') {
      pdfList.push(srcFile);
    }
  }
  pdfList.sort()  //照準でソート
  mergePdfs(srcFolder, fileName, pdfList)
}

13行目のgetMimeType()でPDFファイルだけを対象にしています。また17行目のsort()で配列に格納した各ファイルをファイル名でソートしています。


スプレッドシートのUI機能で汎用的にする

もう少し汎用的に使えるように、スプレッドシートのUI機能を使って、フォルダIDと結合して作成するファイル名をUI上で入力するようにします。

またスプレッドシートのメニューからGASの実行を可能にします。

スプレッドシートの機能を使うので、Googleスプレッドシートの拡張機能から Apps Script を作成する必要があります。


スプレッドシートにメニューに追加する

スプレッドシートが開かれたときにメニューを追加します。こんな感じです。

「mergePDFs」 > 「PDFを結合」 で diaLog関数を実行します。

function onOpen(){ 
  SpreadsheetApp
    .getActiveSpreadsheet()
    .addMenu('mergePDFs', [
      {name: 'PDFを結合', functionName: 'diaLog'}
    ])
}

ダイアログ

詳細の説明は省きますが、「フォルダーID」と「ファイル名」の入力の後に確認画面を出してが簡単なチェックと確認を出力して merge()関数にフォルダIDとファイル名を引き渡します。

ダイアログでフォルダーIDを指定する

またPDFの結合でエラーとなった場合にもエラー出力をするようにしています。

ダイアログでエラーメッセージを出力

下記がサンプルコードとなります。

function diaLog() {
/********************
PDFがあるフォルダを指定 
********************/
  var srcFolderId = Browser.inputBox("結合したいPDFがあるフォルダを指定してください(FolderID)",Browser.Buttons.OK_CANCEL)
  //キャンセルが押下されたら終了
  if (srcFolderId == 'cancel')  {
    return
  }
  try {
    var srcFolder = DriveApp.getFolderById(srcFolderId)
  }
  catch(e) {
    Browser.msgBox('ERROR', srcFolderId + ' is not available', Browser.Buttons.OK)
    return
  }
/********************
ファイル名の指定 
********************/
  var fileName = Browser.inputBox("結合後のファイル名を指定してください(FolderID)",Browser.Buttons.OK_CANCEL)
  //キャンセルが押下されたら終了
  if (fileName == 'cancel')  {
    return
  } else if (fileName == '') {
    Browser.msgBox('ERROR', 'File name is not defined', Browser.Buttons.OK)
    return
  }
/********************
開始の確認 
********************/
  var srcFolderName = srcFolder.getName()

  var result = Browser.msgBox('Confirm', '「' + srcFolderName + '」にあるすべてのPDFを\\n「' + fileName + '」として結合します', Browser.Buttons.OK_CANCEL)
  if (result == 'cancel')  {
    return
  }

  try {
    merge(srcFolderId, fileName)  //PDF格納フォルダ,ファイル名
  }
  catch(e) {
    Browser.msgBox('ERROR', 'Error Occurred during merging', Browser.Buttons.OK)
    return
  }
  
  Browser.msgBox('Complete', 'PDFの結合が完了しました', Browser.Buttons.OK)
}

これで完成です。

スプレッドシートのメニューから dialog()関数を呼び出し、merge()関数でフォルダ内のPDFをリスト化して、mergePDFs()関数でPDFを結合します。

先人の知恵と努力に感謝です。


GASの基礎を学べる参考図書

ある程度プログラミンがわかっていれば、WEBやYoutubeでも十分に調べられると思いますが、初歩的なところからであれば参考図書は有効な学習手段です。

詳解! Google Apps Script完全入門 [第3版]」は、プラグラミング初心者にわかりやすく説明されています。GASを最初に学ぶ一冊として良書です。

Udemy オススメ講座

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

講師:事務職たらこ

印象に残りやすい手書き風スライドを用いGASの基本的なプログラミングを気軽に学ぶことができる。本講座でGASを活用した自動化ができるレベルにはなれないが、基礎としては十分。

Post Date:2022年6月17日 

gasの変数について考えてみる

ゾウでもわかる Google Apps Script

Google Apps Scrit (GAS) で変数を定義するキーワードには、var, let, const の3種類があります。変数と定数の違いは明確ですが、varlet の違いはどのようなところにあるのかをサンプルプログラムを実行しながら確認してみました。


変数と定数

var, let は、再代入(値を入れ替えること)ができる変数で、const は定義した値を変更できない定数です。

再代入とは、下記の例のように、最初に x に 1を代入して、次に x に x+1(=2) を代入するということです。

function argument() {
  let x = 1
  x = x + 1
}

定数の場合には、x に 1を代入したあとに変更ができません。下記を実行するとエラーとなります。

function argument() {
  const x = 1
  x = x + 1
}

変数の利用可能範囲(スコープ)

では、varlet の違いは何でしょうか?

GoogleのV8ランタイムの説明を読むと

let および const キーワードは、ブロックスコープのローカル変数/定数を定義することができます。(和訳)

【引用】 let and const - Google Apps Script

と記載されています。

ブロックとは、{}で括られた処理のことで、例えば、if分も{}で括られた処理です。ローカル変数というのは、そのブロック内でしか使えない変数/定数ということです。

letconst は、同じ関数内であってもif文内で宣言した関数は使えないということになります。ちなみに var の場合は、同じ関数内であれば if文内で宣言した変数を利用することができます。

let and const - Google Apps Script にあるサンプルプログラムに constvar を追加してスコープについて確認してみます。

function myFunction() {
  let x = 'hello'
  const y = 'hello'
  var z = 'hello'
  if (x === 'hello') {
    let x = 'World'
    const y = 'World'
    var z = 'World'
    console.log('let x=', x)      // Prints 'world'
    console.log('const y=', y) // Prints 'world'
    console.log('var z=', z)     // Prints 'world'
  }
  console.log('let x=', x)      // Prints 'hello'
  console.log('const y=', y) // Prints 'hello'
console.log('var z=', z)     // Prints 'world' }

let, const の有効範囲はブロック内です。5行目からのif文のブロックの中では、6,7行目で変数の宣言と代入がされている 'world' が出力されます。

しかし、13,14行目のログ出力では、myFunction() として、2,3行目で変数の宣言と代入がされている 'hello' が有効な変数となります。

一方、var で定義した変数 xは、15行目のログ出力で 'world' と出力されます。これは var 変数は同一関数内で有効であり、かつ次に説明する再宣言ができるので、console.log が実行される直前(11行目)に宣言と代入がされた変数の値が出力されます。


関数で定義した変数はif, for のブロック内でも使える

上位のブロックで let, const で宣言された変数は、下位のブロックでも参照できます。

下記の例で説明します。

function checkScope() {
  let x = 0
  if (x==0)  {
    let y = 0
    for (let i=0; i<10; i++) {
      x = x + 1
      y = y + 1
    }
    console.log('y=', y)
  }
  console.log('x=', x)
}

変数 x は、checkScope() 関数で定義しているので、下位ブロックのif文、さらにその下位にあたる forループでも参照することができます。なので、x=x+1 が10回実行され、forループ、if文を抜けたあとのログ出力で x=10 と出力することができます。

変数 y は、if文の中で宣言されているので、下位ブロックのforループで参照することができます。forループでの処理で再代入された値が、if文内のログ出力で可能です。

しかし、if文を出た後にログ出力をしようとすると y は定義されていないとエラーとなります。

function checkScope() {
  let x = 0
  if (x==0)  {
    let y = 0
    for (let i=0; i<10; i++) {
      x = x + 1
      y = y + 1
    }
    console.log('y=', y)
  }
  console.log('x=', x)
  console.log('y=', y)
}

また forループで使っている変数 i も let で定義しているので forループ内だけで有効です。これを for (var i=0; ....) とすると、変数 i は、関数内で参照できる変数となります。

また 変数 i を宣言するときに、let, var のキーワードを付けないと(忘れると)、変数 i は、グローバル変数となり、変数が宣言された以降に実行されるどの関数でもアクセスできるようになってしまいます。

function checkScope() {
  let x = 0
  if (x==0)  {
    let y = 0
    for (i=0; i<10; i++) {
      x = x + 1
      y = y + 1
    }
    console.log('y=', y)
  }
  console.log('x=', x)
  print()
}
function print()	{
  console.log('i=', i)
}

再宣言

変数のスコープで var の再宣言についてふれましたが、もう少し簡単な例で説明します。下記のように var は、同じ関数内で何度でも宣言できます。

function redeclaration() {
  var x = 1
  x = x + 1
  console.log('x=', x)
  var x = 'Hello'
  console.log('x=', x)
}

let, const は同一ブロック内では1回しか宣言できません。下記のプログラムは構文エラーとなり保存できません。

function test() {
  let x = 1
  x = x + 1
  console.log('x=', x)
  let x = 'Hello'
  console.log('x=', x)
}

var, let, constの違い(まとめ)

var, int, const の違いを表にまとめます。

キーワード 再代入 再宣言 スコープ
var 可能 可能 同一関数内
let 可能 不可 ブロック内
const 不可 不可 ブロック内

参照できる範囲が少なく、再宣言ができないということは、より明示的に変数を使うということになるので、「varではなくlet を利用しましょう」というのも納得できます。


関数間で値の引き渡し

関数の中で関数を呼び出す場合には、引数として関数に値を引き渡すことができます。また、関数での実行結果を戻す場合には、戻り値として結果を返却することができます。

function argument() {
  let x = 1
  let y = 2
  let z = cal(x, y)
  console.log('z=', z)
}
function cal(a, b)	{
  let c = a + b
  return c
}

cal() を呼び出すときに引数として x, y をセットしています。7行目の function cal(x, y)では、4行目で設定した引数 x, y をそれぞれ a, b にセットしています。この関数の中では、合算した値(1+2)を cに代入して、cを戻り値としています。

関数の呼び出し側は、戻り値を変数zに代入するために let z = cal(x, y) としています。


グローバル変数

最後にグローバル変数についてです。関数内ではなくプログラムのトップレベルで定義された変数/定数は、プログラ内のどこから(同じプロジェクト内のどの関数から)でもアクセスすることができます。

const x = 1
const y = 2
function main()	{
  sub1()
  sub2()
  console.log('x=', x)
  console.log('y=', y)
}
function sub1()	{
  console.log('x=', x)
}
function sub2()	{
  console.log('y=', y)
}

変数も奥が深いですね。


GASの基礎を学べる参考図書

ある程度プログラミンがわかっていれば、WEBやYoutubeでも十分に調べられると思いますが、初歩的なところからであれば参考図書は有効な学習手段です。

詳解! Google Apps Script完全入門 [第3版]」は、プラグラミング初心者にわかりやすく説明されています。GASを最初に学ぶ一冊として良書です。

Udemy オススメ講座

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

講師:事務職たらこ

印象に残りやすい手書き風スライドを用いGASの基本的なプログラミングを気軽に学ぶことができる。本講座でGASを活用した自動化ができるレベルにはなれないが、基礎としては十分。

Post Date:2022年5月7日 

Googleスプレッドシートの更新された範囲をURLとして通知する

ゾウでもわかる Google Apps Script

シートの更新通知を使うと確認が必要のない更新通知も送られてくるので、自分に必要な項目が更新されたときだけに通知が欲しい。

また、どこが変更されたのかが分かると、通知を受けた人に優しい仕様となります。

象と散歩: Googleスプレッドシートの更新された値を知るで、変更された箇所の行番号と列番号を取得する方法を紹介しましたが、変更範囲をセル範囲が指定されたリンクとして作成するGASプログラムを作ってみました。


URLの取得

onEdit()関数については、象と散歩: Googleスプレッドシートの更新された値を知る で説明していますが、スプレッドシートが更新されたときに実行される関数です。

onEdit(e)	{
  var ssUrl = e.source.getUrl()	//スプレッドシートのURL
  console.log(ssUrl)
}

セルの内容が更新されると、上記の関数が実行されます。マニュアルで実行するとエラーとなりますので、セルの値を更新してログを確認してください。

onEdit()関数の引数に e を指定していますが、e.source でスプレッドシートオブジェクトが取得でき、getUrl()でスプレッドシートのURLが取得できます


シートはGIDパラメータで指定する

上記で取得したスプレッドシートのURLは、下記のような構成になっています。

https://docs.google.com/spreadsheets/d/xxxxx/edit

複数シートがある場合には、URLにGIDパラメータが付与されています。

https://docs.google.com/spreadsheets/d/xxxxx/edit#gid=749420395

最初のシート(シート 1)は、必ず gid=0 ですが、getSheetId() で GIDを取得することができます。

onEdit(e)	{
  var sheet = e.source.getActiveSheet()
  var sheetId = sheet.getSheetId()	//シートID
  console.log(sheetId)
} 

セル範囲はRANGEで指定する

セルを右クリックして"このセルへのリンクを取得"をクリックすると

範囲を指定してリンクを取得する

下記のようなURLが取得できます。

https://docs.google.com/spreadsheets/d/xxxxx/edit#gid=0&range=C2

また複数セルを選択した状態で右クリックして"この範囲のリンクを取得"をクリックすると下記のようなURLが取得できます。

https://docs.google.com/spreadsheets/d/xxxxx/edit#gid=0&range=A3:C3

"range=" で範囲を指定したURLを取得できます。


A1形式で範囲を取得する

onEdit()で実行されたときにrangeで変更範囲が取得できますが、A3:C3のようなA1形式で範囲を取得するには、range.getA1Notation() を使います

更新範囲がひとつのセルならA3、範囲ならA3:C3のように取得することができます。

onEdit(e)	{
  var sheetRange = e.range.getA1Notation()	//変更範囲
  console.log(sheetRange)
}

シートの値を変更して、ログを確認してください。複数セルの範囲は、シート上で範囲選択をしてコピペをすることで確認できます。


シートと範囲を指定したURLを作成

シートID(GID)と範囲(RANGE)を指定したURLを作成します。

function onEdit(e) {
  var ssUrl = e.source.getUrl()	//スプレッドシートのURL
  var sheet = e.source.getActiveSheet()
  var sheetId = sheet.getSheetId()	//シートID
  var sheetRange = e.range.getA1Notation()	//変更範囲
  var url = ssUrl + '#gid=' + sheetId + '&range=' + sheetRange
  console.log(url)
}

ログに出力されたURLをコピペして、範囲選択がされた状態でスプレッドシートが開くかを確認してください。


変更範囲の確認

特定の範囲が更新されたときだけ通知があるように、更新されたセルが対象としたいセル範囲内にあるかを確認します。

下記のサンプルプログラムでは、targetStartColumn, targetEndColumn で対象列を、targetStartRow, targetEndRow で対象行を指定しています。

下例では、C列の2行目から1000行目が更新されたかを確認するサンプルコードとなります。

function onEdit(e)  {
  var targetStarColumn =3 //対象セル(開始列)
  var targetEndColumn = 3 //対象セル(終了列) 
  var targetStartRow = 2  //対象セル(開始列)
  var targetEndRow = 1000 //対象セル(終了列)

  var rowStart = e.range.rowStart //更新開始行の取得
  var rowEnd = e.range.rowStart   //更新終了行の取得
  var columnStart = e.range.columnStart //更新開始列の取得
  var columnEnd = e.range.columnEnd     //更新終了列の取得

  var ssUrl = e.source.getUrl() //スプレッドシートのURL
  var sheet = e.source.getActiveSheet()
  var sheetId = sheet.getSheetId()  //シートID
  var sheetRange = e.range.getA1Notation()  //変更範囲

  var text = '変更箇所の通知\n'
  if (targetStarColumn <= columnStart &&  columnEnd <= targetEndColumn
      &&  targetStartRow <= rowStart &&  rowEnd <= targetEndRow) {
    text = text + ssUrl + '#gid=' + sheetId + '&range=' + sheetRange
  } else  {
    text = '対象範囲外の更新'
  }
  console.log(text)
}

対象範囲が更新された場合に "更新されたシートとセル範囲を指定したURL" を作成します。シートを更新して実行結果をログで確認してください。


メールを送信する

シンプルトリガーのonEdit()ではメール送信ができないので、function名を変更して、トリガーを設定します。

トリガーの設定方法については、

を参考にしてください。

メール送信は GmailAppクラスのsendEmailメソッドを使います。

GmailApp.sendEmail(宛先, 件名, 本文, {オプション})

オプションは省略可能です。(詳細はClass GmailAppを参照してください)

mailTo で指定しているメールアドレスは、自分のメアドに変更してください。

function updateNotice(e) {
  var ssUrl = e.source.getUrl()	//スプレッドシートのURL
  var sheet = e.source.getActiveSheet()
  var sheetId = sheet.getSheetId()	//シートID
  var sheetRange = e.range.getA1Notation()	//変更範囲
  var url = ssUrl + '#gid=' + sheetId + '&range=' + sheetRange

  // メール送信
  var mailTo   = 'sample@gmail.com'
  var subject  = '更新通知'
  var bodyText = '変更箇所の通知\n'
  bodyText     = bodyText + url
	
  GmailApp.sendEmail(
    mailTo,
    subject,
    bodyText
  )
}

特定のセルが更新されたときにメールを出す場合には下例を参考にしてください。

function updateNotice(e) {
  var targetStarColumn = 3	//対象セル(開始列)
  var targetEndColumn = 3	//対象セル(終了列) 
  var targetStartRow = 2	//対象セル(開始列)
  var targetEndRow = 1000	//対象セル(終了列)

  var rowStart = e.range.rowStart //更新開始行の取得
  var rowEnd = e.range.rowStart   //更新終了行の取得
  var columnStart = e.range.columnStart //更新開始列の取得
  var columnEnd = e.range.columnEnd     //更新終了列の取得

  var ssUrl = e.source.getUrl() //スプレッドシートのURL
  var sheet = e.source.getActiveSheet()
  var sheetId = sheet.getSheetId()  //シートID
  var sheetRange = e.range.getA1Notation()  //変更範囲

  var text = '変更箇所の通知\n'
  if (targetStarColumn <= columnStart &&  columnEnd <= targetEndColumn
      &&  targetStartRow <= rowStart &&  rowEnd <= targetEndRow) {
    text = text + ssUrl + '#gid=' + sheetId + '&range=' + sheetRange
    sendMail(text)
  }
}
function sendMail(text)	{
  // メール送信
  var mailTo   = 'sample@gmail.com'
  var subject  = '更新通知'
  var bodyText = text

  GmailApp.sendEmail(
    mailTo,
    subject,
    bodyText
  )
}

上記例では更新されたセル範囲でURLを作成していますが、range=開始行番号:終了行番号とすると、更新された行をフォーカスしたURLが作成できます。

https://docs.google.com/spreadsheets/d/XXXXX/edit#gid=0&range=3:3

上記も、rowStart と rowEnd を使って簡単に作成できます。


GASの基礎を学べる参考図書

ある程度プログラミンがわかっていれば、WEBやYoutubeでも十分に調べられると思いますが、初歩的なところからであれば参考図書は有効な学習手段です。

詳解! Google Apps Script完全入門 [第3版]」は、プラグラミング初心者にわかりやすく説明されています。GASを最初に学ぶ一冊として良書です。

Udemy オススメ講座

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

講師:事務職たらこ

印象に残りやすい手書き風スライドを用いGASの基本的なプログラミングを気軽に学ぶことができる。本講座でGASを活用した自動化ができるレベルにはなれないが、基礎としては十分。

Post Date:2022年3月6日 

GASでExcelをGoogleスプレッドシートに変換する

ゾウでもわかる Google Apps Script

ExcelファイルのデータをGASで処理するには、GoogleDrive上でExcelファイルを開いてGoogleスプレッドシートで保存する必要があります。

ExcelをGoogleスプレッドシートとして保存

小さなExcelファイルなら上記の方法でも構いませんが、大きなExcelファイルだと ”Googleスプレッドシートとして保存” で時間がかかりすぎて保存できない、、、。

また複数ファイルがあるときは一括変換できれば楽ちんです。

ということで、GASでExcelファイルをGoogleスプレッドシートに変換する2つの方法について説明します。

  1. Excelファイルを指定してスプレッドシートに変換する
  2. フォルダにあるExcelファイルを一括変換する

Excel to Google Sheets には Drive APIが必要

Google Apps Script でExcelファイルを開く場合には、Googleドライブのファイルやフォルダを操作できる DriveAppクラス を使います。

但し、そのまま、DriveAppのコードを書いて実行しても

エラー ReferenceError: Drive is not defined

と、実行できません。


Drive APIサービスを追加する

DriveAppクラスを使うためには、Apps Scriptエディターの左側のメニューにある「サービス」からDrive APIを追加する必要があります。

① サービスの右側にある+をクリック

サービスの追加

② 一覧から Drive API を選択して追加

Drive APIを選択

Drive APIが追加されると左メニューのサービスの下にDriveが表示されます。

サービスにDriveが追加

これで DriveAppクラスが利用できます。


Excelファイルを指定してスプレッドシートに変換する

Excelファイルを指定して、指定したフォルダにGoogleスプレッドシートを出力するサンプルコードとなります。

Excelファイルと出力先のフォルダはIDで指定します。


ExcelファイルとフォルダのID

GoogleドライブからExcelファイルを開いたURLのXXXXXの部分がIDとなります。

https://docs.google.com/spreadsheets/d/XXXXX/edit

ExcelのファイルID

GoogleドライブのフォルダIDは、XXXXXの部分がIDになります。

https://docs.google.com/drive/u/0/folder/XXXXX

フォルダID


サンプルコード(Excelファイル指定)

上記で説明したExcelファイルと出力先のフォルダのIDを指定する、簡単なサンプルコードです。

12行目で取得したExcelファイル名を13行目でログに出力していますが、変換したGoogleスプレッドシート名も同じファイル名にしています。

function convertExcel()  {
  //変換するExcelファイル
  let excelFileId = 'XXXXX'

  //スプレッドシート出力先フォルダー
  let destFolderId = 'XXXXX'

  //ExcelファイルをファイルIDで取得
  var excelFile = DriveApp.getFileById(excelFileId)

  //Excelファイル名取得
  var fileName = excelFile.getName()
  Logger.log(fileName)

  var option =  {
    mimeType:MimeType.GOOGLE_SHEETS,   //Google sheets
    parents:[{id:destFolderId}],                       //出力先フォルダー
    title:fileName                                          //出力先ファイル名
  }
  Drive.Files.insert(option,excelFile)
}

20行目の

Drive.Files.insert(option,excelFile)

で、変換を実施していますが、15〜19行目のオプションで、

  • MIMEタイプ
  • 出力先フォルダー
  • 出力先ファイル名

を指定しています。

スプレッドシートへの変換なのでMIMEタイプをGOOGLE_SHEETSとしていますが、Enum MimeType | Apps Script | Google Developers に全てのMIMEタイプが記載されています。


変換後に処理を続ける

Googleスプレッドシートに変換してから、そのままシートをGAS処理する場合には、20行目からを下記のように変更してください。

取得したシート名をログに出力する簡単なサンプルです。

function convertExcel()  {
  //変換するExcelファイル
  let excelFileId = 'XXXXX'

  //スプレッドシート出力先フォルダー
  let destFolderId = 'XXXXX'

  //ExcelファイルをファイルIDで取得
  var excelFile = DriveApp.getFileById(excelFileId)

  //Excelファイル名取得
  var fileName = excelFile.getName()
  Logger.log(fileName)

  var option =  {
    mimeType:MimeType.GOOGLE_SHEETS,   //Google sheets
    parents:[{id:destFolderId}],                       //出力先フォルダー
    title:fileName                                          //出力先ファイル名
  }
  var sheetObj = Drive.Files.insert(option,excelFile)

  //スプレッドシートIDを使って、スプレッドシートオブジェクトを取得
  var sheet = SpreadsheetApp.openById(sheetObj.id).getActiveSheet()
  Logger.log(sheet.getName())  
}

変換したスプレッドシートにシートが複数ある場合には、getSheetByName() でシート名を指定します。


フォルダにあるExcelファイルを一括変換する

次は、フォルダにある複数のExcelファイルを一括でGoogleスプレッドシートに変換する方法です。

フォルダにExcelファイル以外がある場合には処理されないようにしています。

function convertExcels() {
  //Excelがあるフォルダ
  let sourceFolderId = 'XXXXX'
  //スプレッドシート出力先フォルダー
  let destFolderId = 'XXXXX'

  // フォルダ配下のファイルを取得
  var sourceFolder = DriveApp.getFolderById(sourceFolderId)
  var folderFiles  = sourceFolder.getFiles()

  // Excelファイルをイテレートして順にスプレッドシートに変換
  while(folderFiles.hasNext()) {
    var file = folderFiles.next()
    //Excelファイルの判断   
    if (file.getMimeType() == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')  {
      var fileName  = file.getName()
      Logger.log(fileName)
      Logger.log(file.getMimeType())
      var option =  {
        mimeType:MimeType.GOOGLE_SHEETS,  //Google sheets
        parents:[{id:destFolderId}],      //出力先フォルダーを指定
        title:fileName                    //出力先ファイル名
      }
      Drive.Files.insert(option,file)
    }
  }
}

フォルダにあるファイル一覧を取得しているのが、8〜9行目です。

そして、12行目の while文のhasNext() で13行目の next()で取得したファイル一覧から取り出せるファイルが残っているかを調べて、順番にファイルを処理していきます。

Excelファイルだけを変換するために、取り出したファイルがEXCELファイルかを15行目で調べています。

18行目でgetMimeType()でファイルのMIMEタイプを出力していますが、application/vnd.openxmlformats-officedocument.spreadsheetml.sheet が、拡張子xlsのExcelファイルとなります。


GASの基礎を学べる参考図書

ある程度プログラミンがわかっていれば、WEBやYoutubeでも十分に調べられると思いますが、初歩的なところからであれば参考図書は有効な学習手段です。

詳解! Google Apps Script完全入門 [第3版]」は、プラグラミング初心者にわかりやすく説明されています。GASを最初に学ぶ一冊として良書です。

Udemy オススメ講座

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

【新IDE対応】Google Apps Script(GAS)の基礎を完全習得

講師:事務職たらこ

印象に残りやすい手書き風スライドを用いGASの基本的なプログラミングを気軽に学ぶことができる。本講座でGASを活用した自動化ができるレベルにはなれないが、基礎としては十分。

広告

象と散歩:人気の投稿(過去7日間)