做数独游戏的时候,画在纸上很容易弄花眼,所以我考虑用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
猜你喜欢
- 4天前(兰州旅游文化产业发展有限公司)甘肃省兰州市2023年乡村旅游暨A级旅游景区管理工作培训班开班
- 4天前(三亚海棠湾君悦度假酒店)三亚海棠湾君悦酒店暑期夏令营悦趣海岛游招募中
- 4天前(瑞士大酒店-自助餐怎么样)瑞意心旅,以食为先 瑞士酒店开启全新"瑞士早餐计划"
- 4天前(屿见不一样是哪个酒店)屿见白纱,遇见自己 “佳能PhotoGirls屿见白纱”摄影派对玩转海岛
- 4天前(兵团猛进秦剧团持续开展“戏曲进校园”活动)兵团猛进秦剧团持续开展“戏曲进校园”活动
- 4天前(甘肃文化旅游宣传片)甘肃文旅推介走进重庆
- 4天前(希尔顿集团2021年筹建的酒店)希尔顿集团两大重点项目亮相第四届上海旅游投资促进大会
- 4天前(大黄山景区高质量发展联盟成立多少年)大黄山景区高质量发展联盟成立
- 4天前(“三天跨两城”催生租车新需求,神州租车清明跨城订单同比增长416%)“三天跨两城”催生租车新需求,神州租车清明跨城订单同比增长416%
- 4天前(筑格集团有限公司)洲际酒店集团旗下筑格酒店品牌正式亮相大中华区
网友评论
- 搜索
- 最新文章
- (2020广州车展哈弗)你的猛龙 独一无二 哈弗猛龙广州车展闪耀登场
- (哈弗新能源suv2019款)智能科技颠覆出行体验 哈弗重塑新能源越野SUV价值认知
- (2021款全新哈弗h5自动四驱报价)新哈弗H5再赴保障之旅,无惧冰雪护航哈弗全民电四驱挑战赛
- (海南航空现况怎样)用一场直播找到市场扩张新渠道,海南航空做对了什么?
- (visa jcb 日本)优惠面面俱到 JCB信用卡邀您畅玩日本冰雪季
- (第三届“堡里有年味·回村过大年”民俗花灯会活动)第三届“堡里有年味·回村过大年”民俗花灯会活动
- (展示非遗魅力 长安启源助力铜梁龙舞出征)展示非遗魅力 长安启源助力铜梁龙舞出征
- (阿斯塔纳航空公司)阿斯塔纳航空机队飞机数量增至50架
- (北京香港航班动态查询)香港快运航空北京大兴新航线今日首航
- (我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉)我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉
- 热门文章