背景需求
搭档提出给小班孩子过生日,感受学校温馨
她圈出了9月过生日的四位孩子。
我想在手机上做个备忘录提示,到了生日时组织集体唱生日歌。
设计过程
点名单按照先男后女,先大后小,所以男女生日分开的。我重新按年龄大小(不考虑那男女)排了一下。
发现男孩子是老大,女孩是老么。10牛14虎
我把生日用Deepseek计算了三年的日期和星期
'''
小2班幼儿生日,制作小班2025-2026,中班2026-2027,大班2027-2028的日趋,遇到双休日,前移
Deepseek,阿夏
20250913
'''
import openpyxl
from datetime import datetime, timedelta
def get_weekday_name(date_obj):
"""获取中文星期几"""
weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
return weekdays[date_obj.weekday()]
def get_previous_friday(date_obj):
"""获取前一个星期五的日期"""
# 计算距离上一个星期五的天数
days_to_subtract = (date_obj.weekday() - 4) % 7
if days_to_subtract == 0:
days_to_subtract = 7 # 如果是星期五,取上一个星期五
previous_friday = date_obj - timedelta(days=days_to_subtract)
return previous_friday
def format_date_with_weekday(date_obj):
"""格式化日期为年月日星期几的样式"""
weekday_name = get_weekday_name(date_obj)
return f"{date_obj.year}年{date_obj.month}月{date_obj.day}日{weekday_name}"
def process_excel_file():
# 读取Excel文件
path = r'C:Usersjg2yXRZOneDrive桌面20250902小2班家长沟通'
workbook = openpyxl.load_workbook(path + r'20250902小2班幼儿生日提示.xlsx')
sheet = workbook.worksheets[0] # 获取第一个工作表
# 设置列标题
sheet['G1'] = "出生日期年月日星期"
sheet['H1'] = "小班生日"
sheet['I1'] = "小班生日前移"
sheet['J1'] = "中班生日"
sheet['K1'] = "中班生日前移"
sheet['L1'] = "大班生日"
sheet['M1'] = "大班生日前移"
# 设置列宽为25
for col in ['G', 'H', 'I', 'J', 'K', 'L', 'M']:
sheet.column_dimensions[col].width = 25
# 处理F列的数据
for row in range(2, sheet.max_row + 1): # 从第2行开始(假设第1行是标题)
f_cell = sheet[f'F{row}']
# 检查单元格是否有值
if f_cell.value is None:
continue
# 处理日期值(可能是字符串或datetime对象)
if isinstance(f_cell.value, str):
# 如果是字符串格式的日期
try:
date_obj = datetime.strptime(f_cell.value, '%Y/%m/%d')
except ValueError:
print(f"第{row}行F列的日期格式无法解析: {f_cell.value}")
continue
elif isinstance(f_cell.value, datetime):
# 如果已经是datetime对象
date_obj = f_cell.value
else:
print(f"第{row}行F列的数据类型无法处理: {type(f_cell.value)}")
continue
# 格式化原始日期并写入G列
formatted_date = format_date_with_weekday(date_obj)
sheet[f'G{row}'] = formatted_date
# 计算小班生日(原始日期+4年)
xiaoban_date = date_obj.replace(year=date_obj.year + 4)
xiaoban_formatted = format_date_with_weekday(xiaoban_date)
sheet[f'H{row}'] = xiaoban_formatted
# 如果是星期六或星期日,写入前一个星期五的日期到I列
if xiaoban_date.weekday() in [5, 6]: # 5=星期六, 6=星期日
previous_friday = get_previous_friday(xiaoban_date)
friday_formatted = format_date_with_weekday(previous_friday)
sheet[f'I{row}'] = friday_formatted
# 计算中班生日(原始日期+5年)
zhongban_date = date_obj.replace(year=date_obj.year + 5)
zhongban_formatted = format_date_with_weekday(zhongban_date)
sheet[f'J{row}'] = zhongban_formatted
# 如果是星期六或星期日,写入前一个星期五的日期到K列
if zhongban_date.weekday() in [5, 6]: # 5=星期六, 6=星期日
previous_friday = get_previous_friday(zhongban_date)
friday_formatted = format_date_with_weekday(previous_friday)
sheet[f'K{row}'] = friday_formatted
# 计算大班生日(原始日期+6年)
daban_date = date_obj.replace(year=date_obj.year + 6)
daban_formatted = format_date_with_weekday(daban_date)
sheet[f'L{row}'] = daban_formatted
# 如果是星期六或星期日,写入前一个星期五的日期到M列
if daban_date.weekday() in [5, 6]: # 5=星期六, 6=星期日
previous_friday = get_previous_friday(daban_date)
friday_formatted = format_date_with_weekday(previous_friday)
sheet[f'M{row}'] = friday_formatted
# 保存为新文件
workbook.save(path + r'20250902小2班学生生日日期提示.xlsx')
print("处理完成,文件已保存为20250902小2班学生生日日期提示.xlsx")
if __name__ == "__main__":
process_excel_file()
本次我就只做小班一年的生日提醒。
手机同屏幕,等于用电脑模拟手机屏幕操作,设定日程记录
UIBOT添加手机记录提醒(因为它有文字识别。Python没有)
第一种,自动添加日期(时间很长)
Dim temp,sText,姓名生日,objExcelWorkBook,arrayRet,姓名,iRet,写入文字,实际生日,显示日期
Rem 打开excle读取数据
objExcelWorkBook = Excel.OpenExcel('''C:Usersjg2yXRZOneDrive桌面20250902小2班家长沟通20250902小2班学生生日日期提示.xlsx''',true,"Excel","","")
姓名=Excel.ReadColumn(objExcelWorkBook,"Sheet1","D1",true)
小班实际=Excel.ReadColumn(objExcelWorkBook,"Sheet1","H1",true)
小班前移=Excel.ReadColumn(objExcelWorkBook,"Sheet1","I1",true)
行数=Excel.GetRowsCount(objExcelWorkBook,"Sheet1")
Rem 拖动显示时间和日期页面
Mouse.Drag(1580, 128, 1580, 236, "left", [],{"iDelayAfter": 1000, "iDelayBefore": 200})
Rem 点击日期
Mouse.Move(1615, 206, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 500, "iDelayBefore": 300})
For i = 17 To 行数 -1
Rem 点击加号
Mouse.Move(1785, 876, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 500, "iDelayBefore": 300})
// 数组索引从0开始
// 第一种情况:小班前移为空,小班实际不为空
If 小班前移[i] = "" And 小班实际[i] <> ""
写入文字 = 姓名[i] & '生日,实际' & 小班实际[i]
TracePrint 写入文字
Rem 标题
Mouse.Move(1541, 305, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Keyboard.Input(写入文字,{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "message"})
Rem 选择日期
Mouse.Move(1750, 494, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 循环向下按日期
Do
Rem 识别显示日期
实际生日 = 小班实际[i]
显示日期=LocalOCR.ScreenOCR(@ui"窗口_Loading..",{"x":62,"y":418,"width":253,"height":49},"SceneText",10000,{"bContinueOnError":false,"iDelayAfter":300,"iDelayBefore":200,"bSetForeground":true})
TracePrint($PrevResult)
If 显示日期<>实际生日
Keyboard.Press("Down", "press", [],{"iDelayAfter": 200, "iDelayBefore": 200, "sSimulate": "simulate"})
Continue
End If
If 显示日期=实际生日
Mouse.Move(1748, 881, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem
Rem 选择时间
Mouse.Move(1795, 527, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 点击分
Mouse.Move(1680, 684, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 显示在年月上
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Keyboard.Press("Right", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
For i = 0 To 10 step 1
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Next
Rem 确认
Mouse.Move(1739, 875, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
Rem 打勾确认
Mouse.Move(1808, 180, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
End If
Break
Loop
Continue
End If
// '第二种情况:小班前移不为空,小班实际不为空
If 小班前移[i] <> "" and 小班实际[i]<>""
写入文字 = 姓名[i] & '生日,实际' & 小班实际[i] & '。前移' & 小班前移[i]
TracePrint 写入文字
Rem 标题
Mouse.Move(1541, 305, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Keyboard.Input(写入文字,{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "message"})
Rem 选择日期
Mouse.Move(1750, 494, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 循环向下按日期
Do
Rem 识别显示日期
实际生日 = 小班前移[i]
TracePrint($PrevResult)
显示日期=LocalOCR.ScreenOCR(@ui"窗口_Loading..2",{"x":51,"y":420,"width":279,"height":47},"SceneText",10000,{"bContinueOnError":false,"iDelayAfter":1000,"iDelayBefore":200,"bSetForeground":true})
TracePrint($PrevResult)
If 显示日期<>实际生日
Keyboard.Press("Down", "press", [],{"iDelayAfter": 200, "iDelayBefore": 200, "sSimulate": "simulate"})
Continue
End If
If 显示日期=实际生日
Mouse.Move(1748, 881, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 选择时间
Mouse.Move(1795, 527, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 点击分
Mouse.Move(1680, 684, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 显示在年月上
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Keyboard.Press("Right", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
For i = 0 To 10 step 1
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Next
Rem 确认
Mouse.Move(1739, 875, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
Rem 打勾确认
Mouse.Move(1808, 180, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
End If
Break
Loop
Continue
End If
Next
主要步骤:
一、只有一个实际日期的情况
运行UIBOT,UIBOT页面最小化,等10秒跳出EXCLE
鼠标拖动下滑
新建记事本
识别显示的黑色日期与表格里写的日期是否一样
如果不一样,就自动下移一个日期(1秒一次,进行识别)
如果显示日期与实际日期一样,就点击确定
我是在早上6点干活,开始时间就7点,它默认从8点结束,我需要时间长,一整天。
自动下移11次
继续写第二个人
二、实际日期和前移日期都存在。
如果有前移日期(生日正好是双休日,就前移到周五)
说明里面就有实际日期和前移日期,两个日期的文字总数控制在两行内,否则日期和时分的点击位置就会错误。
这里总是报错,后来发现主要问题是开始下一次循环continue一没有添加
程序都正确了,但存在问题:选日期时间太长了
2025年的孩子选择日期的下移次数还少一点,但2026年小月龄的孩子很多,选择日期下移次数最多要350多次=360秒5分钟,时长很长。
所以2个小时也只做了16个人(不过也包含修改代码的时间)
三、Uibot写标题+手动选时间
我等不及了,就想试试看用手动选日期(手机滑动屏幕选日期更快),其他都用UIBOT来点击.
Dim temp,sText,姓名生日,objExcelWorkBook,arrayRet,姓名,iRet,写入文字,实际生日,显示日期,dictRet,手动选日期
Rem 打开excle读取数据
objExcelWorkBook = Excel.OpenExcel('''C:Usersjg2yXRZOneDrive桌面20250902小2班家长沟通20250902小2班学生生日日期提示.xlsx''',true,"Excel","","")
姓名=Excel.ReadColumn(objExcelWorkBook,"Sheet1","D1",true)
小班实际=Excel.ReadColumn(objExcelWorkBook,"Sheet1","H1",true)
小班前移=Excel.ReadColumn(objExcelWorkBook,"Sheet1","I1",true)
行数=Excel.GetRowsCount(objExcelWorkBook,"Sheet1")
Rem 拖动显示时间和日期页面
Mouse.Drag(1580, 128, 1580, 236, "left", [],{"iDelayAfter": 1000, "iDelayBefore": 200})
Rem 点击日期
Mouse.Move(1615, 206, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 500, "iDelayBefore": 300})
For i = 1 To 行数 -1
Rem 点击加号
Mouse.Move(1785, 876, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 500, "iDelayBefore": 300})
// 数组索引从0开始
// 第一种情况:小班前移为空,小班实际不为空
If 小班前移[i] = "" And 小班实际[i] <> ""
写入文字 = 姓名[i] & '生日,实际' & 小班实际[i]
TracePrint 写入文字
Rem 标题
Mouse.Move(1541, 305, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Keyboard.Input(写入文字,{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "message"})
Rem 选择日期
Mouse.Move(1750, 494, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
手动选日期=Dialog.MsgBox("","Laiye Automation",0,1,0)
Rem 确定
Mouse.Move(1734, 875, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 选择时间
Mouse.Move(1795, 527, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 点击分
Mouse.Move(1680, 684, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 显示在年月上
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Keyboard.Press("Right", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
For i = 0 To 10 step 1
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Next
Rem 确认
Mouse.Move(1739, 875, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
Rem 打勾确认
Mouse.Move(1808, 180, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
End If
// '第二种情况:小班前移不为空,小班实际不为空
Continue
If 小班前移[i] <> "" and 小班实际[i]<>""
写入文字 = 姓名[i] & '生日,实际' & 小班实际[i] & '。前移' & 小班前移[i]
TracePrint 写入文字
Rem 标题
Mouse.Move(1541, 305, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Keyboard.Input(写入文字,{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "message"})
Rem 选择日期
Mouse.Move(1750, 494, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 循环向下按日期
手动选日期=Dialog.MsgBox("","Laiye Automation",0,1,0)Rem 确定
Mouse.Move(1734, 875, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 选择时间
Mouse.Move(1795, 527, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 点击分
Mouse.Move(1680, 684, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 300, "iDelayBefore": 300})
Rem 显示在年月上
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Keyboard.Press("Right", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
For i = 0 To 10 step 1
Keyboard.Press("Down", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Next
Rem 确认
Mouse.Move(1739, 875, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
Rem 打勾确认
Mouse.Move(1808, 180, false,{"iDelayAfter": 300, "iDelayBefore": 200})
Mouse.Click("left", "click", [],{"iDelayAfter": 1000, "iDelayBefore": 300})
End If
Continue
Next
程序自动输入标题(姓名、实际时间、前移时间),点击日期,跳出日期时间的弹框,然后就出现“消息对话框”,把程序暂停
在手机上手动滑,很快就能进入6月
选好日期,再点确定,关闭对话框
后面的程序和前面一样,点击确定,选择时分(+11),确定,打钩,重新点加号。这些都是系统自己做的。
四、节假日也要前移。
在手动调时间过程中,我发现最后两位孩子生日在7月8月,也就是暑假(7月13日周六前移到7月12日周五也没有用,假期根本不可能在幼儿园过生日)需要提早到6月底进行。
于是检查了所有孩子的生日日期。发现几个孩子生日可能会遇到“国定假日(国庆、寒暑假、劳动节等)”
(2026年的放假安排还没有出来,不知道会不会遇到端午,)
手动把这些日期都改成月底,考虑到假日前幼儿会提早回老家,旅游等,所以提示时间有5天,25-30日
看看效果
因此下一次做EXCLE表格的时,还要增加:
1、5月1-5日劳动节、2月寒假、7-8月暑假、10月1-8日国庆节出生幼儿的的提示时间需要另外做一套说明,时间用暂停功能后手动调整。
2、希望我能在这个班级呆的长久一点吧。(过去3年都是只待半年、一年的样子。)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...