All Forums
 Категория Visio
 Форум Вопросы и ответы
 Работа с текстом
Author Previous Topic Topic Next Topic  

Michael

49 Posts

Posted - 06/29/2006 :  16:59:14
Возникла проблема
в документе визио со страницы на страницу передается строка текста
(к примеру данные с разделителем)
Нужно, чтобы пользователь мог вручную исправить на текущей (на странице-получателе) странице эту строку, а затем данная строка разбивалась бы по разделителю на подстроки макросом...
Причем количество ручных исправлений и, как следствие, обработки макросом, не ограничивается...
Что-то я уже и не знаю как это лучше сделать...

Tumanov

Russia
1198 Posts

Posted - 06/29/2006 :  18:57:47
Ну, поконкретнее надо бы спрашивать, больше рассказывать, зачем это нужно.
А то вопрос "как лучше?", а что именно надо - совершенно не понятно.
В чем строка передается и куда результаты поступят? И как ее может понадобиться опять делить, если после первого раза разделителей уже не останется?
Go to Top of Page

Michael

49 Posts

Posted - 06/30/2006 :  09:05:25
2 Tumanov: Сам уже понял, что бестолково рассказал... :-)
Попробую по-другому.
На одной странице есть объект, для которого пользователем заполняются кастом пропертис, на второй странице существует другой объект, для которого в кастом пропертис передаются некоторые строки из первого
(Pages[Page-1]!Sheet.1!Prop.Row_1 и т.д.)
В частности передается текстовая строка, где разделителями будут пробелы.
Так вот, в чем проблема: Нужно позволить пользователю, работающему на второй странице изменять полученные данные через форму кастом пропертис и одновременно с этим делать вывод преобразованных данных в какой-нибудь шейп (пришедшую строку надо вывести в столбик...).
Есть идея использовать временные ячейки (типа Scratсh) для хранения поступившей строки, строку передавать и в К.П. и в скрэтч, тока вот как будет выглядеть макрос и на какое событие его вешать...
Go to Top of Page

Tumanov

Russia
1198 Posts

Posted - 06/30/2006 :  19:31:00
Для передачи строки в данном случае макрос не требуется. Ссылка - они и есть ссылка.
Из двух разных шейпов, естественно, тоже можно сослаться на один и тот же шейп, но по-разному обработать источник. В одном шейпе будет строка в неизменном виде, во втором она будет выглядеть столбиком.
Но, как я понял, во втором шейпе надо отражать уже результаты редактирования? Тогда ссылкой не обойдешься.
Напрашивается вариант - обработать событие изменения формулы или ячейки. Обработчик сработает, как только завершится редактирование.
Можно обрабатывать событие изменения области селекции. Оно будет происходить не по завершении редактирования, а когда Вы уйдете с первого шейпа и выберете какой-нибудь другой (или не выберете ничего).
Плохо то, что такие обработчики надо вешать на другой объект. Например,
Dim WithEvents Pag As Visio.Page
позволит обрабатывать Pag_CellChanged и Pag_FormulaChanged
Dim WithEvents Win As Visio.Window
даст доступ к Win_SelectionChanged
Значит обработчики будут срабатывать слишком часто, в них надо будет ставить дополнительные If, чтобы отловить только нужные изменения.
Проще всего (если это устроит) запускать макрос из контекстного меню шейпа. Обработали строку - щелкнули правой кнопкой - выбрали пункт меню "преобразовать". Лишнее нажатие, зато проще всего для программиста.
Go to Top of Page

Michael

49 Posts

Posted - 07/01/2006 :  16:07:50
Благодарю за ответы.
Столкнулся с тем, что такая конструкция
Set sss = shpObj.Cells("Prop.Row_1")
при вводе в кастом пропертис строку, содержащую внутри (то есть не первый и не последний) символ пробела, возвращает ноль.
Как это побороть?
Go to Top of Page

Michael

49 Posts

Posted - 07/01/2006 :  21:55:15
Поборол...
На страничке http://www.mvps.org/visio/VBA.htm был пример
и если вместе с
Set sss = shpObj.Cells("Prop.Row_1")
использовать
s = sss.ResultStr(Visio.visNone)
то все прекрасно работает.

Далее в шейп-листе можно использовать формулу типа
=DOCMD(1312)+RUNMACRO("mm.Module1.m1"),
но пункт контекстного меню шейп->кастом пропертис остается и если менять КП через контекстное меню, макрос, соответственно, не срабатывает.
Не могли бы вы подробнее рассказать как написать обработчик, скажем, изменения содержимого ячейки?

Edited by - Michael on 07/02/2006 12:03:22
Go to Top of Page

Michael

49 Posts

Posted - 07/02/2006 :  12:14:52
Все, теперь работает...
в DVS четко сказано, что можно использовать во такое
DEPENDSON(Prop.Row_1)+RUNMACRO("mm.Module1.m1")
То есть симулируется обработка изменения ячейки 1 Кастом пропертис.

Однако, от объяснения по обработчикам я не откажусь.
Go to Top of Page

Tumanov

Russia
1198 Posts

