|    | 
     みなさん初めまして。 
Windows7にてExcel2007を使ってVBAでプログラミングをしているかなたんといいます。 
まずは、リバーシのプログラムを組んでいたときの話です。 
(初めに書いておきます。 これは半分前置きのような話です。) 
対戦が終わった最後、どちらが勝ったのかを比べるために以下の方法をとりました。 
---------------------------------------------------------------------- 
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 
Sub 判定() 
  MsgBox "どっちが勝ったか比べてみましょう。", vbOKOnly, "リバーシ" 
  Dim Bc As Byte, Bm As Byte, Bi As Byte, Bb As Boolean, Wc As Byte, Wm As Byte, Wi As Byte, Wb As Boolean 
    Bc = 1 
    Bb = True 
    Wc = 1 
    Wb = True 
  For R = 1 To 8 '盤面のこまをすべて緑に変える。 
    For C = 1 To 8 
      ActiveSheet.Shapes("N" & R & "_" & C).Select 
      Selection.ShapeRange.Line.ForeColor.SchemeColor = 17 
      Selection.ShapeRange.Fill.ForeColor.SchemeColor = 17 
    Next 
  Next '1. 
  MsgBox "どっちが勝ったのでしょう?", vbOKOnly, "リバーシ" 
Again: 
  Sleep 100 
  If Bc <= Range("K5") Then '黒が取ったこまの数だけ行う 
    Bm = Bc Mod 8 
    If Bm = 0 Then 
      Bm = 8 
      Bi = Int(Bc / 8) 
    Else 
      Bi = Int(Bc / 8) + 1 
    End If 
    ActiveSheet.Shapes("N" & Bi & "_" & Bm).Select 
    Selection.ShapeRange.Line.ForeColor.SchemeColor = 8 
    Selection.ShapeRange.Fill.ForeColor.SchemeColor = 8 '2. 
    Bc = Bc + 1 
  Else 
    Bb = False 'もう黒のこまはないと言う 
  End If 
  If Wc <= Range("K7") Then '白がとったこまの数だけ行う 
    Wm = Wc Mod 8 
    If Wm = 0 Then 
      Wm = 1 
      Wi = (9 - Int(Wc / 8)) 
    Else 
      Wm = (9 - Wm) 
      Wi = (9 - (Int(Wc / 8) + 1)) 
    End If 
    ActiveSheet.Shapes("N" & Wi & "_" & Wm).Select 
    Selection.ShapeRange.Line.ForeColor.SchemeColor = 8 
    Selection.ShapeRange.Fill.ForeColor.SchemeColor = 9 '3. 
    Wc = Wc + 1 
  Else 
    Wb = False 'もう白のこまはないと言う 
  End If 
  If Bb = True Or Wb = True Then 'もしどちらかのこまがあれば 
    GoTo Again 'Againに戻ってもう一度行う 
  End If 
  Application.Run "勝ち.勝ち" 
End Sub 
---------------------------------------------------------------------- 
すると、盤面を緑に変える前(あるいはその動作が飛ばされたあと?)に2のメッセージボックスが出てきてしまい、黒と白のこまを並べる部分では、カーソルが変わって処理中なのはわかるのですが、盤面が変わらずに4のメッセージボックスが出てきてしまいました。 
そこで、このコードの先頭(Subの次の行)に 
Application.ScreenUpdating = True 
と書いてみたのですが、それでも盤面が変わらずにメッセージボックスが出てくるだけでした。 
なので、1.2.3.のあとに↑のコードを書いたところ、今度は盤面が変わってからメッセージボックスが出るようになりました。 
そのときは、「VBAが画面の更新をサボったんだなぁ」と勝手に思っていました。 
 
