第6講 If文(分岐)を理解しよう

第21話 Long型変数を排除

解答例

Private Sub CommandButton1_Click()
        ・
        ・
        ・

  For i = 0 To 9
    Cells(20, 1 + i) = 0
  Next
  For i = 0 To 80
    a = i Mod 9
    s = Int(i / 9)
    k = Cells(7 + a, 9 + s)
    Cells(20, k) = 1
    If a = 8 Then
      w = Cells(20, 1) * Cells(20, 2) * Cells(20, 3) * Cells(20, 4) * Cells(20, 5) * Cells(20, 6) * Cells(20, 7) * Cells(20, 8) * Cells(20, 9)
      If w = 1 Then Cells(16, 9 + s) = "○" Else Cells(16, 9 + s) = "×"
      Cells(20, 1) = 0
      Cells(20, 2) = 0
      Cells(20, 3) = 0
      Cells(20, 4) = 0
      Cells(20, 5) = 0
      Cells(20, 6) = 0
      Cells(20, 7) = 0
      Cells(20, 8) = 0
      Cells(20, 9) = 0
      w = 1
    End If
  Next

  For i = 0 To 9
    Cells(20, 1 + i) = 0
  Next
  w = 1
  For i = 0 To 80
    a = i Mod 9
    s = Int(i / 9)
    k = Cells(7 + s, 9 + a)
    Cells(20, k) = 1
    If a = 8 Then
      w = Cells(20, 1) * Cells(20, 2) * Cells(20, 3) * Cells(20, 4) * Cells(20, 5) * Cells(20, 6) * Cells(20, 7) * Cells(20, 8) * Cells(20, 9)
      If w = 1 Then Cells(7 + s, 18) = "○" Else Cells(7 + s, 18) = "×"
      Cells(20, 1) = 0
      Cells(20, 2) = 0
      Cells(20, 3) = 0
      Cells(20, 4) = 0
      Cells(20, 5) = 0
      Cells(20, 6) = 0
      Cells(20, 7) = 0
      Cells(20, 8) = 0
      Cells(20, 9) = 0
      w = 1
    End If
  Next


  Dim a3a As Byte, a3s As Byte 'a3aはaを3で割った余り。a3sはaを3で割った余り。aはiを9で割った余り。
  Dim s3a As Byte, s3s As Byte 's3aはsを3で割った余り。s3sはsを3で割った余り。sはiを9で割った余り。
  w = 1
   For i = 0 To 9
    Cells(20, 1 + i) = 0
  Next
  For i = 0 To 80
    a = i Mod 9
    s = Int(i / 9)
    a3a = a Mod 3
    a3s = Int(a / 3)
    s3a = s Mod 3
    s3s = Int(s / 3)
    k = Cells(7 + 3 * s3s + a3s, 9 + 3 * s3a + a3a)
    Cells(20, k) = 1
    If a = 8 Then
      Cells(17 + s3s, 5 + 6 * s3a) = "第"
      Cells(17 + s3s, 6 + 6 * s3a) = s + 1
      Cells(17 + s3s, 7 + 6 * s3a) = "ブロック"
      w = Cells(20, 1) * Cells(20, 2) * Cells(20, 3) * Cells(20, 4) * Cells(20, 5) * Cells(20, 6) * Cells(20, 7) * Cells(20, 8) * Cells(20, 9)
      If w = 1 Then Cells(17 + s3s, 9 + 6 * s3a) = "○" Else Cells(17 + s3s, 9 + 6 * s3a) = "×"
      Cells(20, 1) = 0
      Cells(20, 2) = 0
      Cells(20, 3) = 0
      Cells(20, 4) = 0
      Cells(20, 5) = 0
      Cells(20, 6) = 0
      Cells(20, 7) = 0
      Cells(20, 8) = 0
      Cells(20, 9) = 0
      w = 1
    End If
  Next


  Range("A20:J20").Select
  Selection.ClearContents '一時的に借りたセルをお掃除
  Range("A1").Select

End Sub

参考ファイル

