渓のライフマネジメント日記

日々の活動と雑感をゆるゆると記録するところです。みんなHAPPYになっちゃえ。

LINE Payの履歴をエクセルのデータにしてみよう

みなさん、各種ペイの支払い履歴はどのように管理していますか?

今回はLINE Payの支払い履歴をエクセルに取り込んでみたいと思います

 

 

 

各種ペイにはCSV出力が存在しない

各種Payの履歴はCSV出力などという洒落た仕組みは存在せず、アプリから読むしかないのが現状です。しかも、d払いなどは半年分のログしかなく、年間の支出記録を作ろうと思っても今更探すことはできません。

LINE Payも基本的には同じなのですが、LINE Payの場合、LINEウォレットをユーザー登録しておくと、履歴を教えてくれるサービスがあります。

このログは、トーク履歴として保存可能なため、このトーク履歴を解析できれば、簡単にデータ化できるのではないかというのが今回のテーマです。

 

まずはLINEからトーク履歴の保存

LINEウォレットの画面から、トーク履歴を保存を選びます。

 

保存したファイルはメールか何かでパソコンに送りましょう。僕はiCloudドライブへの保存を選びました。パソコンから簡単に開けるしね。

 

テキストファイルを開くと、ポイントやお金の入出に関して言えば、

 

日付

時刻 サービス名 適用 ポイント 単位 処理

 

のような形式になっていることがわかります。

例えば

 

2018/11/05(月)
15:07 LINEウォレット LINEポイント 【クイズ】LINE MUSICで3ポイント獲得しました

 

のような感じですね。

 

同じ日に複数のイベントがある場合には

2019/11/03(日)
19:47 LINEウォレット LINEポイント 今だけ!8000ポイントバックで1ポイント獲得しました
19:56 LINEウォレット LINEポイント LINE証券Wキャンペーン中で1ポイント獲得しました

というように、改行して処理されるようです。

 

というわけで、まずはエクセルのシート”log”に、テキストの中身を直貼りして処理していきましょう。

 

代表のパターンを探す

処理にはいくつかの種類がありました。LINE Payの入出金、ポイントの獲得・利用、LINE PAYでの店舗支払い、LINE内の各種サービスでの利用あたりです。

 

というわけで、代表的なのを集めてみました。

15:37 LINEウォレット LINE Pay : ツルハグループで2ポイント獲得しました
08:42 LINEウォレット "LINE Pay お支払い 428 円
08:41 LINEウォレット "LINE Pay チャージ 1,000 円
16:35 LINEウォレット LINEギフト:商品購入で1032ポイント利用しました
19:33 LINEウォレット "LINE Pay 獲得 333 P

このあたりでしょうか。

 

基本的処理

まずはlogシートの各行を入力する動的配列linelog()と、データを格納しておく動的配列linedata() を宣言します。

Dim linelog() As Variant
Dim linedata() As Variant

ループする回数を決めるため、行数をカウントしておきましょう。linedata()は支出名 日付 件名 金額 入出の区別がわかればよさそうなので2次元の配列を作ります。

TotalRow = Cells(Rows.Count, 1).End(xlUp).Row
ReDim linelog(TotalRow)

ReDim linedata(TotalRow, 4)

linelogに各行の文字列データを入れていきます。

For n = 1 To TotalRow 'セルA1~データの終わりまで1行ずつループ
linelog(n) = Cells(n, 1).Value
Next n

これで、全データがlinelogに取り込まれました。

 

ん?これ別にTXTからLine Inputで一行ずつ抜いても同じだったね・・・。

 

 

 

まあいいや。

 

 

出力データ形式を定義する

記録先のシート名は”LINE Pay”とします。

記録するデータは以下のように定義します。

 

 列A 支出元(今回の場合はLINE Pay固定):String

 列B 日付:String リテラル 日付形式 "YYYY/MM/DD"

 列C 件名:String

 列D 金額:long カンマ区切り無し

 列E 入出の別:「出金」又は「入金」

  

先頭行は項目名にしたいので2行目から記録していきます。

ループカウンタと別に行数を管理しなければならないので新しい変数を定義しましょう。

Dim RowCount As Variant

全然関係ないですが変数の命名規則は昔はハンガリアン記法を採用していましたが、最近はどストレートな名前を使っています。

そんな面倒なプログラム書かないしね・・・

あとはlinedataの(a,b)がそれぞれCells(a,b)に対応する配列とします。

 

ループ処理

ループ処理は、1行ずつのループと、各行をとりあえず半角スペースで区切った場合のループの2種類が必要です。

また、各行のlinelogをSplitしたデータを記録する配列も必要なので再び定義します。ループ回数は配列の要素数によるので、それを判定して処理させましょう。

RowCount = 2
For n = 1 To TotalRow 'セルA1~データの終わりまで1行ずつループ
rowdata = Split(linelog(n), " ")
For i = LBound(rowdata) To UBound(rowdata) '分解した要素の終わりまで1ブロックずつループ

(なんかの処理(適当))

next i

next n

 

