Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


786 / 13645 ツリー ←次へ | 前へ→

【78305】Randomwalk kinoko 16/6/23(木) 17:16 質問[未読]
【78306】Re:Randomwalk β 16/6/23(木) 18:11 発言[未読]
【78309】Re:Randomwalk kinoko 16/6/24(金) 0:03 回答[未読]
【78310】Re:Randomwalk β 16/6/24(金) 0:46 発言[未読]
【78307】Re:Randomwalk カリーニン 16/6/23(木) 21:23 発言[未読]
【78308】Re:Randomwalk β 16/6/23(木) 21:48 発言[未読]
【78311】Re:Randomwalk β 16/6/24(金) 8:54 発言[未読]
【78312】Re:Randomwalk kinoko 16/6/24(金) 12:36 質問[未読]
【78313】Re:Randomwalk β 16/6/24(金) 13:40 発言[未読]
【78314】Re:Randomwalk カエムワセト 16/6/24(金) 18:36 発言[未読]
【78315】Re:Randomwalk β 16/6/24(金) 20:32 発言[未読]

【78305】Randomwalk
質問  kinoko  - 16/6/23(木) 17:16 -

引用なし
パスワード
   プログラム初心者です。
ランダムウォークを簡単な処理で作ってみました。


Sub randomwalk1()

  Dim r As Integer
  Dim c As Integer
  Dim i As Integer
  
  ActiveSheet.Cells.Clear

  Randomize
  
  Cells.RowHeight = 5
  Cells.ColumnWidth = 0.5
  
  r = 50
  c = 50
  
  Cells(r, c).Select
  
  For i = 1 To 10000

    i = Int(9 * Rnd() + 1)

      If i = 1 Then

        r = r + 1
        c = c

        Cells(r, c).Interior.ColorIndex = 3

      ElseIf i = 2 Then

        r = r + 1
        c = c + 1

        Cells(r, c).Interior.ColorIndex = 3

      ElseIf i = 3 Then

        r = r
        c = c + 1

        Cells(r, c).Interior.ColorIndex = 3


      ElseIf i = 4 Then

        r = r - 1
        c = c + 1

        Cells(r, c).Interior.ColorIndex = 3


      ElseIf i = 5 Then

        r = r - 1
        c = c

        Cells(r, c).Interior.ColorIndex = 3

      ElseIf i = 6 Then

        r = r - 1
        c = c - 1

        Cells(r, c).Interior.ColorIndex = 3

      ElseIf i = 7 Then

        r = r
        c = c - 1

        Cells(r, c).Interior.ColorIndex = 3

      ElseIf i = 8 Then

        r = r + 1
        c = c - 1

        Cells(r, c).Interior.ColorIndex = 3

      Else

        r = r
        c = c

        Cells(r, c).Interior.ColorIndex = 3

      End If

  Next i

End Sub


ここから壁に跳ね返る処理と重なる部分の色を変えていく処理を追加したいのですが分かりません。簡単な処理でやってみたいです。お願いします。

【78306】Re:Randomwalk
発言  β  - 16/6/23(木) 18:11 -

引用なし
パスワード
   ▼kinoko さん:

>プログラム初心者です。
>ランダムウォークを簡単な処理で作ってみました。

という割には、おもしろそうなことをしておられますね。

>ここから壁に跳ね返る処理

壁 とは 具体的にどこを想定されています?
PC画面に見えている範囲のことですか?

>色を変えていく処理

どんなように変化させていきたいですか?


ところで、このコード、すぐに行や列の番号が 0 になって、エラーで止まりませんか?

【78307】Re:Randomwalk
発言  カリーニン  - 16/6/23(木) 21:23 -

引用なし
パスワード
   横から失礼します。

面白そうですね。やってることは違いますが、昔似たような?ことをしたことがありますので
参考出品します。
test
の中の
Call main(200)
の数値を変えて試してみてください。

Option Explicit
Public mystop As Boolean
Public r As Range

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Dim saidai As Long
Dim saishou As Long
Dim cnt As Long
Dim NRng As Range
Dim hantei As Boolean
Dim bl As Boolean
Dim prerng As Range
Dim iti As String

