ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 计算24点的VBA程序

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-12-24 11:00 | 显示全部楼层 |阅读模式
想在网上找个“计算24点”的VBA程序,未果,于是自己编了一个。
参考了 CSDN 网站上一个C++计算24点的程序 https://blog.csdn.net/gxgdcyy/article/details/136046031


我的VBA只是一知半解的水平,把代码发出来也是抛砖引玉,欢迎大家指正。


首先编了一个“四则计算”的函数,包括  a+b、a-b、a*b、a/b、b-a、b/a 6种情况
  1. Public Function 四则计算(ByVal x As Double, ByVal y As Double, ByVal z As Integer) As Double
  2.     If x = 0 And y = 0 Then
  3.         四则计算 = Switch(z = 1, x + y)
  4.     ElseIf x = 0 Then
  5.         四则计算 = Switch(z = 1, x + y, z = 2, x - y, z = 3, x * y)
  6.     ElseIf y = 0 Then
  7.         四则计算 = Switch(z = 1, x + y, z = 3, x * y, z = 5, y - x)
  8.     Else
  9.         四则计算 = Switch(z = 1, x + y, z = 2, x - y, z = 3, x * y, z = 4, x / y, z = 5, y - x, z = 6, y / x)
  10.     End If
  11. End Function
复制代码


TA的精华主题

TA的得分主题

 楼主| 发表于 2024-12-24 11:02 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
然后把其他功能全部写在主程序里面了。(系统提示文字太长了,只能分成两段了)

