Для русскоязычных пользователей Visio. Начинающих и профессионалов. Где взять, как сделать, что купить и т.д.

Диалоговые окна



При построении дополнений, взаимодействующих с файлами данных или документами, часто возникает вопрос - как из Visio открыть нужный файл. Вопрос не простой, особенно если нужно открыть не файл Visio, а какой-то другой. Поэтому рекомендую обратить внимание на вопрос Подскажите пожалуйста, есть ли в Visio FileDialog как в Excel? ниже.

К сожалению, нужно отметить, что это один из случаев, когда сказывается разрядность Visio. Приведенный вариант с использованием Win32 API будет работать только в 32-разрядных приложениях. Для 64-разрядных код должен отличаться. Это можно посмотреть в источнике (http://visguy.com/vgforum/index.php?topic=738.0). То есть либо нужно заранее знать, где будет работать макрос, либо усложнять его, чтобы на лету узнать разрядность и использовать соответствующий фрагмент кода.

Еще один вариант связан с тем, что чаще всего приходится открывать как раз файлы Excel. А так как в Excel хороший диалог существует, то можно использовать следующую последовательность: создать приложение Excel (без документа), запустить в этом приложении диалог открытия файла и, получив имя файла, открывать в том же приложении книгу Excel. Довольно удобно и не нужно думать о разрядности.

Перечень литературы

06.08.2017  Команды DoCmd/DOCMD  Microsoft.   

Ответы на вопросы

Как открыть линк в новом окне?

Подскажите как сделать так, чтобы линк открывался в отдельном окне.
Страница сохранена как htm файл. Одна из форм содержит гиперлинк на xml файл. Нужно, чтоб он не открывался в текущем окне браузера, а открывал новое окно. Если это невозможно сделать при помощи гиперлинка, то любые другие опции тоже подойдут. 

В html файле за новое окно отвечает тег target.
То есть ссылка вида 

<a href="MyPage.htm">MyPage</a> 

откроется в том же окне, а ссылка 

<a href="MyPage.htm" target="new">MyPage</a> 

откроется в новом окне.
Вы имеете возможность подредактировать htm файл? 

Спасибо! Я знаю, как это делается в html, но дело в том, что этот линк должен находиться внутри шейпа. Либо открываться при клике на сам шейп. 

Ну так, в HTML это и делается. Когда Visio сохраняет страницу в HTML, он прописывает там и ссылки href=... Причем в текст вставляется даже почти нужный атрибут target="_top". Мешает только то, что перед top стоит знак подчеркивания. Если его убрать, то ссылка будет открываться в новом окне.
Можно это сделать вручную, можно программно.
Чтобы убрать вручную, придется открыть нужный файл .htm из папки files в любом текстовом редакторе, выполнить замену _top на top во всем файле и сохранить его. После этого ссылки будут открываться в новом окне. 

Удаление окна поиска в окне Stencil

Если кто знает подскажите. Открываю набор шейпов в Delphi используя DrawingControl.
MyVisioApp.Documents.Open(Dir+'SHAPES\Shtamps.vss');
Открывается окно с набором шейпов с окном поиска, этих же самых шейпов. Приходится вытаскивать окно шепов из окна поиска, после закрывать последнее чтобы не мешалось. 

Нужно сделать его невидимым. Смотри цитату: 

Windows(1).ItemFromID(Visio.visWinIDShapeSearch).Visible = False
To expose the Shape Search window in the stencil pane, set the same value to True.
Note: You can only manage the visibility of the Shape Search window on a per window basis. 

Как отобразить окно Pan&Zoom?

Подскажите пожалуйста, как мне программно отобразить окно Pan&Zoom? 

Через DoCmd 

Application.DoCmd(visWinIDPanZoom); 

Окно специальных настроек

Помогите с маленькой проблемой. Создал смарт-шейп, к котором определил необходимые поля. Хочу по двойному клику на шейпе вызывать окно специальных настроек, которое можно вызвать следующим способом: правой кнопкой по шейпу, форма, специальные настройки. Так в настройке "Режимы" я такой не нашел. Попробовал записать макрос, но тоже не получилось. Как быть? 

Достаточно в ячейку EvntDblClick секции Events шейпа записать =DOCMD(1312) и все. 

Control в отдельном окне

Рассказываю по порядку. В Visio можно вставить Control (Нпример ListBox). Но в моем документе он мне не нужен, нужен только в процессе редактирования документа. Возникла идея вставить Control в отдельное окно (тем более таких окон нужно несколько). Получается что-то похожее на stencil (но stencil в данном случае не подходит).
Window fWindow = mVisioApp.Windows.Add("Wnd",0,0,0,0,100,100,0,null,null);
Непонятно как вставить Control в окно. Нужно ли создавать документ для этого окна или еще каким-либо способом? 

А почему обязательно в документ...
Control можно вставить в отдельную форму и в нужный момент эту форму вызывать. Будет окошко, высвечаваемое по событиям или по запуску макроса.
Ну а более сложный вариант - сделать так называемое Anchored Window. Оно создается как дочернее и может болтаться в любом месте либо прикрепляться к какой-то из сторон родительского окна. (Как я понимаю, это и есть что-то типа UML Model Explorer)
Если поискать в MSDN слова Anchored Window, то обязательно наткнетесь на пример создания такого окна.
Вот примерчик. Может поможет... 

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Public Const GWL_STYLE = (-16)
Public Const WS_CHILD = &H40000000
Public Const WS_VISIBLE = &H10000000

Public m_Base As Base

Public Sub ShowBase()

Dim wAddon As Visio.Window
Set wAddon = ActiveWindow.Windows.Add("Base", visWSVisible, visAnchorBarAddon, , , 300, 210)

Set m_Base = New Base
m_Base.Caption = "Base"

Dim FormHandle As Long
FormHandle = FindWindow(vbNullString, "Base")

SetWindowLong FormHandle, GWL_STYLE, WS_CHILD Or WS_VISIBLE

SetParent FormHandle, wAddon.WindowHandle32

Dim pnLeft As Long, pnTop As Long, pnWidth As Long, pnHeight As Long
wAddon.GetWindowRect pnLeft, pnTop, pnWidth, pnHeight
wAddon.SetWindowRect pnLeft, pnTop, pnWidth + 1, pnHeight
For Each sh In ActivePage.Shapes
m_Base.ListBox1.AddItem sh.Name
Next

End Sub 

Спасибо. Заработало. 

Как убрать окно объектов

Имеется многостраничный документ .vsd в котором по двойному щелчку на шейпах организованы переходы между страницами. Документ используется в режиме просмотра, но при этом постоянно присутствует окно объектов(трафаретов) уменьшая тем самым область просмотра. Как его убрать, и сделать область просмотра максимальной. В полноэкранном режиме не работают переходы по двойному щелчку 

Закройте трафареты (командой Close в контекстном меню на окне каждого трафарета).
Затем закройте все окно Shapes, просто щелкнув по его крестику.
Сохраните документ.
В следующий раз он должен открыться без окна трафаретов. 

Центрирование видимого окна по шейпу

Есть схема. Программно выделяю объект.
Как программно центрировать область видимости по объекту? Т.е. сдвинуть видимый прямоугольник окна так, чтобы выделенный объект был по центру экрана. Объект двигать нельзя. 

Пока приходит в голову только узнавать координаты шейпа и программно устанавливать размеры видимого прямоугольника.. но может есть способ более изящный?
Не изящный способ работает :) 

