Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 3278|回复: 7

[已解决]自定义函数只能引用单元格,不能引用常量的问题

[复制链接]
发表于 2013-12-26 08:55 | 显示全部楼层 |阅读模式
从网上下载到一段公历转农历的自定 义函数,但这个函数有个问题是,参数只能引用单元格,不能直接使用常量,应该如何进行修改,源代码如下
  1. Private Const ylData = "AB500D2,4BD0883," _
  2.       & "4AE00DB,A5700D0,54D0581,D2600D8,D9500CC,655147D,56A00D5,9AD00CA,55D027A,4AE00D2," _
  3.       & "A5B0682,A4D00DA,D2500CE,D25157E,B5500D6,56A00CC,ADA027B,95B00D3,49717C9,49B00DC," _
  4.       & "A4B00D0,B4B0580,6A500D8,6D400CD,AB5147C,2B600D5,95700CA,52F027B,49700D2,6560682," _
  5.       & "D4A00D9,EA500CE,6A9157E,5AD00D6,2B600CC,86E137C,92E00D3,C8D1783,C9500DB,D4A00D0," _
  6.       & "D8A167F,B5500D7,56A00CD,A5B147D,25D00D5,92D00CA,D2B027A,A9500D2,B550781,6CA00D9," _
  7.       & "B5500CE,535157F,4DA00D6,A5B00CB,457037C,52B00D4,A9A0883,E9500DA,6AA00D0,AEA0680," _
  8.       & "AB500D7,4B600CD,AAE047D,A5700D5,52600CA,F260379,D9500D1,5B50782,56A00D9,96D00CE," _
  9.       & "4DD057F,4AD00D7,A4D00CB,D4D047B,D2500D3,D550883,B5400DA,B6A00CF,95A1680,95B00D8," _
  10.       & "49B00CD,A97047D,A4B00D5,B270ACA,6A500DC,6D400D1,AF40681,AB600D9,93700CE,4AF057F," _
  11.       & "49700D7,64B00CC,74A037B,EA500D2,6B50883,5AC00DB,AB600CF,96D0580,92E00D8,C9600CD," _
  12.       & "D95047C,D4A00D4,DA500C9,755027A,56A00D1,ABB0781,25D00DA,92D00CF,CAB057E,A9500D6," _
  13.       & "B4A00CB,BAA047B,B5500D2,55D0983,4BA00DB,A5B00D0,5171680,52B00D8,A9300CD,795047D," _
  14.       & "6AA00D4,AD500C9,5B5027A,4B600D2,96E0681,A4E00D9,D2600CE,EA6057E,D5300D5,5AA00CB," _
  15.       & "76A037B,96D00D3,4AB0B83,4AD00DB,A4D00D0,D0B1680,D2500D7,D5200CC,DD4057C,B5A00D4," _
  16.       & "56D00C9,55B027A,49B00D2,A570782,A4B00D9,AA500CE,B25157E,6D200D6,ADA00CA,4B6137B," _
  17.       & "93700D3,49F08C9,49700DB,64B00D0,68A1680,EA500D7,6AA00CC,A6C147C,AAE00D4,92E00CA," _
  18.       & "D2E0379,C9600D1,D550781,D4A00D9,DA400CD,5D5057E,56A00D6,A6C00CB,55D047B,52D00D3," _
  19.       & "A9B0883,A9500DB,B4A00CF,B6A067F,AD500D7,55A00CD,ABA047C,A5A00D4,52B00CA,B27037A," _
  20.       & "69300D1,7330781,6AA00D9,AD500CE,4B5157E,4B600D6,A5700CB,54E047C,D1600D2,E960882," _
  21.       & "D5200DA,DAA00CF,6AA167F,56D00D7,4AE00CD,A9D047D,A2D00D4,D1500C9,F250279,D5200D1"

  22. Private Const ylMd0 = "初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五" _
  23.       & "十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十 "
  24. Private Const ylMn0 = "正二三四五六七八九十冬腊"
  25. Private Const ylTianGan0 = "甲乙丙丁戊已庚辛壬癸"
  26. Private Const ylDiZhi0 = "子丑寅卯辰巳午未申酉戌亥"
  27. Private Const ylShu0 = "鼠牛虎兔龙蛇马羊猴鸡狗猪"
  28. Function NongLi(ByVal strDate As String) As String
  29.     On Error GoTo aErr
  30.     If Not IsDate(strDate) Then Exit Function
  31.     Dim setDate As Date, tYear As Integer, tMonth As Integer, tDay As Integer
  32.     setDate = CDate(strDate)
  33.     tYear = Year(setDate): tMonth = Month(setDate): tDay = Day(setDate)
  34.     If tYear > 2100 Or tYear < 1900 Then Exit Function
  35.     Dim daList() As String * 18, conDate As Date, thisMonths As String
  36.     Dim AddYear As Integer, AddMonth As Integer, AddDay As Integer, getDay As Integer
  37.     Dim YLyear As String, YLShuXing As String
  38.     Dim dd0 As String, mm0 As String, ganzhi(0 To 59) As String * 2
  39.     Dim RunYue As Boolean, RunYue1 As Integer, mDays As Integer, i As Integer
  40.     ReDim daList(tYear - 1 To tYear)
  41.     daList(tYear - 1) = H2B(Mid(ylData, (tYear - 1900) * 8 + 1, 7))
  42.     daList(tYear) = H2B(Mid(ylData, (tYear - 1900 + 1) * 8 + 1, 7))
  43.     AddYear = tYear
  44. initYL:
  45.     AddMonth = CInt(Mid(daList(AddYear), 15, 2))
  46.     AddDay = CInt(Mid(daList(AddYear), 17, 2))
  47.     conDate = DateSerial(AddYear, AddMonth, AddDay)
  48.     getDay = DateDiff("d", conDate, setDate) + 1
  49.     If getDay < 1 Then AddYear = AddYear - 1: GoTo initYL
  50.     thisMonths = Left(daList(AddYear), 14)
  51.     RunYue1 = Val("&H" & Right(thisMonths, 1))
  52.     If RunYue1 > 0 Then
  53.         thisMonths = Left(thisMonths, RunYue1) & Mid(thisMonths, 13, 1) & Mid(thisMonths, RunYue1 + 1)
  54.     End If
  55.     thisMonths = Left(thisMonths, 13)
  56.     For i = 1 To 13
  57.         mDays = 29 + CInt(Mid(thisMonths, i, 1))
  58.         If getDay > mDays Then
  59.             getDay = getDay - mDays
  60.         Else
  61.             If RunYue1 > 0 Then
  62.                 If i = RunYue1 + 1 Then RunYue = True
  63.                 If i > RunYue1 Then i = i - 1
  64.             End If
  65.             AddMonth = i
  66.             AddDay = getDay
  67.             Exit For
  68.         End If
  69.     Next
  70.     dd0 = Mid(ylMd0, (AddDay - 1) * 2 + 1, 2)
  71.     mm0 = Mid(ylMn0, AddMonth, 1) + "月"
  72.     For i = 0 To 59
  73.         ganzhi(i) = Mid(ylTianGan0, (i Mod 10) + 1, 1) + Mid(ylDiZhi0, (i Mod 12) + 1, 1)
  74.     Next i
  75.     YLyear = ganzhi((AddYear - 4) Mod 60)
  76.     YLShuXing = Mid(ylShu0, ((AddYear - 4) Mod 12) + 1, 1)
  77.     If RunYue Then mm0 = "闰" & mm0
  78.     NongLi = "农历" & YLyear & "(" & YLShuXing & ")年" & mm0 & dd0
  79. aErr:
  80. End Function
  81. Private Function H2B(ByVal strHex As String) As String
  82.     Dim i As Integer, i1 As Integer, tmpV As String
  83.     Const hStr = "0123456789ABCDEF"
  84.     Const bStr = "0000000100100011010001010110011110001001101010111100110111101111"

  85.     tmpV = UCase(Left(strHex, 3))

  86.     For i = 1 To Len(tmpV)
  87.         i1 = InStr(hStr, Mid(tmpV, i, 1))
  88.         H2B = H2B & Mid(bStr, (i1 - 1) * 4 + 1, 4)
  89.     Next

  90.     H2B = H2B & Mid(strHex, 4, 2)

  91.     H2B = H2B & "0" & CStr(Val("&H" & Right(strHex, 2)))
  92. End Function