Part 1:


  1. Sub 计算24点()

  2.     On Error Resume Next

  3.     Sheets(1).[c4].Clear

  4.     ' 先将4个数字排序、写入数组arr1
  5.     Dim dic_temp, arr(4), arr1(), str_temp As String
  6.    
  7.     Set dic_temp = CreateObject("scripting.dictionary") ' 创建一个字典,用来消除重复的排序
  8.    
  9.     arr(1) = Int(Sheets(1).[b4].Value)
  10.     arr(2) = Int(Sheets(1).[b5].Value)
  11.     arr(3) = Int(Sheets(1).[b6].Value)
  12.     arr(4) = Int(Sheets(1).[b7].Value)
  13.    
  14.     For i = 1 To 4
  15.         For j = 1 To 4
  16.             If i <> j Then
  17.                 For k = 1 To 4
  18.                     If k <> i And k <> j Then
  19.                         For l = 1 To 4
  20.                             If l <> i And l <> j And l <> k Then
  21.                            
  22.                                 ' 检查排序是否已经存在
  23.                                 str_temp = arr(i) & "," & arr(j) & "," & arr(k) & "," & arr(l)
  24.                                 
  25.                                 ' 如果不存在,则写入字典、数组
  26.                                 If Not dic_temp.exists(str_temp) Then
  27.                                     dic_temp(str_temp) = str_temp
  28.                                     r = r + 1
  29.                                     ReDim Preserve arr1(1 To 4, 1 To r)
  30.                                     
  31.                                     arr1(1, r) = arr(i)
  32.                                     arr1(2, r) = arr(j)
  33.                                     arr1(3, r) = arr(k)
  34.                                     arr1(4, r) = arr(l)
  35.                                 End If
  36.                                 
  37.                             End If
  38.                         Next
  39.                     End If
  40.                 Next
  41.             End If
  42.         Next
  43.     Next

  44.     ' 组合排序完成,为4行、r列

  45.     Dim a1 As Integer, a2 As Integer, a3 As Integer, a4 As Integer  ' 临时存储排序后的数据
  46.     Dim num1 As Double, num2 As Double, num3 As Double  ' 3次计算出来的结果
  47.     Dim ss1 As String, ss2 As String, ss3 As String  ' 用于存储计算中间过程
  48.    
  49.     ' 第一种情况:((a+b)+c)+d
  50.     For loop1 = 1 To UBound(arr1, 2)
  51.         For s1 = 1 To 6 ' 分别代表第一个 + - * /
  52.             num1 = 四则计算(arr1(1, loop1), arr1(2, loop1), s1)
  53.             
  54.             If Err <> 0 Then
  55.                 Err.Clear
  56.                 GoTo 100
  57.             End If
  58.             
  59.             If num1 < 0 Then GoTo 100
  60.             
  61.             For s2 = 1 To 6
  62.                 num2 = 四则计算(num1, arr1(3, loop1), s2)
  63.                
  64.                 If Err <> 0 Then
  65.                     Err.Clear
  66.                     GoTo 200
  67.                 End If
  68.                
  69.                 If num2 < 0 Then GoTo 200
  70.                
  71.                 For s3 = 1 To 6
  72.                     num3 = 四则计算(num2, arr1(4, loop1), s3)
  73.                     
  74.                     If Err <> 0 Then
  75.                         Err.Clear
  76.                         GoTo 300
  77.                     End If
  78.                     
  79.                     If num3 < 0 Then GoTo 300
  80.                     
  81.                     If Abs(num3 - 24) < 0.0001 Then
  82.                         a1 = arr1(1, loop1)
  83.                         a2 = arr1(2, loop1)
  84.                         a3 = arr1(3, loop1)
  85.                         a4 = arr1(4, loop1)
  86.                     
  87.                         ss1 = Switch(s1 = 1, a1 & "+" & a2, _
  88.                                         s1 = 2, a1 & "-" & a2, _
  89.                                         s1 = 3, a1 & "×" & a2, _
  90.                                         s1 = 4, a1 & "÷" & a2, _
  91.                                         s1 = 5, a2 & "-" & a1, _
  92.                                         s1 = 6, a2 & "÷" & a1)
  93.                         ss2 = Switch(s2 = 1, ss1 & "+" & a3, _
  94.                                         s2 = 2, ss1 & "-" & a3, _
  95.                                         s2 = 3 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0, "(" & ss1 & ")×" & a3, _
  96.                                         s2 = 3 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0, ss1 & "×" & a3, _
  97.                                         s2 = 4 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0, "(" & ss1 & ")÷" & a3, _
  98.                                         s2 = 4 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0, ss1 & "÷" & a3, _
  99.                                         s2 = 5 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0, a3 & "-(" & ss1 & ")", _
  100.                                         s2 = 5 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0, a3 & "-" & ss1, _
  101.                                         s2 = 6, a3 & "÷(" & ss1 & ")")
  102.                                        
  103.                         ' 根据不同的情况,添加括号
  104.                         ss3 = Switch(s3 = 1, ss2 & "+" & a4, _
  105.                                         s3 = 2, ss2 & "-" & a4, _
  106.                                         s3 = 3 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, "(" & ss2 & ")×" & a4, _
  107.                                         s3 = 3 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, ss2 & "×" & a4, _
  108.                                         s3 = 4 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, "(" & ss2 & ")÷" & a4, _
  109.                                         s3 = 4 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, ss2 & "÷" & a4, _
  110.                                         s3 = 5 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, a4 & "-(" & ss2 & ")", _
  111.                                         s3 = 5 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, a4 & "-" & ss2, _
  112.                                         s3 = 6, a4 & "÷(" & ss2 & ")")
  113.                                                 
  114.                         Sheets(1).[c4] = ss3 & "=24"
  115.                         
  116.                         Exit Sub
  117.                     End If
  118. 300
  119.                 Next
  120. 200
  121.             Next
  122. 100
  123.         Next
  124.     Next
复制代码


(未完,接下一段)

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-12-24 11:04 | 显示全部楼层
Part 2:

(接上一段)

  1.     ' 第二种情况:(a+b)+(c+d)
  2.     For loop1 = 1 To UBound(arr1, 2)
  3.         For s1 = 1 To 6 ' 分别代表第一个 + - * /
  4.             num1 = 四则计算(arr1(1, loop1), arr1(2, loop1), s1)
  5.             
  6.             If Err <> 0 Then
  7.                 Err.Clear
  8.                 GoTo 150
  9.             End If
  10.             
  11.             If num1 < 0 Then GoTo 150
  12.             
  13.             For s2 = 1 To 6
  14.                 num2 = 四则计算(arr1(3, loop1), arr1(4, loop1), s2)
  15.                
  16.                 If Err <> 0 Then
  17.                     Err.Clear
  18.                     GoTo 250
  19.                 End If
  20.                
  21.                 If num2 < 0 Then GoTo 250
  22.                
  23.                 For s3 = 1 To 6
  24.                     num3 = 四则计算(num1, num2, s3)
  25.                     
  26.                     If Err <> 0 Then
  27.                         Err.Clear
  28.                         GoTo 350
  29.                     End If
  30.                     
  31.                     If num3 < 0 Then GoTo 350
  32.                     
  33.                     If Abs(num3 - 24) < 0.0001 Then
  34.                         a1 = arr1(1, loop1)
  35.                         a2 = arr1(2, loop1)
  36.                         a3 = arr1(3, loop1)
  37.                         a4 = arr1(4, loop1)
  38.                     
  39.                         ss1 = Switch(s1 = 1, a1 & "+" & a2, _
  40.                                         s1 = 2, a1 & "-" & a2, _
  41.                                         s1 = 3, a1 & "×" & a2, _
  42.                                         s1 = 4, a1 & "÷" & a2, _
  43.                                         s1 = 5, a2 & "-" & a1, _
  44.                                         s1 = 6, a2 & "÷" & a1)
  45.                         ss2 = Switch(s2 = 1, a3 & "+" & a4, _
  46.                                         s2 = 2, a3 & "-" & a4, _
  47.                                         s2 = 3, a3 & "×" & a4, _
  48.                                         s2 = 4, a3 & "÷" & a4, _
  49.                                         s2 = 5, a4 & "-" & a3, _
  50.                                         s2 = 6, a4 & "÷" & a3)
  51.                                        
  52.                         ' 根据不同的情况,添加括号
  53.                         ss3 = Switch(s3 = 1, ss1 & "+" & ss2, _
  54.                                         s3 = 2 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, ss1 & "-(" & ss2 & ")", _
  55.                                         s3 = 2 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, ss1 & "-" & ss2, _
  56.                                         s3 = 3 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, "(" & ss1 & ")×(" & ss2 & ")", _
  57.                                         s3 = 3 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, "(" & ss1 & ")×" & ss2, _
  58.                                         s3 = 3 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, ss1 & "×(" & ss2 & ")", _
  59.                                         s3 = 3 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, ss1 & "×" & ss2, _
  60.                                         s3 = 4 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0, "(" & ss1 & ")÷(" & ss2 & ")", _
  61.                                         s3 = 4 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0, ss1 & "÷(" & ss2 & ")", _
  62.                                         s3 = 5 And (s1 - 1) * (s1 - 2) * (s1 - 5) = 0, ss2 & "-(" & ss1 & ")", _
  63.                                         s3 = 5 And (s1 - 1) * (s1 - 2) * (s1 - 5) <> 0, ss2 & "-" & ss1, _
  64.                                         s3 = 6 And (s2 - 1) * (s2 - 2) * (s2 - 5) = 0, "(" & ss2 & ")÷(" & ss1 & ")", _
  65.                                         s3 = 6 And (s2 - 1) * (s2 - 2) * (s2 - 5) <> 0, ss2 & "÷(" & ss1 & ")")
  66.                                                 
  67.                         Sheets(1).[c4] = ss3 & "=24"
  68.                         
  69.                         Exit Sub
  70.                     End If
  71. 350
  72.                 Next
  73. 250
  74.             Next
  75. 150
  76.         Next
  77.     Next
  78.    

  79.     Sheets(1).[c4] = "无法计算出24!"

  80. End Sub
复制代码



这样就完成了,在B4~B7单元格中输入4个数字,在C4单元格中给出“计算24点”的算式。

TA的精华主题

TA的得分主题

发表于 2024-12-24 19:58 | 显示全部楼层
不错的东东,感觉任何4个数都能有结果。

TA的精华主题

TA的得分主题

发表于 2024-12-24 20:15 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
其实负数也能计算,楼主干么要避开负数呢?

4788b491-b460-48eb-b60d-8bc0db6fe456.png

TA的精华主题

TA的得分主题

发表于 2024-12-24 20:19 | 显示全部楼层
我个人感觉if err语句没必要用,完全可以用On Error Resume Next代替。

goto语句都可以不用的。
我屏蔽掉这些语句,代码照样正常运行的。

4772244e-d726-4659-b6d6-9bfe15aa87a9.png

TA的精华主题

TA的得分主题

发表于 2024-12-24 22:17 | 显示全部楼层
如果是用扑克牌,那数字就是1~13的范围内。4张牌全部可能性组合应该是不到2000种?然后每一种4张牌组合,算出一种计算式结果,做成数据库,用查表法就省事多了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-25 03:25 , Processed in 0.039397 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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