Skip to content

Instantly share code, notes, and snippets.

@Surrogate-TM
Last active October 19, 2022 14:00
Show Gist options
  • Save Surrogate-TM/caa23fb3d3816b19c5d0aecfbc209c71 to your computer and use it in GitHub Desktop.
Save Surrogate-TM/caa23fb3d3816b19c5d0aecfbc209c71 to your computer and use it in GitHub Desktop.

Метод XYToPage

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

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

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

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

  • 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.
Предварительно мы должны определить интересующую нас фигуру.
Синтаксис данного метода выглядит так: object.XYToPage(x, y, xprime, yprime).
где object - объект Shape: первые два параметра (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) ' вывод "абсолютных" координат

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

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

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

Нюанс с 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 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment