Форум пользователей Visio
http://visio.getbb.ru/

Add-On Массив: четырёхугольный, по дуге, по дуге из букв
http://visio.getbb.ru/viewtopic.php?f=15&t=1433
Страница 1 из 2

Автор:  Boris [ 19 мар 2019, 13:57 ]
Заголовок сообщения:  Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Удалил файлы поскольку решил попробовать продать сие.
Писал в VS 2017 Community.
Проверял на Visio 2016 и 2007 Другие версии не пробовал.

Убрал ошибку и добавил нерусский язык.

По этой ссылке файла тоже нет, теперь.
кросс-пост

Вложения:
Poster.png
Poster.png [ 191.27 Кб | Просмотров: 1456 ]

Автор:  Foin [ 24 мар 2019, 15:47 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

При создании четырёхугольного массива есть один глюк.
Если выбрать родительский элемент и потом передвинуть его в любую сторону то величина сдвига добавится ко всем элементам массива.
То есть родительский элемент на месте а массив в стороне на величину перемещения родительского шейпа после первого выделения.
И понять не могу из-за чего такой эффект.

Автор:  Гость [ 24 мар 2019, 18:32 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Boris в сообщении писал(а):
Попробую описать что происходит.
Аддон по выделенному шейпу создаёт массив из копий первоначального шейпа. Строит правильно.
Удаляю массив им же. Отдельная кнопочка "Отменить".
И когда после этого на листе перемещаешь первый шейп в другую позицию. Создание следующего массива идёт криво. Причём кривизна зависит от расстояния на которое передвинул первый шейп. То есть программа помнит некоторые данные и пытается применить их.
этот баг описывался на стадии написания аддона

Автор:  Tumanov [ 24 мар 2019, 20:30 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Цитата:
этот баг описывался на стадии написания аддона

Да. И я там даже приводил VBA-тест повторяющий такое поведение.
Код:
    Dim arXY() As Double
    Dim arOb() As Variant
    Dim arId() As Integer
Sub ttt()
    If ActiveWindow.Selection.Count <> 1 Then Exit Sub
    Set shp = ActiveWindow.Selection(1)
    cnt = 1
    ReDim arXY(1 To 2)
    ReDim arOb(1 To 1)
    x0 = shp.Cells("PinX").ResultIU
    y0 = shp.Cells("PinY").ResultIU
    dx = 1
    Set arOb(1) = shp
    arXY(1) = x0 + dx
    arXY(2) = y0
    rez = ActivePage.DropMany(arOb, arXY, arId)
    Set arOb(1) = Nothing
    Set shp = Nothing
End Sub

Однако, как я теперь вижу, в выводы вкралась ошибка. Тогда я решил, что это не баг, а свойство Visio. Типа, так и надо...
Таки нет! Это ошибка программиста! Приведенный выше код (по сравнению с прежним) содержит две лишних очистки в конце. Чистится шейп и массив. И такой код не ошибается.
А вот если чистить что-то одно (хоть шейп, хоть массив), то уже наблюдаестя сдвиг. И не важно, что при следующем запуске шейп перезаписывается в массив, что вроде бы должно и массив очистить.
Так что народ там давал правильный совет - чистить надо все. И тщательнее, тщательнее!

Автор:  Boris [ 25 мар 2019, 08:37 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Этот баг происходит и до построения массива.
Выделяешь шейп и ничего не строя передвигаешь его и нажимаешь кнопку построить.
И тогда массив строится с учетом этого сдвига.

Автор:  Boris [ 25 мар 2019, 12:54 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Дело в том что по задумке.
Пользователь строит массив, удаляет изменяет параметры и строит новый.
В том числе может перемещать родительский шейп. Пока не получит то чего желает.
И если после каждого удаления массива чистить имя шейпа, то пользователю придётся снова повторять процедуру выбора.
Это неудобно.

Кстати в остальных массивах по дуге такого глюка нет.
А ведь разница только в алгоритме построения.
Всё остальное совершенно одинаковое.
Посмотрите проект. Там почти каждая строчка с комментариями.

Автор:  Tumanov [ 25 мар 2019, 15:19 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Да, моя модель несколько отличается от исходной. Мы даже говорили о разных массивах. Я ведь использовал DropMany вместо простого Drop. А там массив строится заранее, еще до прорисовки шейпов. Ну ладно, неважно.
Еще раз разберем задачу.
У Вас образуется некая "скрытая память" исходного шейпа. И эта память начинает учитывать смещение исходного шейпа в последующих запусках. Возможно Visio принимает во внимание уникальный идентификатор шейпа, поэтому даже при обнулении и повторном присвоении объекта считает его тем же самым. Предположим, что мы не можем чистить эту скрытую память, но желательно от нее избавиться.
Я предлагаю следующий метод: размножать не исходный шейп, а его копию. В форме запоминаем исходный шейп. При построении массива создаем копию шейпа. Используем копию в операции Drop. После построения всего массива копию удаляем.
В этом случае на каждом проходе копия будет создаваться заново, поэтому рабочий шейп будет явно другим.
Присмотритесь к этому коду
Код:
                        ' Создание копии первого элемента, установка на место.
                        ' Получение имени полученной копии.
                        visShp = visAcPg.Shapes(Arrey.vPerObjPr)
                        Dim visShp1 As Visio.Shape
                        visShp.Copy(1)
                        visAcPg.Paste(1)
                        visShp1 = ViAp.ActiveWindow.Selection.PrimaryItem
                        vTemp = visAcPg.Drop(visShp1, vX1, vY1).Name
                        visShp1.Delete()
                        visShp1 = Nothing

Я его вставил непосредственно рядом с Drop. Для проверки. Вроде бы ситуация исправляется.
Это только пример. На самом деле копию надо делать перед циклом и удалять после цикла. То есть один раз на весь массив.
И не забыть копировать с опцией visCopyPasteNoTranslate, чтобы копия попадала на то же самое место, что и исходный шейп. (А может это и не важно).

Автор:  Boris [ 25 мар 2019, 16:11 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Если включена привязка к первому то строится правильно.
Если после этого строить ещё раз но уже без привязки то тоже нормально.
Колдовством попахивает, однако.

Автор:  Tumanov [ 25 мар 2019, 16:37 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Последнее сообщение не понял...
Если так, то нормально. Если так, то тоже нормально.
А ненормально бывает? Или можно считать, что все заработало?

Автор:  Tumanov [ 25 мар 2019, 17:11 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Кстати, о птичках...
Читаю справку по поводу Drop
Цитата:
If ObjectToDrop is a Master, the pin of the master is dropped at the specified coordinates.

Типа, если дропаем мастер, то да, он ляжет в указанные координаты. А если нет, то ничего не сказано. Может и промахнется! Таки да, это и наблюдаем. В некоторых случаях промахивается. Но как тонко это отражено в документации :) То есть, они знали, просто не стали все подробности расписывать.
А ведь помнится, много лет тому назад я читал какое-то предупреждение о неточности Drop. И еще тогда взял за правило во всех программах - всегда после дропа подправлять PinX, PinY. Чтобы голова не болела. Чувствую, поэтому и никогда не налетал на такую ситуацию.

Автор:  Boris [ 26 мар 2019, 07:19 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Если после выбора шейпа переместить его то массив строится на удвоенное расстояние перемещения от родительского шейпа.
И по горизонтали и по вертикали.
Но если включить "Привязать к первому" то построение идёт правильно, без смещения.
Если в этом случае удалить массив и построит ещё раз но уже без привязки то тоже строится без смещения.
Вот я и говорю что колдовство однако.

Автор:  Boris [ 26 мар 2019, 07:57 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Вот это полностью вылечило глюк DROP.

vTemp = visAcPg.Drop(visAcPg.Shapes(Arrey.vPerObjPr), vX, vY).Name

'Лечение глюка DROP с точки зрения логики это бредовая конструкция, но ведь работает.
visAcPg.Shapes(vTemp).Cells("PinX").FormulaForce = visAcPg.Shapes(Arrey.vPerObjPr).Cells("PinX").ResultIU + (vX - vXC)
visAcPg.Shapes(vTemp).Cells("PinY").FormulaForce = visAcPg.Shapes(Arrey.vPerObjPr).Cells("PinY").ResultIU + (vY - vYC)

Получается, что в DROP нет необходимости, точнее его функция установки по координатам не работает и нужны костыли.
Интересно а в версиях VISIO домайкрософтовских этот эффект наблюдается?

Автор:  Surrogate [ 26 мар 2019, 08:57 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Борис писал(а):
Интересно а в версиях VISIO домайкрософтовских этот эффект наблюдается?
не знаю поможет ли книжка изданная еще Visio Corporation ?
Tumanov в сообщении #11247 писал(а):
Один запрос в Яндексе - и вижу этой книжку :)
http://www.twirpx.com/file/622740/
пару лет назад находил ссылку на дистрибутивы ранних версий, не помню были ли там версии с поддержкой VBA. Я так и не смог их потестить. Т.к. нужно было установить ну очень древнюю версию Windows (а возможно и MS-DOS, я уже забыл). Честно говоря, не знаю что даст знание как работало это в версиях вышедших еще 20 лет назад ? Если очень интересно, могу поискать ссылки :D
Изображение
Дополнено позднее: Drop method (Version added: 2.0), DropMany method (Version added: 4.5), Duplicate method (Version added: 2.0)

Автор:  Tumanov [ 26 мар 2019, 09:14 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Цитата:
Вот это полностью вылечило глюк DROP.

Не совсем так...
В данном случае - да, но в общем случае все равно могут быть накладки. Ведь что происходит - сначала шейп бросается не туда, потом подтягивается в нужное место. Но бывают ситуации, когда вот это "не туда" может нарушить существующее размещение шейпов.
Поэтому предыдущий способ "лечения" я бы тоже не сбрасывал со счетов и применял по необходимости.
То есть либо пользуемся копией и укладываем ее сразу на место, либо бросаем как попало, но потом притягиваем через PinX, PinY.

Автор:  Tumanov [ 26 мар 2019, 09:17 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Цитата:
Интересно а в версиях VISIO домайкрософтовских этот эффект наблюдается?

Скорее всего наблюдается. Я сам не натыкался (причину уже объяснял). Если будете проверять, могу поискать старенькую версию.

Автор:  Shishok [ 26 мар 2019, 09:25 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

А собственно почему не использовать Shape.Dublicate вместо Drop?

Автор:  Surrogate [ 26 мар 2019, 09:30 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Shishok писал(а):
почему не использовать Shape.Dublicate вместо Drop?
присоединяюсь!

Автор:  Boris [ 26 мар 2019, 10:41 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Интерес к работе старых версий чисто академический.
То есть если в версии 5 такого глюка нет то его добавил всеми любимый майкрософт.
Дупликате - хороший вариант, я именно его и использовал в своих первых проектах.
Но он создаёт эелемент, где-то там, который потом надо ещё ставить на место.
Поэтому и выбрал Дроп. Он всё делает одной операцией.
Кто же знал о подводных камнях?

Автор:  Tumanov [ 26 мар 2019, 10:49 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

Цитата:
Поэтому и выбрал Дроп. Он всё делает одной операцией.

Более того, есть еще операция DropMany, которая весь этот массив нарисует действительно одной операцией. И по логике как раз ее следовало использовать.
Но у нее точно такой же "подводный камень" :)

Автор:  Boris [ 26 мар 2019, 13:47 ]
Заголовок сообщения:  Re: Add-On Массив: четырёхугольный, по дуге, по дуге из букв

К тому же всё равно придётся ещё и поворачивать каждый объект по отдельности.
Код становится трудночитаемым. Хотя и компактным. Для прямоугольных массивов.

Страница 1 из 2 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/