LibreOffice Calcで為替レートを取得する。その4

マクロセキュリティの設定を「中」にすればマクロの実行ができることを確認できたので、為替レート(USD-JPY)の取得をマクロとして登録してみます。

その1で書いた次のコードをベースとします。

import urllib.request
import re

f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
s = f.read().decode('utf-8').split('\n')
for l in s:
    if 'price noLine' in l:
        jpy = float(re.search('[0-9\.]+', l).group())
        print(jpy)

やり方としては、unoモジュールをインポートしてドキュメントオブジェクトを作成し、そのオブジェクトのシートのセルを指定して書き込む、ということになります。

ところでunoモジュールとは何でしょうか。Python Guide - Introductionに説明がありました。

What is PyUNO?
LibreOffice has the ability to write macros in several interpreted languages, one of them is Python. PyUNO is the component that gives us access to the application programming interface (API hereinafter by its acronym Application Programming Interface) of LibreOffice with Python.

簡単に言えばPythonからLibreOfficeにアクセスするためのAPI、だそうです。LibreOfficeの関連では直接このPyUNOを説明しているものはないようですが、その前身となったOpenOffice.orgのほうにPyUNO bridgeとしてありました。でもかなり古いです。一番下のところに "このページの最終更新日時は 2010年3月28日 (日) 23:06 です。" なんて書いてあります。さらにそのページからダウンロードできるアーカイブには、"Last updated \$Date: 2007/11/26 19:36:55 \$" なんてあります。

ということは実際には "C:\Program Files\LibreOffice\program\uno.py" を読まなければわからないということでしょうか。
uno.pyをpydocに処理させてみたのですが、詳しいことは書いてありませんでした。あとはサンプルを見ろよ、ということかしら。
とりあえずやってみましょう。

import uno
import urllib.request
import re

def get_usd_jpy():
    doc = XSCRIPTCONTEXT.getDocument()

    f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
    src = f.read().decode('utf-8').split('\n')
    for line in src:
        if 'price noLine' in line:
            rate = float(re.search('[0-9\.]+', line).group())

    cell = doc.Sheets[0]['A1']
    cell.setValue(rate)
    return

これをLibreOffice Calcのマクロに登録します。


そして実行すると…。

できてしまいました。え?いや、もっと手こずるかと思ったんですが…。

となると、あとは体裁を整えるというか、"ドル円レート | (レート) | 2018年10月20日 12:00現在" みたいな感じで入れてやればいい感じになりそうです。

import uno
import urllib.request
import re
from datetime import datetime 

def get_usd_jpy(dummy):
    doc = XSCRIPTCONTEXT.getDocument()

    f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
    src = f.read().decode('utf-8').split('\n')
    for line in src:
        if 'price noLine' in line:
            rate = float(re.search('[0-9\.]+', line).group())

    now = datetime.now()
    doc.Sheets[0]['A1'].setString('ドル円レート 1USD=')
    doc.Sheets[0]['B1'].setValue(rate)
    doc.Sheets[0]['C1'].setString('円 {}年{}月{}日 {}時{}分現在'.format(now.year, now.month, now.day,now.hour,now.minute))
    return

2018/11/21 ソースコード改定 関数に引数を設定しないとエラーが出るようになったためdummyを追加。

ここで注意しなくてはいけないのは、ASCII文字以外(日本語とか)を書くときには文字コードをUTF-8に指定しておく必要があることです。


ということでできました。

あとはこのセルを参照するような使い方をすればいいでしょう。

本音を言えば、ワークシートを開いたときに自動でアップデートできるとか、あるいはボタンを配置してそれをクリックするとアップデートできるとか、そんな風にしてもいいかなとは思いますが、とりあえず目的は達成できました。

0 件のコメント:

コメントを投稿

WesternDigitalこわれた。

たぶん寿命を過ぎてるのでクレームとまではいかないのだけれど。 WesternDigitalのWD60EFRXが壊れました。モノは2014年11月に購入。ところが3年で壊れ、RMAにより2017年11月に交換したものです。BlackBlazeでも故障率がそれなりに高かったので、そう...