📌Преобразование в абсолютные координаты страницы

Метод XYToPage - позволяет преобразовать относительные координаты элемента фигуры [вершины/точки соединения/управляемые точки(контрола)] в абсолютные координаты страницы.

Немного теории

Давайте рассмотрим пример определения координат управляемой точки. Речь идет о точке желтого цвета, она же точка привязки текста фигуры.

Координаты элементов внутри фигуры всегда локальные, точкой отсчета является левый нижний угол фигуры! Координата этой точки осчета фигуры состоит из двух составляющих:

  • PinX/PinY - абсолютная координата Положения булавки (подробнее о Положении булавки)

  • LocPinX/LocPinY - относительное Положение булавки внутри фигуры

Положение "точки отсчета" в таблице свойств фигуры можно определить: PinX-LocPinX и PinY-LocPinY по осям X и Y соответственно. Если мы хотим узнать абсолютное положение управляемой точки то формулы будут такие: PinX-LocPinX+Controls.TextPosition и PinX-LocPinX+Controls.TextPosition по осям X и Y соответственно. Таким образом для получения абсолютного положения управляемой точки нам придется получить эти шесть параметров параметры программно !

Dim xp as Double, xy as Double
xp = sh.Cells("PinX") + sh.Cells("LocPinX") + sh.Cells("Controls.TextPosition")
yp = sh.Cells("PinY") + sh.Cells("LocPinY") + sh.Cells("Controls.TextPosition.Y")

Похожим образом определяются координаты фигур вложенных в группы, для этого еще придется программно определять "родительскую" фигуру и приводить локальные размещения внутри "родительской" фигуры к абсолютным координатам страницы. Для определения родительской фигуры нужно использовать свойство sh.Parent. Если мы имеем дело с многократной вложенностью фигур, то придется пересчитывать координаты столько раз сколько имеется уровней вложенности! При использовании классического подхода сложность растет!!!

Преимущества метода XYToPage

В качестве решения рекомендуется использовать метод XYToPage. Предварительно мы должны определить интересующую нас фигуру. Синтаксис данного метода выглядит так: Shape.XYToPage(x, y, xprime, yprime). Где первые два параметра являются "входными", т.е. в них нужно указать координаты какого локального элемента мы хотим узнать. Вторые два параметра "выходные", они получают абсолютные координаты элемента в дюймах. Если вернуться к нашему примеру управляемой точкой, то синтаксис определения ее абсолютных координат будет выглядеть:

Dim x As Double, y As Double
sh.XYToPage sh.Cells("Controls.Row_1"), sh.Cells("Controls.Row_1.Y"), x, y
Debug.Print "Controls: ", Application.ConvertResult(x, visNoCast, visMillimeters), _
Application.ConvertResult(y, visNoCast, visMillimeters) ' вывод "абсолютных" координат

Вышеуказанный код также подойдет для случая "вложенных" фигур, при этом "глубина" вложенности не имеет значения !

Тестируем работу данного метода

В нашем тесте участвуют несколько элементов относящихся к "вложенной" фигуре:

Ниже приведен Код и Вывод результатов соответственно.

Нюанс с PinX/PinY

📝 По выводу результатов можно сделать вывод о некорректном отображении для параметра PinX/PinY! Вместо него в данной ситуации уместнее использовать LocPinX/LocPinY

Код

Sub XYToPage()
Dim sj As shape, x As Double, y As Double
Set sj = ActivePage.Shapes.ItemFromID(6)
sj.XYToPage sj.Cells("Geometry1.X1"), sj.Cells("Geometry1.Y1"), x, y
Debug.Print "Geometry: ", Application.ConvertResult(x, visNoCast, visMillimeters), _
Application.ConvertResult(y, visNoCast, visMillimeters)
sj.XYToPage sj.Cells("Controls.Row_1"), sj.Cells("Controls.Row_1.Y"), x, y
Debug.Print "Controls: ", Application.ConvertResult(x, visNoCast, visMillimeters), _
Application.ConvertResult(y, visNoCast, visMillimeters)
sj.XYToPage sj.Cells("Connections.X1"), sj.Cells("Connections.Y1"), x, y
Debug.Print "Connections: ", Application.ConvertResult(x, visNoCast, visMillimeters), _
Application.ConvertResult(y, visNoCast, visMillimeters)
sj.XYToPage sj.Cells("PinX"), sj.Cells("PinY"), x, y
Debug.Print "Pin: ", Application.ConvertResult(x, visNoCast, visMillimeters), _
Application.ConvertResult(y, visNoCast, visMillimeters)
sj.XYToPage sj.Cells("LocPinX"), sj.Cells("LocPinY"), x, y
Debug.Print "LocPin: ", Application.ConvertResult(x, visNoCast, visMillimeters), _
Application.ConvertResult(y, visNoCast, visMillimeters)
End Sub

Вывод результатов

Geometry:      29,9999889143772            14,9999986483354 
Controls:      59,9999968226014            24,9999989487053 
Connections:   90,0000047308256            34,9999992490752 
Pin:           69,9999858463991            34,9999986483354 
LocPin:        59,9999968226014            24,9999989487053 

Last updated