ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 8242|回复: 38

[Excel 程序开发] [第53期]EXCEL26进制来回转换 ---------已结

[复制链接]

TA的精华主题

TA的得分主题

发表于 2009-9-17 10:13 | 显示全部楼层 |阅读模式
前几天有会员把清风版主4年前老贴翻了上来。
将数字转化为字符26进制(以A-Z表示)的自定义函数http://club.excelhome.net/thread-89959-1-2.html
这对VBA的用户来说是很有吸引力的,把它改编扩展作为本期竞赛题。
清风版主的代码如下:请复制以便验证

  1. Function NumToChar_26(Num As Double) as string
  2.     Dim iMod As Integer, dInt As Double, sChar As String
  3.     'Application.Volatile
  4.     iMod = Num Mod 26
  5.     dInt = Num \ 26
  6.     If iMod > 0 Then
  7.         sChar = Split(Columns(iMod).Address(0, 0), ":")(0)
  8.     ElseIf dInt > 0 Then
  9.         dInt = dInt - 1
  10.         sChar = "Z"
  11.     End If
  12.     Do While dInt > 0
  13.         iMod = dInt Mod 26
  14.         dInt = dInt \ 26
  15.         If iMod > 0 Then
  16.             sChar = Split(Columns(iMod).Address(0, 0), ":")(0) & sChar
  17.         ElseIf dInt > 0 Then
  18.             dInt = dInt - 1
  19.             sChar = "Z" & sChar
  20.         End If
  21.     Loop
  22.     NumToChar_26 = sChar
  23. End Function
复制代码
题目1:1分
请编写反向函数 例如把 IV 转化成 256, XFD转换为16384。
答题 统一格式如下

  1. Function N2Char26R(ByVal L As String)  As Double
  2. '你的代码 要求EXCEL2003下可运行
  3. '要求不仅限于 2003的IV(256) 和 2007 的XFD(16384列)
  4. '具体要求请运行 验证1
  5. End Function
  6. Sub 验证1()
  7.     Dim x As Double, y As Double, z As Double, s As String, v As Byte
  8.     On Error Resume Next
  9.     x = 2147483647      '(不考虑小数 负数 和 0)
  10.     s = NumToChar_26(x)
  11.     y = N2Char26R(s)
  12.     z = N2Char26R("fywmusmjify")
  13.     If y = x Then v = 1
  14.     If z = 987654321012345# And v = 1 Then v = 2
  15.    
  16.     If v = 2 Then
  17.         MsgBox "正确,可得1分"
  18.     ElseIf v = 1 Then
  19.         MsgBox "代码需要调试。可得0.5分,视最后得分是否< 1 取舍。"
  20.     Else
  21.         MsgBox "错误,继续努力"
  22.     End If
  23. End Sub
复制代码
题目2: 1-2分
NumToChar_26 函数毕竟是 清风版主4年前的代码,我们还有优化的空间。
NumToChar_26 转换最大值就是 验证1 里的 2147483647 ,
编写函数以实现可以转换大于2147483647 的数,并且尝试提速
函数统一格式如下:

  1. Function N2Char26(ByVal L as  Double) As String
  2. '你的代码 要求EXCEL2003下可运行
  3. '具体要求请运行 验证2
  4. End Function
  5. Sub 验证2()
  6.     Dim x As Double, y As Double, s1 As String, s2 As String
  7.     x = 2147483647   '(不考虑小数 负数 和 0)
  8.     y = x * 10
  9.     t = Timer
  10.     Const runtm = 10000
  11.     On Error GoTo 111
  12.     For i = 1 To runtm
  13.         s1 = NumToChar_26(x)
  14.     Next
  15.     tm1 = Timer - t '  大约 1 秒钟
  16.     t = Timer
  17.     For i = 1 To runtm
  18.         s2 = N2Char26(y)
  19.     Next
  20.     tm2 = Timer - t
  21.     If s2 = "BQMKIGNV" Then
  22.         MsgBox "结果正确,可得1分"
  23.     Else
  24.         MsgBox "结果错误, 不得分"
  25.         Exit Sub
  26.     End If
  27.     If tm2 * 2 < tm1 Then
  28.         MsgBox tm1 & "  " & tm2 & " 速度达标,可再得1分"
  29.     Else
  30.         MsgBox tm1 & "  " & tm2 & " 太慢了,继续努力"
  31.     End If
  32. Exit Sub
  33. 111
  34. MsgBox "运行错误, 不得分"
  35. End Sub
