第6講 If文(分岐)を理解しよう
第11話 1次元のFor文で2次元ループをする方法による列部分の改良
1次元のFor文で2次元ループをする方法による改良例
Private Sub CommandButton1_Click()
Dim w As Byte, i As Byte, h As Byte
Dim s As Byte, a As Byte, k As Byte '最初から使うので中程から移動
h = 1
w = 0
k = Int(6 * (6 * 6 + 1) / 2) '毎回計算させないようにするための変更
For i = 0 To 35
a = i Mod 6
s = Int(i / 6)
w = w + Cells(7 + a, 1 + s)
If a = 5 Then
If h = 1 Then If w <> k Then h = 0
Cells(13, 1 + s) = w
w = 0
End If
Next
w = 0
For i = 0 To 5
w = w + Cells(7, 1 + i)
Next
If h = 1 Then If w <> k Then h = 0 '毎回計算させないようにするための変更
・
・
・
Dim v As Long, x As Long '毎回計算させないようにするための変更
v = 1
x = CLng(1) * CLng(2) * CLng(3) * CLng(4) * CLng(5) * CLng(6) * CLng(7) * CLng(8) * CLng(9) '毎回計算させないようにするため
For i = 0 To 8
v = v * CLng(Cells(7 + i, 9))
Next
If v = x Then Cells(16, 9) = "○" Else Cells(16, 9) = "×" '毎回計算させないようにするための変更
・
・
・
End Sub
Private Sub CommandButton2_Click()
Range("A13:F16").Select
Selection.ClearContents
Range("G7:G12,I16:v19,R7:R15").Select
Selection.ClearContents
Range("A1").Select
End Sub
参考ファイル
解説
Dim s As Byte, a As Byte, k As Byte '最初から使うので中程から移動
1次元のFor文で2次元ループをする方法にするために
aとsを使うので、2行目に移動しました。
中程のものは削除しておかないと、
同じ宣言を2回することになりエラーするので気をつけてください。
k = Int(6 * (6 * 6 + 1) / 2) '毎回計算させないようにするための変更
は前回までのものは毎回Int(6 * (6 * 6 + 1) / 2)を計算させていて、
明らかに無駄な計算をさせていましたので導入しました。
数独自動生成ソフト(アプリ)の計算量は膨大ですから、
できるだけ無駄をさせないようにして、
処理速度を上げるように努めなければなりません。
1回だけ計算させ、それを変数に入れておいて再利用するようにしたわけです。
If h = 1 Then If w <> k Then h = 0 '毎回計算させないようにするための変更
が再利用の部分です。
If h = 1 Then If w <> Int(6 * (6 * 6 + 1) / 2) Then h = 0
からの変更です。
以降もすべて変更してあります。
変更は手作業で行ったのではなく、
一括置換で行いました。
Dim v As Long, x As Long '毎回計算させないようにするための変更
x = CLng(1) * CLng(2) * CLng(3) * CLng(4) * CLng(5) * CLng(6) * CLng(7)
* CLng(8) * CLng(9) '毎回計算させないようにするため
If v = x Then Cells(16, 9) = "○" Else Cells(16, 9) = "×" '毎回計算させないようにするための変更
についても同様です。
CLng(1) * CLng(2) * CLng(3) * CLng(4) * CLng(5) * CLng(6) * CLng(7) * CLng(8) * CLng(9)
の計算が1回で済むようにしてあります。
さて、
h = 1
w = 0
k = Int(6 * (6 * 6 + 1) / 2) '毎回計算させないようにするための変更
For i = 0 To 35
a = i Mod 6
s = Int(i / 6)
w = w + Cells(7 + a, 1 + s)
If a = 5 Then
If h = 1 Then If w <> k Then h = 0
Cells(13, 1 + s) = w
w = 0
End If
Next
メインの部分を解説しましょう。
iが0から35までというのは、
36回のループ処理ということです。
最後が35なので35回と勘違いしがちですが、
0から始まっていますので36回なのです。
なぜ36回でしょうか。
1列あたり6行あり、全部で6列あるので
6×6=36
です。
wを0戻すタイミングが問題です。
wを適切なタイミングで0に戻さないと、
すべて積算されていってしまいます。
戻すタイミングは、a = 5のときであり、
しかもCells(13, 1 + s) = wで表示を行った後です。
頭が混乱しますね。
難解ですので、トレースをしてみたいと思いますが、
ファイルがかなり大きくなったので次話で行います。
トレースを読まなくても理解できた方は、
今回の列部分の改良を参考にして、
是非とも行部分の改良に取り込まれてください。
初心者のためのc++ vc++ c言語 入門 基礎から応用までへ
初心者のための excel 2007 2010 2013 vba マクロ 入門 基礎から応用まで
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
vb講義トップへ
VB講義基礎へ
専門用語なしのC++入門へ
専門用語なしのJava入門へ
専門用語なしのVBA入門
数独のページ
魔方陣のページ
数学研究室に戻る
本サイトトップへ