Форум пользователей Visio http://visio.getbb.ru/ |
|
Поиск шейпов при определённом событии http://visio.getbb.ru/viewtopic.php?f=6&t=1041 |
Страница 1 из 3 |
Автор: | Machestro [ 20 окт 2016, 10:21 ] |
Заголовок сообщения: | Поиск шейпов при определённом событии |
Продолжаю тему начатую в viewtopic.php?f=6&t=1038 Задач поставил себе много, будем постепенно их реализовывать. Первое, что я хотел сделать - научиться искать шейпы во всём документе при изменении определённой ячейки в Shape Data. Собственно вот мой первый код Код: Private WithEvents vsoApplication As Visio.Application Public Sub CellChanged_Example() Set vsoApplication = Application End Sub Private Sub vsoApplication_CellChanged(ByVal vsoCell As IVCell) Dim shChanged As Shape 'Шейп в котором произошли изменения Dim strSubject As String 'То, что будем искать Set shChanged = vsoCell.Shape If vsoCell.RowName = "Row_1" Then strSubject = shChanged.Cells("Prop.Row_1.value").ResultStr(0) SearchShapes (strSubject) 'MsgBox strSubject End If End Sub Function SearchShapes(strSubject As String) Dim sh As Shape 'Один проверяемый шейп Dim vsoShapes As Visio.Shapes 'Набор шейпов на странице Dim shapeCell As String 'Проверяемая ячейка Dim vsoPages As Visio.Pages 'Все страницы документа Dim intCounter As Integer 'Счётчик шейпов Dim intPageCounter As Integer 'Счётчик страниц Dim totalShapes As Integer 'Кол-во шейпов на странице Dim numOfPages As Integer 'Число страниц в документе numOfPages = ActiveDocument.Pages.Count For intPageCounter = 1 To numOfPages 'перебераем страницы Set vsoShapes = ActiveDocument.Pages.Item(intPageCounter).Shapes 'для каждой страницы определяем набор вставленных шейпов. totalShapes = vsoShapes.Count 'Определяем кол-во шейпов на странице If totalShapes > 0 Then ' Если есть шейпы на странице то продолжаем перебирать их For intCounter = 1 To totalShapes Set sh = vsoShapes.Item(intCounter) 'Выбираем один из шейпов If sh.CellExists("Prop.Row_1.value", 1) Then 'Есть ли вообще нужная ячейка shapeCell = sh.Cells("Prop.Row_1.value").ResultStr(0) 'если да, то берём её значение в виде String If shapeCell = strSubject Then 'Если значение равно искомому MsgBox "You did it :)" Else MsgBox "This shape Doesn' have " & strSubject End If End If Next intCounter ' переходим к следующему шейпу Else MsgBox "No Shapes on Page №" & intPageCounter End If Next intPageCounter ' переходим к следующей странице End Function Краткое пояснение. Если возникло изменение в ячейке Prop.Row_1 любого шейпа, то запускается сканер, который ищет шейпы на всех страницах с таким же значением в Prop.Row_1.Value. На удивление код работает, хотя он скорее относится к разряду "говнокод". Однако если добавляется новая страница, то возникает ошибка Run-time error '-2032466967 (86db03e9)': Непредвиденный конец файла. Очень прошу оценить написанный код, и дать советы по его улучшению, а так же помочь разобраться с ошибкой. |
Автор: | 9rey [ 20 окт 2016, 11:05 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
совет: лучше использовать for each Page in Pages и for each Shape in Shapes чтобы не связываться с индексами. может поэтому ошибка вылезает, хотя не вникал. |
Автор: | Shishok [ 20 окт 2016, 11:07 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
У тебя возникает ошибка так как на новом листе нет шейпов. И shChanged становится страницей(это тоже как бы шейп ). И Id у страницы = 0. Как исправить? Ну например. Добавь в процедуру vsoApplication_CellChanged вот это: Код: If shChanged.ID = 0 Then Exit Sub после строки: Код: Set shChanged = vsoCell.Shape
|
Автор: | Surrogate [ 20 окт 2016, 11:09 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
нет визио под рукой потестить код. сразу бросилось в глаза, не хватает рекурсии ! Код: Set vsoShapes = ActiveDocument.Pages.Item(intPageCounter).Shapes 'для каждой страницы определяем набор вставленных шейпов. очень часто бывает, что шейпы сгруппированы ! totalShapes = vsoShapes.Count 'Определяем кол-во шейпов на странице If totalShapes > 0 Then ' Если есть шейпы на странице то продолжаем перебирать их For intCounter = 1 To totalShapes Код: numOfPages = ActiveDocument.Pages.Count можно заменить на перебор страницFor intPageCounter = 1 To numOfPages Код: Dim AP as Page
For Each AP in ActiveDocument.Pages ' перебор всех страниц в активном документе |
Автор: | Surrogate [ 20 окт 2016, 11:37 ] | ||
Заголовок сообщения: | Re: Поиск шейпов при определённом событии | ||
таки зашел с планшета на рабочий ноут по RDP! потестил немного. по мере добавления свойств к шейпу первый раз мессадж-бокс вылезает несколько раз !
|
Автор: | nbelyh [ 20 окт 2016, 11:40 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Ещё один совет - лучше использовать FormulaChanged (если данные меняет только пользователь), потому что CellChanged вызывается на каждый чих (пользователь перемещает фигуру например). Не будет работать (скорее всего повиснет) на мало-мальски реальной диаграмме (имеющей пару десятков фигур например, о сотнях или тысячах вообще речи нет). |
Автор: | Surrogate [ 20 окт 2016, 11:50 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
nbelyh писал(а): Ещё один совет - лучше использовать FormulaChanged (если данные меняет только пользователь), потому что CellChanged вызывается на каждый чих (пользователь перемещает фигуру например) золотые слова ! как раз в моем примере MsgBox вылетал ровно столько раз, сколько фигур на листе ! Machestro писал(а): Краткое пояснение. Если возникло изменение в ячейке Prop.Row_1 любого шейпа, то запускается сканер, который ищет шейпы на всех страницах с таким же значением в Prop.Row_1.Value. ага, всё же столько раз сколько шейпов имеющих prop.row_1.
|
Автор: | nbelyh [ 20 окт 2016, 11:56 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Ещё штука в том что CellChanged триггерится для PinX, PinY, Width, Height и подобных, Которые меняются сотнями-тысячами при простейших действиях пользователя (move-resize), особенно если фигуры составные (эти события генерируются также для вложенных фигур). В результате будешь иметь сотни-тысячи "холостых" вызовов Oncellchanged. |
Автор: | Surrogate [ 20 окт 2016, 12:00 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
честно говоря непонятно зачем, 100500 раз выводить сообщения о содержимом ячейки prop.row_1 ? может лучше как-то визуально их показывать ? например вставив строчку Код: ActiveWindow.Select sh, visSelect перед Код: MsgBox "You did it :)"
|
Автор: | Shishok [ 20 окт 2016, 12:14 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Интересно, за каким чертом генерится событие FormulaChanged(или CellChanged) при добавлении нового листа? Причем два раза. А при вставке фоновой страницы - не возникает этих событий! |
Автор: | Surrogate [ 20 окт 2016, 12:16 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Shishok писал(а): генерится событие FormulaChanged(или CellChanged) при добавлении нового листа? думаю, в процессе добавления какая-нибудь ячейка да изменится может и не раз
|
Автор: | Tumanov [ 20 окт 2016, 12:29 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
!!!!!!! Цитата: Не будет работать (скорее всего повиснет) на мало-мальски реальной диаграмме (имеющей пару десятков фигур например, о сотнях или тысячах вообще речи нет). Самый существенный момент! Использовать FormulaChanged, CellChanged нужно вообще в крайних случаях. Когда других вариантов нет. А здесь они скорее всего есть. Попробовать прицепиться к обновлению источника или завершению редактирования конкретных шейпов. То есть "поучиться" такому приему конечно можно. Но вставлять его в CAD-решение крайне нежелательно. |
Автор: | 9rey [ 20 окт 2016, 12:42 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
пусть автор расскажет, чего он хочет добиться. может и правда не придется использовать CellChanged |
Автор: | Machestro [ 20 окт 2016, 12:49 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Пытаюсь переварить всё это, за что спасибо. Хочу я следующее. Если у Шейпа изменилось значение конкретной ячейки, например в Shape Data есть строка Prop.Row_1 и изменилось значение в Value. В этом случае нужно посмотреть есть ли Шейпы с этим же значением в этой же ячейке во всём документе |
Автор: | Surrogate [ 20 окт 2016, 12:57 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Machestro писал(а): Если у Шейпа изменилось значение конкретной ячейки, например в Shape Data есть строка Prop.Row_1 и изменилось значение в Value это отлавливание изменений должно постоянно происходить в процессе работы с документом ? . или уже при финальном редактировании документа ?Machestro писал(а): В этом случае нужно посмотреть есть ли Шейпы с этим же значением в этой же ячейке во всём документе тогда можно формировать список таких шейпов, указанием листа и имени шейпа! Просто MsgBox что у какого-то шейпа (не явно указанного) есть свойство prop.row_1 и совпадает/не совпадает с искомым значением - абсолютно не информативно IMHO
|
Автор: | Machestro [ 20 окт 2016, 13:01 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Surrogate писал(а): это отлавливание изменений должно происходить в процессе работы с документом ? . или уже при финальном редактировании документа ? - Да при работе с документомЯ понимаю, что MSBox это не информативно, просто это для меня был самый простой способ показать себе что есть ещё такие шейпы. Это же не финальная функция, я диш пытаюсь понять принцип и реализовать его |
Автор: | Surrogate [ 20 окт 2016, 13:01 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Machestro писал(а): - Да это за какой вариант ?
|
Автор: | Machestro [ 20 окт 2016, 13:03 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Surrogate писал(а): Machestro писал(а): - Да это за какой вариант ?Изменил свой комент. Вообщем при работе с документом |
Автор: | Surrogate [ 20 окт 2016, 13:06 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Machestro писал(а): Вообщем при работе с документом а насколько велика вероятность что совпадения значения у разных шейпов в пределах документа ?
|
Автор: | Machestro [ 20 окт 2016, 13:08 ] |
Заголовок сообщения: | Re: Поиск шейпов при определённом событии |
Совпадения будут происходить регулярно |
Страница 1 из 3 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |