PDF（SBI証券、くりっく株365、取引残高報告書）からCSV（テキスト）を作成する

2022-09-07 使い方の改善。setwd()、getwd()
2020-02-12 v0.3.3 SBI証券、仕様変更（x6:証拠金の残高が削除されたための対応）
2020-12-28 v0.3.2 バグ修正（ページ下部の明細抽出もれ、x座標のソート）
2020-10-14 .txt → .csv
2020-10-12 Rパッケージ化
#<h1>はじめに</h1>
世界の株価指数に投資することが出来る金融商品として、
くりっく株365があります。

上場CFD（東京金融取引所に上場する株価指数証拠金取引）ですが、
　個人だと申告分離課税、
　法人だと総合課税と、
確定申告をしなければなりません。

毎月の取引残高報告書に基づいて申告するのですが、
SBI証券の場合、PDFなのですよ。

これを手作業で集計するのが面倒なので、

PDF、取引残高報告書のうち（２頁〜）証拠金入出金明細書を
CSV（テキスト）にします。

これを会計ソフトと税務ソフト（eTaxの①預貯金）反映させることを目的としています。

#<h6>注意点</h6>
テスト不足です。
~~・複数頁にまたがる場合は、どうだろう。。~~ 　→　修正済み
・未使用と思われる列にデータがあると、誤動作するでしょう。
#<h1>想定PDF</h1>
７列の表ですが、
摘要(３列)と備考(７列）にはデータが無いと想定しています。

![2020-10-20 18.39のイメージ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374784/4b371dba-1b93-ec3b-ec26-55cb326442b6.jpeg)
#<h1>使い方（パッケージ版）</h1>
githubにパッケージを作ったのでインストールしてください。

```r:準備.r
library( devtools ) # install.packages("devtools")
install_github("nt1969m/sbitools") #面倒な事を聞かれたら、3: Noneで、  
```
PDFのあるファイルパスを指定、実行

```r:CSV作成.R
# setwd() ※PDFのあるディレクトリーを設定
    # R本体の場合、  「メニュー」 → 「その他」 → 「作業ディレクトリの変更」
    # RStudioの場合、「メニュー」→「Session」→「Set Working Directory」→「Choose Directory」
d <- getwd()
library(sbitools) 
dummy <- CFD( d ) # ファイルが作成されます。PDFのあるディレクトリーに、
```
CSVファイル(証拠金入出金明細書.csv)が作られたはず。

（コンティンジェンシー・プラン）
もしもの場合、
SBI証券がPDFの仕様を変更した（無意識も含めて）ことにより、
うまく動かない場合、
設定ファイルを作って下さい。
（PDFのあるディレクトリーを指定。dを設定の上で）

```r:設定変更.R
  d <- "./inst/extdata/"  # （例）PDFのあるディレクトリー
  spec <- data.frame( matrix( NA ,0 ,4 ) )
  colnames( spec ) <- c("h1","h2","x1","x4")
  spec[1,1:2] <- c("証拠金入出金明細書","受渡日")
  spec[1,3:4] <- c(25,488)　# <------　ここをいじってみる
  save( spec ,file=file.path( d,"specCFD.Rda" ) )
```
specCFD.Rdaというファイルが作成されると、
デフォルト設定ではなく、
特注設定で実行します。

いじる箇所は以下
３列"x1":受渡日の先頭ポジション
4列"x4":減少の最終ポジション（減少と増加の判定に使用）

#↓過去の出来事
#<h1>使い方（ソース直書き版）</h1>
```r:使い方.R
source(	"PDF_CFD_SBI.R"	) 
	# PDFのあるディレクトリーを指定
d <- file.path( ... ,"B_0988_SBI証券" ,"CFD" )

出入 <- CFD.main( d )

```
csvファイル（証拠金入出金明細書.txt）が作成される。


```r:PDF_CFD_SBI.R
	# pdfデータをインポートするため
library( pdftools )	# install.packages("pdftools")

CFD.main <- function( d ) {
		print( d )
	CFD <- CFD.init()	# ファイル別
	files	<- dir( d ,pattern=".pdf$" ,ignore.case=T )
	for( f in files) {
		p <- pdf_info( file.path( d ,f ) )$pages
		df <-	pdf_data( file.path( d ,f ) )
			print( c( f , p ) )
		CFD <- rbind( CFD ,CFD.pdf( df ,p ) )
	}
	csv <- CFD.fin( CFD )
	f <- file.path( d ,"証拠金入出金明細書.txt" )	
	write.csv( csv ,file=f )	
	print( f )
	
return( csv )
}
print( c( "CFD.main()" ,CFD.main ) )

CFD.pdf <- function( df ,p ) {
	CFD <- CFD.init()	# PDF別
	for( i in 1:p ) {  # i <- 2
		print( i )
		df_p <- sapply( df[[ i ]] ,"[" )  [ ,c("x","y","text") ]  
		x <- as.integer( df_p[ ,"x" ] )
		y <- as.integer( df_p[ ,"y" ] )

		h1 <- subset( df_p ,df_p[,"text"] == "証拠金入出金明細書" )
		h1_y <- as.integer( h1[,"y"] )
		if ( nrow( h1 ) == 0 ) next
		print( h1 )

		h2 <- subset( df_p ,df_p[,"text"] == "受渡日" )
		h2_y <- as.integer( h2[,"y"] )
		m <- df_p[ y > h2_y , ]
		r <- subset( m, m[ ,"x"] == 25 )
		CFD <- rbind(CFD ,CFD.line( m ,r ) )
	}
return( CFD )
}
print( c( "CFD.pdf()" ,CFD.pdf ) )

CFD.line <- function( m ,r ) {
	CFD <- CFD.init()	
	for( j in 1:nrow( r ) ) {  
		CFD[ j ,1 ] <- r[ j,"text"]	
		行 <- subset( m ,m[ ,"y" ]==r[ j , "y" ] )
		CFD[ j ,2 ] <- 行[ 2,"text"]	
		if( as.integer( 行[ 3,"x"] ) <= 488 ) {
			CFD[ j ,4 ] <- 行[ 3,"text"]
		} else {
			CFD[ j ,5 ] <- 行[ 3,"text"]
		}	
		CFD[ j ,6 ] <- 行[ 4,"text"]
			# 想定外かも？
		switch( ( nrow( 行 ) - 4 ) 
		,"1" = {
			print( 行 ) 
			}	
		)
	}
return( CFD )
}
print( c( "CFD.line()" ,CFD.line ) )

CFD.fin <- function( 出入 ) {
	出入[ ,1] <- gsub( "/" ,"-" ,出入[ ,1] )
	出入[ ,4] <- as.integer( gsub( "," ,"" ,出入[ ,4] ) )
	出入[ ,5] <- as.integer( gsub( "," ,"" ,出入[ ,5] ) )
	出入[ ,6] <- as.integer( gsub( "," ,"" ,出入[ ,6] ) )
	print( paste0("証拠金の増減=" ,sum( 出入[ ,5] ,na.rm=T ) - sum( 出入[ ,4] ,na.rm=T ) ) ) 

return( 出入 )
}
print( c( "CFD.fin()" ,CFD.fin ) )

CFD.init <- function( n=1 ) {
			# 列数
	df <- data.frame( matrix( NA ,0 ,7 ) )
			# 列名
	colnames( df ) <- c(
	 "受渡日="			# 列1
	,"区分="		# 列2
	,"摘要="			# 列3
	,"証拠金の減少="	 #,"証拠金の減少（円）="		# 列4
	,"証拠金の増加=" #,"証拠金の残高（円）="		# 列5
	,"証拠金の残高="	 #,"証拠金の残高（円）="		# 列6
	,"備考="		# 列7
	)
	switch( n
	, "1" =  {		# （２頁〜）証拠金入出金明細書
		#	print( sapply( df ,mode ) )
		}
	)
return( df )
}
print( c( "CFD.init()" ,CFD.init ) )
#
```