2007年6月27日水曜日

第13回目 データ処理マクロの基礎2

○第13回目 データ処理マクロの基礎2
 マクロの実物を掲載するようになりましたので、こういう際のお決まりを申し述べておきます。
[免責事項]
 このブログに掲載するマクロを使用した際に不具合が生じても、筆者がその責任を負うことはありません。
 また、紹介するマクロ等に関しても同様です。
 あくまで自己責任でご利用ください。
 この旨は、第1回目にも追記しました。

 数独表などの形式(罫線などの見てくれ)は、通常のエクセル操作でしてください。
 今回は、数独表の分析を例にとって見ましょう。
 具体的には、
 あるブロックを決めた時、ある数値がそのブロックに入る可能性があるのかないのかを求めます。
 ブロックの種類としては、縦列ブロック、横列ブロック、3×3のブロックの3種類でそれぞれ9ブロックあり、全部で27ブロックとなります。
 ここに数値(1-9)が絡んでくるので、9×27=243の判定をしようということになります。
 1は入る可能性がある、9はそのブロックの中にあるのでもう入れないという意味とします。
 さて243も必要ですので、縦に長くなったり横に長くなったりしますので、工夫をします。
 前回でE15から81行を使っていますので、その横に、列ブロック、横ブロック、3×3ブロックの、三つに分けて展開します。列としては、M列、O列、Q列とします。
 最初の9行は、第一ブロックについて、1-9までを表します。
 ですから、15行は、数値"1"について、第1列、第1行、第1の3×3ブロックで入るのか、入れないのかを表します。
 20行目は、数値"6"についてです。
 24行目からは第2ブロックに移ります。
 30行目は数値"7"について、第2ブロックについてとなります。(7=30-(15-1)-9)
 
 表のイメージはよろしいでしょうか。
 
 列と行は簡単なのでまずはそこまで。
 一行目に、エクセル操作で"=column()"といれて、後ろまでコピーしてください。列番号がわかりますので、指をおらずに考えることが出来ます。
 
 数独ですの、ある数値がブロックに入るのは1個だけです。ですからすでにそのブロックに数値が入っていればもうは入れません。原理は簡単です。
 
 まず最初は、1が一列目にあるかどうかを見ればいいのです。
 ii=1
 flag=1
  for j=0 to 8
 if cells(4+j,3) = ii then
  flag=9
  exit for
 end if
  next j
'flagが1の時、何もないのではいる可能性あり。9の時、すでに入っている。
検査結果を入れる場所は、M15なのでcells(15,13)=cells(14+ii,13)となります。
15は、"14+ii"と考えることが出来ます。
if flag=9 then
cells(14+ii,13)=9
else
cells(14+ii,13)=1
end if

 ここでiiが1-9まで動くので、for文で包みます。
 

for i =0 to 8
 ii=i+1
 flag=1
  for j=0 to 8
 if cells(4+j,3) = ii then
  flag=9
  exit for
 end if
  next j

if flag=9 then
cells(14+ii,13)=9
else
cells(14+ii,13)=1
end if

next i

 さらに、列が1-9と動くので、for文で包みます。

Sub a19数独数値の有無のチェック()
'ある数値が、ブロックごとに入れるかどうかをチェックする

for k =0 to 8

for i =0 to 8
 ii=i+1
 flag=1   '=⇒フラッグの初期化はここでいいのか
  for j=0 to 8
 if cells(4+j,3) = ii then  '=⇒3を動かす必要がある。
  flag=9
  exit for
 end if
  next j

if flag=9 then
cells(14+ii,13)=9  '=⇒14+iiを工夫する必要がある
else
cells(14+ii,13)=1  '=⇒14+iiを工夫する必要がある
end if

next i
next k

end sub
 上の状態はただ単にfor文で包み、必要なところに、コメントをおいたものです。
 列が動くということと、検査結果を入れる場所が変わるということ大切なところです。
 列は3列目が順番に動くので、3の代わりに、3+kでいいでしょう。
 結果を入れる場所は、列が進むと下に移動します。正確には列が一つ進むと、次のブロックにいくので下に9つ動きます。すなわち、13の代わりに、13+k*9とすればいいということです。
 フラッグの初期化の場所は、最小単位の検査が始まる直前なので、現在のままで大丈夫です。

 上に述べた置き換えをして実行してください。
 チェックもお忘れなく。
 横にあるE列にある数値とはまったく関係がありませんので、かなりこんがります。ゆっくりと進んでください。
 
 かなり長くなりましたので、ここで一区切りとします。
 

0 件のコメント: