用Excel辅助做数独

news2024/10/7 14:23:22

做数独游戏的时候,画在纸上很容易弄花眼,所以我考虑用Excel辅助做一个。
界面如下:
在这里插入图片描述
按下初始化表格区域按钮,会在所有单元格中填充“123456789”。如下图:
在这里插入图片描述
当某个单元格删除得只剩一个数字时,会将同一行、同一列和同一区域的其它单元格中的相同数字删除。如下图:
在这里插入图片描述
实现上述效果的VBA如下:
1、初始化按钮的代码:

Sub startup_Click()
    Dim row%, col%
    For row = 1 To 9
        For col = 1 To 9
            Cells(row, col) = "'123456789"
        Next
    Next
End Sub

以上代码仅仅简单遍历相关单元格并填充字符串。
实现自动删除关联单元格中的数字的功能的代码放在工作表的Worksheet_Change事件中,这样,只要修改相关游戏区域中的单元格,就会自动执行检查并删除有关数字。代码如下:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim row%, col%, changeRow%, changeCol%, rngRow%, rngCol%, txt$
    changeRow = Target.row
    changeCol = Target.Column
    
    '记录刚修改单元格的内容
    txt = Cells(changeRow, changeCol)
    
    '如果刚修改的单元格只剩下一个数字,则执行自动消除
    If Len(txt) = 1 Then
        '防止修改单元格内容时工作表改变事件被循环触发
        Application.EnableEvents = False
        
        '确定同一区域单元格第一行行号
        If changeRow < 4 Then
            rngRow = 1
        ElseIf changeRow > 6 Then
            rngRow = 7
        Else
            rngRow = 4
        End If
        '确定同一区域单元格第一列列号
        If changeCol < 4 Then
            rngCol = 1
        ElseIf changeCol > 6 Then
            rngCol = 7
        Else
            rngCol = 4
        End If
 
        '将同一行、列及区域单元格中相关的数字删除
        For row = 1 To 9
            For col = 1 To 9
                If row = changeRow Or col = changeCol Or (row >= rngRow And row < rngRow + 3 _
                            And col >= rngCol And col < rngCol + 3) Then
                    Cells(row, col) = Replace(Cells(row, col), txt, "")
                End If
            Next
        Next
        Cells(changeRow, changeCol) = txt
        '恢复事件处理以继续响应工作表改变事件
        Application.EnableEvents = True
    End If
End Sub

下面再附上一个用VBA做数独的程序,不过没有优化:

Sub VBA做数独()
    Dim targetRegion As String
    Dim origStr, tmpStr, tStr As String
   'i, j, r, c, tmpr, tmpc, tr, 用于遍历表格
    'stackR为堆栈指针
    Dim i, j, r, c, tmpr, tmpc, tr, tc, tmpLen, targetRow, targetCol, stackR As Integer

    Dim change As Boolean
    Dim startTime, endTime As Date

   startTime = Now()
   origStr = "1,2,3,4,5,6,7,8,9"
   targetRegion = "A1:I9"
   stackR = 1
   Application.ScreenUpdating = False   

