我对如何在 Excel 中制作宏知之甚少。
7 回答
你可以通过谷歌找到很多例子。
第一个结果是来自 David Gainer 博客的一篇文章,该文章使用 Conway 的生命游戏来教授循环引用公式和迭代(不涉及 VBA):
http://blogs.office.com/2007/11/02/iteration-conways-game-of-life
很久以前就应该这样做,但这是我在 Excel 中的康威生活版本。
这是代码的hack。绝不是一个完美的解决方案(没有花时间在这上面),但你也许可以从中挑选出一些东西。
Private arrGrid(100, 100) As Boolean
Private arrGridNextGeneration(100, 100) As Boolean
Private Sub PopulateParentArrayData()
For k = 1 To Sheet1.Range("C2:AM20").Cells.Count
If Sheet1.Range("C2:AM20").Cells(k).Interior.Color = Sheet1.Range("A1").Interior.Color Then
arrGrid(Sheet1.Range("C2:AM20").Cells(k).Row, Sheet1.Range("C2:AM20").Cells(k).Column) = True
Else
arrGrid(Sheet1.Range("C2:AM20").Cells(k).Row, Sheet1.Range("C2:AM20").Cells(k).Column) = False
End If
DoEvents
Next
End Sub
Private Sub ApplyParentArrayData()
For k = 1 To Sheet1.Range("C2:AM20").Cells.Count
If arrGrid(Sheet1.Range("C2:AM20").Cells(k).Row, Sheet1.Range("C2:AM20").Cells(k).Column) Then
Sheet1.Range("C2:AM20").Cells(k).Interior.Color = Sheet1.Range("A1").Interior.Color
Else
Sheet1.Range("C2:AM20").Cells(k).Interior.Color = Sheet1.Range("B1").Interior.Color
End If
DoEvents
Next
End Sub
Private Sub ApplyNextGenerationArrayData()
For k = 1 To Sheet1.Range("C2:AM20").Cells.Count
If arrGridNextGeneration(Sheet1.Range("C2:AM20").Cells(k).Row, Sheet1.Range("C2:AM20").Cells(k).Column) Then
Sheet1.Range("C2:AM20").Cells(k).Interior.Color = Sheet1.Range("A1").Interior.Color
Else
Sheet1.Range("C2:AM20").Cells(k).Interior.Color = Sheet1.Range("B1").Interior.Color
End If
DoEvents
Next
End Sub
Private Function GetNeighbourCount(ByVal pintRow As Integer, ByVal pintColumn As Integer) As Integer
Dim intCount As Integer
intCount = 0
For r = pintRow - 1 To pintRow + 1
For c = pintColumn - 1 To pintColumn + 1
If r <> pintRow Or c <> pintColumn Then
If arrGrid(r, c) Then
intCount = intCount + 1
End If
End If
Next c
Next r
GetNeighbourCount = intCount
End Function
Private Sub PopulateNextGenerationArray()
Dim intNeighbours As Integer
For r = 0 To 100
For c = 0 To 100
If r > Sheet1.Range("C2:AM20").Rows(0).Row Then
If r <= Sheet1.Range("C2:AM20").Rows(Sheet1.Range("C2:AM20").Rows.Count).Row Then
If c > Sheet1.Range("C2:AM20").Columns(0).Column Then
If c <= Sheet1.Range("C2:AM20").Columns(Sheet1.Range("C2:AM20").Columns.Count).Column Then
intNeighbours = GetNeighbourCount(r, c)
If arrGrid(r, c) Then
'A1 cell
If intNeighbours < 2 Or intNeighbours > 3 Then
arrGridNextGeneration(r, c) = False
Else
arrGridNextGeneration(r, c) = True
End If
Else
'B1 cell
If intNeighbours = 3 Then
arrGridNextGeneration(r, c) = True
Else
arrGridNextGeneration(r, c) = False
End If
End If
End If
End If
End If
End If
DoEvents
Next c
Next r
End Sub
Private Sub ActionLogic()
'Application.ScreenUpdating = False
PopulateParentArrayData
PopulateNextGenerationArray
ApplyNextGenerationArrayData
'Application.ScreenUpdating = True
End Sub
要使其正常工作,只需将单元格 A1 的背景设为黑色,将单元格 B1 的背景设为白色,然后在 C2:AM20 范围内添加一些黑色背景并运行 ActionLogic 方法。
您将需要两个宏。第一个应该格式化游戏表,使单元格是方形的。
让用户运行此宏。之后,她应该为每个活着的单元格输入一个 1。使用条件格式将单元格完全变黑(如果值!= 0,则背景 = 黑色)
现在有第二个宏,它计算背景表(另一张表)中的下一步。使用相对单元定位(相对于 ActiveCell)和两个嵌套循环。完成后,将所有值从背景表复制到游戏表。
搜索它并查看他们的代码。很多人都把用 Excel 制作完整的游戏作为一种爱好。
为什么说 Excel 是错误的选择?
我认为 Excel 是解决此问题的最佳方法:
Excel 用 1 行解决了这个问题: IF(OR(SUM(B2:D4)-C3=3,AND(SUM(B2:D4)-C3=2,C3=1)),1,0)
*以上是返回单元格 C3 的下一代值的表达式。
这是演示: https ://docs.google.com/open?id=0B4FcWULw3iQidlZSdG9GRDh0TXM
如果您必须从头开始实现这类事情,那么函数式编程是最好的选择。否则,Excel 工作得非常好。为什么?因为 Excel 是一个强制你只输入纯函数的系统。你看,模拟这个生命游戏的关键是要认识到细胞的每个状态都是前一个状态的 PURE FUNCTION。Excel 自然会迫使你这样想。
另一个关于 excel 循环引用的教程可以在这里找到:http ://chandoo.org/wp/2009/01/08/timestamps-excel-formula-help/
这个解释了如何使用循环引用插入时间戳。
Excel 绝对是此类问题的错误选择。至于怎么可能:首先了解生活游戏,然后在 Excel 中使用Visual Basic 。