前編
https://ameblo.jp/araya-benki/entry-12795889773.html
後編
https://ameblo.jp/araya-benki/entry-12796631197.html
https://ameblo.jp/araya-benki/entry-12795889773.html
後編
https://ameblo.jp/araya-benki/entry-12796631197.html
特別編
前回までのあらすじ
前編では、openpyxlというモジュールのざっくりした使い方、
後編では、PySimpleGUIと組み合わせた完成品を公開しましたが、
最近のPySimpleGUIは、仕様が変わりまして、
31日後までに登録が必要になること、
さらに、後で調べたら、PySimpleGUIのライセンスがLGPLであること(ライセンス汚染する)、
また、ライセンス以外でも、無料版は細かな制限が発生するので、
無料で使い続けることはできることはできるのですが、
使用者にめんどくさいことを押し付けるのはいやだ!
と、そんなこんなで改良版をお送りします。
細かいことはできないけど手っ取り早くGUIを作れるappJar
appJarは、Apacheライセンス2.0です。
著作権表示と、ライセンス表示が必要だそうです。
openpyxlはMITライセンスです。
まあ、厳密にはApacheライセンスのほうが、ちょっと厳しいけど、
MITとApache2のライセンスは、汚染しないし、自由に使えるしで、いいことづくめなので、
使ってしまいましょう。
さてと、PySimpleGUIも、appJarも、おおざっぱなものしか作れないし、
もともと、GUIでさえあれば、レイアウトとかそこまで気にしていないので、
どちらを使ってもほぼ同じなので、appJarを使います。
appJarの使い方
appJarの使い方は、このページに書かれていることがすべてです。
やれることが少ない==覚えることが少なくて済む
ということなので、画面なんかてきとうでいい場合には、おすすめです。
あと、ここに書かれていないことは、これくらい?
モジュールをインストールしないと使えません。
pip install appJar
100年カレンダー作り機改良版
これを使うには、次のコマンドを打ち込む必要があります。
pip install openpyxl appJar
やっぱり必要なのが、ExcelまたはLibreOffice。
ほかのOffice製品でちゃんと使えるかどうかは、確かめていません。
(KingSoft Officeとか買う余裕ないし)。
肝心なスクリプトは、前回のものをちゃちゃっと改造してみますね。
import openpyxl
from openpyxl.styles import Font
from openpyxl.styles import Alignment
import sys
from appJar import gui
#A~Zを配列にする。A~Zは26文字
a2z=["","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
#ここからは追加させていく
i=1
j=1
while j<5:
while i<=26:
bufstr = a2z[j] + a2z[i]
a2z.append(bufstr)
i+=1
i=1
j+=1
#曜日を知る法則が通じないので、力技を使う。
#年,曜日
kako=[4000,0]
mirai=[-46,0]
kiroku=[2023,7]
#基準[2023,1,0,]
#関数化
def karendaa(kako,mirai,kiroku):
#西暦か紀元前か
def AD_BC(ahi):
if ahi[0]<=0:
return "B.C. "+str(abs(ahi[0])+1)
else:
return "A.D. "+str(ahi[0])
#うるう判定
def uruu_hantei(aieee):
ughhh=False
if aieee%4==0:
ughhh=True
if aieee%100==0 and aieee%400!=0:
ughhh=False
return ughhh
#曜日を調整する関数
def hiku_and_tasu(ahi):
kiroku=[2023,7]
while kiroku[0]!=ahi[0]:
#なぜか過去に遡る分のうるう年だけ計算のタイミングが合わないので、
#無理やりタイミングを合わせる
if ahi[0]<2023 :
if uruu_hantei(kiroku[0]-1)==True :
kiroku[1]-=2
else:
kiroku[1]-=1
kiroku[0]-=1
#未来をたどる分には計算のタイミングが合う
if ahi[0]>2023 :
if uruu_hantei(kiroku[0])==True :
kiroku[1]+=2
else:
kiroku[1]+=1
kiroku[0]+=1
if ahi[0]==2023:
ahi[1]=0
if ahi[0]==kiroku[0]:
while ahi[1]<0:
ahi+=7
ahi[1] = kiroku[1]%7
#曜日を調べる
hiku_and_tasu(kako)
#ブック作成
book=openpyxl.Workbook()
#シートを作成
sheet=book['Sheet']
ws=book.active
#シートのレイアウトの設定
#横向き
ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE
#フッターヘッター
#ws.oddFooter.center.text = "&[Page] / &N ページ"
#ws.oddHeader.center.text = "一覧表"
#作ったものに合わせて縮小しない
ws.sheet_properties.pageSetUpPr.fitToPage = False
#余白(単位はインチ 1inch=2.54cm)
ws.page_margins.top = 0.7874
ws.page_margins.left = 0.7480
ws.page_margins.bottom = 0.7874
ws.page_margins.right = 0.7480
#わからない設定。いるのだろうか?
ws.print_options.horizontalCenterd = True
ws.print_options.verticalCenterd = True
#高さ、幅の大きさ変更
#何ページ分作るかのカウンター
peezi={"zissaino_kaunto":0,"peezisuu":0}
#カレンダー作成用
gatu=[None,31,28,31,30,31,30,31,31,30,31,30,31]
koyomi=[None,"1 January","2 February","3 March","4 April","5 May","6 June","7 July","8 August","9 September","10 October","11 November","12 December"]
sitiyou=["S","M","T","W","T","F","S"]
nengappi=[kako[0],1,1,kako[1] ]
#なぜかは知らないけど、
#forやwhileで規定数回して高さを変更することができない
#どういうわけか、全部指定することはできる。
sheet.row_dimensions.width = 16.2857
def seru_no_reiauto():
#お目当ての年の1月1日の曜日を取得しなければならなくなった
buf_array=[ nengappi[0] ,0]
m=0
while m<2:
k=0
while k<6:
#列の幅を変更(ABC・・・)1≒0.1958cm
j=0
i=1
while j<7:
while i<=7:
sheet.column_dimensions[ a2z[i+j*8] ].width = 2.84
i+=1
i=1
j+=1
if j!=6:
sheet.column_dimensions[ a2z[j*8] ].width = 0.82
#行の高さを変更(123・・・)1≒0.035cm
buf_int = (32*abs(peezi["zissaino_kaunto"]))+1
buf_str = ("A{0}:AU{1}").format(buf_int , buf_int)
sheet.row_dimensions[buf_int].height = 22.8571
#セルの書式
so1=Font(size=14,bold=True)
so2=Font(size=11,bold=True,color='ff000000')
so3=Font(size=11,bold=True,color='ffff0011')
so4=Font(size=11,bold=True,color='ff2200ff')
so5=Font(size=11,bold=False,color='ff000000')
so6=Font(size=11,bold=False,color='ffff0011')
so7=Font(size=11,bold=False,color='ff2200ff')
align = Alignment(horizontal='center', vertical='center')
#セルの書式設定と一部セル埋め
ws["A"+str(abs(peezi["zissaino_kaunto"])*32+1)].font=so1
ws["A"+str(abs(peezi["zissaino_kaunto"])*32+1)].alignment=align
ws["A"+str(abs(peezi["zissaino_kaunto"])*32+1)]=AD_BC(nengappi)
#セルの結合
sheet.merge_cells(buf_str )
#月
buf_str=a2z[8*k+1]+str(abs(2+(16*(m+peezi["peezisuu"]*2))))
buf_str2=a2z[8*k+7]+str(abs(2+(16*(m+peezi["peezisuu"]*2))))
sheet.merge_cells(buf_str+":"+buf_str2 )
ws[buf_str].font=so2
ws[buf_str].alignment=align
ws[buf_str]=koyomi[nengappi[1] ]
#曜日のセル書式
buf_str = a2z[8*k+1] +str(abs( 3+(16*(m+peezi["peezisuu"]*2))))
ws[buf_str].font=so3
ws[buf_str].alignment=align
buf_str2 = a2z[8*k+7] +str(abs( 3+(16*(m+peezi["peezisuu"]*2)) ))
ws[buf_str2].font=so4
ws[buf_str2].alignment=align
i=2
while i<=6:
ws[ a2z[ 8*k + i]+str(abs( 3+(16*(m+peezi["peezisuu"]*2))) )].font=so2
ws[ a2z[ 8*k + i]+str(abs( 3+(16*(m+peezi["peezisuu"]*2))) )].alignment=align
i+=1
#七曜
i=1
while i<=7:
ws[ a2z[ 8*k + i ]+str(abs( 3+(16*(m+peezi["peezisuu"]*2)) ))]=sitiyou[i-1]
i+=1
#カレンダー部分の色分け用のセル設定
i=4
while i<=9:
buf_str = a2z[ 8*k+1 ] + str(abs( i+(16*(m+peezi["peezisuu"]*2)) ))
ws[buf_str].font = so6
ws[buf_str].alignment=align
i+=1
i=4
while i<=9:
buf_str = a2z[ 8*k+1 +6 ] + str(abs( i+(16*(m+peezi["peezisuu"]*2))) )
ws[buf_str].font=so7
ws[buf_str].alignment=align
i+=1
j=0
i=4
while j<5:
while i<=9:
buf_str = a2z[ 8*k + j+2 ] + str(abs( i+(16*(m+peezi["peezisuu"]*2)) ))
ws[buf_str].font=so5
ws[buf_str].alignment=align
i+=1
i=4
j+=1
j=0
#月に応じた日数を取得する
buf_int2 = gatu[nengappi[1] ]
uruu=False
if nengappi[0]%4 == 0:
uruu=True
if nengappi[0]%100==0 and nengappi[0]%400!=0:
uruu=False
if uruu==True and nengappi[1]==2:
buf_int2=29
#日数に応じてセルを埋める
i=1
hiku_and_tasu(buf_array)
guhehe=abs(4+(16*(m+peezi["peezisuu"]*2)))
if nengappi[1]==1:
nengappi[3]=buf_array[1]
while i<=buf_int2:
buf_str = a2z[ k*8 + abs(nengappi[3])+1] + str(guhehe)
ws[buf_str]=i
nengappi[3]+=1
i+=1
if nengappi[3]>=7:
nengappi[3]-=7
guhehe+=1
k+=1
nengappi[1]+=1
if nengappi[1]>12:
nengappi[1]-=12
k=0
m+=1
m=0
#暦を12個作ったら年月日を移動させる
if kako[0]>mirai[0]:
nengappi[0]-=1
else:
nengappi[0]+=1
#カウント用
while abs(peezi["peezisuu"]) <= abs(mirai[0]-kako[0]):
seru_no_reiauto()
if kako[0]>mirai[0]:
peezi["peezisuu"]-=1
peezi["zissaino_kaunto"]+=1
else:
peezi["peezisuu"]+=1
peezi["zissaino_kaunto"]+=1
#シートの中身
#aaa="あーん、ドーナツが食べたいよう。"
#bbb="222"
#ws=book.active
#ws["A1"]=aaa
#ws["B2"]=bbb
#シートの名前を変える
#sheet.title='シートン博士'
#保存
if kako[0]<=0:
buf_str1="BC"+str(abs(kako[0]-1))
else:
buf_str1=str(kako[0])
if mirai[0]<=0:
buf_str2="BC"+str(abs(mirai[0]-1))
else:
buf_str2=str(mirai[0])
if kako[0]==mirai[0]:
buf_str=("{0}.xlsx".format(buf_str2))
else:
buf_str=("{0}-{1}.xlsx".format(buf_str1,buf_str2))
#ファイル名をつけてエクセルファイルを保存
book.save(buf_str)
def ripureesu(bstr):
bstr=bstr.replace("0","0")
bstr=bstr.replace("1","1")
bstr=bstr.replace("2","2")
bstr=bstr.replace("3","3")
bstr=bstr.replace("4","4")
bstr=bstr.replace("5","5")
bstr=bstr.replace("6","6")
bstr=bstr.replace("7","7")
bstr=bstr.replace("8","8")
bstr=bstr.replace("9","9")
bstr=bstr.replace("年","")
bstr=bstr.replace("AD","")
bstr=bstr.replace("A.D.","")
bstr=bstr.replace("ad","")
bstr=bstr.replace("a.d.","")
bstr=bstr.replace("紀元後","")
bstr=bstr.replace("キリスト歴","")
bstr=bstr.replace("西暦","")
bstr=bstr.replace("AD","")
bstr=bstr.replace("A.D.","")
bstr=bstr.replace("あD","")
bstr=bstr.replace("あ。D。","")
bstr=bstr.replace(" ","")
bstr=bstr.replace(" ","")
return bstr
def mainasu1(bstr):
if ("B.C." in bstr)==True or \
("BC" in bstr)==True or \
("b.c." in bstr)==True or \
("bc" in bstr)==True or \
("BC" in bstr)==True or \
("B.C." in bstr)==True or \
("bc" in bstr)==True or \
("b。c。" in bstr)==True or \
("紀元前" in bstr)==True :
return True
else:
return False
def kigenzen_kesu(bstr):
bstr=bstr.replace("B.C.","")
bstr=bstr.replace("BC","")
bstr=bstr.replace("b.c.","")
bstr=bstr.replace("bc","")
bstr=bstr.replace("B.C.","")
bstr=bstr.replace("BC","")
bstr=bstr.replace("b。c。","")
bstr=bstr.replace("bc","")
bstr=bstr.replace("紀元前","")
return bstr
def tukuru():
buf_bool=False
try:
str1=app.getEntry("おしっこ")
str2=app.getEntry("うんこ")
kako[0]=int(str1)
mirai[0]=int(str2)
buf_bool=True
except :
if str1=="" and str2=="":
app.setLabel("9",'空欄とかだめ~!')
buf_bool=False
else:
try:
str1=ripureesu(str1)
str2=ripureesu(str2)
boo1=mainasu1(str1)
boo2=mainasu1(str2)
str1=kigenzen_kesu(str1)
str2=kigenzen_kesu(str2)
kako[0]=int(str1)
mirai[0]=int(str2)
if boo1==True:
kako[0]*=-1
kako[0]+=1
boo1=False
if boo2==True:
mirai[0]*=-1
mirai[0]+=1
boo2=False
buf_bool=True
except:
app.setLabel("9",'いや~ん! もう~! いけず~!')
app.setEntry("おしっこ","")
app.setEntry("うんこ","")
buf_bool=False
if kako[0]>mirai[0]:
buf=kako[0]
kako[0]=mirai[0]
mirai[0]=buf
if buf_bool==True:
app.setLabel("9",'作るよ~!')
karendaa(kako,mirai,kiroku)
buf_bool=False
app.setLabel("9",'できた~!')
#appJarのGUI
app=gui("カレンダーを何百年分も作る機","320x320")
app.setBg("#559955")
app.setFg("white")
app.setFont(10)
app.addLabel("-1","")
app.addLabel("0","これは過去から未来まで、指定したカレンダーの")
app.addLabel("1","エクセルファイルを作るソフトです。 ")
app.addLabel("2","過去と未来の欄に西暦を入れてね。 ")
app.addLabel("3","紀元前は「BC」を入れるかマイナス数字で。 ")
app.addLabel("4","")
app.addLabel("5","")
app.addLabel("6","過去?(半角数字で)")
app.entry("おしっこ",label=False,focus=True)
app.addLabel("11","")
app.addLabel("7","未来?(半角数字で)")
app.entry("うんこ",label=False,focus=False)
app.addLabel("8","")
app.addButtons(["作る"],tukuru)
app.addLabel("9","")
app.addLabel("10","")
#なぜか最初のフォーカス位置を設定できない
app.setFocus("おしっこ")
app.go()
参考資料
appJar(github)
https://github.com/jarvisteach/appJar/?tab=License-1-ov-file#readme
Excelからデータ抽出!Python(OpenPyXL)の読み込み方法まとめ (駆け出し物語)
http://kakedashi-xx.com:25214/index.php/2021/08/22/post-3086/
appJar(github)
https://github.com/jarvisteach/appJar/?tab=License-1-ov-file#readme
Excelからデータ抽出!Python(OpenPyXL)の読み込み方法まとめ (駆け出し物語)
http://kakedashi-xx.com:25214/index.php/2021/08/22/post-3086/