填写:
   change = False
    For r = 1 To 9
       For c = 1 To 9
           If Len(Cells(r, c)) > 1 Then
                tmpStr = Cells(r, c) '单元格内容为已去掉用过的数字后的字串
           ElseIf Len(Cells(r, c)) = 1 And Cells(r, c) > 0 Then
                 GoTo 跳到下一单元格  '单元格数字已确定,跳到下一单元格
           Else
                tmpStr = origStr '单元格为空单元格,设定内容为原始字符串
           End If 
                '将同一行中已用过的数字从原始字串中去除
                For tmpc = 1 To 9
                    If Len(Cells(r, tmpc)) = 1 Then
                        If InStr(tmpStr, Cells(r, tmpc)) > 0 Then
                            tmpStr = Replace(tmpStr, Cells(r, tmpc), "")
                            change = True
                        End If
                    End If
                Next
                 '将同一列中已用过的数字从原始字串中去除
                For tmpr = 1 To 9
                    If Len(Cells(tmpr, c)) = 1 Then
                        If InStr(tmpStr, Cells(tmpr, c)) > 0 Then
                           tmpStr = Replace(tmpStr, Cells(tmpr, c), "")
                            change = True
                        End If
                    End If
                Next
                '将同一区域中已用过的数字从原始字串中去除
                If r < 4 Then
                    tr = 1
                ElseIf r > 6 Then
                    tr = 7
                Else
                    tr = 4
                End If               

                If c < 4 Then
                    tc = 1
                ElseIf c > 6 Then
                    tc = 7
                Else
                    tc = 4
                End If

                For tmpr = tr To tr + 2
                    For tmpc = tc To tc + 2
                        If Len(Cells(tmpr, tmpc)) = 1 Then
                            If InStr(tmpStr, Cells(tmpr, tmpc)) > 0 Then
                                tmpStr = Replace(tmpStr, Cells(tmpr, tmpc), "")
                                change = True
                            End If
                        End If
                    Next
                Next

                tStr = Replace(tmpStr, ",", "")
                '某个单元格的数字全部删完,那么这种填法错误
                If Len(tStr) = 0 Then
                    If stackR > 10 Then
                       '出栈
                       Range("A" & stackR & ":i" & stackR + 8).Select
                       Selection.Cut
                       Range("A1").Select
                       Paste
                       '调整堆栈指针
                       stackR = stackR - 10
                       GoTo 填写
                    Else
                        MsgBox "(@﹏@)~,这题无解。" '堆栈到底,没有可能情况了,无解
                        Exit Sub
                    End If            

                ElseIf Len(tStr) = 1 Then
                    Cells(r, c) = tStr
                Else
                    Cells(r, c) = tmpStr
                End If
                tmpStr = origStr
                tStr = ""           

跳到下一单元格:
       Next
      Next      

      If change = False Then
         For r = 1 To 9
                For c = 1 To 9 
                        '分析同一行的情况,判断是否出现可确定数字的单元格
                        For tmpc = 1 To 9
                            If Len(Cells(r, tmpc)) > 1 Then
                                tStr = tStr & Cells(r, tmpc)
                            End If
                        Next                       

                        For i = 1 To 9
                            If Len(tStr) - Len(Replace(tStr, i, "")) = 1 Then
                                For tmpc = 1 To 9
                                    If InStr(Cells(r, tmpc), i) > 0 Then
                                       Cells(r, tmpc) = i
                                        GoTo 填写
                                    End If
                                Next
                            End If
                        Next
                        tStr = ""
                         '分析同一列的情况,判断是否出现可确定数字的单元格
                        For tmpr = 1 To 9
                            If Len(Cells(tmpr, c)) <> 1 Then
                                tStr = tStr & Cells(tmpr, c)
                            End If
                        Next

                        For i = 1 To 9
                            If Len(tStr) - Len(Replace(tStr, i, "")) = 1 Then
                                For tmpr = 1 To 9
                                    If InStr(Cells(tmpr, c), i) > 0 Then
                                        Cells(tmpr, c) = i
                                        GoTo 填写
                                    End If
                                Next
                            End If
                        Next
                        tStr = ""

                        '分析同一区域的情况,判断是否出现可确定数字的单元格

                        If r < 4 Then
                            tr = 1
                        ElseIf r > 6 Then
                            tr = 7
                        Else
                            tr = 4
                        End If

                        If c < 4 Then
                            tc = 1
                        ElseIf c > 6 Then
                            tc = 7
                        Else
                            tc = 4
                        End If

                        For tmpr = tr To tr + 2
                            For tmpc = tc To tc + 2
                                If Len(Cells(tmpr, tmpc)) <> 1 Then
                                    tStr = tStr & Cells(tmpr, tmpc)
                                End If
                            Next
                        Next
                        For i = 1 To 9
                            If Len(tStr) - Len(Replace(tStr, i, "")) = 1 Then
                                For tmpr = tr To tr + 2
                                    For tmpc = tc To tc + 2
                                        If InStr(Cells(tmpr, tmpc), i) > 0 Then
                                               Cells(tmpr, tmpc) = i
                                               GoTo 填写
                                        End If
                                    Next
                                Next
                            End If
                        Next 
                Next
       Next

       For r = 1 To 9
           For c = 1 To 9
                If Len(Cells(r, c)) > 1 Then
                    '找到可填数字最少的未定单元格(也就是其中字符串长度最短的),使堆栈最小
                    tmpLen = 17
                    For i = 1 To 9
                        For j = 1 To 9
                           If Len(Cells(i, j)) <> 1 And Len(Cells(i, j)) < tmpLen Then
                                tmpLen = Len(Cells(i, j))
                                targetRow = i
                                targetCol = j
                           End If
                        Next
                    Next
                    Range(targetRegion).Copy
                    p = 1
                    s = Replace(Cells(targetRow, targetCol), ",", "")
                    '将所有可能情况入栈,最后一种可能情况直接在目标区修改
                    While p < Len(s)
                        stackR = stackR + 10
                        Range("A" & stackR).Select
                        Paste
                        Cells(stackR + targetRow - 1, targetCol) = Mid(s, p, 1)
                        p = p + 1
                    Wend
                    Cells(targetRow, targetCol) = Mid(s, p, 1)
                    GoTo 填写
                End If
           Next
       Next  

    Else
     GoTo 填写
    End If
   Application.ScreenUpdating = True
   endTime = Now()
   MsgBox "~\(≧▽≦)/~,解决了!耗时:" + Application.Text(endTime - startTime, "m:s")