复制代码
全部验证通过可得3分。
答题者请跟帖占位,跟帖中不要出现与题目相关的内容,否则不予评分。
截止日期 2009-10-20 以发邮件时间为准。
答案请按如下格式发送到邮箱 26258103@163.com (不需要附件,纯文字即可)

邮件主题: VBA53期答案
邮件内容:

  1. '论坛ID:xxxxxxx  
  2. Function N2Char26R(ByVal L As String)  As Double
  3. '你的代码 要求EXCEL2003下可运行
  4. End Function

  5. Function N2Char26(ByVal L as  Double) As String
  6. '你的代码 要求EXCEL2003下可运行

  7. End Function
复制代码
临近国庆中秋长假8天,所以提前出题,分也比较好得。
此题说难不难,说易不易。
说不难是因为用不到高深生僻的语句,仅仅是数字和字符串操作,初学者也有机会得分。
说不易是因为要得全分就要对VBA 操作符的限制有一定的了解,以及代码优化的经验。

答题愉快,节日快乐。


参考答案:

  1. 'ID :LDY
  2. Function N2Char26(ByVal L As Double) As String
  3.     Do While L > 0
  4.         N2Char26 = Chr(L - Int(L / (26.0000000000001)) * 26 + 64) & N2Char26
  5.         L = Int(L / (26.0000000000001))
  6.     Loop
  7. End Function
  8. Function N2Char26(ByVal L As Double) As String '第二版本,稍微慢一点,便于和玩转N进制比较
  9.     Const Jzs As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  10.     Do
  11.         N2Char26 = Mid(Jzs, L - Int(L / 26.0000000000001) * 26, 1) & N2Char26
  12.         L = Int(L / (26.0000000000001))
  13.     Loop While L > 0
  14. End Function
  15. Function N2Char26R(ByVal L As String) As Double
  16.     L = UCase(L)
  17.     For i% = 1 To Len(L)
  18.         N2Char26R = N2Char26R + (Asc(Mid(L, i)) - 64) * 26 ^ (Len(L) - i)
  19.     Next
  20. End Function
复制代码

结贴 http://club.excelhome.net/viewthread.php?tid=484032&page=4#pid3244334

[ 本帖最后由 ldy 于 2009-10-22 15:11 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-9-17 20:02 | 显示全部楼层
请刘版查收.审核

您的邮件已发送
此邮件发送成功,并已保存到“已发送”文件夹。


刘版 能否结出 参赛者 的运行速度



  1. '论坛ID:泓()  OK  +3
  2. Function N2Char26(ByVal L As Double) As String
  3.     Dim a() As Byte, i As Long, v As Double, s As String
  4.     For i = 1 To 10000
  5.         ReDim Preserve a(1 To i)
  6.         v = Int(L / 26 ^ (i - 1))
  7.         If v > 26 Then
  8.             a(i) = v - Int(v / 26) * 26
  9.             If a(i) = 0 Then a(i) = 26
  10.             L = L - a(i) * 26 ^ (i - 1)
  11.         Else
  12.             a(i) = v
  13.             Exit For
  14.         End If
  15.     Next
  16.     For i = 1 To UBound(a)
  17.         s = Chr(a(i) + 64) & s
  18.     Next
  19.     N2Char26 = s
  20. End Function
  21. Function N2Char26R(ByVal L As String) As Double
  22.     Dim n As Long, i As Long, v As Double
  23.     n = Len(L)
  24.     If n = 0 Then Exit Function
  25.     L = UCase(L)
  26.     ReDim a(1 To n)
  27.     For i = 1 To n
  28.         a(i) = Asc(Mid(L, i, 1)) - 64
  29.         v = a(i) * 26 ^ (n - i) + v
  30.     Next
  31.     N2Char26R = v
  32. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:42 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-9-18 08:13 | 显示全部楼层
占位


  1. '论坛ID:Zhoukick   26的整倍数未通过验证 错误(26=AZ ?)  Z = 0  ? ,不得分 谢谢参与
  2. Function N2Char26R(ByVal L As String) As Double
  3. '你的代码 要求EXCEL2003下可运行
  4.     Dim N As Double, J As Double, P As Integer
  5.     J = 1
  6.     L = UCase(L)
  7.     For i = Len(L) To 1 Step -1
  8.         P = Asc(Mid(L, i, 1)) - 64
  9.         If P = 26 Then P = 0
  10.         N = N + P * J
  11.         J = J * 26
  12.     Next
  13.     N2Char26R = N
  14. End Function
  15. Function N2Char26(ByVal L As Double) As String
  16.     '你的代码 要求EXCEL2003下可运行
  17.     Dim X As Double, P As Integer, S As String
  18.     While L > 0
  19.         X = Int(L / 26)
  20.         P = L - X * 26
  21.         L = X
  22.         If P = 0 Then P = 26
  23.         P = P + 64
  24.         S = Chr(P) & S
  25.     Wend
  26.     N2Char26 = S
  27. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:44 编辑 ]

TA的精华主题

TA的得分主题

发表于 2009-9-18 09:07 | 显示全部楼层
邮件已发送,请斑竹查收



  1. '论坛ID:formatd  26的整倍数未通过验证  错误(52=BZ ?) ,1 分
  2. Function N2Char26R(ByVal L As String) As Double
  3. '你的代码 要求EXCEL2003下可运行
  4. '要求不仅限于 2003的IV(256) 和 2007 的XFD(16384列)
  5. '具体要求请运行 验证1
  6.     Dim v As Double
  7.     L = UCase(L)
  8.     For i = 1 To Len(L)
  9.         v = v * 26 + Asc(Mid(L, i, 1)) - 64
  10.     Next i
  11.     N2Char26R = v
  12. End Function
  13. Function N2Char26(ByVal L As Double) As String
  14. '你的代码 要求EXCEL2003下可运行
  15. ' 简单递归代替循环方式-ldy
  16. Dim iMod As Integer, s As String, is26 As Integer, iDiv as Double
  17.     If L <= 26 Then
  18.         N2Char26 = Chr(L + 64)
  19.     Else
  20.         iDiv = CLng(L / 26 - 0.5)
  21.         iMod = L - iDiv * 26
  22.         is26 = Int(iMod = 26)
  23.         s = IIf(iMod = 0, "Z", Chr(64 + iMod))
  24.         N2Char26 = N2Char26(iDiv - is26) & s
  25.     End If
  26. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:45 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-9-18 15:08 | 显示全部楼层
