Excel VBA检查邻近的单元格内容

我正在做的是在Excel中创build一个扫雷游戏。 我的问题出现在试图计算给定单元的邻近单元中的地雷数量。 我用一个“x”表示一个矿井里的矿井,

这是我的代码:

Sub countMines(ByVal x As Integer, ByVal y As Integer) Dim mineCount As Integer mineCount = 0 If Cells(x, y) = "x" Then 'Do nothing if cell has mine MsgBox "Cell contains x" & x & y Else If Cells(x -1, y) = "x" Then MsgBox "Cell " & x & y & "has an x near it" End If End If End Sub 

如果一个单元格包含一个“x”,那么第一个消息框会起作用,它会正确地提醒我该单元格的位置。

但是, If Cells(x -1, y) = "x" Then第二个If Cells(x -1, y) = "x" Then则会导致a

运行时错误“1004”:应用程序定义或对象定义的错误

我可以在网上find关于这个错误的负载,因为这是一个非常通用的消息,但似乎没有适用于我的情况。

这是我唯一一次使用VBA,所以这很可能是一个非常简单的错误,可能是一个重复的问题,但我找不到答案。

只是为了这个问题可以被标记为回答,就像@Comintern所说,你必须检查以确保xy不会降到零(或超出Excel的最大范围)。

(我upvoted他的评论,但因为他没有发布在这里… ::耸耸肩::)

如果你决定让这个游戏成为一个非常的扫雷游戏,请检查以确保你不会超过32,767

作为一个侧面说明,即使Run-time error '1004'听起来是通用的,但通常只有在引用不存在(或不能被识别)的对象时才会popup。

如果你正在“跨越”代码,并且注意到你在循环开始的时候得到了1004错误,那么你有95%的开始循环的索引点不好。 你可以用任何代码块来获得同样的情况,就像你在这里的if语句一样。

 'Use following code to count all "x" in all neabouring cells 'except the host cell. But take care that minus operation does not cross excel boundaries Function countMines(ByVal x As Integer, ByVal y As Integer) Dim mineCount As Integer mineCount = 0 For Each c In Range(Cells(x - 1, y - 1), Cells(x + 1, y + 1)) If c.Address <> Cells(x, y).Address Then If c = "x" Then mineCount = mineCount + 1 End If End If Next c countMines = mineCount 'return value to calling function MsgBox "Total mines in surrounding cells = " & mineCount End Function 

你已经得到了关于你正在挣扎的错误的答案

这个答案只是抛出你可能会考虑使用WorksheetFunction.CountIf()方法来计算围绕给定单元格的范围内的所有“x”发生,如下所示:

 mineCount = WorksheetFunction.CountIf(Cells(x, y).Offset(-1, -1).Resize(3, 3), "x") 

这也会计算单元格本身,但如果你把它放在If Cells(x, y) = "x" Then False分支就不会有害

当然,抵消和resize必须适合不超过你的field限制。 所以上面的说法可能会变成:

 mineCount = WorksheetFunction.CountIf(Cells(x, y).Offset(-xOffset, -yOffset).Resize(xResize, yResize), "x") 

你必须正确地调整xOffsetyOffsetxResizeyResize与实际单元格位置( xy )和字段限制( nRowsnColumns

  xOffset = IIf(x = 1, 0, 1) yOffset = IIf(y = 1, 0, 1) xResize = IIf(x = nRows, 1, 2) + xOffset yResize = IIf(y = nColumns, 1, 2) + yOffset