复制代码

引用单元格的效果

引用单元格的效果

直接常量的效果

直接常量的效果



最佳答案
2013-12-26 09:30
  1. =NongLi(TEXT("2013/12/24"+10,"e/m/d"))
复制代码
这样可以。
发表于 2013-12-26 09:23 | 显示全部楼层
参数是字符串,你用=nongli("2013-11-1")试试。
回复

使用道具 举报

 楼主| 发表于 2013-12-26 09:26 | 显示全部楼层
hwc2ycy 发表于 2013-12-26 09:23
参数是字符串,你用=nongli("2013-11-1")试试。

这个是可以的,但如果我想求N天后的农历,有时就要用到如这样的公式
  1. =nongli("2013-11-1"+10)
复制代码
这样的话,就又不能出结果了,那么应该如何修改才能兼容这样的格式

回复

使用道具 举报

发表于 2013-12-26 09:27 | 显示全部楼层
我这测试你的案例是对的了,直接引用单元格也好,都可以呀。
QQ截图20131226093020.jpg
回复

使用道具 举报

发表于 2013-12-26 09:27 | 显示全部楼层
返回空白的话只能说明传递的值不对。
回复

使用道具 举报

发表于 2013-12-26 09:28 | 显示全部楼层
蝶·舞 发表于 2013-12-26 09:26
这个是可以的,但如果我想求N天后的农历,有时就要用到如这样的公式这样的话,就又不能出结果了,那么应该 ...

数值加减后再转成日期格式。
回复

使用道具 举报

发表于 2013-12-26 09:30 | 显示全部楼层    本楼为最佳答案   
  1. =NongLi(TEXT("2013/12/24"+10,"e/m/d"))
复制代码
这样可以。
回复

使用道具 举报

发表于 2013-12-26 09:31 | 显示全部楼层
如果不用TEXT转,那就得单元格的格式是日期格式才成。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-26 18:07 , Processed in 0.746622 second(s), 9 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表