年前我们推送了一篇文章Excel四季日历[可打印版本](下载链接),有读者朋友留言说想要可以显示农历的版本,于是就有了今天的推文!
Excel中本身是没有农历日期转换函数的,Excel表哥也是查阅了网络资料后得到了如下一些解决方法,在次分享给大家。
只需要在上文模板中略加修改即可拥有带农历的万年历啦!
01
方法一:TEXT+MID函数法
例如B12单元格是公历日历,则可以使用如下的公式将其转换为阴历日期:
=MID(甲乙丙丁戊己庚辛壬癸,MOD(TEXT(B12,[-]e)-4,10)+1,1)MID(子丑寅卯辰巳午未申酉戌亥,MOD(TEXT(B12,[-]e)-4,12)+1,1)年TEXT(B12,[-][DBNum1]m月d日)▲左右滑动查看完整公式
在上述阴历转换公式中,核心公式为TEXT(B12,[-]e-mm-dd),这个公式属于TEXT的隐藏用法,需要以上版本的EXCEL才支持,这个公式的关键是:[-],它可以将Excel中阳历转化为以农历表示的的年月日,e-mm-dd则表示日期的显示形式。
另外增加了参数[DBNum1],表示数值以“一、二、三......”中文格式显示。
▍注:上述公式存在一个问题是没法计算闰月,凡是有闰月的年份,它直接表示一年13个月。
02
方法二:TEXT+MID+CHOOSE+YEAR函数
可以看到方法一显示的公式除了注释中的问题之外,对于阴历月份当月十一日之前的显示方法也是和我们的常见说法不同,于是网上还找到了第二种TEXT+MID+CHOOSE+YEAR函数组合成的第二种公式:
=CHOOSE(MOD(YEAR(B13)-,10),庚,辛,壬,癸,甲,乙,丙,丁,戊,己)CHOOSE(MOD(YEAR(B13)-,12),子,丑,寅,卯,辰,巳,午,未,申,酉,戌,亥)TEXT(B13,[dbnum1][-]年m月IF(--TEXT(B13,[-]d)11,初,)TEXT(B13,[dbnum1][-]d))
从上述公式的运算结果我们看到更加符合我们常见的阴历日期称法,即增加了对月初时初几的显示。
对于上面介绍的两种方法,我们都可以使用公式运算求值进行按步骤计算,有助于我们理解公式的意义。
▍注-上述公式中:
甲,乙,丙,丁,戊,己,庚,辛,壬,癸,表示天干,十年一轮回;
子,丑,寅,卯,辰,巳,午,未,申,酉,戌,亥表示地支,十二年轮回一次。
而-1-1则是Excel中可以表示的最小日期。
03
自定义公式法
上面介绍的Excel公历转农历都是使用Excel内置函数完成的,有一个弊端就是公式太长(而且根本记不住),如果使用自定义函数,在公式就可以简化输入。
我在网上找到了一段VBA代码,可以实现将年至年时间范围内所有的公历日期转换为农历,代码总计行,我也验证过了,并且根据自己的实际操作添加了部分注释。现在也贴出来供大家参考:
向上滑动阅览
PublicFunctionNongLi(OptionalXX_DATEAsDate)DimMonthAdd(11),NongliData(),TianGan(9),DiZhi(11),ShuXiang(11),DayName(30),MonName(12)DimcurTime,curYear,curMonth,curDayDimGongliStr,NongliStr,NongliDayStrDimi,m,n,k,isEnd,bit,TheDate获取当前系统时间curTime=XX_DATE天干名称TianGan(0)=甲TianGan(1)=乙TianGan(2)=丙TianGan(3)=丁TianGan(4)=戊TianGan(5)=己TianGan(6)=庚TianGan(7)=辛TianGan(8)=壬TianGan(9)=癸地支名称DiZhi(0)=子DiZhi(1)=丑DiZhi(2)=寅DiZhi(3)=卯DiZhi(4)=辰DiZhi(5)=巳DiZhi(6)=午DiZhi(7)=未DiZhi(8)=申DiZhi(9)=酉DiZhi(10)=戌DiZhi(11)=亥属相名称ShuXiang(0)=鼠ShuXiang(1)=牛ShuXiang(2)=虎ShuXiang(3)=兔ShuXiang(4)=龙ShuXiang(5)=蛇ShuXiang(6)=马ShuXiang(7)=羊ShuXiang(8)=猴ShuXiang(9)=鸡ShuXiang(10)=狗ShuXiang(11)=猪农历日期名DayName(0)=*DayName(1)=初一DayName(2)=初二DayName(3)=初三DayName(4)=初四DayName(5)=初五DayName(6)=初六DayName(7)=初七DayName(8)=初八DayName(9)=初九DayName(10)=初十DayName(11)=十一DayName(12)=十二DayName(13)=十三DayName(14)=十四DayName(15)=十五DayName(16)=十六DayName(17)=十七DayName(18)=十八DayName(19)=十九DayName(20)=二十DayName(21)=廿一DayName(22)=廿二DayName(23)=廿三DayName(24)=廿四DayName(25)=廿五DayName(26)=廿六DayName(27)=廿七DayName(28)=廿八DayName(29)=廿九DayName(30)=三十农历月份名MonName(0)=*MonName(1)=正MonName(2)=二MonName(3)=三MonName(4)=四MonName(5)=五MonName(6)=六MonName(7)=七MonName(8)=八MonName(9)=九MonName(10)=十MonName(11)=十一MonName(12)=腊公历每月前面的天数MonthAdd(0)=0MonthAdd(1)=31MonthAdd(2)=59MonthAdd(3)=90MonthAdd(4)=MonthAdd(5)=MonthAdd(6)=MonthAdd(7)=MonthAdd(8)=MonthAdd(9)=MonthAdd(10)=MonthAdd(11)=农历数据NongliData(0)=年NongliData(1)=年NongliData(2)=NongliData(3)=...省略若干行NongliData(96)=NongliData(97)=NongliData(98)=NongliData(99)=NongliData()=年NongliData()=...省略若干行NongliData()=NongliData()=NongliData()=9NongliData()=NongliData()=+=年生成当前公历年、月、日==GongliStrcurYear=Year(curTime)curMonth=Month(curTime)curDay=Day(curTime)GongliStr=curYear年If(curMonth10)ThenGongliStr=GongliStr0curMonth月ElseGongliStr=GongliStrcurMonth月EndIfIf(curDay10)ThenGongliStr=GongliStr0curDay日ElseGongliStr=GongliStrcurDay日EndIf计算到初始时间年2月8日的天数:-2-8(正月初一)TheDate=(curYear-)*+Int((curYear-)/4)+curDay+MonthAdd(curMonth-1)-38If((curYearMod4)=0AndcurMonth2)ThenTheDate=TheDate+1EndIf计算农历天干、地支、月、日isEnd=0m=0DoIf(NongliData(m))Thenk=11Elsek=12EndIfn=kDoIf(n0)ThenExitDoEndIf获取NongliData(m)的第n个二进制位的值bit=NongliData(m)Fori=1TonStep1bit=Int(bit/2)Nextbit=bitMod2If(TheDate=29+bit)ThenisEnd=1ExitDoEndIfTheDate=TheDate-29-bitn=n-1LoopIf(isEnd=1)ThenExitDoEndIfm=m+1LoopcurYear=+mcurMonth=k-n+1curDay=TheDateIf(k=12)ThenIf(curMonth=(Int(NongliData(m)/)+1))ThencurMonth=1-curMonthElseIf(curMonth(Int(NongliData(m)/)+1))ThencurMonth=curMonth-1EndIfEndIf生成农历天干、地支、属相==NongliStrNongliStr=农历TianGan(((curYear-4)Mod60)Mod10)DiZhi(((curYear-4)Mod60)Mod12)年NongliStr=NongliStr(ShuXiang(((curYear-4)Mod60)Mod12))生成农历月、日==NongliDayStrIf(curMonth1)ThenNongliDayStr=闰MonName(-1*curMonth)ElseNongliDayStr=MonName(curMonth)EndIfNongliDayStr=NongliDayStr月NongliDayStr=NongliDayStrDayName(curDay)NongLi=NongliStrNongliDayStrEndFunction▲左右滑动查看完整代码
以-1-1为例使用自定义公式Nongli()计算得到的农历日期为:
上面的日期结果中包含了完整的农历描述,如果我们还希望能简化,则再结合字符串函数MID或者RIGHT即可!
我们在文章Excel四季日历[可打印版本](下载链接)的基础上,在每一行日历下增加一行,并添加如下公式,如图所示:
=MID(NongLi(B4),FIND(),NongLi(B4))+1,99)
我们以)为查找符,找到Nongli公式转换出来的字符串农历辛丑年(牛)十一月廿三中的)位置,继而使用MID函数提取阴历月份和日期,一般的农历月份日期为4个或者是5个汉字,这里的99只要是=5就ok。
另外,我们还要留意一下当月月初不属于本月的日期,可以通过修改条件格式将其设置为灰色即可。
今天的分享到此结束,恭喜读者朋友们又获得一项新技能!
作者:Excel表哥
需要此包含农历日期的万年历模板的读者朋友,请在Excel表哥百家号回复即可获取下载链接。
延伸阅读:
已获+付费下载的项目管理模板:
项目管理模板V4.1更新(WinMac电脑通用)