CATDrawingのテキストボックスサイズの取得|CATIAマクロの作成方法

最近CATDrawingでのマクロを作成していると、「テキストボックスのサイズを取得したい」という場面に出くわしました。

そこで、テクストボックスを操作するための「DrawingTextオブジェクト」を調べたのですが、どうやらサイズを取得するためのプロパティやメソッドは存在しないようです。

テキストボックスは中に入力された文字列の長さや、フォント、フォントサイズ等あらゆるもの影響されて、その大きさを変形していきます。

これをどうにか取得したいと思いいろいろ試したところ、どうにか取得することができたので覚書き程度にまとめていきます。

VBAでテキストボックスのサイズを取得したい方は是非参考にして見て下さい。

 

テキストボックスの取得コード

任意のテキストボックスを選択した状態で、以下のコードを実行すると
・「テキストボックスの4隅の頂点の座標」
・「テキストボックスの高さ/幅を取得」
の以上2点を取得することができます。

取得の結果は表示しませんが、代わりにテキストボックスの4辺に直線を作成しています。
この4つの直線がテキストボックスの各辺と一致すれば取得ができていることが確認できます。

Option Explicit
Sub CATMain()

Dim SEL As Selection
Set SEL = CATIA.ActiveDocument.Selection

Dim SELTXT As DrawingText
Set SELTXT = SEL.Item(1).Value
    

'左側マージン取得*****************************************************
SELTXT.AnchorPosition = catTopLeft

Dim LeaderLeft As DrawingLeader
Set LeaderLeft = SELTXT.Leaders.Add(SELTXT.x - 100, SELTXT.y)

Dim LeaderPointLeftX As Double
Dim LeaderPointLeftY As Double
LeaderLeft.GetPoint 0, LeaderPointLeftX, LeaderPointLeftY

Dim LeftMargin As Double
LeftMargin = SELTXT.x - LeaderPointLeftX


'右側マージン取得*****************************************************
SELTXT.AnchorPosition = catTopRight

Dim LeaderRight As DrawingLeader
Set LeaderRight = SELTXT.Leaders.Add(SELTXT.x + 100, SELTXT.y)

Dim LeaderPointRightX As Double
Dim LeaderPointRightY As Double
LeaderRight.GetPoint 0, LeaderPointRightX, LeaderPointRightY

Dim RightMargin As Double
RightMargin = LeaderPointRightX - SELTXT.x


'アンカーポイント左上を基準に4つの頂点を取得*****************************
SELTXT.AnchorPosition = catTopLeft
LeaderLeft.GetPoint 0, LeaderPointLeftX, LeaderPointLeftY
LeaderRight.GetPoint 0, LeaderPointRightX, LeaderPointRightY


'テキストボックス高さ*************************************************
Dim TXTHeight As Double
TXTHeight = SELTXT.y - LeaderPointLeftY

'テキストボックス幅**************************************************
Dim TXTWidth As Double
TXTWidth = LeaderPointRightX - LeaderPointLeftX - LeftMargin - RightMargin


'頂点①(左上)*******************************************************
Dim Point1X As Double
Dim Point1Y As Double

Point1X = SELTXT.x
Point1Y = SELTXT.y


'頂点②(左下)*******************************************************
Dim Point2X As Double
Dim Point2Y As Double

Point2X = SELTXT.x
Point2Y = SELTXT.y - TXTHeight


'頂点③(右下)*******************************************************
Dim Point3X As Double
Dim Point3Y As Double

Point3X = SELTXT.x + TXTWidth
Point3Y = SELTXT.y - TXTHeight


'頂点④(右上)*******************************************************
Dim Point4X As Double
Dim Point4Y As Double

Point4X = SELTXT.x + TXTWidth
Point4Y = SELTXT.y


'Leader削除*******************************************************
On Error Resume Next
SELTXT.Leaders.Remove SELTXT.Leaders.Count
SELTXT.Leaders.Remove SELTXT.Leaders.Count
On Error GoTo 0


'テキストボックスサイズ取得確認用************************************
Dim SELView As DrawingView
Set SELView = SELTXT.Parent.Parent

SELView.Activate

Dim Fac2D As Factory2D
Set Fac2D = SELView.Factory2D

Dim LINE1 As Line2D
Set LINE1 = Fac2D.CreateLine(Point1X, Point1Y, Point2X, Point2Y)