Posted - 07/02/2006 :  13:11:11
Да, про DEPENDSON время от времени забывают... Не очень расхожая фукнция :)
По обработчикам изменения ячейки нормально написано в SDK в References / Events / CellChanged.
Могу только своими словами немного добавить... :)
Через DEPENDSON Вы подключили макрос в виде обработчика на изменение одного конкретного свойства в одном конкретном шейпе.
Если бы таких свойств было несколько и нужно было следить за каждым, то такая система становится уже менее приятной.
А обработчик события CellChanged вешается на некоторый объект со всеми его внутренностями.
То есть можно повесить его на шейп - будем следить за изменением любой ячейки шейпа. Повесим на отдельную ячейку - будем следить только за ней. Совсем глобально - можно повесить на Application :)
В процессе обработки придется, конечно, отсеять нужные ячейки от ненужных (пропустить часть событий без обработки)...
Ну и еще немного комментариев по поводу примера из SKD:

Dim WithEvents m_shpObj As Visio.Shape
Public Sub InitWith(ByVal aShape As Visio.Shape)
Set m_shpObj = aShape
End Sub
Private Sub m_shpObj_CellChanged(ByVal Cell As Visio.IVCell)
Debug.Print Cell.Shape.Name & " " & Cell.Name & " changed to =" & Cell.Formula
End Sub

Здесь обработчик вешается на шейп.
Так как по умолчанию Visio предлагает обработчики только для объекта Document, нам приходится указать, что события некоего m_shpObj тоже следует обрабатывать. Это делается строкой
Dim WithEvents m_shpObj As Visio.Shape
Мало этого, теперь m_shpObj нужно связать с неким конкретным шейпом. В примере это делается в процедуре InitWith, которой кто-то передал нужный шейп.
Public Sub InitWith(ByVal aShape As Visio.Shape)
Set m_shpObj = aShape
End Sub
Сделать это, можно и любым другим путем, но в любом случае обработчик начнет срабатывать только после выполнения связывания Set m_shpObj = какому-нибудь существующему шейпу. Это можно сделать при открытии рисунка, при появлении шейпа на странице, из меню - да когда угодно. Важно только не забыть.
Ну и все. После этого при изменении значения любой ячейки в шейпе начнет срабатывать Sub m_shpObj_CellChanged. В качестве параметра Вам будет передаваться Cell - ячейка, которая изменилась. Можно будет вычислить, к какому шейпу она принадлежит, имя этого шейпа, на какой странице и т.д. Вся объектная модель в Ваших руках.
Go to Top of Page

Michael

49 Posts

Posted - 07/02/2006 :  15:51:02
Спасибо господину Туманову, обязательно скачаю SDK и с вашими комментариями разберусь.

Начал переносить макрос в стенсил и никак не могу оттуда вызвать...
не пойму какие параметры нужны для Callthis.

CALLTHIS("ThisDocument.family","Диплом")
где соответственно family - имя макроса,
Диплом - вроде как имя стенсила, но у него ведь есть еще и мастера, а макрос записывается в мастер...
И еще, может надо указывать физический файл стенсила, или визио анализирует все доступные файлы, типа из папки My Shapes...?
Go to Top of Page

Michael

49 Posts

Posted - 07/03/2006 :  13:12:21
И еще трабл...
При перетаскивании мастера на лист, на листе появляется шейп, он же является группой. И макрос, если его запускать из меню тулс-макрос-ран (с указанием откуда брать макрос), запускается... но вот доступа к члену группы , в который он будет писать результат, получить не может...
Разгруппировывать не хочется, там стоят всякие привязки и защиты... Можно ли получить доступ к члену группы или здесь проблема в чем-то другом?
Go to Top of Page

Tumanov

Russia
1198 Posts

Posted - 07/03/2006 :  16:17:05
Если шейп является группой, то у него есть своя коллекция Shapes (так же, как у страницы).
Если обычный шейп можно адресовать как Page.Shapes(1), то член группы адресуется прмерно так Page.Shapes(1).Shapes(1)
Таких вложений может быть много (сколько раз группировали).
Go to Top of Page

Michael

49 Posts

Posted - 07/03/2006 :  21:51:37
Еще раз благодарю за помощь!
Пока не понятно, как брать макрос из стенсила, придется сделать все в темплейте...
Кстати, были уже подобные вопросы на забугорных сайтах, например
http://www.officehelp.in/showthread.php?t=35908
Только вот не понятно, чем все закончилось.
И, кстати, если использовать в редакторе VB установку связей, все замечательно работает... Только вот связи эти не сохраняются и не передаются.. :-(
Go to Top of Page
  Previous Topic Topic Next Topic  
Данный сайт является архивом форума visio.artberg.ru, который был закрыт в связи с переходом на новую платформу visio.getbb.ru
Все материалы доступны только для чтения! Если у вас появились вопросы, или вы хотите что-то обсудить, связанное с Visio, обращайтесь на новый форум!
Архив был создан благодаря совместным усилиям Генадия Туманова @Tumanov (visio.artberg.ru), Александра ака @Surrogate (visio.getbb.ru), и Николая Белых @nbelyh (unmanagedvisio.com)