今神経衰弱を作ろうと思っていて、このApplication.ScreenUpdatingであれ?っと思ったことがあるので質問させてください。 
(今回はこちらが本題です。) 
シャッフルを次の方法でさせています。 
----------------------------------------------------------------------- 
Sub 切る() 
  Application.ScreenUpdating = False 
  Dim T As Byte, i(3) As Byte 
  Dim Memo(1 To 52), Mark(3) As String, JQ(11 To 12) As String 
    Mark(0) = "ダイヤ" 
    Mark(1) = "ハート" 
    Mark(2) = "スペード" 
    Mark(3) = "クラブ" 
    JQ(11) = "J" 
    JQ(12) = "Q" 
  Dim R As Byte, C As Byte 
  Randomize 
  i(0) = Int(52 * Rnd) + 1 '最初の数字を選ぶ 
  i(1) = Int(i(0) / 13) 
  i(2) = i(0) Mod 13 
  If i(2) = 0 Then '選ばれた数字によって配置するカードを決める 
    Memo(1) = Mark(i(1) - 1) & "のK" 
    Worksheets(1).Cells(2, 2) = Mark(i(1) - 1) & "のK" 
    Worksheets(1).Cells(3, 2) = "K" 
  ElseIf i(2) >= 11 Then 
    Memo(1) = Mark(i(1)) & "の" & JQ(i(2)) 
    Worksheets(1).Cells(2, 2) = Mark(i(1)) & "の" & JQ(i(2)) 
    Worksheets(1).Cells(3, 2) = JQ(i(2)) 
  Else 
    Memo(1) = Mark(i(1)) & "の" & i(2) 
    Worksheets(1).Cells(2, 2) = Mark(i(1)) & "の" & i(2) 
    Worksheets(1).Cells(3, 2) = i(2) 
  End If 
  Application.ScreenUpdating = False 
  Worksheets(1).Shapes(Memo(1)).Top = 67.5 '決められたカードの位置を変更する 
  Worksheets(1).Shapes(Memo(1)).Left = 45 
  Application.ScreenUpdating = False 
  For T = 2 To 52 '上と同じようなことを繰り返す 
Again: 
    i(0) = Int(52 * Rnd) + 1 
    i(1) = Int(i(0) / 13) 
    i(2) = i(0) Mod 13 
    If i(2) = 0 Then 
      Memo(T) = Mark(i(1) - 1) & "のK" 
    ElseIf i(2) >= 11 Then 
      Memo(T) = Mark(i(1)) & "の" & JQ(i(2)) 
    Else 
      Memo(T) = Mark(i(1)) & "の" & i(2) 
    End If 
    For i(0) = 1 To (T - 1) 
      If Memo(T) = Memo(i(0)) Then 'もし今選んだカードが一度選ばれていたならば 
        GoTo Again 'Againに戻ってもう一度選びなおす 
      End If 
    Next 
    If (T Mod 13 = 0) Then 
      R = 2 * Int(T / 13) 
      C = 50 
    Else 
      R = 2 * Int(T / 13) + 2 
      C = (4 * (T Mod 13) - 3) + 1 
    End If 
    If i(2) = 0 Then 
      Worksheets(1).Cells(R, C) = Mark(i(1) - 1) & "のK" 
      Worksheets(1).Cells((R + 1), C) = "K" 
    ElseIf i(2) >= 11 Then 
      Worksheets(1).Cells(R, C) = Mark(i(1)) & "の" & JQ(i(2)) 
      Worksheets(1).Cells((R + 1), C) = JQ(i(2)) 
    Else 
      Worksheets(1).Cells(R, C) = Mark(i(1)) & "の" & i(2) 
      Worksheets(1).Cells((R + 1), C) = i(2) 
    End If 
    Application.ScreenUpdating = False 
    Worksheets(1).Shapes(Memo(T)).Top = 67.5 * (R / 2) 
    Worksheets(1).Shapes(Memo(T)).Left = 45 * (Int((C - 2) / 4) + 1) 
    Application.ScreenUpdating = False 
  Next 
  Application.ScreenUpdating = True 
End Sub 
----------------------------------------------------------------------- 
最初は"Application.ScreenUpdating = False"等はどこにも書かずにいたのですが、画面がちらついて背面に配置していたカードの数字が書いてあるものが、カードの絵柄の前にチラッと出てきてしまっているように見えてしまいます。 
そこで、次に先頭に"Application.ScreenUpdating = False"を書いたのですが、それでも状況が変わりません。 
そこで、ためしに↑のコードのようにカードを移動させる前と移動させたあとにも書き加えたのですが、それでも状況は変わりません。 
そこで、最後に"Application.ScreenUpdating = True"を書き加えたのですが、やはりそれでも状況はまったっく変わりません。 
 
"Application.ScreenUpdating = False"は画面の更新を抑制するためのコードだと思っているのですが、なぜ↑のコードでは抑制されないのでしょうか? 
私なりにGoogleで調べてみようと思い、検索の候補(?)にあがっていた「application.screenupdating false 効かない」というので調べてみたのですが、いろいろと見てみましたがなぜこのコードでこうなってしまうのかがわかりませんでした。 
シャッフルするときにどこに何があるのかが見えてしまわないようにシャッフルさせたいのですが、どのように書き直せばそういうことができるのでしょうか? 
どなたか知っている人がいましたら、どうかよろしくお願いいたします。 
 | 
     
    
   |