日付印を作成 ② 各座標を初期設定する
先日から時代の流れに逆らって、Excelで日付印の描画に挑戦している。
前回は、各座標を求める計算を一通り行った。これについて幾つか間違いが
あったため、まず修正したものを再掲する。
日付印の作成は、以下の手順で行う。
- 必要な座標などを全て最初に計算する。
- 円の描画と文字セット
- 水平線を描画
- テキストボックス(または相当品)の描画と文字セット
- グループ化
そこで今日は、円の描画と文字セットまでを行ってみよう。
以降は全て、クラスモジュール「Stamp」に記載している。
必要な変数の宣言
円や線などの描画で、複数回同じ座標が登場する。
一方で、各オートシェイプの描画処理は、サブプロシージャを分けておきたい。
ということで必要な座標などは全て、モジュールレベル変数として使いまわし
できるようにする。
Option Explicit ' 日付印を作成するセル。 Dim TargetRange As Range ' シート左上から指定セル上辺までの距離。 Dim T As Double 'シート左上から指定セル左辺までの距離。 Dim L As Double ' H(1):指定セルの高さ。 ' H(2):中央の日付を挟むように描画される水平線間の距離。 ' H(3):部署名の上辺から、氏名の下辺までの距離。 Dim H(3) As Double ' 指定セルの幅。 Dim W As Double ' 円の原点。 Dim Ox As Double Dim Oy As Double ' 円の直径。 Dim D As Double ' 円の半径。 Dim R As Double ' 指定セルの高さおよび幅のうち小さい方と、円の直径の比率。 ' ※指定セル内に収めるために設定。 ' ※ρ1=1のとき、円は指定セルの幅または高さのうち、狭い方に内接する。 Public ρ1 As Double ' 直径Dに対するH(2)の比率。 Public ρ2 As Double ' 直径Dに対するH(3)の比率。 Public ρ3 As Double ' 各描画の始点。 Dim Sx(5) As Double Dim Sy(5) As Double ' 各描画の終点。 Dim Ex(5) As Double Dim Ey(5) As Double ' 描画線の幅。 Public LineWeight As Double ' 指定色。 Public StampColor As Long ' 部署名。 Public StampPart As String ' 氏名。 Public StampName As String ' フォント名。 Public FontName As String ' 各描画したオートシェイプ。 Dim Shape(5) As Excel.Shape ' 各描画したオートシェイプの名前。 ' ※最後にグループ化の際に使用する。 Dim ShapeNames(1 To 5) As String
初期化
ユーザーが任意に微調整したい(であろう)パラメーターは、とりあえず
こちらで設定しておく。日付印を描画する前に、追加で変更(上書き)可。
Private Sub Class_Initialize() ' 初期値設定。 ' ※この後のタイミングで、日付印作成前に変更可能。 ρ1 = 0.9 ρ2 = 0.35 ρ3 = 0.9 LineWeight = 1.5 End Sub
初期設定
日付印を描画する場所や色、線の太さ、記載内容などを設定する。
' 描画前の設定。 ' この設定で、描画に必要な座標値などを得る。 Public Sub init(target_range As Range, _ Optional stamp_color As Long = vbBlack, _ Optional stamp_part As String = "部署名", _ Optional stamp_name As String = "氏名", _ Optional font_name As String = "メイリオ", _ Optional fit_to_cell As Boolean = True) If target_range Is Nothing Then Set TargetRange = Selection(1) ElseIf target_range.MergeCells Then Set TargetRange = target_range ElseIf target_range.Count >= 2 Then Set TargetRange = target_range.Range("A1") Else Set TargetRange = target_range End If T = TargetRange.Top H(0) = TargetRange.Height L = TargetRange.Left W = TargetRange.Width D = WorksheetFunction.Min(H(0), W) * ρ1 R = D / 2 H(2) = D * ρ2 H(3) = D * ρ3 Ox = L + W / 2 Oy = T + H(0) / 2 Sx(1) = Ox - R Sy(1) = Oy - R Ex(1) = Ox + R Ey(1) = Oy + R Sx(2) = Ox - (R ^ 2 - (H(2) / 2) ^ 2) ^ 0.5 Sy(2) = Oy - H(2) / 2 Ex(2) = Ox + (R ^ 2 - (H(2) / 2) ^ 2) ^ 0.5 Ey(2) = Sy(2) Sx(3) = Sx(2) Sy(3) = Oy + H(2) / 2 Ex(3) = Ex(2) Ey(3) = Sy(3) Sx(4) = Ox - (R ^ 2 - (H(3) / 2) ^ 2) ^ 0.5 Sy(4) = Oy - H(3) / 2 Ex(4) = Ox + (R ^ 2 - (H(3) / 2) ^ 2) ^ 0.5 Ey(4) = Ey(2) Sx(5) = Sx(4) Sy(5) = Sy(3) Ex(5) = Ex(4) Ey(5) = Oy + H(3) / 2 StampColor = stamp_color StampPart = stamp_part StampName = stamp_name FontName = font_name End Sub
円の描画と文字セット。
円を描画して、文字をセット。さらに
- 線色、線幅、塗り潰しなどについて設定。
- 文字のセットとフォントサイズの自動調整。
などを行う。なお、フォントサイズの自動調整と、その後に必要となる
円位置の再調整については、先日作成したものを再掲する。
' 円作成。 Private Sub DrawCircel() ' 円描画。 Set Shape(1) = ActiveSheet.Shapes.AddShape(msoShapeOval, Sx(1), Sy(1), D, D) With Shape(1) ' 線色設定。 .Line.ForeColor.RGB = StampColor ' 線幅設定。 .Line.Weight = LineWeight ' 塗り潰し設定。塗り潰さない。 .Fill.Visible = msoFalse End With With Shape(1).TextFrame2 ' 今日の日付をセット。 .TextRange.Characters.Text = Format(Date, "'yy.mm.dd") ' 文字色設定。 .TextRange.Font.Fill.ForeColor.RGB = StampColor ' 文字の折り返し設定。折り返さない。 .WordWrap = msoFalse ' 文字位置設定。中心に配置する。 .VerticalAnchor = msoAnchorMiddle .TextRange.ParagraphFormat.Alignment = msoAlignCenter ' 上下左右の余白を0にする。 .MarginLeft = 0 .MarginRight = 0 .MarginTop = 0 .MarginBottom = 0 End With ' 文字サイズを、円のサイズに合わせてフィットさせる。 TextToFitShape Shape(1) ' フィットの際に円の位置がずれる場合があるため、 ' 指定セルの中心と円の中心を合わせる。 FitCenter TargetRange, Shape(1) ShapeNames(1) = Shape(1).Name End Sub
Function TextToFitShape(target_shape As Excel.Shape) As Double ' テキストの有無確認。無い場合は、Functionを終了する。 If target_shape.TextFrame2.TextRange.Characters.Text = vbNullString Then Exit Function End If ' オートシェイプのサイズ取得。 Dim H(1) As Double: H(0) = target_shape.Height Dim W(1) As Double: W(0) = target_shape.Width ' オートシェイプを一旦、文字サイズに合わせてサイズ変更。 target_shape.TextFrame2.AutoSize = msoAutoSizeShapeToFitText ' 変更後のサイズ取得。 H(1) = target_shape.Height W(1) = target_shape.Width ' オートシェイプの縦と横、各々の縮小(もしくは拡大)率のうち、 ' 小さい方を取得(大きい方だと、オートシェイプから食み出る)。 Dim ρ As Double ρ = WorksheetFunction.Min(H(0) / H(1), W(0) / W(1)) ' もとのフォントサイズにρを掛け、目安のフォントサイズを得る。 Dim FontSize As Double FontSize = target_shape.TextFrame2.TextRange.Font.Size * ρ Dim i As Long Do ' フォントサイズ仮決め。 target_shape.TextFrame2.TextRange.Font.Size = FontSize ' 改めて、オートシェイプを文字サイズに合わせてサイズ変更。 target_shape.TextFrame2.AutoSize = msoAutoSizeShapeToFitText ' 変更後のサイズを得る。 H(1) = target_shape.Height W(1) = target_shape.Width ' 縦と横どちらか一方でも元のサイズを越えたら、そこで終了。 If H(1) > H(0) Or W(1) > W(0) Then Exit Do ' そうでなければ、まだピッタリではない。フォントサイズを1増加。 Else FontSize = FontSize + 0.1 End If ' 無限ループ防止。 i = i + 1: If i >= 100 Then Exit Do Loop ' サイズを越えてから抜けたので、1引いて丁度のサイズにする。 FontSize = FontSize - 0.1 ' オートサイズ解除。 target_shape.TextFrame2.AutoSize = msoAutoSizeNone ' オートシェイプを最初の大きさに戻す。 target_shape.Height = H(0) target_shape.Width = W(0) ' フォントサイズを最終値に変更。 target_shape.TextFrame2.TextRange.Font.Size = FontSize ' 戻り値としてフォントサイズを返す。 TextToFitShape = FontSize End Function
Function FitCenter(target_range As Range, target_shape As Excel.Shape) As Excel.Shape Dim W As Double W = target_shape.Width Dim H As Double H = target_shape.Height Dim T As Double T = target_range.Top + (target_range.Height - H) / 2 Dim L As Double L = target_range.Left + (target_range.Width - W) / 2 target_shape.Top = T target_shape.Left = L Set FitCenter = target_shape End Function
日付印作成
ここまでの結果を、日付印作成用サブプロシージャにまとめる。
といっても、この段階ではまだ一行しかない。
' 日付印作成。 Public Sub DrawStamp() ' 円作成。 DrawCircel End Sub
結果の確認
それでは、標準モジュールに作成した以下で、結果を確認してみよう。
Sub 日付印() Dim Stamp As VBAProject.Stamp Set Stamp = New VBAProject.Stamp Stamp.init Selection End Sub
期待した結果を得ることができた。
次回に続きます。
参考まで。