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

Копирование листа
http://visio.getbb.ru/viewtopic.php?f=6&t=1049
Страница 2 из 4

Автор:  Shishok [ 13 ноя 2016, 20:25 ]
Заголовок сообщения:  Re: Копирование листа

Цитата:
Как выделить не все шейпы на листе, а только те, которые находятся в границах печати листа?

Посмотри вот тут:
http://visio.getbb.ru/viewtopic.php?f=15&t=671

Для решения задачи нужно нарисовать прямоугольник по размерам страницы минус поля и методом SpatialNeighbors
определить попавшие под прямоугольник шейпы. Ну и выделить их.
Впрочем в данном случае поля наверное можно проигнорировать.

И еще. На листе могут быть невидимые и/или заблокированные слои. Шейпы с этих слоев естественно не выделятся.
Надо проверять это.

Автор:  Alex_ST [ 13 ноя 2016, 23:01 ]
Заголовок сообщения:  Re: Копирование листа

Я, вообще-то, программирую в основном в Excel. Да и там программное создание DrawingObjects - далеко не мой конёк :oops:
Поэтому
Shishok писал(а):
нарисовать прямоугольник по размерам страницы минус поля
для меня задача хоть наверняка и вполне выполнимая, но требующая длительного изучения Справки (которая мало того, что паршиво сделана, в отличие от отличной Справки 2003, так ещё и по-английски, а на инглише я читаю далеко не бегло, к сожалению).
Вот потому меня и интересовал код процедур Tumanov из ShapeComparer чтобы поучиться. Сам-то стенсил я качнул. Но проект VBA запаролен и автор его "по просьбам зрителей" не раскрывает.
(Придётся самому взломать пароль и посмотреть. Авось разберусь. Но тогда уж ссылку в своём коде на автора ставить не буду не корректно это)

Автор:  Tumanov [ 14 ноя 2016, 00:04 ]
Заголовок сообщения:  Re: Копирование листа

Цитата:
Вот потому меня и интересовал код процедур Tumanov из ShapeComparer чтобы поучиться. Сам-то стенсил я качнул. Но проект VBA запаролен и автор его "по просьбам зрителей" не раскрывает.

Вообще-то ни одной просьбы я не заметил.
Хотя намеки, пожалуй, были.
Кстати, после первого же намека я выложил для интересующихся текст программы. Правда, это было в другом топике... Ну так, где намекали, там и выложил.
viewtopic.php?f=29&t=877&st=0&sk=t&sd=a&start=20
И как минимум двое этот файлик заметили и скачали.
Цитата:
Придётся самому взломать пароль и посмотреть. Авось разберусь.

Можно, конечно, и так.
Цитата:
Но тогда уж ссылку в своём коде на автора ставить не буду не корректно это

Согласен. Вскрыть чужой код, да еще и поставить ссылку - это некорректно :)

Автор:  Shishok [ 14 ноя 2016, 00:15 ]
Заголовок сообщения:  Re: Копирование листа

Цитата:
для меня задача хоть наверняка и вполне выполнимая, но требующая длительного изучения Справки


В общем я выложил в Копилку макросов, что у меня получилось в итоге.

Автор:  Alex_ST [ 14 ноя 2016, 10:04 ]
Заголовок сообщения:  Re: Копирование листа

Shishok писал(а):
выложил в Копилку макросов

Уже не первый раз слышу про эту копилку...
Поиск по форуму *копилка* не даёт ничего, *макросов* - только сообщения о том, что туда что-то выложено :evil:
Сейчас тупо потыкался по форуму и таки-нашёл "Копилку"! Правда, расположена она почему-то не в ветке "Программирование", называется "Склад полезных макросов" и слово "макросов" в названии почему-то не ищется Поиском :)

Автор:  Alex_ST [ 14 ноя 2016, 10:12 ]
Заголовок сообщения:  Re: Копирование листа

Tumanov писал(а):
Ну так, где намекали, там и выложил.

Прошу прощения. Или я почему-то не заметил аттача, или он появился не сразу после ответа, а в результате редактирования ранее написанного поста.
Спасибо. Скачал. Ломать пароль не будем. Будем посмотреть.

