2010年6月26日土曜日

第150回目、複数個のコピー元をある規則性を持った場所にコピーする

○第150回目、複数個のコピー元をある規則性を持った場所にコピーする

 今までのコピーは、あるものをあるところにコピー
          あるものをあるブロックにコピー
          あるブロックのものをあるところにコピー
          あるブロックのものをあるところに複数回コピー
 というものでした。上から、1=⇒1、1=⇒N、N=⇒N、N=⇒N×i、ということを意味しています。
 これで十分だと思うのですが、いろいろやっていくと、コピー元がブロックであり、複数個ある場合があります。N×i=⇒N×iのパターンです。
 具体的には、2列ごとにある4つのブロックを3列ごとにコピーするというものです。コピー先をずらしていくという形もあると思います。

【例1】







【例2】








 次に、1*N=⇒N*iというのもあります。
【例3】




 テーマはお分かりになったでしょうか。飛んだ場所を、飛んだところに、コピーしようということなのです。
 ここでのコピーとは、計算式の場合は移植となり、数値の場合はコピーということにします。

Qus.計算式の移植、計算式のコピーとはどう違うのですか。
=⇒計算式の移植とは、計算式がそのまま移ります。ですから計算値は変わりません。計算式のコピーとは、通常のコピー・ペーストで貼付けるもので、計算式内の座標が原則的に変わります。計算値も変わることになります。ですから移植では、計算式をデータとみなして、そのデータを別のセルに計算式として入れるということになります。
Qus.計算式の移植を選択したということですが、コピーじゃ何か都合が悪いことがあるんですか。
=⇒例1のように、コピー元とコピー先の中での位置関係が違うことを想定しているので、二番目以降の計算式がまったくおかしなものになってしまうからです。
Qus.なるほど思いますが、前提に制約をつければ、コピー系でも有益なものがあるのではないでしょうか。
=⇒コピー元とコピー先の中での位置関係を同じにして、コピー先の間の情報をまったく変えずに飛び飛びでコピーするというのは機能としてはありうるかもしれません。
しかし、間のセルの情報を気にしなければ、全体を指定して一気にコピーすればいいことになります。あまり先々の展開は望めないのではないかと思い、コピー系ではなく、移植系としました。
=⇒なるほど。

 【例1】と【例2】の場合
 0.コピー元の最初のブロックを指定してマクロを実行する。
 1.座標情報の取得
 2.次のコピー元の先頭のセルを指定する。1と2で、たて・横の偏位がわかり、後のコピー元の位置がわかる
 3.コピー回数を入力する
 4.最初のコピー先の先頭のセルを指定する
 5.次のコピー先の先頭のセルを指定する。4と5で、たて・横の偏位がわかり、後のコピー先の位置がわかる
 6.コピー元の計算式を変数にとり、コピー先のセルに入れる(小ループ)
 7.6をコピー回数分繰り返す(大ループ)

 三種の神器ではないが、1.指定場所情報の取得、2座標情報の指定、3.パラメータの指定でほとんど終了になってしまいます。いわゆる、"おわ"ですね。
 コピー元の偏差として、hensa1_xとhensa1_yとし、コピー先の偏差として、hensa2_xとhensa2_yとすればいいでしょう。
 6の小ループは、イメージ的に言えば、1の行数です(列数の場合や行数×列数の場合もあります)。
 7の大ループは、3のコピー回数です。
 計算式の取得(ない場合は値の取得)は
 If Cells(,).HasFormula = True Then
  mm() = Cells(,).Formula
 Else
  mm() = Cells(,).Value
 End If
 計算式の移植は
 Cells(,).Formula = mm()
 または
 Cells(,) = mm()
 上のように、いったん配列の変数に入れなくても、計算式の取得と移植を一気にやる方法もありそうですね。
 すると、
 If Cells(,).HasFormula = True Then
  Cells(,).Formula = Cells(,).Formula
 Else
  Cells(,) = Cells(,).Value
 End If
 となりますが、添え字のコントロールを間違えないようにしてください。

Qus.【例1】と【例2】の使用例を教えてください。事例が思い浮かびません。
=⇒確かに、移植という事例はほとんどないですね。
 一例です。ある制度では、年齢に応じた額を支払うことにしているとします。簡単にするために、毎年支払う金額は年齢と同額とします。60歳の人には60円を、70歳の人には70円をということになります。
 あるとき制度を変更して、今時点で59歳以下の人には、これまでの額の80%、60歳以上の人にはこれまでの額の90%を支払うように制度を改めたとします。
 すると、今後を経過年度別に見ると、年齢が一つ上がっていきますので、90%のグループと80%のグループが斜めに移動していくことになります。
 さてこのような金額表をどうやってスムーズに作ったらいいでしょうか。
 このようなときに威力を発揮します。金額の計算式が複雑であればあるほど威力を発揮します。
Qus.やり方のイメージがわきません。
=⇒別なところで【例2】をやった後に、その結果を【例1】により、計算式を置きたい場所に移植します。
 1.たてに、1~115までの数字を入れます。これは年齢です(場合によっては、-40~115でも結構です)。
 2.その隣の2列に、59歳までは0.8と年齢×前の列の値(0.8)、60歳以上は0.9と年齢×前の列の値(0.9)という計算式を入れます。このとき年齢の列は絶対参照にしてください。
 3.2の列を横に、20組、列コピーします。
 4.例2により、このコピーした20組のうち奇数番の列20列(計算式ではなく、0.8とか0.9という値になっている列)を一つずつ下にずらして移植します。移植先の列は連続でかまいません。すると、四角にはなっていませんが求めたいものができたことになります。
 5.4で求めたもので空きが出てくることがありますが、それは通常のコピーで埋めてください。
 6.5で求めたもので必要な四角形を選択し、例1により、3.の値の場所に移植します。今度は移植先で列の間隔があいています。

Qus.処理対象は計算式ではないではないですか。
=⇒ご指摘はごもっともです。ものごとをわかりやすく単純化したためにこのような例をとりました。ご勘弁願います。
 本論には関係がないのですが、この処理は、計算式を取得して、その計算式を移植するという単純な処理なのですが、処理時間がかなり長いのが気になります。

※今回のテーマとは直接は関係がないように見えるのですが、コピー機能でこんなのに出会いました。スムーズに行うにはどうしたらいいでしょうか。
 たてブロックである計算式があります。それを原型として、コピーしたいのですが、コピー先は6列ずつ離れています(間に5列あるということ。また、コピー先は複数あります)。
計算式中の参照セルは、次の列にして欲しいのです。(単純に次の列にコピーして、その間に5列または5列分のセルを挿入するという方法は、他の部分に影響を与えてしまいます。他の部分に影響を与えないという前提とします)
 さらに、2.参照列の偏差がさまざまだったらどうでしょうか。
=⇒2番目にはまったく手も足も出ないので、今回は考えないことにしますが、一番目はこうしたらどうでしょうかというアイデアがあります。
 1.原型の計算式ブロックのよこに、10列挿入します。(列単位に10個コピーするとします)
 2.その10列に原型の計算式をコピーします。行番号は変わらずに、列番号だけが原則的に一つずれていきます。
 3.この10ブロックを、今回紹介したマクロで移植するのです。移植元は連続列、移植先は6列おきという規則性がありますので、今回のマクロが利用できます。
 4.最後に挿入した10列を削除します。

Qus.なるほどそのようなニーズがあったらとても便利でしょうね。それはさておき【例3】はなんか面白そうなので早く紹介してください。
=⇒長くなりましたので、今回はこれでおしまいにして、次回紹介します。

0 件のコメント: