PythonからGoogleスプレッドシートを操作する方法 スプレッドシートの設定

Python学習【365日チャレンジ!】356日目のマスターU(@Udemy11)です。

いよいよPython学習365日チャレンジ最後の月になる2月に突入し、残り日数も今日を入れて、あと10日で、カウントダウンできるところまでやってきました!

途中、何度か挫折しそうになる時期はありましたが、なんとか切り抜けて、Python学習を継続することができています。

ここまで継続できたのは、私の人生の中ではじめてなので、あらためてよく続いているよな〜と自分で自分に感心してしまいます。

といってもあと10日、気を抜かずにGoalしたいと思います。

ということで、今日もPython学習を始めましょう。

昨日の復習

昨日は、GoogleスプレッドシートをPythonから操作するコードを書いて実際に動かしてみました。

スプレッドシートのセルを指定して値を取得したり、計算したあとスプレッドシートに書き込んだりすることができました。MySQLなどのデータベースの場合は、データベースの中身をイメージするのがちょっとむずかしいのですが、スプレッドシートだと目に見えるので、データベースの取り扱いに慣れていなくても扱いやすいのが特徴です。

昨日の学習内容については、こちらの記事をごらんください。

今日は、スプレッドシートキーと秘密鍵のファイル名を入力して、数値を入れたら計算結果がスプレッドシートに入力されるアプリを作ってみます。

シートキーとjsonファイル

Googleスプレッドシートを操作するので、Google Cloud Platformから取得した認証情報が入ったjsonファイルを用意して、スプレッドシートの共有設定を完了しておきます。

この2つの記事を参考に準備を整えておきましょう。

準備ができたら、コードを書いていきます。

インターフェイス

スプレッドシートキーと秘密鍵のファイル名、値を入力する次のような入力フォームをTkinterで作成します。

Tkinterで作った入力フォーム

ということで、この入力フォームのコードがこちら。

interface.py

import tkinter as tk

import control

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master.geometry()
        self.master.title('get number and calculate')
        self.menu_bar = tk.Menu(self.master)
        self.master.config(menu=self.menu_bar)

        self.entry = tk.Entry(self.master, width=40)
        self.entryf = tk.Entry(self.master, width=40)
        self.entry2 = tk.Entry(self.master, width=10)
        self.lavel = tk.Label(text='シートキー:')
        self.lavelf = tk.Label(text='ファイル名:')
        self.lavel2 = tk.Label(text='値を入力:')

        self.create_widgets()

    def clear_all(self):
        self.entry2.delete(0, tk.END)

    def cal(self):
        keys = self.entry.get()
        numbers = self.entry2.get()
        file_name = self.entryf.get()
        control.main(numbers, keys, file_name)

    def create_widgets(self):
        file_menu = tk.Menu(self.menu_bar)
        file_menu.add_command(label='Exit', command=self.master.quit)
        self.menu_bar.add_cascade(label='File', menu=file_menu)
        self.entry.grid(row=1, column=2, columnspan=6, pady=10, padx=10)
        self.entryf.grid(row=2, column=2, columnspan=6, pady=10, padx=10)
        self.entry2.grid(row=3, column=2, pady=10)
        self.lavel.grid(row=1, column=1)
        self.lavelf.grid(row=2, column=1)
        self.lavel2.grid(row=3, column=1)
        self.entry.focus_set()

        tk.Button(self.master, text='Clear', width=4,
                  command=self.clear_all).grid(row=4, column=6)

        tk.Button(self.master, text='計算', width=4,
                  command=self.cal).grid(row=4, column=7, pady=10)

root = tk.Tk()
app = Application(master=root)
app.mainloop()

ベースとなっているのは、下記の記事で作ったGoogle検索の結果からデータを抽出するアプリのコードです。

3行目でインポートしているのは、作業を行うメインのPythonファイル(control.pyです。
このファイルのコードはあとで解説します。

5行目からのtk.Frameを継承したApplicationクラスを作るコードの初期化関数や49行目からのインスタンスの作成、mainloog()の実行は、Tkinterのお決まりコードです。

13行目から18行目で【スプレッドシートキー】【秘密鍵のファイル名】【計算のもととなる値】を入力するテキストボックスとラベルを作っています。

__init__()の20行目で実行するcreate_widgets()は、31行目から41行目に定義していて、それぞれのパーツを配置して、ボタンには動作をさせる関数(clear_all()cal())を割り当てています。

22行目で定義しているclear_all()は、数値のテキストボックスを空にする関数で、25行目で定義しているcal()は、control.pymain()に取得した【スプレッドシートキー】【秘密鍵のファイル名】【計算のもととなる値】を渡して実行する関数です。

続いて、計算実行ファイルを見てみましょう。

計算実行ファイル

こちらのコードは、昨日の記事で解説したコードに、一部関数を追加したり、フォームから取得する値を使用するコードに変更したりしています。

control.py

import gspread
from oauth2client.service_account import ServiceAccountCredentials

def main(numbers, keys, file_name):
    scopes = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
    credentials = ServiceAccountCredentials.from_json_keyfile_name(file_name, scopes)
    gc = gspread.authorize(credentials)
    SHEET_KEY = keys
    worksheet = gc.open_by_key(SHEET_KEY).sheet1

    import_value = int(numbers)

    worksheet.update_cell(1, 1, import_value)
    for i in range(10):
        num_v = import_value * (i + 1)
        worksheet.update_cell((i + 1), 2, num_v)

if __name__ == '__main__':
    main()

ハイライトしている部分が追加、変更したコードですが、一番の大きな違いは、main関数で、3つの引数(numbers, keys, filename)を取得して、最後にいつもの実行コードを加えているところです。

6行目のfile_nameがダウンロードしたjsonファイル名で、8行目のkeyがスプレッドシートキー、11行目のnumbersが、計算のもとになる、前回、スプレッドシートのA1セルに入力されていた値です。

13行目で、スプレッドシートのA1セルに取得した値numbersを入れて、14行目からの計算は昨日と同じコードで、取得した整数numbersに1から10までを掛けた値をB1からB10に入力するforループになります。

動作確認

interface.pyを実行して、実際に計算できるか確認してみました。

スプレッドシードキーとjsonファイルを指定できるので、Pythonのコードをいちいち変更することなく、書き込むスプレッドシートを変更することができます。

とはいえ、この計算は待ったくもって使いみちがないのですが、決まった計算をさせるプログラムがあって、その計算結果をスプレッドシートに書き込みたいときに、このような使い方が生きてくるのではないかと思います。

まとめ

まだまだ実用的なプログラムではありませんが、少しずつPythonで何かを操作することができるようになってくると、コードを書くのが楽しくなってきます。

楽しいと感じるのは結構重要で、楽しさは、何かを継続するための大切な要素です。

同じようなコードをちょっとだけ変更してみるとか、必要なパーツを追加したり削除したりして改変すれば、どのコードがどんな役割を持っているのか、少しずつですが理解できるようになっていきます。

1つのリソースを何度も繰り返してマルチに活用すれば、コードの復習ができるし、新しいコードも学ぶことができるので、コードのシングルリソースマルチユースは、一石二鳥の学習方法といえます。

数の修行をしないことには、自分のものにはならないので、どんどん同じようなコードを書いてPythonのコードを極めていきましょう!

それでは、明日もGood Python!