Sub test()
Call main(200)
End Sub

Function main(ByVal maxnum As Long)
Dim ws As Worksheet
mystop = True
saidai = 4
saishou = 1
cnt = 1
Set ws = ThisWorkbook.Worksheets(1)
Application.ScreenUpdating = False
ws.Cells.Delete
Application.ScreenUpdating = True
ws.Cells.ColumnWidth = 2.5
ws.Cells(1, 1).Value = cnt
Set r = ws.Cells(1, 1)
bl = False
Do Until bl = True
 If mystop = False Then Exit Do
 bl = False
 Call nextrng
 cnt = cnt + 1
 '**********
 If cnt = 2 Then
   Set prerng = ws.Cells(1, 1)
'   Set r = prerng
   If NRng.Address = prerng.Offset(1).Address Then
    With prerng
    '上
     With .Borders(xlEdgeTop)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
     End With
    '左
     With .Borders(xlEdgeLeft)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
     '右
     With .Borders(xlEdgeRight)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    End With
   Else
    With prerng
    '上
     With .Borders(xlEdgeTop)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
     '下
     With .Borders(xlEdgeBottom)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '左
     With .Borders(xlEdgeLeft)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    End With
   End If
 Else
   iti = prerng.Row - r.Row & _
   prerng.Column - r.Column & r.Row - NRng.Row & r.Column - NRng.Column
  'MsgBox cnt & " " & iti
 Select Case iti
  Case "-10-10"
  Call kei1
  Case "-100-1"
  Call kei2
  Case "-1001"
  Call kei3
  Case "1010"
  Call kei1
  Case "100-1"
  Call kei4
  Case "1001"
  Call kei5
  Case "0-1-10"
  Call kei5
  Case "0-110"
  Call kei3
  Case "0-10-1"
  Call kei6
  Case "01-10"
  Call kei4
  Case "0110"
  Call kei2
  Case "0101"
  Call kei6
 End Select
 End If
 If cnt = maxnum Then
   If NRng.Address = r.Offset(1).Address Then
    With NRng
    '左
     With .Borders(xlEdgeLeft)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '右
     With .Borders(xlEdgeRight)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '下
     With .Borders(xlEdgeBottom)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    End With
   ElseIf NRng.Address = r.Offset(-1).Address Then
    With NRng
    '左
     With .Borders(xlEdgeLeft)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '右
     With .Borders(xlEdgeRight)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '上
     With .Borders(xlEdgeTop)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    End With
   ElseIf NRng.Address = r.Offset(, 1).Address Then
    With NRng
    '右
     With .Borders(xlEdgeRight)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '上
     With .Borders(xlEdgeTop)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '下
     With .Borders(xlEdgeBottom)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    End With
   Else
    With NRng
    '左
     With .Borders(xlEdgeLeft)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '上
     With .Borders(xlEdgeTop)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    '下
     With .Borders(xlEdgeBottom)
     .LineStyle = xlContinuous
     .Weight = xlThin
     .ColorIndex = xlAutomatic
     End With
    End With
   End If
 End If
 If cnt > 1 Then
   Set prerng = r
 Else
   Set prerng = Worksheets(1).Cells(1, 1)
 End If
 NRng.Value = cnt
 Set r = NRng
 Call hukuro
 Application.StatusBar = cnt
 DoEvents
 If hantei = True Then
   'bl = True
   Call main(maxnum)
   Exit Do
 End If
 'Sleep 10
 Sleep 1
  If cnt = maxnum Then
   ws.UsedRange.EntireColumn.AutoFit
    bl = True
   MsgBox "完了"
   Exit Do
  End If
 Loop
 'If cnt = maxnum Then MsgBox "完了"
 Set ws = Nothing
End Function