End Sub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1411755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安利一款抢票软件堪称“业界良心”,全网好评!

马上就到了春运了&#xff0c;有不少网友反映12306买票太难了。 有粉丝在后台留言问有没有抢票软件&#xff1f; 知名公司开发的抢票软件&#xff0c;需要助力、需要用钱买加速包&#xff0c;这对于需要白嫖的朋友来说无疑是“雪上加霜”&#xff01; 这里从解决实际问题的角度…

RocketMQ源码安装

RocketMQ源码安装 1.官方下载地址 http://rocketmq.apache.org/dowloading/releases/ 2.环境要求 1.Linux64位系统 2.JDK1.8(64位) 3.Maven 3.2.x以上 3.IntelliJ IDEA导入 导入后执行Maven命令install mvn install -Dmaven.test.skiptrue 4.调试RocketMQ源码 4.1启动…

5JS语句

表达式在JavaScript中是短语&#xff0c;那么语句&#xff08;statement&#xff09;就是JavaScript整句或命令。 表达式计算出一个值&#xff0c;但语句用来执行以使某件事发生。诸如赋值和函数调用这些有副作用的表达式&#xff0c;是可以作为单独的语句的&#xff0c;这种把…

gitlab设置/修改克隆clone地址端口

最近由于公司要停测试库云服务器? 什么?要停测试库服务器??? 是的! 你没听错。 真是醉了,多大的集团,为了省钱,也真是拼了, 作为开发人员,没有测试服务器,犹如断臂之人。 所以,在之前搭建环境的时候都没有写文档,今天算是弥补上,以后都可以作为参考了, …

vue3 根据点击位置,实现一个用户头像弹框定位

vue3 根据点击位置&#xff0c;实现一个用户头像弹框定位 需求背景 最近在做直播后台&#xff0c;涉及到对用户的一些操作&#xff0c;比如关注/取关/禁言/踢出直播间。多个地方都要用&#xff0c;需要封装一个弹框组件 效果图 实现过程分析 根据点击元素&#xff0c;获取元…

在游戏里开公司!基于ERNIE SDK的多智能体游戏应用

在虚拟世界有一座神奇的办公室&#xff0c;当你输入你的创业方向&#xff0c;办公室的智慧打工人们将团结合作&#xff0c;为你的项目勤劳奔走&#xff0c;并在过程中&#xff0c;把日报周报都写好&#xff0c;让你随时掌握项目进度和最终成果&#xff01;该项目基于ERNIE SDK开…

频率的高低与辐射强度有关系吗?

频率的高低和辐射强度之间存在一定的关系。 一般而言&#xff0c;频率越高&#xff0c;辐射强度越大&#xff0c;即电磁辐射的能量越大。这是因为电磁波的能量与其频率成正比。在电磁波谱中&#xff0c;如X光和伽玛射线具有高频率和强辐射强度&#xff0c;可以破坏构成人体组织…

Python静态web服务器实战

准备html页面&#xff0c;包含两个页面(index.html, index2.html)和一个404(404html)页面&#xff0c;目录示意&#xff1a; 1.返回固定页面 with open("website/index.html","r") as file: import socket# # 返回固定的页面 website/index.html if __na…

