2008年3月2日日曜日

第83回目 図形作成システムの完成度を求めて(その6)

○第83回目 図形作成システムの完成度を求めて(その6)

 今回は、残りました、
 1.図形番号の並べ替え
 2.図形のグループ化及び解除
 を取り上げます。

 まず、"2.図形のグループ化及び解除"です。
 グループ化とその解除のコマンドはどうなっているでしょうか。
 マクロの記録をとってみると、
 グループ化は、
ActiveSheet.Shapes.Range(Array(……)).Select)
で図形を指定して、
Selection.ShapeRange.Group.Select
 です。
 解除は、グループ化するとそのグループ群は図形としては一つとなりますので、その図形番号を選択して
Selection.ShapeRange.Ungroup.Select
 です。
 グループ化した場合、テキストの書き込みはできず、エラーとなります。当然取得もエラーとなります。注意してください。
 ここで更なる問題が発生しました。複数の図形の一括選択はすでに、"図形の整列"で行なっていたので大丈夫だと思ったのですが、ダミーで繰り返し図形を選択し続けるという、あのやり方ではダメだったのです。

 現象としてはこういうことです。
 図形番号の変数としては100個用意されています。
 3個の図形を選択したら、グループ化されたのは、2番目と3番目だけでした。
 4個の図形を選択したら、4つともグループ化されました。
 5個の図形を選択したら、エラーとなりました。
 7個の図形を選択したら、1番目と2番目の図形だけがグループ化されました。
 100個の変数を10個にしたら4個の場合でも全部はグループ化されませんでした。
 100個とか10個というのも絡んでいそうです。
 理由は?
 この現象から帰納的にしばらく考えてみました。
 3と100、1個のみ対象外。
 そういえば、100を3で割れば、1余るなあ。
 でも、4と5は両方とも割り切れる。でも結果が正反対。
 ということで、しばらく考えた結果、商もかかわりあがるということに気がつきました。
 わかると簡単です。array文で図形を選択するのですが、その数がわからないため、工夫として繰り返したのでした。その繰り返しの回数が鍵を握っていたのでした。まずは、選択、次は解除、その次は選択、その次は解除というふうになっていたようです。
 ですから、偶数回繰り返すと解除になってしまうのです。
 4個では大丈夫で、5個ではだめだった理由はここにあります。
 3個の場合は、33回目に選択した段階ですべてが選択されていました。次の1回で一番目が解除されたのです。そこで100個は終了したしましたので、2,3番目だけが有効となったのです。
 さてどうやってこれを解消しましょうか
 まず対応としては、繰り返すものをすべてではなく、第一番目の図形番号だけにします。すると被害は、一つの図形だけになります。また、確率は半々になります。
 したがって、二つのものを用意しておき、そのときの状況によって、どちらかを選択すればいいのです。
 全部を201個として、正味の選択する図形を例えば9とすると、繰り返し指定しなければならない回数は、201-9=192となります。この場合は、すでに選択していることから、偶数回は元に戻りますので、選択となります。よって、201個の指定のままでいいことになります。
 選択図形が10個だったらどうでしょうか。残りは奇数になります。この場合は、選択の解除となります。この場合は、200個までの指定にしておけばいいのです。200個までの指定では、偶数回の選択になりますので、9個の例と同じように、選択となります。
 ですから、とても長いArray文、201個のものと200個のものをつくり、条件によって選択すれば解決となります。
 長いコマンド文になりますが、コピー・修正を繰り返せがそれほどではなく出来上がります。継続行の指定は数の制限があるので、物理的な1行で20個記述することにしてください。
  ActiveSheet.Shapes.Range(Array( _
nn(0), nn(1), nn(2), nn(3), nn(4), nn(5), nn(6), nn(7), nn(8), nn(9), nn(10), nn(11), nn(12), nn(13), nn(14), nn(15), nn(16), nn(17), nn(18), nn(19) _
     :     :     :     :
, nn(180), nn(181), nn(182), nn(183), nn(184), nn(185), nn(186), nn(187), nn(188), nn(189), nn(190), nn(191), nn(192), nn(193), nn(194), nn(195), nn(196), nn(197), nn(198), nn(199), nn(200) _
)).Select
 というような感じです。
 後は注意すべき点はありません。

 1.図形番号の並べ替え です。
 やっとロジック系のマクロになりまた。
 ここでは番号の若いもの(新しい番号におけるもの)から、図形を一番前(図形番号では一番大きい)においていきます。全部終われば、一番最初に処理したものが一番後ろ(図形番号では一番小さい)になります。
 新しい番号体系(次の操作を前提とすれば連番である必要はない。しかしマクロを動かす時は、B列は連番であることが必須です)はB列に書き込まれているとします。C列は古い番号が書き込まれています。
【手作用により新しい番号体系を連番にする】
 1.BとC列を指定してB列順にソートします。
 2.A列に1からの連番を振ります。
 3.A-C列を指定して、C列順にソートします。
 4.A列をB列にコピーします。
 これでB列に連番の新しい番号がはいります。

 処理の考え方は次のようになります。
 1.B列から1番のものを探す。
 2.1番の図形番号(C列)を最前面(=図形番号が一番大きくなる=ii9となる)に移します
  (エクセルの内部では図形番号が自動的に更新されます。そのため3.の処理が必要となります)
 3.当該図形番号より大きい図形番号をマイナス1します。

 4.B列から2番目の図形を探す。
 5.2から4.の繰り返しです。
 変数としては、
n_old(200)…初めの図形番号
n_new(200)…並べ替えたい新しい図形番号
n_gen(200)…一回ずつ並べ替えた後、更新した図形番号
を設定します。
1.で判断する図形番号は、n_new(k)の中に入っているものです。添え字ではありません。
 3.で判断する図形番号は、n_gen(k)の中に入っているものです。添え字ではありません。
現在、新しい番号で何番目の図形を処理しているかを、iとします。
1.は、if n_new(j)=i となります。
2.は、n_gen(j)を最前面にします。あわせてn_gen(j)=ii9とします。
3.は、n_gen(j)より大きいn_gen(k)をマイナス1します。n_gen(k)=n_gen(k)-1
i=i+1として、繰り返しです。
最前面にするのは、おさらいですが、次のようになります。
ActiveSheet.Shapes(j).Select
Selection.ShapeRange.ZOrder msoBringToFront

余裕があれば、マクロの中で、B列の数値を順番に並べ替え、1からの連番にする機能を入れてください。
これはこんがります。いや、こんがりました。

0 件のコメント: