ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[Excel 函数与公式] [第62期]计算乒乓球排名。(分数统计表已出,请大家检查是否有误。)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2010-7-29 11:22 | 显示全部楼层
原帖由 feipeng1 于 2010-7-29 09:33 发表


乒乓球规则是胜一场积2分 ,负一场积一分,弃权0分,被弃权方按比赛赛制(五局三胜/三局二胜/七局四胜)分别以3:0,2:0,4:0计算.

这次所有的公式都需要单无格内有数据时才能进行正确计算.倒是用if函数对单无格数据进 ...

==============================
按这种说法积分应该用函数先求出,我还是支持用补助列的方法,可以提高excel的运行速度,以实用为主。平时竞赛题提倡不用补助列,本人认为不实用,但他对提高函数水平很有帮助。

TA的精华主题

TA的得分主题

发表于 2010-7-29 13:38 | 显示全部楼层

feipeng1 或许梦寐以求的效果 我只是用VBA去实现她


  1. Sub aSort()
  2.     Dim r As Range, d As Object
  3.     a = Cells(1, 1).End(xlDown).Row - 1
  4.     ReDim jf(1 To a), fb(1 To a, 1 To 2), rr(1 To a, 1 To 2), tmp(1 To a)
  5.     Set d = CreateObject("scripting.dictionary")

  6.     For i = 1 To a
  7.         Set r = Cells(i + 1, 2).Resize(1, a)
  8.         f = 0: b0 = 0: b1 = 0
  9.         For Each c In r
  10.             If InStr(c, ":") Then
  11.                 v0 = Val(Split(c, ":")(0)): v1 = Val(Split(c, ":")(1))
  12.                 b0 = b0 + v0: b1 = b1 + v1
  13.                 If v0 > v1 Then
  14.                     f = f + 2
  15.                 ElseIf v0 < v1 Then
  16.                     f = f + 1
  17.                 End If
  18.             End If
  19.         Next
  20.         jf(i) = f: fb(i, 2) = b0 / IIf(b1 = 0, 1, b1)
  21.         If Not d.exists(f) Then d(f) = i Else d(f) = d(f) & " " & i
  22.     Next

  23.     k = d.keys: t = d.items
  24.     For i = 0 To d.Count - 1
  25.         it = Split(t(i))
  26.         If UBound(it) > 0 Then
  27.             For y = 0 To UBound(it)
  28.                 b0 = 0: b1 = 0
  29.                 For x = 0 To UBound(it)
  30.                     c = Cells(it(y) + 1, 1).Offset(0, it(x))
  31.                     If InStr(c, ":") Then
  32.                         b0 = b0 + Val(Split(c, ":")(0))
  33.                         b1 = b1 + Val(Split(c, ":")(1))
  34.                     End If
  35.                 Next
  36.                 fb(it(y), 1) = b0 / IIf(b1 = 0, 1, b1)
  37.             Next
  38.         End If
  39.     Next

  40.     For i = 1 To a
  41.         tmp(i) = jf(i) * 10000 + fb(i, 1) * 1
  42.     Next
  43.     St = bSort(tmp, False)
  44.     For i = 1 To a
  45.         tmp(i) = St(i) * 10000 + fb(i, 2) * 1
  46.     Next
  47.     St = bSort(tmp, True)
  48.     For i = 1 To a
  49.         rr(i, 1) = jf(i)
  50.         rr(i, 2) = St(i)
  51.     Next
  52.     Cells(2, a + 2).Resize(a, 2) = rr
  53. set r=nothing
  54. set d=nothing
  55. End Sub


  56. Private Function bSort(arry(), bl As Boolean)
  57.     ub = UBound(arry)
  58.     ReDim tmp(1 To ub), temp(1 To ub), t(1 To ub)
  59.     For i = 1 To ub
  60.         If bl = False Then
  61.             tmp(i) = WorksheetFunction.Small(arry, i)
  62.         Else
  63.             tmp(i) = WorksheetFunction.Large(arry, i)
  64.         End If
  65.         temp(i) = i
  66.         If i > 1 Then
  67.             If tmp(i) = tmp(i - 1) Then temp(i) = temp(i - 1)
  68.         End If
  69.     Next
  70.     For i = 1 To ub
  71.         n = WorksheetFunction.Match(arry(i), tmp, 0)
  72.         t(i) = temp(n)
  73.     Next
  74.     bSort = t
  75. End Function


  76. Private Sub Worksheet_Change(ByVal Target As Range)
  77.     a = Cells(1, 1).End(xlDown).Row
  78.     If Target.Row <= a And Target.Column <= a Then
  79.         If InStr(Target, ":") Then
  80.             Cells(Target.Column, Target.Row) = Split(Target, ":")(1) & ":" & Split(Target, ":")(0)
  81.             Call aSort
  82.         End If
  83.     End If

  84. End Sub
复制代码

[ 本帖最后由 泓() 于 2010-7-29 14:08 编辑 ]

本帖子中包含更多资源

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

x

TA的精华主题

TA的得分主题

发表于 2010-7-29 18:27 | 显示全部楼层
如果说速度稍慢些 主要慢在工作表函数排序上
而且我采用了2次排序(只有经过2次排序才是正确的答案)

如果 vba 又引用原本函数公式的那样做 可快些
但我不那样做
因为应付 这么些数据 目前的代码足已

TA的精华主题

TA的得分主题

发表于 2010-7-29 18:04 | 显示全部楼层
没有辅助列
VBA代码还可以的
速度是过得去的
喜不喜欢当然由你
权当练习 谢谢提供题目

这题就是当作ExcelVBA竞赛题 也要喘口气的

TA的精华主题

TA的得分主题

发表于 2010-7-29 17:43 | 显示全部楼层
原帖由 泓() 于 2010-7-29 13:38 发表

Sub aSort()
    Dim r As Range, d As Object
    a = Cells(1, 1).End(xlDown).Row - 1
    ReDim jf(1 To a), fb(1 To a, 1 To 2), rr(1 To a, 1 To 2), tmp(1 To a)
    Set d = CreateObject("scripting. ...



谢谢泓 的程序.
刚试用过,程序速度占用Cpu过高,还有溢出堆栈空间.在复制数据时会出错.
Vba不太懂,这些天倒是天天泡在一些实例上慢慢研究.估计弄懂这个还需时日.
如果鸿兄有空还请完善下这个程序.权当练手.

另外可能在一张表格内小组可能会有四个或者更多小组,程序移植是否能顺下复制倒不清楚.
个人感觉代码有些长,有公式300多字符,如果用Vba更为冗长还不如直接用公式.

我的思路可能是这样,只对积分相同选手之间的胜率进行操作,而不作过多的参数,
对Vba纯属没基本,权当瞎扯.

TA的精华主题

TA的得分主题

发表于 2010-7-29 19:57 | 显示全部楼层
原帖由 泓() 于 2010-7-29 18:04 发表
没有辅助列
VBA代码还可以的
速度是过得去的
喜不喜欢当然由你
权当练习 谢谢提供题目

这题就是当作ExcelVBA竞赛题 也要喘口气的



谢谢,非喜欢不喜欢,能够帮忙的就是好同志.HOHO,欢迎到成都来作客.
我运行的时候出现过好几次错误,可能是检查或者要求的比较严.

TA的精华主题

TA的得分主题

发表于 2010-7-29 20:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
胡闹
其实你一点都不懂VBA
复制时出错我明白在哪里
其它的不出一个问题
你说说还有错在哪里?

TA的精华主题

TA的得分主题

发表于 2010-7-29 20:46 | 显示全部楼层
原帖由 泓() 于 2010-7-29 20:06 发表
胡闹
其实你一点都不懂VBA
复制时出错我明白在哪里
其它的不出一个问题
你说说还有错在哪里?



我本来就不懂的呀. 删除时也会出错.还有次是出现溢出.我只是说说而已.
软件有Bug很正常的呀,有则过之,无则加冕.

你水平比我高,但我确实是在实际中确实会出现了这样的问题.

TA的精华主题

TA的得分主题

发表于 2010-7-29 20:49 | 显示全部楼层

本帖子中包含更多资源

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

x

TA的精华主题

TA的得分主题

发表于 2010-7-29 22:53 | 显示全部楼层
当出现如上楼对话框时,单击调试

就可以发现 出错在哪一句:这个很重要

在复制时 出错在“If InStr(Target, ":") Then” 主要是在选择时 并不在一个单元格,可以这样修改:
Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Count > 1 Then Exit Sub'加这句就行了
    a = Cells(1, 1).End(xlDown).Row
    If Target.Row <= a And Target.Column <= a Then
        If InStr(Target, ":") Then
            Cells(Target.Column, Target.Row) = Split(Target, ":")(1) & ":" & Split(Target, ":")(0)
            Call aSort
        End If
    End If

End Sub

----------------------------------------------
VBA错误信息:堆栈空间溢出(错误 28)

堆栈是内存的一个工作区,会随着程序运行的需要而增长或缩小。此错误有以下的原因和解决方法:

有太多活动的Function、Sub或Property过程调用。
检查过程的嵌套是否太深,尤其是递归过程,即自己调用自己的过程。确保递归能终止,使用“调用”对话框来查看活动的过程 (在堆栈上)。

本地变量需要更多可用的本地变量空间。
试着在模块级别中声明某些变量。可以在静态过程,即在Property、Sub或Function关键字前加上Static,声明所有变量,或可以在过程内使用Static语句来声明各个Static变量。

有太多定长字符串。
定长字符串在过程中可快速访问,比可变长度字符串使用更多堆栈空间,因为字符串数据本身要放在堆栈上。可试着重新定义一些定长字符串成为变长字符串。当声明一变长字符串时,只有字符串描述符 (非数据本身) 会放在堆栈上。可以在没有堆栈空间的模块层次上定义字符串。在模块层次申明变量是缺省为Public,所以在模块上所有过程皆可见到字符串。

DoEvents函数调用的嵌套太多。
利用“调用”对话框,在堆栈上查看正在活动的过程。

代码引起了事件层叠。
所谓事件层叠就是引起一个事件,此事件会调用已在堆栈上的事件过程。事件层叠和不能中止的递归过程调用是相似的,但不太明显,因为是由 Visual Basic 所调用,而不是在代码中调用。使用“调用”对话框来查看那些正在活动的过程 (在堆栈上)。

显示“调用”对话框,在“调试”窗口中选取过程框右边的“调用”按钮或选择“调用”命令。详细信息,可选取有问题的项目,并按下 F1 (在Windows中)或HELP(在Macintosh中)键

修改了bSort 中的变量
Private Function bSort(arry, bl As Boolean)
    ub = UBound(arry)
    ReDim tmp2(1 To ub), temp(1 To ub), tt(1 To ub)
    For i = 1 To ub
        If bl = False Then
            tmp2(i) = WorksheetFunction.Small(arry, i)
        Else
            tmp2(i) = WorksheetFunction.Large(arry, i)
        End If
        temp(i) = i
        If i > 1 Then
            If tmp2(i) = tmp2(i - 1) Then temp(i) = temp(i - 1)
        End If
    Next
    For i = 1 To ub
        n = WorksheetFunction.Match(arry(i), tmp2, 0)
        tt(i) = temp(n)
    Next
    bSort = tt
End Function

这样是否还有出现问题
---------------------------------------
另外 本想 做一个工作表中可以支持多组
因为 你不太喜欢用VBA来计算
话语中 并不尊重VBA

如果有需要的话 当然可以继续 如果需要的话

[ 本帖最后由 泓() 于 2010-7-29 23:26 编辑 ]
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-28 05:08 , Processed in 0.034295 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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