概要
現象
Firefoxで、しばらく前から、はてなブログの自分のブログを開いても、自分のアカウント名が表示されず、「ログイン」というリンクの表示になっていた。
また一方で、「ログイン」をクリックすると、ログインされた状態で自分のダッシュボードに移動する。つまり、はてなブログにログインはしている状態である。
一度ログアウトして再度ログインし直したものの、改善は見られなかった。
これは、以前は次のように表示されていたものである。
Firefoxで、しばらく前から、はてなブログの自分のブログを開いても、自分のアカウント名が表示されず、「ログイン」というリンクの表示になっていた。
また一方で、「ログイン」をクリックすると、ログインされた状態で自分のダッシュボードに移動する。つまり、はてなブログにログインはしている状態である。
一度ログアウトして再度ログインし直したものの、改善は見られなかった。
これは、以前は次のように表示されていたものである。
Private Reserve社という、万年筆インクを製造している会社があった。
その会社が製造するインクは発色がよく、染料インクなので扱いやすく、混色も可能というものだった。
そのため、自分で好みの色のインクを調合できる店であるカキモリのInkstandにおいて、混色用のインクとして2017年頃まで使われていた。しかし、安定した入手が困難になったため、現在は独自の顔料系インクに切り替わっている。
なぜインクが入手困難になったのか?
https://www.fountainpennetwork.com/forum/topic/355755-private-reserve-ink-status/
このフォーラムを追っていくと経緯が書いてある。フォーラムの記載によると、次のようなことがあったらしい。
まず、元々の会社のオーナーが逝去したとのことで、そのためインクが生産できなくなった。新しく生産されないため、在庫がなくなると入手困難状態になっていた。
その後、従業員であったDarla Aniline氏が2018年にPrivate Reserve社を購入し、一人会社として運営されていた。インク調合のレシピがほとんど残されていなかったので再生産が難しかったという事情もあり、配合を再現しようと化学者と共同して作業していたらしい。しかし、2020年9月にAniline氏も早逝。会社は機能停止したことになる。
さて少し経って、Cult Pensという文具ショップのFacebook投稿によると、2021年3月に元々のものと同じレシピ(the original formula)で新しく製造・販売が開始されたとのこと。
私が気づいたときにはCult Pensで在庫切れになっいたが、その後在庫が復活したので、2021年8月にインクを購入した。
箱には製造者については書かれていないが、ヨーロッパで製造、アメリカで包装とあり、また www.PrivateReserveInkUSA.com というアドレスが書かれている。これにアクセスすると yafabrands.com のページにリダイレクトされる。これはYafaというアメリカの筆記具会社らしい。
探すとYafa社がPrivate Reserve社を買収したと書かれているPDFがあった。
https://www.yafa.com/outlet/images/Pen_world_article.pdf
というわけで、2021年3月ころからYafaブランドの元で新しく製造されたPrivate Reserveインクの流通が始まったらしいことが分かった。当分の間は安定した供給が見込めそうである。とりあえずは一安心という感じだ。
日本からも、CultPensなどの日本へも配送してくれるネットショップで購入できる。しかし、私が2021年8月に購入した時は3つのボトルを購入して送料が1500円程度(恐らく14~15 USD)だったものの、現在購入しようとしたら安い運送方法の選択肢がなくなって5800円程度(たぶん50 USD)はかかるようで、躊躇している。
Ebayとかで購入する方が配送料が安い(3千円以内)っぽいので、今はそっちで購入するのがいいのかもしれない。もうちょっと円が強いときに買いたいが…。
ところで、私が混色に使っていたFoam Greenというインクを含む数色が、新体制では製造されなくなってしまったらしく、手元で今までと同じ色のインクを調合することが難しくなってしまった。別のインクを使って近い色にできるように試行錯誤しなければならない。まあそれは追い追い。
Cult Pensでインクを購入した時、“This is a pencil.”と書かれた鉛筆がおまけに付いてきた。すき。
日本Amazonにあるじゃん!例→https://www.amazon.co.jp/-/PR17019/dp/B0B2MTLK7Z/
「Private Reserve Ink」や「プライベート リザーブ インク」などで検索してみてください。
AWSのAmazon Timestreamというデータベースにセンサーデータを蓄積している。このデータをローカルにダウンロードして利用したい。
Pythonとboto3ライブラリを利用して、Timestreamのデータベースからそこそこ大量のデータを取得しようとしたところ、レスポンスのRows
が空だった。
データがある程度小さくなるクエリでやってみると、問題なくデータが取得できるのが確認できた。
TimestreamQuety.Client.query()
を呼び出す際に、MaxRows
キーワード引数を指定しないと、取得結果のサイズが1MB以上になる場合に、Rows
が空の状態でレスポンスが返ってくる。その代わり、NextToken
がレスポンスに含まれる。
Otherwise, the initial invocation of Query only returns a NextToken , which can then be used in subsequent calls to fetch the result set. To resume pagination, provide the NextToken value in the subsequent command.
TimestreamQuery — Boto3 Docs 1.21.37 documentation
要するに、取得するデータがでかいと1回で取得することができないようになっている。
ページネーションする。
TimestreamQuety.Client.query()
にNextToken
を指定して呼び出すと、サイズが1MB未満になるような個数のデータ(Rows
)が返される。
更にまだ未取得のデータがある場合には、次のデータに対応するNextToken
もレスポンスに含まれる。データをすべて取得してしまった場合には、レスポンスにはNextToken
が存在しないので、終了判定にも使える。
実際にはこういう手順になる。
NextToken
と空のRows
が得られる。NextToken
を利用して1MB程度分のデータ(Rows
)と次のデータに対応するNextToken
を得る。NextToken
がレスポンスに含まれなくなるまで続け、今までに返されたRows
をすべて合体させれば欲しいデータが得られる。Rows
だけ連結して返すみたいなPython 3コードを示す。
import json import boto3 from botocore.config import Config #リージョン名, ID, secret keyは省略 config = Config(region_name = '……') config.endpoint_discovery_enabled = True timestream_query_client = boto3.client('timestream-query', aws_access_key_id="……", aws_secret_access_key="……", config=config) #クエリの例 QUERY = """SELECT "time", "measure_name", "measure_value::double" FROM "mydatabase"."mytable" AND time between '2021-01-01 00:00' and '2022-01-01 00:00' ORDER BY time ASC""" #データ取得用の関数 def getdata(next_token = None): if next_token: #next_tokenが指定された場合はNextTokenを指定してクエリ result = timestream_query_client.query( QueryString=QUERY, NextToken=next_token ) else: #next_tokenなし=初回呼び出し result = timestream_query_client.query( QueryString=QUERY ) ret_rows = result["Rows"] #list of data if "NextToken" in result: #次のページ(未取得データ)が存在する場合 return ret_rows + getdata(result["NextToken"]) #再帰呼び出し else: #欲しいデータはすべて取得した場合 return ret_rows rows = getdata() print(len(rows)) print(rows[0])
PythonのElementTreeを使ってXMLを解析するときに少し悩んだので、忘れないようにメモ。
もっと例を洗練させるべきだとは思うが、後回しにする。
import xml.etree.ElementTree as ET tree = ET.parse('country_data.xml') root = tree.getroot()
一方、ET.fromstring()
メソッドで作成する場合、返されるのはルート要素となる。
以下、elem
は何らかのタグに対応する要素とする(上のroot
など)
.find()
メソッドは直下のもののみ、最初に一致した要素一つだけを返す。
target_tag = elem.find("target")
これは後述するXPath記法と組み合わせることで格段に便利になる。
マッチしない場合はNone
になる。ただし、
if target_tag: #この書き方では動かない #マッチした場合
みたいには書けない(マッチした場合でも実行されない)。なので、
if target_tag is not None: #マッチした場合
みたいに書いたら動いた。
.findall()
メソッドは直下のもののみ、一致した要素をすべて含むリストを返す。
for target_tag in elem.find("target"): #...
内側のタグには添え字でもアクセスできる。直下で最初くるタグのそのまた直下の最初に来るタグだと次のように書ける。
elem[0][0]
これを使えると格段に解析効率が上がる
//
という、子要素やその子孫の要素すべてを対象とする記法が使える。
target = elem.find(".//target")
<a><b><c>こんにちは</c></b></a>
element = ET.fromstring("<element><a><b><c>こんにちは</c></b></a></element>") target_c = element.find("a/b/c")
target = elem.find("target[@attrib='value']")
属性が"
や'
を含む場合、エスケープするなり引用符を変更するなどすれば動く。
element = ET.fromstring('''<root><target name="Do's and dont's">some text</target></root>''') target = element.find('''target[@name="Do's and dont's"]''')
target = elem.find("target[@attrib1='value 1'][@attrib2='value 2']")
element = ET.fromstring('<greetings myvalue="hello world"/>') element.get("myvalue") #"hello world"
<a>あ<b>いz<c>う</c></b><d>え</d>お</a>
みたいな構造があった場合、
a.text
は「あ」になる
a = ET.fromstring("<a>あ<b>い<c>う</c></b><d>え</d>お</a>") print(a.text) #"あ"
ここで、「あいうえお」が欲しければ、
print( "".join(a.itertext()) ) #あいうえお
のようにするとよい。.itertext()
で現在の要素以下のテキストを順番に返すイテレータが得られるので、それを合体させている。
注意: 素人が調べたことなので間違い等を含む可能性があります。専門家の意見を聞くなり自分で原文にあたるなりして判断してください。
改定された「電子帳簿保存法」が2022年1月1日から施行され、通販などで領収書等をWebサイトで出力するものについて、プリントアウトして保存しておくことは認められなくなった*1。
…となるはずだったが、2023年12月31日までの取引は、経過措置として、電子保存できないことについて「所轄税務署長がやむを得ない事情があると認め」た場合にはプリントアウトで保管してもよいということになったらしい*2。
やむを得ない事情があると認めた場合云々といっても、特に申請や手続きは必要ない*3ため、来年末まではプリントアウトして保存しておいても問題なさそうではある。
とはいえ、2年のうちに準備しておかなければならない。
会計ソフトやクラウドサービスを利用している場合は、電子領収書等のデータを保存するための仕組みが多分つくられているだろうから、それを利用するのが簡単だと思われる。
そういうのを使わない場合はどうするか。
凡例: 鍵括弧「~」は用語や引用を表す。
「電子取引」とは、取引情報(注文書、契約書、送り状、領収書、見積書等の情報)をインターネットや電子メール、EDI取引等でやりとりすることを指すとのこと*4。
通販のWebサイトで出力した領収書PDFは電子取引の取引情報に該当するわけなので、電子的に保存する必要がある。
電子データとして保存する場合、次のような方法が認められる*5。以下に引用する。
引用終わり。基本的にPDFか、PDFが難しければスクリーンショット画像として保存するようである。
「電子取引の取引情報に係る電磁的記録の保存等を行う場合」には、次の要件を満たす必要があるらしい*6。
このうち、「電子計算機処理システムの概要を記載した書類の備付け」はまあ自分でプログラム書かなければ関係なさそう。
「見読可能装置の備付け等」は、電子取引の取引情報にアクセスできるパソコンを用意しておいて、税務調査のときにそれを利用してすぐに見せることができるようにしておけばいいらしい*7。
あとは「検索機能の確保」と改竄防止措置である。
検索機能の確保については次の要件を満たす必要があるとのこと*8。
これは、次のような方法で対応できる。
「2022年(令和4年)10月31日に株式会社国税商事から受領した110,000円の請求書」の場合であれば、
20221031_㈱国税商事_110000
などと、日付、取引先名、金額を含む規則的なファイル名をつけておくとよいとのこと*9。
このような規則的な名づけを行うことで、ファイラーを使って検索ができ、検索要件を満たすことができるようだ。*10
しかしこのままでは範囲検索はできない。範囲検索がなくても、税務職員の求めに応じて提出できるようにしておけば、検索要件を満たすとしてよいらしい*11。
また、検索要件は年商1000万円以下の場合は免除されるっぽい*12ので、該当する場合はこの名前付け自体必須ではないようだ。ただし必要に応じて提出できるようにしておく必要はあるはずだが。
「電子的に受け取った請求書や領収書等」の「真実性を確保する観点から、以下のいずれかの条件を満たす必要があ」るとのこと*14。以下引用する。
引用終わり。
さて、改竄等を防ぐための措置が必要であるが、クラウド会計サービスなどを使うのでなければ個人で改竄防止システムを用意するのは難しい。Gitだって歴史を改変できるので。
これは4.に従って、「電子取引データの訂正及び削除の防止に関する事務処理規程」を備え付けることで(そしてそれに従って管理することで)いいらしい*15。
規程のサンプルは次のページからダウンロードできる。
以下のような感じでデータ保存を行えば問題ないと思われる。
私は専門家ではないので正しさの保証はできません。最終的には参考の欄に挙げたPDFを自分で読んだり、専門家の意見を聞いて判断してください。
電子帳簿保存法一問一答 【電子取引関係】 令和3年12月 国税庁(PDF) (2022/02/02閲覧)
*1:「所得税(源泉徴収に係る所得税を除きます。)及び法人税の保存義務者が取引情報(注文書、領収書等に通常記載される事項)を電磁的方式により授受する取引(電子取引)を行った場合には、その取引情報を電磁的記録により保存しなければならない」(『電子帳簿保存法一問一答 【電子取引関係】』問1)
*2:『電子帳簿保存法一問一答 【電子取引関係】』問41-2~問41-3
*3:『電子帳簿保存法一問一答 【電子取引関係】』問41-4
*11:「当該電磁的記録について、税務職員による質問検査権に基づくダウンロードの求めに応じることができるようにしている場合には、この項目を組み合わせて条件を設定できる機能(及び範囲を指定して条件を設定できる機能)は不要となります」(『電子帳簿保存法一問一答 【電子取引関係】』問32)
登録番号さえ用意して追加すれば適格請求書を作成できる(と思われる)システムを、Microsoft Excel, Microsoft Word, Pythonを利用して構成した。
データ入力をExcelで行い、Pythonスクリプトで形を変換し、そのデータを元にWordで差し込み印刷を行うことにより請求書を得る仕組みを作った。
作成したファイルやスクリプトは次のURLに置いた:
GitHub - nixeneko/seikyusho_sample: Microsoft Word, ExcelとPythonを使って請求書を作るサンプル
インボイス制度とかいうものが始まるらしい、なんかやらないといけないらしい。
制度に関する説明は次のサイトがわかりやすい。
www.itmedia.co.jp
曰く、2023年10月から「適格請求書」というのを発行しないと、(得意先における)消費税の控除関係で不利になるらしい。なので「適格請求書」を必要になったら発行できるように準備しておきたい。
請求書に次の内容を含めないといけないらしい。
参照:
現行の「区分記載請求書」では、6.と7.が要らないということで、この分が増えることになる。なお、6.の登録番号の発行は申請が必要となっている。とりあえず、6.は2023年10月から必要になるので、それまでは、いつでも追加できるようにしておいて、登録番号の表記を入れれば適格請求書となる状態をつくりたい。
なお、この記事では登録番号の発行を受けるための申請については扱わないこととする。
さて、請求書を発行するといっても、そのために専用のソフトを新しく買ったりとかはしたくない。
Microsoft WordとExcelを使うと差し込み印刷ができるらしいので、Microsoft Officeを基本として使うことにする。事務処理でMicrosoft Officeは使っていることも多いと思うので。
Wordには、Excelなどのデータを読み込んで文面を差し替える機能が備わっていて、「差し込み印刷」という。
差し込み印刷については次のページなどが参考になる:
差し込み印刷で請求書のように複数レコードや合計を表示したい:Word(ワード)2013基本講座
以下、Microsoft OfficeのバージョンはMicrosoft 365 MSO (バージョン 2112 ビルド 16.0.14729.20156) 64 ビットを使っているが、基本的に別のバージョンでも問題ないと思われる。
サンプルデータを用意した。こんな感じのものであれば差し込み印刷で問題なく使える。シートの名前は「請求書」とした。
必要なのはテキストや数値のみであって、幅やフォーマットは関係ない。
グレーの部分はデータとしては利用していないので、空欄や別の値でも問題ない。
[差し込み文書]タブを開く→[差し込み印刷の開始]→[標準のWord文書]をクリック
[宛先の選択]→[既存のリストを使用(E)...]をクリック
先ほどサンプルデータを用意したエクセルファイルを選んで、[開く(O)]を押す。
[テーブルの選択]ウィンドウが出るので、データのあるシート(ここでは「請求書$」)を選択して[OK]を押す。
([先頭行をタイトル行として使用する(R)]にチェックが入っていることを確かめる。)
___様
となっているところにカーソルを移動して、[差し込みフィールドの挿入]→「被請求者」を選択すると«被請求者»
と書かれたものが挿入される。
同様に年月日のところに「年」「月」「日」の差し込みフィールドを挿入する。
注文内容の部分には工夫が必要である。
1行目は次のように差し込みフィールドを挿入する。
ここで、挿入された«単価»
を右クリックし、[フィールド コードの表示/非表示(T)]をクリック。
すると{ MERGEFIELD 単価 }
というような表示になるので、閉じ曲括弧}
の直前に\# ¥,0
を入力して次のようにする。
{ MERGEFIELD 単価 \# ¥,0 }
これを再度右クリックして[フィールド コードの表示/非表示(T)]をクリック。
追加したコードの意味は次のようになっている。
\#
はnumeric picture switchというWordの機能らしく、数値の表示形態を指定する。¥
は円記号(U+00A5)である。
¥
(U+00A5)の代わりにバックスラッシュ\
(U+005C)を用いる場合は、\\
としなければならない。ただ、最新のコンピュータではバックスラッシュが円記号で表示されないことも多くなってきているし、円記号の方を使っておけばいいと思う。昔のシステムではわからないが…,
は3桁ごとにコンマ区切りをすることを表す。0
は整数で、1桁の場合でも先頭を0パディングしないことを表す。参考: Fix the Formatting of an Excel Mail Merge Field in a Word Document
同様に«品目小計»
のフォーマットも指定する。
2行目の品目の欄に移動し、[ルール]→[Next Record If (条件により次のレコード)(X)...]をクリック。
[Wordフィールドの挿入: Next Record If]ウィンドウが表示されるので、
にして[OK]をクリックすると«Next Record If»
と挿入される。
その直後に「品目」という差し込みフィールドを挿入する。
2行目の他のセル、税込単価, 個数, 小計のところは1行目と同じでよい。
Next Record If
というのがなぜ必要かというと、これがないと一つの請求書で1つの行しか参照せず、同じ品目が並ぶことになる。そのため、「次の行に進んでください」とWordに指示を出すコマンドが必要で、それがNext Record If
である。ここでは「請求書ID」が空白でない場合のみ次の行に移るように設定したので、空白行より先には進まないでそこで止まる。
3行目以降は2行目と同じてよく、2行目をコピペすればよい。
また、他のものについても同様に差し込みフィールドを挿入し、フィールドコードを編集することで円記号前置+コンマ区切りを指定する。
{ MERGEFIELD 代金計 \# ,0 }
{ MERGEFIELD 代金計 \# ¥,0 }
{ MERGEFIELD 標準税率対象 \# ¥,0 }
{ MERGEFIELD 標準税 \# ¥,0 }
{ MERGEFIELD 軽減税率対象 \# ¥,0 }
{ MERGEFIELD 軽減税 \# ¥,0 }
{ MERGEFIELD 消費税計 \# ¥,0 }
出来上がったものは次のような見た目になる。
ここで、[差し込み文書]タブの[結果をプレビュー]をクリックしてオンにすると最初のデータがプレビューされる。
実際の差し込みでは、[差し込み文書]タブの[完了と差し込み]から[個々のドキュメントの編集(E)]でWordファイルを作成するか、[文書の印刷(P)]で印刷することになると思う。
実際に差し込みを行ったものが次図である。
制限としては、この請求書の書式では注文内容の明細を示すための欄を16行しか確保していないので、16種類以上の品目が出てきた場合に望む結果が得るられないことになる。
とはいえそんなたくさんの品目を扱うならもっとちゃんとしたシステム導入するでしょという気もする。
さて、差し込みは出来上がったものの、差し込み用のExcelデータを手入力するのはすごく面倒である。
そのため、必要最低限の情報を入力するExcelファイルを作り、適宜変換することにする。Excelは入力には便利なので。
もちろん注文内容をデータで持っているのであればそれを変換してやればそれで済むのだが、紙ベースで管理しているので入力するしかない。
変換は、本当であればすべてExcelでやりたかったのだが、やり方がよくわからなかったのでPythonで変換することとした。Pythonを選んだのは単に使い慣れてるからで、同じことができれば何でもよい。
入力用Excelファイル → 変換 → 出力用Excelファイル → Word差し込み → 請求書Wordファイル ……という流れになる。
さて、Pythonで変換するにあたって、
出力にあたって必要なのは
であり、品目についてはさらに
をもつ必要がある。
また、品目については、送料を最後にまとめて表示するようにしたい。
税率の計算では小数点以下を扱う必要が生じるが、これはdecimalを利用する。誤差があると困るのでfloatは使わない方がいい。
消費税の計算については、
という順番(ただし1.と2.は順不同)で、税率ごとの対象金額の合計に対して整数に丸め、合計することになっている。
整数への丸め方(端数処理)は、切り捨て、切り上げ、四捨五入などのどれでもよいとのこと。とりあえず四捨五入にしておく…。
参考: 切り捨て?切り上げ?請求書の端数処理について解説 | 経営者から担当者にまで役立つバックオフィス基礎知識 | クラウド会計ソフト freee
入力用のExcelファイルは次のようなものを作った。
以下概略である。
プルダウンリストの[元の値]にテーブルを利用するには、INDIRECT()
関数を使う。
連動するドロップダウンリストをテーブルを利用して作成する:Excelの基本操作
データの入力規則として、ドロップダウンリストと自由入力を混在させるためには、[データの入力規則]の[エラーメッセージ]タブの設定を変更する。
Excel:入力規則でドロップダウンリストと入力を混在させたい −教えて!HELPDESK
KEN_ALL.CSV
を選択、[インポート]を押す。郵便番号表
にする(しなくてもいい)。郵便番号テーブル
にするseikyusho_sample/convert.py at main · nixeneko/seikyusho_sample · GitHub
変換用のPythonスクリプトを用意した。
実行に必要なのは
である。
次のリンクからダウンロードできます。
github.com
なお、動作保証等はしませんので、利用される場合は自己責任で行ってください。
請求書を手書きからコンピュータ作成に移行しようというところだったので、ついでに適格請求書に対応できるような仕組みを準備した。
取扱商品が少なく固定されている場合は商品ごとに列を用意して数だけ入力するとかにしてもよいし、自分のところで扱っている商品によってシステムを構成することでかなり楽ができる。
効率化していきましょう。
Microsoft Word (.docx)ファイルには本文以外にも、作成者名やファイルパス等の個人情報がメタデータとして含まれている可能性がある。
公開前に消しときたいというのはある。
ついでにExcelやPower Pointなどの他のMicrosoft Officeファイルでも同様である。
参考: Word , Excel , PowerPoint のタイトルや作成者などプロパティ情報を変更または削除する方法。 | PC&IT ~i-TSUNAGU~
Wordのバージョンは「Microsoft® Word for Microsoft 365 MSO (バージョン 2112 ビルド 16.0.14729.20156) 64 ビット」である。
[ファイル]→[情報]を開くと、右側に[関連ユーザー]のところに[作成者]と[最終更新者]が表示されている。
[作成者]についてはこのユーザーを右クリックして削除や変更ができるが、[最終更新者]については変更ができない用に見える。
これらを消すためには、
このような手順でできる。
.docxファイルがXMLファイル等を.zip圧縮したものであるというのは周知の通りである。
なので、展開して内部のXMLファイルを変更し、再度圧縮して.docxという拡張子に戻すことで変更できる。
テキストファイルなので全文検索を通しておくと安心だと思う。
今回自分が編集していたWordファイルでは、
docProps/core.xml
のdc:creator
, cp:lastModifiedBy
タグに作者の名前が出るっぽかったので、書き換えると良さそう。あと、差し込み文書用データのExcelファイルのパスが
word/_rels/settings.xml.rels
word/settings.xml
に含まれていたので、ファイルの場所を個人情報を含まないものに変更しておくなどするとよいかもしれない。