怎么将word转换成pdf?一步到位,轻松搞定!

怎么将word转换成pdf&#xff1f;在数字时代&#xff0c;我们经常需要将文档转换为PDF格式&#xff0c;以便在不同的设备和平台上共享和查看。然而&#xff0c;许多人对如何将Word转换成PDF感到困惑。本文将为你详细介绍将Word转换成PDF的步骤&#xff0c;让你轻松掌握这一技能…

php+Layui开发的网站信息探针查询源码

信息探针是一款基于layui开发的专业查询好友个人信息的程序。 自定义设置探针页面&#xff0c;探针功能&#xff0c;QQ分享&#xff0c;通知邮箱等功能。 生成页面链接好友点击会出现好友ip 位置信息&#xff0c;手机型号ua头浏览器等信息 gps需要注册百度地图开发者才可以使用…

【RabbitMQ】延迟队列之死信交换机

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《RabbitMQ实战》。&#x1f3af;&#x1f3af; &am…

代码随想录算法训练营第31天(贪心算法01 | ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

贪心算法01 理论基础455.分发饼干解题思路 376. 摆动序列解题思路拓展 53. 最大子序和解题思路常见误区注意点 贪心算法其实就是没有什么规律可言&#xff0c;所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其规律&#xff0c; 没有思路就立刻看题解。…

mysql入门到精通002--基础篇

1、基础篇课程内容 2、MySQL概述 2.1 数据库相关概念 2.1.1、数据库 存储数据的仓库 2.1.2、SQL 操作关系型数据库的一套标准语言&#xff0c;定义了一套关系型数据库的统一标准。 2.1.3、关系型数据库管理系统 2.2 mysql数据库 2.2.1 安装与使用 下载地址&#xff1a;…

婴幼儿营养之道:新生儿补充磷脂酰丝氨酸的关键

引言&#xff1a; 磷脂酰丝氨酸是一种对于新生儿神经系统发育和整体健康至关重要的成分。在新生儿成长的早期阶段&#xff0c;科学合理的补充磷脂酰丝氨酸有助于促进大脑和神经系统的发育&#xff0c;为宝宝的智力和身体健康奠定坚实基础。本文将深入探讨磷脂酰丝氨酸的作用、…

24.1.25 DAY2 C++

思维导图&#xff1a; 2.题目&#xff1a; 自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周…

Android串口通讯 报错 NO_READ_WRITE_PERMISSION

在调试Android串口通讯的时候&#xff0c;特别是串口连接使用的usb接口作为物理介质的时候&#xff0c;报错 NO_READ_WRITE_PERMISSION &#xff0c;一个很容易忽略的问题就是串口地址错误 因为每个机器都有自己的串口地址名称定义方式。 解决办法&#xff1a;1、通过cmd sh…

Google Chrome RCE漏洞 CVE-2020-6507 和 CVE-2024-0517的简单分析

本文深入研究了两个在 Google Chrome 的 V8 JavaScript 引擎中发现的漏洞&#xff0c;分别是 CVE-2020-6507 和 CVE-2024-0517。这两个漏洞都涉及 V8 引擎的堆损坏问题&#xff0c;允许远程代码执行。通过EXP HTML部分的内存操作、垃圾回收等流程方式实施利用攻击。 CVE-2020-…

查询机器近期的重启记录

打开Command Prompt命令行&#xff0c;运行下面命令&#xff1a; systeminfo | find "System Boot Time:" 如图&#xff0c;这台设备上一次重启时间是1月21日。

Ant Design Vue详解a-tree-select使用树形选择器,递归渲染数据,点击选项回显,一二级菜单是否可选等问题

后台给的树形数据&#xff1a; {"code": 200,"data": [{"code": "jsd","children": [{"code": "hx","children": [],"name": "航向","id": 8,"libTable…

YOLOv8改进 | Conv篇 | 利用DualConv二次创新C2f提出一种轻量化结构(轻量化创新)

一、本文介绍 本文给大家带来的改进机制是利用DualConv改进C2f提出一种轻量化的C2f,DualConv是一种创新的卷积网络结构,旨在构建轻量级的深度神经网络。它通过结合33和11的卷积核处理相同的输入特征映射通道,优化了信息处理和特征提取。DualConv利用组卷积技术高效排列卷积…