double xPos;
double yPos;
// Узнаем координаты шейпа
xPos = shape.get_Cells("PinX").ResultIU;
yPos = shape.get_Cells("PinY").ResultIU;
// Центрируем видимый прямоугольник окна по выделенному объекту
// Цифры прибавляемые к xPos и yPos - это размеры окна в дюймах,
// меняя их мы можем менять масштаб видимости шейпа.
axDrawingControl.Window.SetViewRect(xPos-4, yPos+2, 8, 4); 

Начиная с Visio 2010 у окна появился метод CenterViewOnShape 

Window.CenterViewOnShape 

 

Подскажите пожалуйста, есть ли в Visio FileDialog как в Excel?

Подскажите пожалуйста, есть ли в Visio аналог Excel-евского FileDialog? Вернее, почти готов поспорить, что есть, только не могу сообразить как его запустить. Мне даже кажется, должна быть возможность использовать сам FileDialog, только как? 

Возможно три варианта:
С использованием DOCMD (http://visguy.com/vgforum/index.php?topic=738.0), работает когда нужно открыть документы Visio. 

Public Sub openDoc()
Dim visApp As Visio.Application
Set visApp = Application
Dim visDoc As Visio.Document
visApp.Application.DoCmd (VisUICmds.visCmdFileOpen)
Set docObj = visApp.ActiveDocument
End Sub 

C использованием диалогового окна приложений MS Office (http://www.cyberforum.ru/vba/thread325133.html). 

Sub P1()
'Чтобы было проще код писать (чтобы выскакивали подсказки после того
'как точку ставите) - подключите библиотеку Word:
'Tools - References... - Microsoft Word Object Library.
'Обращаться к программе Word будем через переменную Ворд.
Dim wd As New Word.Application
wd.Visible = True
'Собственно работа с диалоговым окном
With wd.FileDialog(msoFileDialogFilePicker)
.Show
Debug.Print .SelectedItems(1)
End With
'Закрываем программу Word.
wd.Quit
Set wd = Nothing
'Здесь дальше код.
End Sub 

С использованием API (https://artberg-visio-forum.github.io/topic.asp@TOPIC_ID=132.html) 

Private Declare Function GetOpenFileName _
Lib "COMDLG32.DLL" Alias "GetOpenFileNameA" _
(pOpenfilename As OPENFILENAME) As Long
Private Declare Function GetSaveFileName _
Lib "COMDLG32.DLL" Alias "GetSaveFileNameA" _
(pOpenfilename As OPENFILENAME) As Long

' Объявление структур
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
Flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type

' И собственно использование
Sub GetFileFromAPI ()
Dim OFN As OPENFILENAME
With OFN
.lStructSize = Len(OFN) ' Size of structure.
.nMaxFile = 260 ' Size of buffer.
' Create buffer.
.lpstrFile = String(.nMaxFile - 1, 0)
Ret = GetOpenFileName(OFN) ' Call function.
If Ret <> 0 Then ' Non-zero is success.
' Find first null char.
n = InStr(.lpstrFile, VbNullChar)
' Return what's before it.
MsgBox Left(.lpstrFile, n - 1)
End If
End With
End Sub