用Excel辅助做数独
做数独游戏的时候,画在纸上很容易弄花眼,所以我考虑用Excel辅助做一个。
界面如下:

按下初始化表格区域按钮,会在所有单元格中填充“123456789”。如下图:

当某个单元格删除得只剩一个数字时,会将同一行、同一列和同一区域的其它单元格中的相同数字删除。如下图:

实现上述效果的VBA如下:
1、初始化按钮的代码:
Sub startup_Click()Dim row%, col%For row = 1 To 9For col = 1 To 9Cells(row, col) = "'123456789"NextNext
End Sub
以上代码仅仅简单遍历相关单元格并填充字符串。
实现自动删除关联单元格中的数字的功能的代码放在工作表的Worksheet_Change事件中,这样,只要修改相关游戏区域中的单元格,就会自动执行检查并删除有关数字。代码如下:
Private Sub Worksheet_Change(ByVal Target As Range)Dim row%, col%, changeRow%, changeCol%, rngRow%, rngCol%, txt$changeRow = Target.rowchangeCol = Target.Column'记录刚修改单元格的内容txt = Cells(changeRow, changeCol)'如果刚修改的单元格只剩下一个数字,则执行自动消除If Len(txt) = 1 Then'防止修改单元格内容时工作表改变事件被循环触发Application.EnableEvents = False'确定同一区域单元格第一行行号If changeRow < 4 ThenrngRow = 1ElseIf changeRow > 6 ThenrngRow = 7ElserngRow = 4End If'确定同一区域单元格第一列列号If changeCol < 4 ThenrngCol = 1ElseIf changeCol > 6 ThenrngCol = 7ElserngCol = 4End If'将同一行、列及区域单元格中相关的数字删除For row = 1 To 9For col = 1 To 9If row = changeRow Or col = changeCol Or (row >= rngRow And row < rngRow + 3 _And col >= rngCol And col < rngCol + 3) ThenCells(row, col) = Replace(Cells(row, col), txt, "")End IfNextNextCells(changeRow, changeCol) = txt'恢复事件处理以继续响应工作表改变事件Application.EnableEvents = TrueEnd If
End Sub
下面再附上一个用VBA做数独的程序,不过没有优化:
Sub VBA做数独()Dim targetRegion As StringDim 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 IntegerDim change As BooleanDim startTime, endTime As DatestartTime = Now()origStr = "1,2,3,4,5,6,7,8,9"targetRegion = "A1:I9"stackR = 1Application.ScreenUpdating = False 填写:change = FalseFor r = 1 To 9For c = 1 To 9If Len(Cells(r, c)) > 1 ThentmpStr = Cells(r, c) '单元格内容为已去掉用过的数字后的字串ElseIf Len(Cells(r, c)) = 1 And Cells(r, c) > 0 ThenGoTo 跳到下一单元格 '单元格数字已确定,跳到下一单元格ElsetmpStr = origStr '单元格为空单元格,设定内容为原始字符串End If '将同一行中已用过的数字从原始字串中去除For tmpc = 1 To 9If Len(Cells(r, tmpc)) = 1 ThenIf InStr(tmpStr, Cells(r, tmpc)) > 0 ThentmpStr = Replace(tmpStr, Cells(r, tmpc), "")change = TrueEnd IfEnd IfNext'将同一列中已用过的数字从原始字串中去除For tmpr = 1 To 9If Len(Cells(tmpr, c)) = 1 ThenIf InStr(tmpStr, Cells(tmpr, c)) > 0 ThentmpStr = Replace(tmpStr, Cells(tmpr, c), "")change = TrueEnd IfEnd IfNext'将同一区域中已用过的数字从原始字串中去除If r < 4 Thentr = 1ElseIf r > 6 Thentr = 7Elsetr = 4End If If c < 4 Thentc = 1ElseIf c > 6 Thentc = 7Elsetc = 4End IfFor tmpr = tr To tr + 2For tmpc = tc To tc + 2If Len(Cells(tmpr, tmpc)) = 1 ThenIf InStr(tmpStr, Cells(tmpr, tmpc)) > 0 ThentmpStr = Replace(tmpStr, Cells(tmpr, tmpc), "")change = TrueEnd IfEnd IfNextNexttStr = Replace(tmpStr, ",", "")'某个单元格的数字全部删完,那么这种填法错误If Len(tStr) = 0 ThenIf stackR > 10 Then'出栈Range("A" & stackR & ":i" & stackR + 8).SelectSelection.CutRange("A1").SelectPaste'调整堆栈指针stackR = stackR - 10GoTo 填写ElseMsgBox "(@﹏@)~,这题无解。" '堆栈到底,没有可能情况了,无解Exit SubEnd If ElseIf Len(tStr) = 1 ThenCells(r, c) = tStrElseCells(r, c) = tmpStrEnd IftmpStr = origStrtStr = "" 跳到下一单元格:NextNext If change = False ThenFor r = 1 To 9For c = 1 To 9 '分析同一行的情况,判断是否出现可确定数字的单元格For tmpc = 1 To 9If Len(Cells(r, tmpc)) > 1 ThentStr = tStr & Cells(r, tmpc)End IfNext For i = 1 To 9If Len(tStr) - Len(Replace(tStr, i, "")) = 1 ThenFor tmpc = 1 To 9If InStr(Cells(r, tmpc), i) > 0 ThenCells(r, tmpc) = iGoTo 填写End IfNextEnd IfNexttStr = ""'分析同一列的情况,判断是否出现可确定数字的单元格For tmpr = 1 To 9If Len(Cells(tmpr, c)) <> 1 ThentStr = tStr & Cells(tmpr, c)End IfNextFor i = 1 To 9If Len(tStr) - Len(Replace(tStr, i, "")) = 1 ThenFor tmpr = 1 To 9If InStr(Cells(tmpr, c), i) > 0 ThenCells(tmpr, c) = iGoTo 填写End IfNextEnd IfNexttStr = ""'分析同一区域的情况,判断是否出现可确定数字的单元格If r < 4 Thentr = 1ElseIf r > 6 Thentr = 7Elsetr = 4End IfIf c < 4 Thentc = 1ElseIf c > 6 Thentc = 7Elsetc = 4End IfFor tmpr = tr To tr + 2For tmpc = tc To tc + 2If Len(Cells(tmpr, tmpc)) <> 1 ThentStr = tStr & Cells(tmpr, tmpc)End IfNextNextFor i = 1 To 9If Len(tStr) - Len(Replace(tStr, i, "")) = 1 ThenFor tmpr = tr To tr + 2For tmpc = tc To tc + 2If InStr(Cells(tmpr, tmpc), i) > 0 ThenCells(tmpr, tmpc) = iGoTo 填写End IfNextNextEnd IfNext NextNextFor r = 1 To 9For c = 1 To 9If Len(Cells(r, c)) > 1 Then'找到可填数字最少的未定单元格(也就是其中字符串长度最短的),使堆栈最小tmpLen = 17For i = 1 To 9For j = 1 To 9If Len(Cells(i, j)) <> 1 And Len(Cells(i, j)) < tmpLen ThentmpLen = Len(Cells(i, j))targetRow = itargetCol = jEnd IfNextNextRange(targetRegion).Copyp = 1s = Replace(Cells(targetRow, targetCol), ",", "")'将所有可能情况入栈,最后一种可能情况直接在目标区修改While p < Len(s)stackR = stackR + 10Range("A" & stackR).SelectPasteCells(stackR + targetRow - 1, targetCol) = Mid(s, p, 1)p = p + 1WendCells(targetRow, targetCol) = Mid(s, p, 1)GoTo 填写End IfNextNext ElseGoTo 填写End IfApplication.ScreenUpdating = TrueendTime = Now()MsgBox "~\(≧▽≦)/~,解决了!耗时:" + Application.Text(endTime - startTime, "m:s")End Sub
相关文章:
用Excel辅助做数独
做数独游戏的时候,画在纸上很容易弄花眼,所以我考虑用Excel辅助做一个。 界面如下: 按下初始化表格区域按钮,会在所有单元格中填充“123456789”。如下图: 当某个单元格删除得只剩一个数字时,会将同一行、…...
arcgis实现截图/截屏功能
arcgis实现截图/截屏功能 文章目录 arcgis实现截图/截屏功能前言效果展示相关代码 前言 本篇将使用arcgis实现截图/截屏功能,类似于qq截图 效果展示 相关代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta nam…...
mysql备份
1.新建备份目录 mkdir -p /data/mysql_dump/#查找mysql配置位置 find / -name "my.cnf" find / -name "mysql.sock" find / -name "mysqldump"2.定时任务 #每天凌晨备份一次 echo "00 00 * * * root /data/mysql_bak.sh" >> /…...
CentOS7 安装PostgreSQL以及配置服务
文章目录 前言1. 安装步骤2. 连接PostgreSQL3. 配置服务配置文件所在路径设置监听地址修改数据库密码已经修改了密码,为什么没有生效?不需要密码就可以连接?设置访问权限4. 新的配置生效前言 PostgreSQL是一种功能强大的开源关系型数据库管理系统,被广泛用于各种应用程序和…...
React 表单、处理受控表单组件、非受控组件
React 表单处理 学习目标: 能够使用受控组件的方式获取文本框 使用 React 处理表单一般有两种方法 受控组件 (推荐)非受控组件 (了解) 1. 受控表单组件 什么是受控组件? input 框自己的状态被 React 组…...
Android开发--状态栏布局隐藏的方法
1.问题如下,安卓布局很不协调 2.先将ActionBar设置为NoActionBar 先打开styles.xml 3.使用工具类 package com.afison.newfault.utils;import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.graph…...
GaussDB如何创建和管理序列、定时任务
前言 GaussDB是华为自主创新研发的分布式关系型数据库,为企业提供功能全面、稳定可靠、扩展性强、性能优越的企业级数据库服务。在实际业务场景使用中,为了提高工作效率,数据库GaussDB提供定时任务的功能,本节为大家讲解GaussDB如…...
mybatis-plus:代码生成器
一、依赖 代码生成器需要添加一下依赖 <dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.0.7.1</version></dependency><!-- https://mvnre…...
几款提高开发效率的Idea 插件
1、ignore 开发代码过程中经常会有一些需要提交到代码仓库的文件,比如java文件生成的.class、.jar 等,如果将编译后的文件都提交到代码库那么代码库会很大,关键是没有必要。 这款插件就可以很方便的解决某类文件或者某个文件夹不需要提交到…...
Redisson 分布式锁可重入的原理
目录 1. 使用 Redis 实现分布式锁存在的问题 2. Redisson 的分布式锁解决不可重入问题的原理 1. 使用 Redis 实现分布式锁存在的问题 不可重入:同一个线程无法两次 / 多次获取锁举例 method1 执行需要获取锁method2 执行也需要(同一把)锁如…...
【Vue实用功能】Vue实现文档在线预览功能,在线预览PDF、Word等office文件
1、Office Web(微软的开发接口) 优点 没有 Office也可以直接查看Office 文件适用于移动端、PC无需下载文件就可以在浏览器中查看 <iframe src"文档地址" frameborder"0" /> const docUrl 外网可预览的地址 const url encodeURIComponent(docUrl…...
【一站解决您的问题】mac 利用命令升级nodejs、npm、安装Nodejs的多版本管理器n、nodejs下载地址
一:下载nodejs 官网地址,点击下载稳定版 https://nodejs.org/en 如果官网下载特别慢,可以点击这个地址下载 点击这里 https://nodejs.cn/download/current/ 安装完成后,就包含了nodejs 和 npm。此时您的版本就是下载安装的版本…...
【RabbitMQ】死信(延迟队列)的使用
目录 一、介绍 1、什么是死信队列(延迟队列) 2、应用场景 3、死信队列(延迟队列)的使用 4、死信消息来源 二、案例实践 1、案例一 2、案例二(消息接收确认 ) 3、总结 一、介绍 1、什么是死信队列(延迟队列) 死信,在官网中对应的单词…...
java 解析word模板(2024-01-25)
本文主要功能是解析word模板 这是一个word解析类,因为我做的系统用到了而且没有可用的帮助类,只能自己写。之前的实现方式是freemarker 模板解析。但是这次要求用poi不在使用freemarker。实现功能比较少,主要是满足开发需求即可,没…...
flutter-相关个人记录
1、flutter 安卓打包打包报错 flutter build apk -v --no-tree-shake-icons 2、获取华为指纹证书命令 keytool -list -v -keystore ***.jks 3、IOS项目中私有方法查找隐藏文件中 1、cd 项目目录地址 2、grep -r xerbla. "xerbla"为需要查找的关键字 3…...
互斥锁/读写锁(Linux)
一、互斥锁 临界资源概念: 不能同时访问的资源,比如写文件,只能由一个线程写,同时写会写乱。 比如外设打印机,打印的时候只能由一个程序使用。 外设基本上都是不能共享的资源。 生活中比如卫生间,同一…...
Jackson序列化Bean额外属性附加--@JsonAnyGetter、@JsonUnwrapped用户
1. 场景 有一项工作,需要将数据从一个服务S中读取出来(得到的是一个JSON),将数据解析转换以后构造成一个数组的类型A的对象,写入到一个服务T中。 A.class Data public class A {String f0 ;String f1 ; }在发现需要…...
排序算法——冒泡排序算法详解
冒泡排序算法详解 1.引言2.算法概览2.1输入处理2.2核心算法步骤2.3数据结构2.4复杂度分析 3.算法优化4.边界条件和异常处理5.实验和测试6.应用和扩展7.代码示例8.总结 1.引言 冒泡排序是一种简单而直观的比较排序算法,它通过多次遍历数组,比较相邻元素并…...
宋仕强论道之华强北的缺货潮(十六)
始于2019年缺货潮让华强北又生产一大批亿万富翁,缺货的原因主要是:首先,疫情封控导致大量白领在家远程办公,需要购买电脑、打印机等办公设备,同时孩子们也要在家上网课,进一步增加对电子智能终端产品的需求…...
登录注册页面
前提:基于element-ui环境 模态登录组件 分析Login.vue <template><div class"login"><span click"handleClose">X</span></div> </template><script> export default {name: "Login",m…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
