Dragで移動させられると楽なのにと思っています。
そこで、Drop時にセルの中央に合わせられないかと考えていたのですが、
実現が難しいんですよね。( ̄~ ̄;) ウーン
いろいろと考えて思いついたのが、
図形を一括で整列させる方法です。
Drop時にセル中央に移動しなくても
移動させた図形を一括でセル中央に整列させられれば、
もう少し、直感的な作業ができるのでは!?と考えました。
これなら図形を個々に調整するより楽かもって事で処理を考えてみます。
まず図形がどのセル上にあるか判断する必要があります。
セルが分かれば、そのセルの中央に移動させるだけの処理なので簡単に作れそうです。
シート上の図形を取得して、どのセルか割り出します。
標準モジュール
Option Explicit
Sub CellSearch()
Dim sh As Shape 'シート上の図形取得'
Dim cell As Range '図形下のセルを取得'
For Each sh In ActiveSheet.Shapes
With ActiveSheet.Shapes(sh.Name)
Set cell = Range(.TopLeftCell, .BottomRightCell)
End With
Next
MsgBox cell.Address
End Sub
シート上の図形を探して、どのセル上にあるか調べさせます。
前回記事でも書きましたが、TopLeftCellとBottomRightCellを使って調べます。
図形の左上と右下の角が乗ってるセルを特定する事ができます。
ちなみに、シート上に置くボタンもシェイプ扱いになるので、
操作ボタンは、ユーザーフォームに設定しておく方が無難です。
セルが取得できるかテストしてみます。
問題無く取得できてます。
後は、セルの中央に移動するようにさせるだけです。
標準モジュール
Sub ShapeAlignment()
Dim sh As Shape 'シート上の図形取得'
Dim cell As Range '図形下のセルを取得'
For Each sh In ActiveSheet.Shapes
With ActiveSheet.Shapes(sh.Name)
Set cell = Range(.TopLeftCell, .BottomRightCell)
.Top = cell.Top + (cell.Height - .Height) / 2
.Left = cell.Left + (cell.Width - .Width) / 2
End With
Next
End Sub
図形を見つけたらセル位置を割出して、
そのセルの中央に移動させるだけになります。
For Each sh In ActiveSheet.Shapes~Nextで、シート上の全ての図形を取得できるので、
全図形に中央揃えが適用されます。
これで問題無く中央揃えができると思うので、テストしてみます。
こんな感じで配置して、揃えボタンをPush。
なんか無茶苦茶にならんでます。( ゜.゜) ポカーン
TopLeftCellとBottomRightCellは、図形の左上と右下が乗ってるセルを調べるものなので、
当然、セル跨ぎをすると二つのセルが取得される事になります。
なので、均等揃えをすると二つセルの中央に移動してしまいます。(T-T) グスッ
これでは、セルからハミ出るとセル境界を中心に揃ってしまいます。
ある程度セルからハミ出しても、狙いのセルに移動してくれないと
使いにくい感じになるので、修正案を考えてみます。
・一番多く図形が乗ってるセルを探す。
・起点になるセルを作って、図形の位置境界を割出す。
要素としては、この二つくらいでしょうか。
セルに乗ってる面積が割出せれば、比較するのは簡単なんで調べてみました。
けれど、面積を取得する方法を見つける事ができませんでした~ (ノ_<。)うっうっうっ
しかたがないので、二番目の図形位置境界を割出す方法を考えてみます。
図形を二つのセルの中央に配置した時、セルの幅から図形の半分が重なる事になります。
なので、緑線以内なら左のセル、それより大きいなら右のセルと判断できます。
同じように、縦の境界も作って、上下で判断させるようにしてみます。
計算式としては、
左セルの幅-(図形の幅/2)=境界の幅
左セルの高さ-(図形の高さ/2)=境界の高さ
こんな感じになるかと思います。
この境界をIF文で判断させれば上手く機能しそうです。
境界内なら中央に移動させればいいのですが、
境界を超えた場合は、どうしようか?って事なんですが…
左セルの中央に移動させた図形に、セルの幅を足してやれば、
右のセル中央になるので、補正するだけですみそうです。
縦の計算も考えてコードを組んでみます。
標準モジュール
Option Explicit
Sub PositionCheck()
Dim sh As Shape '図形取得'
Dim cell As Range '図形下セル取得'
Dim posLeft As Double '図形の左位置'
Dim posTop As Double '図形の縦位置'
Dim leftBorder As Double '横境界線'
Dim topBorder As Double '縦境界線'
Dim addLeft As Integer '横の補正値'
Dim addTop As Integer '縦の補正値'
For Each sh In ActiveSheet.Shapes
Set cell = ActiveSheet.Shapes(sh.Name).TopLeftCell
addLeft = 0
addTop = 0
'境界線を計算'
leftBorder = cell.Width - (sh.Width / 2)
topBorder = cell.Height - (sh.Height / 2)
'図形の位置を計算'
posLeft = sh.Left - cell.Left
posTop = sh.Top - cell.Top
'境界を越えてるか判断'
If posLeft > leftBorder Then
addLeft = cell.Width
End If
If posTop > topBorder Then
addTop = cell.Height
End If
'図形の移動'
With ActiveSheet.Shapes(sh.Name)
.Top = cell.Top + (cell.Height - .Height) / 2 + addTop
.Left = cell.Left + (cell.Width - .Width) / 2 + addLeft
End With
Next
End Sub
まず、図形の乗ってるセルは左側が分かれば計算できるので、
TopLeftCellだけで取得します。
後は境界を超えたか超えてないか判断して、
起点のセルに中央揃えした後、addLeft とaddTopで補正してやれば、
狙ったセルに移動してくれると思います。
早速テストしてみます。
恐る恐るボタンを押すと…
上手く移動してくれました。(*^_^*)v ヤッタネ
これでDragで図形移動させて、ボタン一発で中央揃えが可能になったので、
より直感的な移動作業ができるようになりました。
しかし、既に中央に揃ってる図形を何度も移動処理させるってのも無駄なんで、
選択した図形だけ整列する処理も作ってみます。
標準モジュール
Option Explicit
Sub SelectedShape()
Dim sh As Shape '図形取得'
Dim cell As Range '図形下セル取得'
Dim posLeft As Double '図形の左位置'
Dim posTop As Double '図形の縦位置'
Dim leftBorder As Double '横境界線'
Dim topBorder As Double '縦境界線'
Dim addLeft As Integer '横の補正値'
Dim addTop As Integer '縦の補正値'
On Error GoTo Unselected
For Each sh In Selection.ShapeRange
Set cell = ActiveSheet.Shapes(sh.Name).TopLeftCell
addLeft = 0
addTop = 0
'境界線を計算'
leftBorder = cell.Width - (sh.Width / 2)
topBorder = cell.Height - (sh.Height / 2)
'図形の位置を計算'
posLeft = sh.Left - cell.Left
posTop = sh.Top - cell.Top
'境界を越えてるか判断'
If posLeft > leftBorder Then
addLeft = cell.Width
End If
If posTop > topBorder Then
addTop = cell.Height
End If
'図形の移動'
With ActiveSheet.Shapes(sh.Name)
.Top = cell.Top + (cell.Height - .Height) / 2 + addTop
.Left = cell.Left + (cell.Width - .Width) / 2 + addLeft
End With
Next
Exit Sub
Unselected:
MsgBox "選択されてないよ!"
End Sub
この記事へのコメント