Автор:  Surrogate [ 14 ноя 2016, 11:36 ]
Заголовок сообщения:  Re: Копирование листа

Alex_ST писал(а):
Сейчас тупо потыкался по форуму и таки-нашёл "Копилку"! Правда, расположена она почему-то не в ветке "Программирование", называется "Склад полезных макросов"
такое у нас разбиение в ветке Форум разработчиков
Изображение
В ветке Программирование - предполагается вопросы-ответы по интересующим вопросам.
В ветке Склад полезных макросов - здесь пользователи могут выкладывать свои готовые работы.
а про то что поиск на форуме работает криво это общеизвестный факт к сожалению…
Alex_ST писал(а):
программное создание DrawingObjects
а это то за зверь ?
Constantin в сообщении #6963 писал(а):
У меня также есть скромный вариант творчества:Содержимое спрятано под спойлер ↓
Спойлер:
Изображение
это что из этой серии ?

Автор:  Alex_ST [ 14 ноя 2016, 12:14 ]
Заголовок сообщения:  Re: Копирование листа

Surrogate писал(а):
а это то за зверь ?
В Excel не вся графика, находящаяся на листе, относится к коллекции Sheet.Shapes.
Например, в эту коллекцию не попадают выпадающие списки, показываемые при выборе ячеек, для которых назначена проверка данных.
Полная коллекция ВСЕХ графических элементов в Excel находится в коллекции Sheet.DrawingObjects
К сожалению, она не официально документирована и в Справке не показывается.
Хотя для обычных целей достаточно обращаться к Sheet.Shapes , я привык всё-таки в Excel работать с Sheet.DrawingObjects.
Под спойлером - несколько примеров для Excel
Содержимое спрятано под спойлер ↓
Спойлер:
Вот например, как можно выбрать на листе ВСЮ графику:
Код:
Private Sub Draws_On_Sheet_Select()   ' выделить все рисунки на листе
   ActiveSheet.DrawingObjects.Select
End Sub
При этом выберутся даже невидимые, пока не выберешь ячейку выпадающие списки проверки данных .
Но можно, конечно, и прямо сразу всё удалить: ActiveSheet.DrawingObjects.Delete
А вот процедура для выбора гнусных "0-размерных" рисунков, остающихся на листе после удаления строк/столбцов, содержащих рисунки и примечания со почеканным свойством "Перемещать и изменять размер вместе с ячейками", задаваемым по умолчанию (такие никому не нужные рисунки часто являются причиной "ожирения" файлов):
Код:
Private Sub Draws_0D_Select()   ' выделить НА ЛИСТЕ все рисунки с нулевыми размерами
   Dim oDraw As Shape
   If ActiveSheet.DrawingObjects.Count = 0 Then:   MsgBox "В выделенном диапазоне нет рисунков", , "Нет объектов!": Exit Sub
   For Each oDraw In ActiveSheet.DrawingObjects.ShapeRange
      If oDraw.Width = 0 Or oDraw.Height = 0 Then oDraw.Select (False)
   Next
End Sub
Ну а уж после того, как то, что нужно, будет выбрано, лучше Del ручками нажать, убедившись, что выбрано то, что нужно :)
И для примера ещё одна "полезняшка" из моей коллекции:
Код:
Private Sub Draws_In_Selection_Select()   ' выделить В ВЫБРАННОМ ДИАПАЗОНЕ все рисунки
   Dim oDraw, rSel As Range
   If ActiveSheet.DrawingObjects.Count = 0 Then:   MsgBox "В выделенном диапазоне нет рисунков", , "Нет объектов!": Exit Sub
   Set rSel = ActiveWindow.RangeSelection   ' диапазон выбранных ячеек листа даже если после этого был выбран графический объект
   For Each oDraw In ActiveSheet.DrawingObjects.ShapeRange
      If Not Intersect(Range(oDraw.TopLeftCell, oDraw.BottomRightCell), rSel) Is Nothing Then oDraw.Select (False)
   Next
End Sub

Автор:  Alex_ST [ 14 ноя 2016, 12:37 ]
Заголовок сообщения:  Re: Копирование листа

A ShapeComparer.vss от Tumanov не порадовал: отказывается копировать страницы, если на них есть сгруппированные объекты.
Посмотрел выложенный текст модуля. Так и предусмотрено автором.