解説
初心者の皆さんには大変酷な課題を出してしまいました。
????
ですよね。

    k = Cells(7 + 3 * s3s + a3s, 9 + 3 * s3a + a3a)
    Cells(20, k) = 1
の2行が謎ですよね。
ですから説明しましょう。
  For i = 0 To 9
    Cells(20, 1 + i) = 0
  Next
または
      Cells(20, 1) = 0
      Cells(20, 2) = 0
      Cells(20, 3) = 0
      Cells(20, 4) = 0
      Cells(20, 5) = 0
      Cells(20, 6) = 0
      Cells(20, 7) = 0
      Cells(20, 8) = 0
      Cells(20, 9) = 0



いったんA20からJ20までのセルがすべて0となっています。


例えば、上のように列に数字の重複があったとします。
ということは数字が1つ抜けているということです。
この場合は、9が抜けています。
ですから
    k = Cells(7 + 3 * s3s + a3s, 9 + 3 * s3a + a3a)
    Cells(20, k) = 1
の2行によって、
Cells(20, 3) = 1の計算は2回行われるのに対して、
Cells(20, 9) = 1の計算は行われません。
すなわち
Cells(20, 9) = 0
のままいじられないということです。
かけ算ですから、
1カ所でも0になると0になります。

    If a = 8 Then
      w = Cells(20, 1) * Cells(20, 2) * Cells(20, 3) * Cells(20, 4) * Cells(20, 5) * Cells(20, 6) * Cells(20, 7) * Cells(20, 8) * Cells(20, 9)
      If w = 1 Then Cells(16, 9 + s) = "○" Else Cells(16, 9 + s) = "×"
×側が実行されることにないます。
実際には

重複がありませんから、
Cells(20, k) = 1
kには順に数独の1列目の数字7,1,2,3,5,8,9,4,6が入りますから
Cells(20, 7) = 1
Cells(20, 1) = 1
Cells(20, 2) = 1
Cells(20, 3) = 1
Cells(20, 5) = 1
Cells(20, 8) = 1
Cells(20, 9) = 1
Cells(20, 4) = 1
Cells(20, 6) = 1
の計算が行われています。
(iを例えば0から8まで動かしてトレースしてみてください。)
順番を並び換えれば
Cells(20, 1) = 1
Cells(20, 2) = 1
Cells(20, 3) = 1
Cells(20, 4) = 1
Cells(20, 5) = 1
Cells(20, 6) = 1
Cells(20, 7) = 1
Cells(20, 8) = 1
Cells(20, 9) = 1
とすべて1に書き換わっていることが分かります。
ですから、すべての積を取ってそれが1ならば
数独の条件(列などに1から9までの数字がもれなく重複なく入っている)
を満たしているし、
0なら満たしていないとなるわけです。


改良によってエレガントになった部分もありますが、
    If a = 8 Then
      
w = Cells(20, 1) * Cells(20, 2) * Cells(20, 3) * Cells(20, 4) * Cells(20, 5) * Cells(20, 6) * Cells(20, 7) * Cells(20, 8) * Cells(20, 9)
      If w = 1 Then Cells(7 + s, 18) = "○" Else Cells(7 + s, 18) = "×"
      
Cells(20, 1) = 0
      Cells(20, 2) = 0
      Cells(20, 3) = 0
      Cells(20, 4) = 0
      Cells(20, 5) = 0
      Cells(20, 6) = 0
      Cells(20, 7) = 0
      Cells(20, 8) = 0
      Cells(20, 9) = 0

      w = 1
    End If
のピンクの部分が、おしゃれでなくなってしまいました。
ですが、この部分は2次元ループを学ぶ際に解消します。

では、これで長くなりすぎた第6講を終わることにします。


20話へ 第7講第1話へ


トップ

初心者のためのc++ vc++ c言語 入門 基礎から応用までへ
初心者のための excel 2007 2010 2013 vba マクロ 入門 基礎から応用まで
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
vb講義トップへ
VB講義基礎へ
専門用語なしのC++入門へ
専門用語なしのJava入門へ
専門用語なしのVBA入門

数独のページ
魔方陣のページ
数学研究室に戻る
本サイトトップへ