Dim LINE2 As Line2D
Set LINE2 = Fac2D.CreateLine(Point2X, Point2Y, Point3X, Point3Y)

Dim LINE3 As Line2D
Set LINE3 = Fac2D.CreateLine(Point3X, Point3Y, Point4X, Point4Y)

Dim LINE4 As Line2D
Set LINE4 = Fac2D.CreateLine(Point4X, Point4Y, Point1X, Point1Y)

End Sub

上記のコードでは以下のとおり取得できます。 

TXTWidth  → テキストボックスの幅
TXTHeight → テキストボックスの高さ
Point1   → テキストボックス左上の頂点(X,Y座標)
Point2   → テキストボックス左下の頂点(X,Y座標)
Point3   → テキストボックス右下の頂点(X,Y座標)
Point4   → テキストボックス右上の頂点(X,Y座標)
※Point1~4の座標はテキストボックスが存在するビュー内での座標

注意点としてはテキストボックスのアンカーポイントが「左上」であることが前提です。
上記のコードを実行すると自動的にアンカーポイントが左上に切り替わるので注意して下さい。
 

コード解説

コード自体は長いですが、やっていることはあまり難しいものではありません。
ただ、少し頭をひねらないと思いつかない方法です。

まずは本コード作成の参考にしたページを紹介します。
Forums : Text box size – COE
テキストボックスのサイズを取得する方法として以下のような案が挙げられていました。

How about this:
 1.add leader to the text (point othe view origin)
 2.use GetPoints to find its path.
 3.delete the leader
 4.change anchor point to catMiddleCenter
 5.add leader to the text (again, point othe view origin)
 6.use GetPoints to find the second leader’s path.
 7.compare the two paths to find your dX and dY.
This is just a thought. I have not tried this myself.


こんな感じでいかがでしょうか:
 1.テキストにリーダーを追加(ポイントotheビューの原点)
 2.GetPointsを使ってパスを見つける
 3.リーダーを削除する
 4.アンカーポイントをcatMiddleCenterに変更する
 5.addリーダーをテキストに(再度、ポイントotheのビューの原点)
 6.GetPointsを使って2番目のリーダーのパスを見つける
 7.2つのパスを比較して、dXとdYを見つける
これは単なる思いつきです。私自身は試したことがありません

上記の案を簡単に説明するとLeader(引出線)を作ることで取得できるポイントを使い、テキストボックスのサイズを計算で導き出そうというものです。

具体的にいうと「DrawingLeaderオブジェクト」の「GetPointメソッド」を使うことで、以下のようにLeaderの始点の座標を取得することができます。

 

今回のサンプルコードではこの考え方をもとにテキストボックスのサイズを求めていきます。
アンカーポイント位置が「左上」を前提としていますが、やっている内容さえ理解できればアンカーポイント位置がどこであっても求めることができるので、コードの書き方というよりは取得のための"考え方"をメインに理解してもらえれば大丈夫です。

 

テキストボックスのサイズ取得コードの解説

テキストボックスの取得

Dim SEL As Selection
Set SEL = CATIA.ActiveDocument.Selection

Dim SELTXT As DrawingText
Set SELTXT = SEL.Item(1).Value

まずは選択状態にあるテキストボックスを取得します。

これが理解できない方は「Selectionオブジェクト」の「Itemメソッド」を参照ください。
 

マージン(余白)サイズの取得

'左側マージン取得*****************************************************
SELTXT.AnchorPosition = catTopLeft

Dim LeaderLeft As DrawingLeader
Set LeaderLeft = SELTXT.Leaders.Add(SELTXT.x - 100, SELTXT.y)

Dim LeaderPointLeftX As Double
Dim LeaderPointLeftY As Double
LeaderLeft.GetPoint 0, LeaderPointLeftX, LeaderPointLeftY

Dim LeftMargin As Double
LeftMargin = SELTXT.x - LeaderPointLeftX


'右側マージン取得*****************************************************
SELTXT.AnchorPosition = catTopRight

Dim LeaderRight As DrawingLeader
Set LeaderRight = SELTXT.Leaders.Add(SELTXT.x + 100, SELTXT.y)

Dim LeaderPointRightX As Double
Dim LeaderPointRightY As Double
LeaderRight.GetPoint 0, LeaderPointRightX, LeaderPointRightY

Dim RightMargin As Double
RightMargin = LeaderPointRightX - SELTXT.x

 
まずはテキストボックス(水色破線)Leaderの始点にあるわずかな隙間のサイズを取得していきます。(下図でいうLeftMargin/RightMargin)

左側のマージン(LeftMargin)はテキストボックスのX座標左側のLeader始点のX座標で取得することができます。

右側のマージン(RightMargin)も考え方は左と同じですが、テキストボックスのアンカーポイントを「右上」に変更する必要があります。
変更後は右側のLeader始点のX座標テキストボックスのX座標で取得することができます。

 

テキストボックスの高さ/幅の取得

'アンカーポイント左上を基準に4つの頂点を取得*****************************
SELTXT.AnchorPosition = catTopLeft
LeaderLeft.GetPoint 0, LeaderPointLeftX, LeaderPointLeftY
LeaderRight.GetPoint 0, LeaderPointRightX, LeaderPointRightY


'テキストボックス高さ*************************************************
Dim TXTHeight As Double
TXTHeight = SELTXT.y - LeaderPointLeftY

'テキストボックス幅**************************************************
Dim TXTWidth As Double
TXTWidth = LeaderPointRightX - LeaderPointLeftX - LeftMargin - RightMargin

まずはRightMarginを取得するために変更していたアンカーポイントを「左上」に戻します。
また、アンカーポイント「左上」の場合のLeaderの始点の座標を取得し直しておきます。
(※アンカーポイントの位置によってLeader始点の座標は変化するため)

上記を行うことで改めて以下のとおり各座標とマージンサイズを取得することができます。

上図を見ればわかるとおり、あとは計算でテキストボックスの高さと幅を取得することができます。

テキストボックスの高さ:テキストボックスのY座標Leader始点のY座標
幅:右側のLeader始点のX座標左側のLeader始点のX座標-(LeftMarginRightMargin)

 

テキストボックスの4隅の頂点の座標取得

'頂点①(左上)*******************************************************
Dim Point1X As Double
Dim Point1Y As Double

Point1X = SELTXT.x
Point1Y = SELTXT.y


'頂点②(左下)*******************************************************
Dim Point2X As Double
Dim Point2Y As Double

Point2X = SELTXT.x
Point2Y = SELTXT.y - TXTHeight


'頂点③(右下)*******************************************************
Dim Point3X As Double
Dim Point3Y As Double

Point3X = SELTXT.x + TXTWidth
Point3Y = SELTXT.y - TXTHeight


'頂点④(右上)*******************************************************
Dim Point4X As Double
Dim Point4Y As Double

Point4X = SELTXT.x + TXTWidth
Point4Y = SELTXT.y

テキストボックスの高さと幅を使って、4隅の頂点の座標も取得していきます。
計算式と下図を見比べれば、上記コードで何をやっているかすぐにわかると思います。

Point1(X,Y)=アンカーポイント(X,Y)
Point2(X,Y)=(Point1(X) , Point1(Y)TXTHeight)
Point3(X,Y)=(Point1(X)TXTWidth , Point1(Y)TXTHeight)
Point4(X,Y)=(Point1(X)TXTWidth , Point1(Y))

 

Leaderの削除

'Leader削除*******************************************************
On Error Resume Next
SELTXT.Leaders.Remove SELTXT.Leaders.Count
SELTXT.Leaders.Remove SELTXT.Leaders.Count
On Error GoTo 0

最後に座標取得用に作成していたLeaderを2つ削除します。

削除内容は「Leadersコレクションの一番最後にあるLeaderを削除」という処理を2回行います。
これで直近で作成した2つのLeaderのみを削除することができます。
(つまり、テキストボックスにもとからLeaderがついていたとしても問題なし)

 

まとめ

今回はVBAで任意のテキストボックスのサイズを取得する方法についての内容でした。

マクロ作成中にテキストボックスのサイズを取得したいという場面にはなかなか出くわさないかもしれませんが、今回紹介した内容を使えば一応取得することはできます。

今回のようにメソッドやプロパティはなくとも、いくつかの用意されているメソッドやプロパティを組み合わせることで取得できる場合も数多くあります。
このようにVBAでマクロを作成するには知識だけでなく、発想力も重要です。

今回紹介してコードはあくまでも一例なので他にもいい方法があるかもしれません。
ぜひ、いろいろ試してみて他の案も探してみて下さい。

目次へ戻る
 

icon-book CATIAマクロを本気で勉強するなら

2024年8月26日CATIA,CATIAマクロ