○第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 件のコメント:
コメントを投稿