Links
Comment on page
📌

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

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

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

Давайте рассмотрим пример определения координат управляемой точки. Речь идет о точке желтого цвета, она же точка привязки текста фигуры.
Рис. 1 - "Абсолютные" координаты управляемой точки
Координаты элементов внутри фигуры всегда локальные, точкой отсчета является левый нижний угол фигуры! Координата этой точки осчета фигуры состоит из двух составляющих:
  • 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) ' вывод "абсолютных" координат
Вышеуказанный код также подойдет для случая "вложенных" фигур, при этом "глубина" вложенности не имеет значения !

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

В нашем тесте участвуют несколько элементов относящихся к "вложенной" фигуре:
Рис. 2 - Элементы "вложенной" фигуры
Ниже приведен Код и Вывод результатов соответственно.

Нюанс с 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