Function nextrng()
Dim Myrnd As Long
Dim chk As Boolean
 chk = True
 Randomize
 Myrnd = Int((saidai - saishou + 1) * Rnd + saishou)
 Select Case Myrnd
  Case 1
  If r.Row = 65536 Then
    chk = False
  Else
    Set NRng = r.Offset(1)
  End If
  Case 2
  If r.Row = 1 Then
    chk = False
  Else
   Set NRng = r.Offset(-1)
  End If
  Case 3
  If r.Column = 256 Then
    chk = False
  Else
    Set NRng = r.Offset(, 1)
  End If
  Case 4
  If r.Column = 1 Then
    chk = False
  Else
    Set NRng = r.Offset(, -1)
  End If
  End Select
 
  If chk = False Then
   Call nextrng
  End If
  If NRng.Value <> "" Then
   Call nextrng
  End If
End Function

Function hukuro()
  hantei = False
  If NRng.Row = 1 Then
   If NRng.Column = 1 Then
     If NRng.Offset(1).Value <> "" And NRng.Offset(, 1).Value <> "" Then
      hantei = True
     End If
   ElseIf NRng.Column = 256 Then
     If NRng.Offset(1).Value <> "" And NRng.Offset(, -1).Value <> "" Then
      hantei = True
     End If
   Else
     If NRng.Offset(1).Value <> "" And NRng.Offset(, 1).Value <> "" And NRng.Offset(, -1).Value <> "" Then
      hantei = True
     End If
   End If
  ElseIf NRng.Row = 65536 Then
   If NRng.Column = 1 Then
     If NRng.Offset(-1).Value <> "" And NRng.Offset(, 1).Value <> "" Then
      hantei = True
     End If
   ElseIf NRng.Column = 256 Then
     If NRng.Offset(-1).Value <> "" And NRng.Offset(, -1).Value <> "" Then
      hantei = True
     End If
   Else
     If NRng.Offset(-1).Value <> "" And NRng.Offset(, 1).Value <> "" And NRng.Offset(, -1).Value <> "" Then
      hantei = True
     End If
   End If
  Else
   If NRng.Column = 1 Then
     If NRng.Offset(, 1).Value <> "" And NRng.Offset(-1).Value <> "" And NRng.Offset(1).Value <> "" Then
      hantei = True
     End If
   ElseIf NRng.Column = 256 Then
    If NRng.Offset(, -1).Value <> "" And NRng.Offset(1).Value <> "" And NRng.Offset(-1).Value <> "" Then
      hantei = True
    End If
   Else
    If NRng.Offset(, -1).Value <> "" And NRng.Offset(, 1).Value <> "" And NRng.Offset(1).Value <> "" And NRng.Offset(-1).Value <> "" Then
      hantei = True
    End If
   End If
  End If
End Function

Function kei1()
  With r
   '左
   With .Borders(xlEdgeLeft)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
   '右
   With .Borders(xlEdgeRight)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
  End With
End Function

Function kei2()
  With r
   '左
   With .Borders(xlEdgeLeft)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
   '下
   With .Borders(xlEdgeBottom)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
  End With
End Function

Function kei3()
  With r
   '右
   With .Borders(xlEdgeRight)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
   '下
   With .Borders(xlEdgeBottom)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
  End With
End Function

Function kei4()
  With r
   '左
   With .Borders(xlEdgeLeft)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
   '上
   With .Borders(xlEdgeTop)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
  End With
End Function

Function kei5()
  With r
   '右
   With .Borders(xlEdgeRight)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
   '上
   With .Borders(xlEdgeTop)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
  End With
End Function

Function kei6()
  With r
   '上
   With .Borders(xlEdgeTop)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
   '下
   With .Borders(xlEdgeBottom)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
   End With
  End With
End Function

【78308】Re:Randomwalk
発言  β  - 16/6/23(木) 21:48 -

引用なし
パスワード
   ▼kinoko さん:

私も一例を。

動きの枠を、今、デスクトップに表示されているエクセルシートの範囲にしています。
ただし、かなり細かなマス目にしてありますよね。【壁】には、なかなか到達しないかもしれません。
気長に眺めていれば、いつかは壁にぶつかって、壁の外にはいかない動きをします。

すでに通り過ぎて色がついているセルについては、HSV色相で左回りに10°ずつ、色を変化させています。
h tps://ja.wikipedia.org/wiki/%E8%89%B2%E7%9B%B8

なお、HSV色相に関してはVBAでは標準の変換関数がないので自前で共通プロシジャとして使っているものを
使います。

Shiftキーを眺めに押せば、終了します。