Автор:  Alex_ST [ 14 ноя 2016, 13:03 ]
Заголовок сообщения:  Re: Копирование листа

К стати, по поводу странного поведения программно создаваемых кнопок интерфейса.
Причёсывая проект с созданием кнопок, выяснил, что для каждого документа открывается отдельный экземпляр программы, наследующий настройки либо с ранее открытого, либо ставя их по умолчанию, если это первый экземпляр.
Так вот: если, открыв документ, создать в меню кнопки, то они унаследуются и следующими экземплярами, открываемыми со следующими документами.
Но если в каком-нибудь экземпляре процесса кнопки удалить, то они удаляются ТОЛЬКО в этом экзкмпляре, а не во всех!
Поэтому в одном окне программно создаваемое выпадающее меню "Копировать..." может присутствовать, а в другом - нет.
Тут, похоже, большая засада: шейп, создающий менюшку, должен открываться и во всех вторичных экземплярах Visio (т.е. должен быть общим, а это невозможно, т.к. аналога Personal.xls Normal.dot в Visio нет)

Автор:  Tumanov [ 14 ноя 2016, 13:19 ]
Заголовок сообщения:  Re: Копирование листа

Цитата:
К стати, по поводу странного поведения программно создаваемых кнопок интерфейса.

В Visio много вариантов построения интерфейса. В том числе, он может действовать и на уровне приложения. То есть вообще всегда и для всех документов Visio.
Просто нужно подобрать тот вариант, которые нужен для конкретного применения.

Автор:  Alex_ST [ 14 ноя 2016, 16:31 ]
Заголовок сообщения:  Re: Копирование листа

Shishok писал(а):
А я себе сделал
Класс! Проверил. Дуплицирование в той же книге работает отлично. Только с именами создаваемых листов что-то надо сделать. Ну, типа как в Excel добавлять суффикс (2), (3) и т.д.
Это я сам попробую допилить.
Правда, сейчас где-то включилась автонумерация страниц (я точно нигде не включал, т.к. раньше просто не знал о такой фиче). Поэтому все новые страницы создаются процедурой с именами Страница-2, … , Страница-6.
Это бы ничего, но если удалить, например, Страница-2, то Страница-3 автоматически переименовывается в Страница-2, Страница-4 - в Страница-3 и т.д. Т.е. в названии явно прописан индекс.
А ещё наткнулся на грабли: если рисунок на странице уже сгруппирован, то на строке
Код:
Set oGroup = ActiveWindow.Selection.Group
вылетает в отладчик с приговором
Цитата:
Run-time error Запрошенная операция сейчас отключена
Вложение:
Shot 2016.11.14 - 15.23.28 - VISIO.EXE (VISIO.EXE).jpg
Shot 2016.11.14 - 15.23.28 - VISIO.EXE (VISIO.EXE).jpg [ 39.14 Кб | Просмотров: 878 ]
При этом если на листе просто всего одна фигура (т.е. группировать нечего), то всё работает. А вот если всё сгруппировано - нет. Чушь какая-то!

Автор:  Alex_ST [ 14 ноя 2016, 17:07 ]
Заголовок сообщения:  Re: Копирование листа

И ещё в процедуре Duplucate_Here_To необходимо учесть, что расширения файлов могут быть написаны и ЗАГЛАВНЫМИ буквами, а оператор сравнения Like - Case Sensitive
Поэтому цикл перебора документов должен быть таким:
Код:
   For Each oDoc In Application.Documents
      If oDoc.Name <> oActiveDoc.Name Then
         If Not LCase(oDoc.Name) Like "*.vss*" Then
            Set oOtherDoc = oDoc
            Exit For
         End If
      End If
   Next
или, просто основываясь на типе документа, таким:
Код:
   For Each oDoc In Application.Documents
      If oDoc.Name <> oActiveDoc.Name Then
         If oDoc.Type = 1 Then '1 == visTypeDrawing
            Set oOtherDoc = oDoc
            Exit For
         End If
      End If
   Next

Автор:  Shishok [ 14 ноя 2016, 17:18 ]
Заголовок сообщения:  Re: Копирование листа