金額(数値)獲得の処理

行と単語に分割したデータを作ったところで、それぞれ評価していきます。

まずはサンプルデータである

15:37 LINEウォレット LINE Pay : ツルハグループで2ポイント獲得しました

を整理していきましょう。

この文章はいくつかのブロックに分かれています。最初に示したように典型的なフォーマットだと思われます。

[時刻][サービス名][件名][獲得ポイント数][獲得単位][処理]

のような並びで、半角スペースで区切られていると仮定します。Pythonなら形態素解析するところですが、ここでは簡単に[処理]=「ポイント獲得」というフレーズをキーにして解析することにしましょう。

 

まず、区切った文節からポイント獲得という文字を検索します。

If InStr(rowdata(i), "ポイント獲得") > 0 Then

 

ポイント獲得という文字の前が数字だと思うので1文字ずつ加算していきます。

ループ回数は、行全体の文字数から、「ポイント獲得」までの文字数(位置)

そこから1文字ずつ前に戻り、数値だったら後ろに結合していきます。数字以外の文字を拾ったときにはループの処理を抜けることにします。

PointNum = Empty
For m = 1 To Len(rowdata(i)) - InStr(rowdata(i), "ポイント獲得")
 NumSet = Mid(rowdata(i), InStr(rowdata(i), "ポイント獲得") - m, 1)
  If IsNumeric(NumSet) = True Then
   PointNum = Mid(rowdata(i), InStr(rowdata(i), "ポイント獲得") - m, 1) & PointNum
  Else: GoTo continue_Point:
  End If
Next m
continue_Point:

 

さて、ここで、数値判定を考えた時に、カンマによる3桁区切りで表記されているケースがあることに気づきましたので、数値判定を以下のように修正します。

 

If IsNumeric(NumSet) = True Then

  ↓

If IsNumeric(NumSet) Or InStr(NumSet, ",") <> 0 = True Then

 

これでカンマ表記にも対応しましたね。

 

日付取得の処理

日付は一つ前の列にありますが、連続している場合は日付ではないので、日付チェックをしながら過去に遡ります。とりあえずPastと定義しましょう。日付データを発見した段階で、日付データを取得します。GetDateだと汎用性が高く今後別に使いそうな雰囲気なので、RecDateにしましょう。

 

この辺の怪しい英語を使ったほうが、それっぽくていい感じですよね。

 

Past = 1
Do While IsDate(Left(Cells(n - Past, 1).Value, 10)) = False
 Past = Past + 1
Loop
 RecDate = Left(Cells(n - Past, 1).Value, 10) '日付GET

 

件名取得の処理

件名はSubjectとしたいですが、一応接頭辞としてLineを付加します。LineSubjectというやや長めの変数名にします。

 

ここでは、

 LINE Pay : ツルハグループ

という文字列を件名として取得したいので、不要なLINEウォレットまでを検索し、更に文字数分を勧めた位置からMID関数で切取ります。

 「件名+数値」の文字数は、LINEウォレットの位置 + 16 から ポイント獲得の位置 - 1なので、ポイント獲得の位置 - 1)- (LINEウォレットの位置 + 16)となり、ポイント獲得の位置 -  LINEウォレットの位置 - 17に、なります。そこから更に数値の文字数分を遡ったところが件名の文字数となります。


LineSubject = Mid(linelog(n), InStr(linelog(n), "LINEウォレット") + 16, _

      InStr(linelog(n), "ポイント獲得") - InStr(linelog(n), "LINEウォレット") _

       - 17 - Len(Format(PointNum, "###0")))

 

 

セルへの記録

さて、ここまでのデータが整ったところで記録していきます。このとき、シート"log"とシート"LINEPAY"間を何度か行き来するので、途中の処理に間違いのないようにSheets("□□□").Activateの処理を挟んでおきましょう。

 

Sheets("LINEPAY").Activate
Cells(RowCount, 1).Value = "LINEPAY"
Cells(RowCount, 2).Value = RecDate
Cells(RowCount, 3).Value = Replace(Replace(LineSubject, " ", " "), " ", " ")
Cells(RowCount, 4).Value = PointNum
Cells(RowCount, 5).Value = "入金"
RowCount = RowCount + 1

End If

 

どうでしょう、ここまでを処理すれば成形されたデータが手に入るのではないでしょうか。忘れずにループを閉じて実行してみましょう。

 

Next i

Next n

 

出力結果

LINEPAY 2018/11/5 LINE Pay :  ツルハグループ 2 入金

バッチリですね!

 

この調子で他の処理も自動化していけばLINE PAYについては手入力しなくてもよさそうです。

 

 

 

 

あれ?

そういえば、わざわざSplitして作ったrowdata(n)って何のために作ったんだっけ・・・?もしかして最初から一行ずつ処理で良かったんじゃ・・・

 

 

まあいいや

 

 

僕はプログラムに美しさなんて求めていない!

狙った通りの結果ができればそれでいいじゃないかと思っています。

 

妥協することで得られるものもある。

僕は強く思いました。まる。

 

 twitter.com