用Excel辅助做数独

做数独游戏的时候,画在纸上很容易弄花眼,所以我考虑用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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[UI5 常用控件] 03.Icon, Avatar,Image

文章目录 前言1. Icon2. Avatar2.1 displayShape2.2 initials2.3 backgroundColor2.4 Size2.5 fallbackIcon2.6 badgeIcon2.7 badgeValueState2.8 active 3. Image 前言 本章节记录常用控件Title,Link,Label。 其路径分别是&#xff1a; sap.m.Iconsap.m.Avatarsap.m.Image 1…

C++面试:散列表

目录 1. 散列表的基本概念 散列表的定义 散列函数 哈希冲突 2. 处理冲突的方法 链地址法&#xff08;Separate Chaining&#xff09; 开放地址法 再散列 3. 散列表的性能分析 1. 平均查找长度&#xff08;ASL&#xff09; 2. 负载因子&#xff08;Load Factor&#…

CAD-autolisp(二)——选择集、命令行设置对话框、符号表

目录 一、选择集1.1 选择集的创建1.2 选择集的编辑1.3 操作选择集 二、命令行设置对话框2.1 设置图层2.2 加载线型2.3 设置字体样式2.4 设置标注样式&#xff08;了解即可&#xff09; 三、符号表3.1 简介3.2 符号表查找3.2 符号表删改增 一、选择集 定义&#xff1a;批量选择…

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空&#xff0c;返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…

《WebKit 技术内幕》学习之十五(6):Web前端的未来

6 Chromium OS和Chrome的Web应用 6.1 基本原理 HTML5技术已经不仅仅用来编写网页了&#xff0c;也可以用来实现Web应用。传统的操作系统支持本地应用&#xff0c;那么是否可以有专门的操作系统来支持Web应用呢&#xff1f;当然&#xff0c;现在已经有众多基于Web的操作系统&…

跟无神学AI之Prompt

在大模型时代会写prompt变得很重要。 Prompt翻译为中文为提示词&#xff0c;在大模型的特定领域指的是大模型使用者给大模型提交的一种有一定格式的交互命令&#xff0c;让我们看看科大讯飞的大模型给出的答案—— Prompt是一种向人工智能模型提供的输入文本或指令&#xff0…

uv胶UV大灯修复液修复汽车车灯大灯尾灯?

使用UV胶进行汽车大灯修复是一种常见的方法&#xff0c;特别是用于修复裂纹、划痕或氧化的透明塑料表面。以下是使用UV胶修复汽车大灯的一般步骤&#xff1a; 1.准备工作&#xff1a; 确保汽车大灯表面是干净的&#xff0c;没有灰尘、油脂或其他污垢。可以使用清洁剂和软布进行…

Microsoft Remote Desktop for Mac(远程桌面连接)激活版

Microsoft Remote Desktop是一款由微软开发的远程桌面连接工具&#xff0c;它允许用户从另一台计算机或移动设备远程连接到Windows桌面或服务器。 以下是该软件的一些主要特点和功能&#xff1a; 跨平台支持&#xff1a;Microsoft Remote Desktop支持Windows、macOS、iOS和Andr…

leetcode:二叉树的中序遍历(外加先序,后序遍历)

题外&#xff1a;另外三种遍历可以看这&#xff1a; 层序遍历&#xff1a; Leetcode:二分搜索树层次遍历-CSDN博客 先序遍历&#xff1a; 二叉树的先序&#xff0c;中序&#xff0c;后序遍历-CSDN博客 后序遍历&#xff1a; 二叉树的先序&#xff0c;中序&#xff0c;后序…

网络安全全栈培训笔记(58-服务攻防-应用协议设备KibanaZabbix远控向日葵VNCTV)

第58天 服务攻防-应用协议&设备Kibana&Zabbix&远控向日葵&VNC&TV 知识点&#xff1a; 1、远程控制第三方应用安全 2、三方应用-向日葵&VNC&TV 3、设备平台-Zabbix&Kibanai漏洞 章节内容&#xff1a; 常见版务应用的安全测试&#xff1a; 1…