●テストモジュール

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long

Sub Sample()
  Dim i As Long
  Dim j As Long
  Dim n As Long
  Dim t As Long
  Dim l As Long
  Dim r As Long
  Dim b As Long
  Dim a As Range
  Dim rtn As Long
  Dim d As HSVSET
  Dim pos As Variant
  
  Cells.Clear

  Randomize

  Cells.RowHeight = 5
  Cells.ColumnWidth = 0.5
  
  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count
    l = .Column
    r = .Columns.Count
  End With
  
  '最初のセルを選定
  i = Int((b - t + 1) * Rnd + t)
  j = Int((r - l + 1) * Rnd + l)
  Cells(i, j).Interior.Color = vbRed
  
  Do
    
    rtn = GetAsyncKeyState(16) 'シフトキー
    rtn = rtn And &H80000000
    If rtn <> 0 Then Exit Do
    
    If i = l And j = t Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = r And j = t Then '領域の右上隅
      pos = Array(4, 6, 7)
    ElseIf i = b And j = l Then '領域の左下隅
      pos = Array(2, 3, 5)
    ElseIf i = b And j = r Then '領域の右下隅
      pos = Array(1, 2, 6)
    ElseIf i = t Then      '領域の上辺
      pos = Array(4, 5, 6, 7, 8)
    ElseIf i = b Then      '領域の下辺
      pos = Array(1, 2, 3, 4, 5)
    ElseIf j = l Then      '領域の左端
      pos = Array(2, 3, 5, 7, 8)
    ElseIf j = r Then      '領域の右端
      pos = Array(1, 2, 4, 6, 7)
    Else
      pos = Array(1, 2, 3, 4, 5, 6, 7, 8)
    End If
    
    n = Int((UBound(pos) - LBound(pos) + 1) * Rnd + LBound(pos))
    n = pos(n)
    
    'セル移動
    Select Case n
      Case 1: i = i - 1: j = j - 1
      Case 2: i = i - 1
      Case 3: i = i - 1: j = j + 1
      Case 4: j = j - 1
      Case 5: j = j + 1
      Case 6: i = i + 1: j = j - 1
      Case 7: i = i + 1
      Case 8: i = i + 1: j = j + 1
    End Select
    
    With Cells(i, j).Interior
      If .ColorIndex = xlNone Then
        .Color = vbRed     '最初は赤
      Else
        d = RGB2HSV(.Color)
        d.h = d.h + 10     '次からは色相を10°左回りに移動した色
        .Color = HSV2RGB(d)
      End If
    End With
    
    Sleep 10
    DoEvents
    
  Loop
  
End Sub

●共通プロシジャモジュール

Public Type HSVSET
  h As Double
  s As Double
  v As Double
End Type

Public Type RGBSET
  r As Long
  g As Long
  b As Long
End Type