Цитата:
А ещё наткнулся на грабли: если рисунок на странице уже сгруппирован, то на строке

Вот это я упустил. Поправил. Скачай заново трафарет.

А с именами страниц просто. После строки:
Код:
Set oPage1 = ActiveDocument.Pages.Add

надо добавить:
Код:
oPage.Name = "Имя страницы" & Свой_Index

или
Код:
oPage.NameU = "Имя страницы"  & Свой_Index

можно еще добавить
Код:
oPage.Index = 1 ' будет стоять первой

или
Код:
oPage.Index = ActiveDocument.Pages.Count + 1 ' будет стоять последней

Автор:  Shishok [ 14 ноя 2016, 17:30 ]
Заголовок сообщения:  Re: Копирование листа

Цитата:
При этом если на листе просто всего одна фигура (т.е. группировать нечего), то всё работает. А вот если всё сгруппировано - нет. Чушь какая-то!

Да нет все нормально. :D
Сгруппированную фигуру нельзя еще раз сгруппировать, а просто фигуру можно. Вот так.

Автор:  Alex_ST [ 14 ноя 2016, 17:43 ]
Заголовок сообщения:  Re: Копирование листа

Shishok, спасибо.
С индексами разберусь. Шаблон с работы качнуть не смогу. Только из дома, если не забуду.
Ещё вопросик по Duplucate_Here_To можно?
Зачем там в конце перед вставкой в другую книгу стоит
Код:
Windows.Item(2).Activate
?
Я сначала подумал, что это ты так в лоб случайно окно другой книги назвал, чтобы оно открылось после завершения процедуры.
Свойства .Parent у Document я не нашёл, поэтому попробовал заменить на более, ИМХО, корректное
Код:
Windows.Item(oOtherDoc.Index).Activate
- не пошло...
Завтра ещё поковыряю в цикле перебора документов - сделаю возможность выбора, в который из открытых документов вставлять
Ухожу дискутировать в твой топик на Складе полезняшек

Автор:  Alex_ST [ 14 ноя 2016, 17:45 ]
Заголовок сообщения:  Re: Копирование листа

Shishok писал(а):
Сгруппированную фигуру нельзя еще раз сгруппировать, а просто фигуру можно

Ещё на попытке копирования просто пустого листа вылетает (так иногда бывает проще задать одинаковые параметры страниц и печати в разных файлах).

Автор:  Shishok [ 14 ноя 2016, 17:57 ]
Заголовок сообщения:  Re: Копирование листа

Зачем там в конце перед вставкой в другую книгу стоит
Код:
Код:
Windows.Item(2).Activate

Это активация окна другого документа. Без этого вставленная группа почему-то не расгруппировывается.

Цитата:
Windows.Item(oOtherDoc.Index).Activate
- не пошло...

То то и оно что не пошло.

Автор:  Shishok [ 14 ноя 2016, 18:05 ]
Заголовок сообщения:  Re: Копирование листа

Вот так наверно лучше:
Код:
Windows.ItemEx("Документ1").Activate ' "Документ1" - это заголовок окна другого документа

Автор:  Alex_ST [ 14 ноя 2016, 22:56 ]
Заголовок сообщения:  Re: Копирование листа

И так, и так коряво и чревато вылетами.
Ведь по "счастливой" случайности (т.е. почти наверняка :) ) oOtherDoc.Index может оказаться равен именно 2.
Ну, а то, что есть открытый документ "Документ1", вообще мало вероятно.
В Excel когда нужно было точно уйти куда-нибудь на наверняка имеющееся окно, я программно создавал книгу. При этом она автоматически активировалась. А потом её сразу же убивал.
При этом не нужно было знать ни имени, ни индекса окна создаваемой временной книги, т.к. это делалось процедурой типа:
Код:
    With Workbooks.Add
        Windows(.Name).Close
    End With
Или, т.к. при создании книга автоматически активируется:
Код:
    With Workbooks.Add
        'Workbooks(.Name).Activate
        ActiveWorkbook.Close
    End With
Наверное, в Visio можно сделать аналогично. А при желании между .Add и .Close вполне можно будет вставить нужные нам процедуры работы с другими листами.

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