![]() |
Форум visio.getbb.ru |
О форумах
Библиотека | Частые вопросы | Литература | Склад материалов Visio Navigator | Blog | Полезные ссылки | О сайте История Visio | Продукты Visio |
Для русскоязычных пользователей Visio. Начинающих и профессионалов. Где взять, как сделать, что купить и т.д. |
Слои (Layers) в Visio несколько отличаются от слоев в других приложениях. Они совершенно не связаны с пространственным положением и взаимным перекрытием шейпов, а выступают в роли неких именованных категорий, повышающих удобство управления шейпами. Все содержимое слоя можно скрыть или вновь показать, можно удалить слой со всеми входящими шейпами, запретить печать или вообще заблокировать любые операции с шейпами на слое.
Для ручного управления свойствами слоев используется специальное диалоговое окно. Даже два окна - второе используется для привязки шейпов к слоям.
Для программного управления слоями используется шейп-лист и методы и свойства некоторых объектов. Таких объектов всего три: страница, мастер и шейп. Причем мастер во многом подобен странице.
Страница содержит перечень и описание всех используемых на ней слоев. Присоединенные шейпы только ссылаются на эти данные. Объект Layer достается из коллекции Layers по имени или индексу. Индекс, как обычно, начинается с 1.
Set layerObj = ActivePage.Item("Plumbing")
Вот так можно просмотреть имена слоев активной страницы
Sub GetLayers ()
For Each layerObj In ActivePage.Layers
Debug.Print layerObj.Name
Next<
End Sub
Каждый слой представлен в шейп-листе страницы отдельной строкой в секции Layers. Свойство Row объекта Layer указывает на номер строки в секции Layers. Индекс в коллекции Layers как правило не совпадает с номером строки.
В шейпе коллекции Layers нет. Количество слоев, ассоциированных с шейпом находится в свойстве LayerCount. Объект Layer доступен через свойство Layer, например,
Set layerObj = shpObj.Layer(2)
Попытка обратиться к свойству Layer при нулевом LayerCount приводит к ошибке.
Чтобы привязать шейп к слою используется метод Add слоя
layerObj.Add shpObj, preserveMembersFlag
Флаг нужен для шейпа группы и касается ее членов. Если флаг имеет значение True, к слою присоединяется только группа без дочерних шейпов. Если флаг нулевой (False), то входящие шейпы тоже попадают на слой.
Удаление происходит аналогично
layerObj.Remove shpObj, preserveMembersFlag
Свойства слоя устанавливаются через свойство CellsC
LayerObj.CellsC(Column)
где Column - индекс колонки, который можно уточнить в справке в списке VisCellIndices.
Например, скрыть слой можно одной из следующих команд
layerObj.CellsC(visLayerVisible).Formula = False
layerObj.CellsC(visLayerVisible).Formula = 0
Кстати, доступ через CellsSrc тоже возможен.
05.06.2020
13.12.2018
24.10.2018
01.01.2017
04.09.2012
08.10.2007
26.03.2004
Как расслоить большую схему?
Есть большая схема сети (ЛВС). Хочу расслоить её, так, чтобы по желанию можно было смотреть или только серверы, или только коммутаторы, или только маршрутизаторы и т.д. по моему усмотрению. В Help-е предлагается править шейпы в Stencil. А уж из исправленного Stencil-а делать схему. Этот вариант работает, но мне не подходит, т.к. готовая схема большая и объекты нафаршированы свойствами. Есть ли возможность слоить готовый рисунок?
Назначить слои мастерам в локальном трафарете и все. Мастеру Server, к примеру, назначить слой Servers.
1) Сделал слой Servers (как help-е) 2) Зашёл в режим редактирования Stencil-а (я правильно понимаю, что это и есть "локальный трафарет", о котором Вы писали?) Название - Stencil Basic Network Shapes 3D 3) Говорю Edit Master 4) Правой клавишей мыши по мастеру -> Format -> Имя Layer-a 5) всё сохраняю. Что неправильно?
Не тот трафарет. Локальный трафарет формируется из всех мастеров, когда-либо помещавшихся на лист. Его можно вызвать из File>Stencils>Document Stencil. В него и надо вносить изменения.
Макрос для управления слоем
Хотелось бы привязать к кнопке свойства вызова окна выбора слоя или закрепить за ней отображение определенного слоя. Знает ли кто, как это сделать в visio 2000
Вот фрагмент кода, выполнявшийся в Add-on. Управляет свойством visLayerVisible (включает/выключает по очередному нажатию кнопки).
If mode = 102 Then 'Layer IP Network Configuration Set objCell = aV.ActivePage.Layers.Item("IP Network Configuration").CellsC(4) If Not (objCell Is Nothing) Then If objCell = 0 Then objCell = 1 Else objCell = 0 End If End If End If
Каждая кнопка запускает Add-on со своим параметром mode. .CellsC(4) это как раз visLayerVisible
Удаление слоя без удаления шейпов, назначенных на удаляемый слой
Можно ли удалить слой, а его шейпы оставить?
Графический интерфейс Visio не допускает такой операции. Удаление слоя влечет за собой удаление всех шейпов назначенных только одному этому слою. Однако, проблему можно решить с помощью VBA. Метод Delete принимает параметр fDeleteShapes Layer.Delete( _fDeleteShapes_ ) Если он равен 1 (True), то назначенные шейпы удаляются. Иначе остаются. Таким образом, можно отrрыть окно Immediate и набрать строку
ActivePage.Layers("NewLayer").Delete 0
и слой будут удален без изменения изображения.
Data Graphics и слои
Можно ли связать Data Graphics со слоями? Я использую Data Graphics, связанные с внешними источниками данных. Поскольку необходимо обмениваться данными с внешними клиентами, иногда требуется скрыть IP адреса. Можно ли вынести одно поле на другой слой, чтобы потом отдельно управлять отображением этого слоя?
Начиная с Visio 2016 появилось специальное служебное окно "Data Graphic Fields". Оно позволяет управлять отображением отдельных полей Data Graphics. В предыдущих версиях такой возможности не было. Вынести одно из полей Data Graphics на отдельный слой штатными средствами невозможно. Data Graphics ассоциируется с специальным слоям, который так и называется "Data Graphics". Тем не менее, можно написать макрос, выполняющий такую операцию. Он будет иметь примерно такой вид:
Sub reassignLayer() For Each shp In ActivePage.Shapes For Each sh In shp.Shapes If sh.Name = "Data bar 1" Then sh.Cells("LayerMember").FormulaForceU = """1""" Next Next End Sub
В подобном макросе нужно задавать имя шейпа, отображающего нужное поле, и идентификатор требуемого слоя. Макрос использует особенность Data Graphics - все шейпы, отображающие одно поле, имеют одно и то же имя.
Фантомные слои
У меня есть файл Visio, используемый в качестве инструмента для дизайна и разработки. В нем примерно 25 старниц, широко используются слои. Некоторые слои являются общими для всех страниц, некоторые уникальны. Однако на каждой странице есть пустые слои, которые отображаются в шейп-листе, но не отображаются в свойствах слоев. Кто-нибудь может объяснить, почему Visio создает эти фантомные слои?
Visio идентифицирует слои номером, а не именем. Таким образом, слои с одинаковым именем могут иметь разные идентификаторы на каждой странице. Когда слои удаляются, Visio просто удаляет имя, строка в PageSheet не удаляется. Слои с пустыми именами не отображаются в диалоговом окне свойств слоя. Visio может впоследствии использовать строки с пустыми именами при добавлении нового слоя на страницу. Источник: visguy.com/vgforum/index.php?topic=7764
Шейпы с несколькими слоями не скрываются
У меня есть шейпы с несколькими слоями. Например, "Инструмент" и "Электрический". Если я снимаю видимость с обоих слоев, шейп скрывается. Если только с одного, шейп остается видимым. Можно ли сделать так, чтобы скрытие любого слоя скрывало шейп?
Не напрямую. Слои глобальны. Если слой видимый, то все принадлежащие ему шейпы видны. Но можно редактировать шейп-лист. Например в секции геометрии ввести условие IF, управляющее видимостью на основе слоев. Кроме того, можно редактировать шейп-лист страницы, создать пользовательские ячейки, обеспечивающие условный ответ на различные комбинации слоев. Потом каждый многослойный шейп сможет ссылаться на эти ячейки. Источник и пример: http://visguy.com/vgforum/index.php?topic=7516.msg31894
Как сделать кнопку, открывающую окно Layer Properties?
У меня много пользователей, которым трудно объяснить, как открыть окно Layer Properties. Как сделать кнопку на странице для открытия этого окна?
Обработчик события должен содержать команду Application.DoCmd (visCmdLayerSetupDlg)
Подсветка слоя с помощью кода
Я могу скрывать и показывать слои в том числе с помощью кода. Но хотелось бы не только уметь показать отдельный слой, изолированный от остального, но и выделить, обвести слой другим цветом. Возможно ли это?
Вот небольшой сниплет, который красит слой в красный цвет:
Dim visPg as Visio.Page Dim visLyr as Visio.Layer Set visPg = Visio.ActivePage Set visLyr = visPg.Layers("Bob") visLyr.CellsC(visio.VisCellIndices.visLayerColor).Formula = "RGB(255,0,0)"
Вы можете удалить подкраску, очистив формулу:
visLyr.CellsC(visio.VisCellIndices.visLayerColor).Formula = ""
Или можно установить результат в 0:
visLyr.CellsC(visio.VisCellIndices.visLayerColor).ResultIU = 0
Одинаковые слои на нескольких страницах
У меня есть чертеж, в котором отдельные страницы используются для раскрытия деталей общего плана. Я настроил несколько слоев для форматирования и управления некоторыми категориями шейпов. Могу ли я использовать слои одной страницы в другой без повторного ввода слоев на каждой странице?
Все что требуется, это скопировать шейп, содержащий нужный слой, на другую страницу. Слой и все его свойства будут скопированы. Потом шейп можно удалить.
Каждый шейп на заданном слое
У меня есть план здания с несколькими слоями, на которые вынесены различные типы оборудования. Проблема в том, что некоторые шейпы имеют маленький фактический размер. Хотелось бы макросом увеличить или уменьшить размер всех шейпов, отнесенных на определенный слой. Как это сделать?
Вот пример кода
Public Sub LayersContent2() Dim PagObj As Visio.Page Dim layersObj As Visio.Layers, layerObj As Visio.Layer Dim shpsObj As Visio.Shapes, shpObj As Visio.Shape Dim I As Long, N As Long For Each PagObj In ActiveDocument.Pages For Each shpObj In PagObj.Shapes N = shpObj.LayerCount If N > 0 Then For I = 1 To N Set layerObj = shpObj.Layer(I) If layerObj.Name = "A" Then shpObj.Cells("Width").Result(visMillimeters) = 60 End If Next I End If Next shpObj Next PagObj End Sub
Источник: http://visguy.com/vgforum/index.php?topic=3488
Счетчик шейпов в слое
Кто-нибудь знает, как исправить счетчик шейпов при назначении слоя шейпу? Например, я создал слой "Computers" и назначил его по умолчанию шейпам Computer и Monitor. Но при опускании такого шейпа на страницу рисунка я получаю приращение количества шейпов на слое на 25 вместо одного.
Эти шейпы являются группами и в количестве шейпов учитываются все входящие в группу шейпы.
Как сослаться на слой через универсальное имя?
Я знаю, что лучше использовать универсальные имена вместо локальных. Но как сослаться на слой через его NameU?
Синтаксис .Layers("MyLocalName") является сокращенным вариантом. На самом деле это должно выглядеть как
.Layers.Item("MyLocalName")
Тогда для универсального имени будет
.Layers.ItemU("MyUniversalName")
Баг со слоями и группами?
Я сделал следующее: Создал два слоя и сделал их видимыми. Создал 3 шейпа: квадрат, круг, треугольник. Назначил два из них (квадрат и треугольник) на первый слой. Сгруппировал все и назначил группу на второй слой. Сделал второй слой скрытым. Квадрат и треугольник остаются видимыми, но не доступны для селектирования.
Я думаю, при назначении второго слоя был установлен флажок "Preserve group member layers". При этом принадлежность слоям у членов группы остается неизменной, то есть они остались на слое 1. Источник и пример: http://visguy.com/vgforum/index.php?topic=6417
Скрытие шейпов при нажатии на кнопку
Ситуация следующая - имеется Visio файл, отражающий структуру серверов и приложений и генерирующий отчеты. Не для каждого отчета нужны все серверы и приложения, поэтому есть желание скрывать ненужные и оставлять то, что требуется для конкретного отчета.
Обратите внимание на слои. Слои принадлежат странице и ассоциируются с шейпами. Слои можно скрывать. Можно создать меню для скрытия-включения слоев. Альтернативный подход - управление видимостью шейпов на основе шейп-листа. Если вы не желаете использовать VBA, можно делать примерно так:
action = setf(getref(action.checked), if(action.checked, 0, 1)) + setf(getref(geometry1.noshow), if(action.checked, 0,1))
Первый SETF переключает флаг в контекстном меню шейпа. Второй в зависимости от флага переключает отображение шейпа. Можно установить флаг в шейп-листе страницы и ссылаться на него из переключаемых шейпов. Некоторые плюсы и минусы решений на основе шейп-листа и VBA. Шейп-лист: не имеет проблем с безопасностью. Недостаток: нужны некоторые априорные сведения для установления связей. И это должно быть сделано на каждой странице, потому что слои привязаны к страницам. VBA: самый большой недостаток - снижение уровня безопасности. И необходимо уметь писать код. Достоинства: наибольшая гибкость, можно обойтись без предварительной настройки, допускает использование дополнительных фильстров.
План зон безопасности
Недавно на одном из форумов был задан вопрос о том, как можно применить слои к плану зон безопасности. Пользователь надеялся использовать слои для цветовой маркировки, какие двери относятся к каким зонам. Двери могут быть отнесены к разным зонам. Это означает, что в какой-то момент появляются уникальные списки для каждого шейпа. Именно в управлении этими списками разработчик начинает видеть сложность создания диалогов для назначения дверей зонам. Я принял решение отнести двери к уникальным слоям, а затем присвоить текстовым шейпам одинаковые имена. Наконец, вместо того, чтобы менять цвет дверей, я добавил необходимые макросы, чтобы открывать и закрывать двери, связанные с отдельными слоями зоны. Используются некоторые примеры кода из Visio SDK (получение списка шейпов для выбранного слоя). Открытие и закрытие дверей основано на событии SelectionChanged и распознавании того, что было выбрано одно из текстовых полей. Источник и пример: http://visguy.com/vgforum/index.php?topic=4202
Включение-выключение слоев
Существует три основных способа скрытия шейпов: 1) переключить ее видимость, 2) назначить ее указанному слою и переключить видимость слоя, 3) уменьшить ее до нулевого размера. Третий метод хорошо работает для импортируемых изображений. Прикрепленный файл охватывает методы (2) и (3). Предусмотрено два подхода: первый использует контекстное меню в любом месте страницы, второй использует выделенный шейп. Источник и пример: http://visguy.com/vgforum/index.php?topic=5740
Пересечение с линией на скрытом слое
Имеются две пересекающиеся линии. Линия 1 "перепрыгивает" линию 2 в точке пересечения. Это нормально. Но когда я делаю слой с линией 2 невидимым, то изображение "перепрыгивания" остается. Есть ли способ сделать так, чтобы пересечение невидимых линий не выделялось?
Можно попробовать добавить в мастер-шейпе условие к ConLineJumpCode, которое проверяло бы, относится ли шейп к скрытому слою и, если относится, включало бы перескок. Вот такая формула решает проблему
=IF(FIND("2",LayerMember),2,0)
Если на невидимом слое, всегда перепрыгивать, иначе поведение по умолчанию. Источник: http://visguy.com/vgforum/index.php?topic=378 Если скрытый слой наперед не известен, можно добавить немного VBA кода. Примерно так:
Sub SetJumpCode() For Each shp In ActivePage.Shapes For i = 1 To shp.LayerCount ln = shp.Layer(i).Name If ActivePage.Layers(ln).CellsC(4) Then 'Visible shp.Cells("ConLineJumpCode") = 0 Else shp.Cells("ConLineJumpCode") = 2 End If Next Next End Sub