邮件已发送,请版主查阅.


  1. '【alzeng】  ok  26的整倍数未通过验证 (26=A@ ?) ,1 分
  2. Function N2Char26R(ByVal L$) As Double
  3.     Dim i As Byte, str$

  4.     str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  5.     L = UCase(L)
  6.     N2Char26R = InStr(str, Right(L, 1))
  7.     If Len(L) > 1 Then
  8.         For i = 1 To Len(L) - 1
  9.             N2Char26R = N2Char26R + InStr(str, Mid(L, i, 1)) * 26 ^ (Len(L) - i)
  10.         Next
  11.     End If
  12. End Function
  13. Function N2Char26(ByVal L#) As String '26的整倍数补答通过验证  
  14.     Dim i, k, Arr
  15.     i = 0
  16.     L = L / 10

  17.     Do Until 26 ^ i / 10 > L
  18.         i = i + 1
  19.     Loop

  20.     ReDim Arr(i)
  21.     Arr(1) = (L + 0.01 - Int((L + 0.01) / 2.6) * 2.6) * 10
  22.     For k = 2 To i
  23.         Arr(k) = Int(L * 10 / 26 ^ (k - 1)) Mod 26
  24.     Next

  25.     For k = 1 To i
  26.         If k < i And Arr(k) < 1 Then Arr(k) = Arr(k) + 26: If k < i Then Arr(k + 1) = Arr(k + 1) - 1
  27.         N2Char26 = IIf(Arr(k) < 1, "", Chr(64 + Arr(k))) & N2Char26
  28.     Next
  29. End Function
  30. Function N2Char26(ByVal L#) As String  '26的整倍数未通过验证 (26=A@ ?)
  31.     Dim str$, i As Byte, k As Byte
  32.     str = "ZABCDEFGHIJKLMNOPQRSTUVWXYZ"

  33.     i = 0
  34.     L = L / 10
  35.     Do Until 26 ^ i / 10 >= L
  36.         i = i + 1
  37.     Loop

  38.     N2Char26 = Mid(str, ((L - Int(L / 2.6) * 2.6) * 10 Mod 26) + 1, 1)
  39.     If i > 1 Then
  40.         L = Int(L / 2.6) * 2.6
  41.         For k = 2 To i
  42.             N2Char26 = Mid(str, Int(L * 10 / 26 ^ (k - 1)) Mod 26 + 1, 1) & N2Char26
  43.             L = L - 26 ^ (k - 1) / 10
  44.         Next
  45.     End If
  46. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:46 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-9-18 15:57 | 显示全部楼层
邮件已发送,请版主审查,第一次参加竞赛,心情老激动了。

哦,刚才贴了附件,谢谢楼上哥们提醒,好像不能发附件的哈。。不好意思,不好意思



  1. '论坛ID:zm0115 26的整倍数未通过验证 (26=A@ ?) ,1 分
  2. Function N2Char26R(ByVal L As String) As Double
  3. Dim num As Double, k As Byte, n As Byte
  4. For n = 1 To Len(L)
  5.     k = Asc(UCase(Mid(L, n, 1))) - 64
  6.     num = num + k * 26 ^ (Len(L) - n)
  7. Next
  8. N2Char26R = num
  9.    
  10. End Function
  11. Function N2Char26(ByVal L As Double) As String
  12. Dim iMod As Integer, dInt As Double, sChar As String, k As Byte
  13.   
  14.     iMod = Int(WorksheetFunction.Log(L, 26))
  15.    
  16.     For x = iMod To 0 Step -1
  17.         k = Int(L / 26 ^ x)
  18.         L = L - k * 26 ^ x
  19.         sChar = sChar & Chr(k + 64)
  20.     Next
  21.    
  22.     N2Char26 = sChar
  23. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:47 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-9-18 16:59 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-9-18 19:07 | 显示全部楼层
占位~邮件已发请版主查收!!

收到。 ldy




  1. '论坛ID:shuts32  OK  + 3  用chr可以简化select

  2. Function N2Char26R(ByVal L As String) As Double
  3. '你的代码 要求EXCEL2003下可运行
  4. '要求不仅限于 2003的IV(256) 和 2007 的XFD(16384列)
  5. '具体要求请运行 验证1
  6.     Dim LenL As Long, i As Long, n2char As Double
  7.     Dim j As String
  8.     LenL = Len(L)
  9.     i = 1
  10.     Do While i <= Len(L)
  11.     j = Mid(L, i, 1) & ":" & Mid(L, i, 1)
  12.     n2char = n2char + Columns(j).Column * 26 ^ (LenL - 1)
  13.     LenL = LenL - 1
  14.     i = i + 1
  15.     Loop
  16.     N2Char26R = n2char
  17. End Function



  18. Function N2Char26(ByVal L As Double) As String
  19. '你的代码 要求EXCEL2003下可运行
  20. '具体要求请运行 验证2
  21. Dim iMod As Integer, dInt As Double, sChar As String
  22.     'Application.Volatile
  23.     iMod = L - Int(L / 26) * 26
  24.     dInt = Int(L / 26)
  25.     Do
  26.         Select Case iMod
  27.             Case 1
  28.             sChar = "A" & sChar
  29.             Case 2
  30.             sChar = "B" & sChar
  31.             Case 3
  32.             sChar = "C" & sChar
  33.             Case 4
  34.             sChar = "D" & sChar
  35.             Case 5
  36.             sChar = "E" & sChar
  37.             Case 6
  38.             sChar = "F" & sChar
  39.             Case 7
  40.             sChar = "G" & sChar
  41.             Case 8
  42.             sChar = "H" & sChar
  43.             Case 9
  44.             sChar = "I" & sChar
  45.             Case 10
  46.             sChar = "J" & sChar
  47.             Case 11
  48.             sChar = "K" & sChar
  49.             Case 12
  50.             sChar = "L" & sChar
  51.             Case 13
  52.             sChar = "M" & sChar
  53.             Case 14
  54.             sChar = "N" & sChar
  55.             Case 15
  56.             sChar = "O" & sChar
  57.             Case 16
  58.             sChar = "P" & sChar
  59.             Case 17
  60.             sChar = "Q" & sChar
  61.             Case 18
  62.             sChar = "R" & sChar
  63.             Case 19
  64.             sChar = "S" & sChar
  65.             Case 20
  66.             sChar = "T" & sChar
  67.             Case 21
  68.             sChar = "U" & sChar
  69.             Case 22
  70.             sChar = "V" & sChar
  71.             Case 23
  72.             sChar = "W" & sChar
  73.             Case 24
  74.             sChar = "X" & sChar
  75.             Case 25
  76.             sChar = "Y" & sChar
  77.             Case 0
  78.             sChar = "Z" & sChar
  79.             dInt = dInt - 1
  80.         End Select
  81.         If dInt = 0 Then Exit Do
  82.         iMod = dInt - Int(dInt / 26) * 26
  83.         dInt = Int(dInt / 26)
  84.     Loop
  85.     N2Char26 = sChar
  86. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:48 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-9-19 11:27 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
邮件发送成功!·邮件已通过卡巴斯基杀毒引擎扫描
·邮件已经自动保存到“已发送”文件夹 [取消自动保存]





  1. 'ID:zldccmx  26的整倍数未通过验证    +1
  2.       '撰写:老朽
  3.       '网址:http://Club.ExcelHome.net
  4.       '日期:2009-9-19 上午 11:18:59
  5. Function N2Char26R(ByVal L As String ) As Double
  6. '你的代码 要求EXCEL2003下可运行
  7. '要求不仅限于 2003的IV(256) 和 2007 的XFD(16384列)
  8. '具体要求请运行 验证1
  9.     For i = 1 To Len(L)
  10.         N2Char26R = N2Char26R + Cells(1, Mid(L, i, 1)).Column * (26 ^ (Len(L) - i))
  11.     Next
  12. End Function

  13.       '撰写:老朽
  14.       '网址:http://Club.ExcelHome.net
  15.       '日期:2009-9-19 上午 11:18:59
  16. Function N2Char26(ByVal L As Double ) As String
  17. '你的代码 要求EXCEL2003下可运行
  18. '具体要求请运行 验证2
  19.     Arr = Array("Z", "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")
  20.     Do While L > 26
  21.         J = Int(L / 26): K = L - J * 26: L = J
  22.         N2Char26 = Arr(K) & N2Char26
  23.     Loop
  24.     N2Char26 = Arr(L) & N2Char26
  25. End Function
复制代码




收到 --ldy

[ 本帖最后由 ldy 于 2009-10-21 16:50 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-9-19 12:29 | 显示全部楼层
很久没有做竞赛题了,看起来这个简单一些,来试试。
邮件已发送,请刘版查收,多谢。



收到 --ldy



  1. '论坛ID: winland  26的整倍数未通过验证   +1
  2. Function N2Char26R(ByVal L As String) As Double
  3. '你的代码 要求EXCEL2003下可运行
  4.     Dim i As Integer, iLen As Integer
  5.     iLen = Len(L)
  6.     For i = 1 To iLen
  7.         N2Char26R = N2Char26R + (Asc(UCase(Mid(L, i, 1))) - 64) * (26 ^ (iLen - i))
  8.     Next i
  9. End Function
  10. Function N2Char26(ByVal L As Double) As String
  11. '你的代码 要求EXCEL2003下可运行
  12.     Dim iLen As Integer, iTemp As Integer, dTemp As Double
  13.     iLen = Int(Log(L) / Log(26))
  14.     dTemp = L
  15.     For i = iLen To 1 Step -1
  16.         iTemp = Int(dTemp / (26 ^ i))
  17.         dTemp = dTemp - iTemp * 26 ^ i
  18.         N2Char26 = N2Char26 & Chr(iTemp + 64)
  19.     Next i
  20.     N2Char26 = N2Char26 & Chr(dTemp + 64)
  21. End Function
复制代码

[ 本帖最后由 ldy 于 2009-10-21 16:51 编辑 ]

评分

1

查看全部评分

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

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-26 20:41 , Processed in 0.053937 second(s), 20 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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