【Web】CTFSHOW SQL注入刷题记录(上)

目录 无过滤注入 web171 web172 web173 web174 web175 时间盲注 写马 过滤注入 web176 web177 web178 web179 web180 web181-182 web183 web184 web185-186 web187 web188 web189 web190 布尔盲注 web191 web192 web193 web194 堆叠注入 web195 …

[C++]使用纯opencv部署yolov8旋转框目标检测

【官方框架地址】 https://github.com/ultralytics/ultralytics 【算法介绍】 YOLOv8是一种先进的对象检测算法&#xff0c;它通过单个神经网络实现了快速的物体检测。其中&#xff0c;旋转框检测是YOLOv8的一项重要特性&#xff0c;它可以有效地检测出不同方向和角度的物体。…

格子表单GRID-FORM | 嵌套子表单与自定义脚本交互

格子表单/GRID-FORM已在Github 开源&#xff0c;如能帮到您麻烦给个星&#x1f91d; GRID-FORM 系列文章 基于 VUE3 可视化低代码表单设计器嵌套表单与自定义脚本交互 新版本功能 &#x1f389; 不觉间&#xff0c;GRID-FORM 已经开源一年&#xff08;2023年1月29日首次提交…

【JaveWeb教程】(28)SpringBootWeb案例之《智能学习辅助系统》的详细实现步骤与代码示例(1)

目录 SpringBootWeb案例011. 准备工作1.1 需求&环境搭建1.1.1 需求说明1.1.2 环境搭建 1.2 开发规范 2. 部门管理 SpringBootWeb案例01 前面我们已经讲解了Web前端开发的基础知识&#xff0c;也讲解了Web后端开发的基础(HTTP协议、请求响应)&#xff0c;并且也讲解了数据库…

QT+VS实现Kmeans聚类算法

1、Kmeans的定义 聚类是一个将数据集中在某些方面相似的数据成员进行分类组织的过程&#xff0c;聚类就是一种发现这种内在结构的技术&#xff0c;聚类技术经常被称为无监督学习。k均值聚类是最著名的划分聚类算法&#xff0c;由于简洁和效率使得他成为所有聚类算法中最广泛使…

Java 基础知识-IO流

大家好我是苏麟 , 今天聊聊IO流 . 资料来源黑马程序员 . IO概述 生活中&#xff0c;你肯定经历过这样的场景。当你编辑一个文本文件&#xff0c;忘记了ctrls &#xff0c;可能文件就白白编辑了。当你电脑上插入一个U盘&#xff0c;可以把一个视频&#xff0c;拷贝到你的电脑硬…

ajax点击搜索返回所需数据

html 中body设置&#xff08;css设置跟进自身需求&#xff09; <p idsearch_head>学生信息查询表</p> <div id"div_1"> <div class"search_div"> <div class"search_div_item"> …

day22 事件委托

目录 事件委托 事件委托 事件委托是利用事件流的特征解决一些开发需求的知识技巧 优点&#xff1a;减少注册次数&#xff0c;提高程序性能原理&#xff1a;事件委托其实是利用事件冒泡的特点 给父元素注册事件&#xff0c;当触发子元素时&#xff0c;会冒泡到父元素上&#x…

automa插件使用的一些实战经验3

1 子流程的变量怎么传回父流程 主流程向子流程传参很容易 在子流程可以看到&#xff0c;父流程定义的表格&#xff0c;在子流程中是看不到的&#xff0c;那么子流程定义的变量如何传回父流程呢&#xff1f;另外在子流程再添加执行工作流&#xff0c;是无法选择父流程本身&…

C++:vector容器(memcpy浅拷贝问题、迭代器失效问题)

文章目录 一. vector 的介绍二. vector 的使用1. string 和 vector<char> 的区别2. 为什么 vector 没有 find() 接口 三. vector 的模拟实现1. vector 的基本框架2. memcpy 和 memmove 的浅拷贝问题3. vector 迭代器失效问题4. 模拟代码 一. vector 的介绍 vector 的文档…