Function RGB2HSV(rgbVal As Long) As HSVSET
  Dim mx As Long
  Dim mn As Long
  Dim r As Long
  Dim g As Long
  Dim b As Long
  Dim z As RGBSET
  
  z = divRGB(rgbVal)
  
  r = z.r
  g = z.g
  b = z.b
  
  mn = WorksheetFunction.Min(r, g, b)
  mx = WorksheetFunction.Max(r, g, b)
  
  If mx = mn Then
    RGB2HSV.h = 0
  Else
    Select Case mx
      Case r
        RGB2HSV.h = (60 * (g - b) / (mx - mn) + 360)
        If (RGB2HSV.h >= 360#) Then
          RGB2HSV.h = RGB2HSV.h - 360#
        End If
      Case g
        RGB2HSV.h = 60 * (b - r) / (mx - mn) + 120
      Case b
        RGB2HSV.h = 60 * (r - g) / (mx - mn) + 240
    End Select
  End If
  
  If mx = 0 Or mx = mn Then
    RGB2HSV.s = 0
  Else
    RGB2HSV.s = 255 * ((mx - mn) / mx)
  End If
  
  RGB2HSV.v = mx
  
End Function

Function HSV2RGB(d As HSVSET) As Long
  Dim r As Long
  Dim g As Long
  Dim b As Long
  Dim f As Double
  Dim i As Long
  Dim p As Long
  Dim q As Long
  Dim t As Long
  Dim h As Double
  Dim s As Double
  Dim v As Double
 
  If d.s = 0 Then
    r = d.v
    g = d.v
    b = d.v
  Else
    h = d.h
    s = d.s
    v = d.v
    If h = 360 Then h = 0
    i = Int(h / 60) Mod 6
    f = h / 60 - Int(h / 60)
    p = Int(CInt(v * (1 - (s / 255))))
    q = Int(CInt(v * (1 - (s / 255) * f)))
    t = Int(CInt(v * (1 - ((s / 255) * (1 - f)))))
    
    Select Case i
      Case 0: r = v: g = t: b = p
      Case 1: r = q: g = v: b = p
      Case 2: r = p: g = v: b = t
      Case 3: r = p: g = q: b = v
      Case 4: r = t: g = p: b = v
      Case 5: r = v: g = p: b = q
    End Select
  End If
  
  HSV2RGB = RGB(r, g, b)
  
End Function

Function divRGB(rgbVal As Long) As RGBSET
  divRGB.b = rgbVal \ 256 ^ 2
  divRGB.g = (rgbVal - divRGB.b * 256 ^ 2) \ 256
  divRGB.r = rgbVal - divRGB.b * 256 ^ 2 - divRGB.g * 256
End Function

【78309】Re:Randomwalk
回答  kinoko  - 16/6/24(金) 0:03 -

引用なし
パスワード
   >壁 とは 具体的にどこを想定されています?
>PC画面に見えている範囲のことですか?

説明を忘れていました。行や列が0をせずになんとか止まらず動かしていきたいって感じです。壁というのは行と列ですね。申し訳ないです。

>色を変えていく処理
>どんなように変化させていきたいですか?

一度通ったところは赤、二度目は青色っていう風にしてみたいんですけど、まず0になってエラー吐くんでできてないんですよね…

【78310】Re:Randomwalk
発言  β  - 16/6/24(金) 0:46 -

引用なし
パスワード
   ▼kinoko さん:

>一度通ったところは赤、二度目は青色っていう

ということなら色相返還をしなくてもいいので、アップした、共通モジュールプロシジャは必要なく
以下のみでOKですね。
色の順番は ★のところで規定しています。

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long

Sub Sample2()
  Dim i As Long
  Dim j As Long
  Dim n As Long
  Dim t As Long
  Dim l As Long
  Dim r As Long
  Dim b As Long
  Dim a As Range
  Dim rtn As Long
  Dim pos As Variant
  Dim color As Variant
  
  Cells.Clear
  
  Randomize

  Cells.RowHeight = 5
  Cells.ColumnWidth = 0.5
  
  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count
    l = .Column
    r = .Columns.Count
  End With
  
  color = Array(vbRed, vbBlue, vbMagenta, vbYellow, vbCyan, vbBlack, vbRed)  '★
  
  '最初のセルを選定
  i = Int((b - t + 1) * Rnd + t)
  j = Int((r - l + 1) * Rnd + l)
  Cells(i, j).Interior.color = vbRed
  
  Do
    
    rtn = GetAsyncKeyState(16) 'シフトキー
    rtn = rtn And &H80000000
    If rtn <> 0 Then Exit Do
    
    If i = l And j = t Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = r And j = t Then '領域の右上隅
      pos = Array(4, 6, 7)
    ElseIf i = b And j = l Then '領域の左下隅
      pos = Array(2, 3, 5)
    ElseIf i = b And j = r Then '領域の右下隅
      pos = Array(1, 2, 6)
    ElseIf i = t Then      '領域の上辺
      pos = Array(4, 5, 6, 7, 8)
    ElseIf i = b Then      '領域の下辺
      pos = Array(1, 2, 3, 4, 5)
    ElseIf j = l Then      '領域の左端
      pos = Array(2, 3, 5, 7, 8)
    ElseIf j = r Then      '領域の右端
      pos = Array(1, 2, 4, 6, 7)
    Else
      pos = Array(1, 2, 3, 4, 5, 6, 7, 8)
    End If
    
    n = Int((UBound(pos) - LBound(pos) + 1) * Rnd + LBound(pos))
    n = pos(n)
    
    'セル移動
    Select Case n
      Case 1: i = i - 1: j = j - 1
      Case 2: i = i - 1
      Case 3: i = i - 1: j = j + 1
      Case 4: j = j - 1
      Case 5: j = j + 1
      Case 6: i = i + 1: j = j - 1
      Case 7: i = i + 1
      Case 8: i = i + 1: j = j + 1
    End Select
    
    With Cells(i, j).Interior
      If .ColorIndex = xlNone Then
        .color = vbRed     '最初は赤
      Else
        n = WorksheetFunction.Match(.color, color, 0)
        .color = color(n)
      End If
    End With
    
    Sleep 10
    DoEvents
    
  Loop
  
End Sub

【78311】Re:Randomwalk
発言  β  - 16/6/24(金) 8:54 -

引用なし
パスワード
   ▼kinoko さん:

アップしたコードにバグありました。
Sample,Sample2 ともに

    If i = l And j = t Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = r And j = t Then '領域の右上隅
      pos = Array(4, 6, 7)

これを

    If i = t And j = l Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = t And j = r Then '領域の右上隅
      pos = Array(4, 6, 7)

にしてください。

【78312】Re:Randomwalk
質問  kinoko  - 16/6/24(金) 12:36 -

引用なし
パスワード
   ▼β さん:

ありがとうございます。参考になりました。
あと一つだけ聞きたいのですが

行と列が0にならないようにする処理はβ さんのプログラムではどこに書かれてますか?

if do loop 乱数発生 case select 値の入れ替えぐらいしか習っていなくて
これらを駆使して作りたいのですが可能ですか?

何度も質問して申し訳ありません...

【78313】Re:Randomwalk
発言  β  - 16/6/24(金) 13:40 -

引用なし
パスワード
    ▼kinoko さん:

通常、あるセルから1つ移動させるとしたら
左上、上、右上
左、右
左下、下、右下
この8方向ですね。
でも、セルの場所によっては、上にいけない、左にいけないといった制約がある場所がありますね。

で、私のコードでは、左上、上、右上、左、右、左下、下、右下 を 1,2,3,4,5,6,7,8 という番号で指定。
現在のセルの場所に応じて、そのセルから移動できる場所番号を配列に格納。
(場所によって、8か所、5か所、3か所)
pos = Array(5, 7, 8) や pos = Array(1, 2, 4, 6, 7) といったところです。

で、この配列内からランダムに要素を1つ取り出し、1〜8 に応じて、現在の行や列に対して必要な変更を行っています。
Case 1: i = i - 1: j = j - 1 や Case 7: i = i + 1 といったところです。

なので、0 になるのを防ぐというより、最初から候補として、0にならないものに絞っているといったほうが
よろしいかもしれませんね。

そちらのコードの、その部分(0を回避)については 各コードブロックで r と c を求めた後
c が 0 なら c を 1 にする、r が 0 なら r を 1にするといった【逃げ】のコードを追加 といった感じですかね。
これで 0 になってエラーになるのは回避されるでしょうけど、右と下の枠も設定しておかなければ、どんどんと
見えない場所にいってしまいますね。



【78314】Re:Randomwalk
発言  カエムワセト  - 16/6/24(金) 18:36 -

引用なし
パスワード
   >行と列が0にならないようにする処理はβ さんのプログラムではどこに書かれてますか?

まずはβさんのコードの解釈を一行づつ付けて行ってみては?
そうすると自ずと分かってくると思います。

【78315】Re:Randomwalk
発言  β  - 16/6/24(金) 20:32 -

引用なし
パスワード
   ▼kinoko さん:

またまたコード不備発見。
A1を左上隅にして実行すれば問題は顕在化しませんが、スクロールされた状態であっても
VisibleRangeを相手にしているのに、その底辺と右端のセットに不備がありました。

Sample/Sample2ともに

  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count
    l = .Column
    r = .Columns.Count
  End With

これを

  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count + .Row - 1
    l = .Column
    r = .Columns.Count + .Column - 1
  End With

こうかえてください。

786 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free