Eigene Shapes – ein Motorradfahrer

Wir bauen einen Motorradfahren mit den visio-eigenen „Hausmitteln“.

20160730Motorrad01Ich beginne mit dem Helm. Hierfür verwende ich einen Kreis und ein Rechteck. Zuerst wird der Kreis markiert, anschließend das Rechteck. Vom Kreis wird über Entwicklertools / Shape-Design / Subtrahieren das Rechteck abgezogen.

20160730Motorrad02

Erneut wir ein Rechteck auf die Form gelegt. Mit dem Bleistift-Werkzeug kann das Rechteck in ein Trapez transformiert werden.

20160730Motorrad03

Beide Shapes werden markiert und über Entwicklertools / Shape-Design / Gesamtmenge verschmolzen.

20160730Motorrad04

Der Helm ist fast fertig – es fehlt noch das Visier.

20160730Motorrad05

Dazu wird erneut ein Rechteck über das Shape gelegt. Das Rechteck wird mit dem Bleistift-Werkzeug deformiert.

20160730Motorrad06

Der fertige Helm – ein bisschen bunt.

20160730Motorrad07

Für den Körper werden Rechtecke übereinandergelegt. Einige werden mit dem Bleistift-Werkzeug modifiziert, andere werden abgerundet (über Format / Linie).

20160730Motorrad08

Die einzelnen Shapes werden markiert und über Entwicklertools / Shape-Design / Gesamtmenge miteinander verschmolzen.

20160730Motorrad09

Möglicherweise muss man einige Knoten entfernen. Hier leistet erneut das Werkzeug „Bleistift“ gute Dienste.

20160730Motorrad11

Für den Reifen werden zwei Kreise aneinander ausgerichtet (Mitte – Mitte). Anschließend mit Entwicklertools / Shape-Design / Kombinieren ein „Loch“ erzeugt.

20160730Motorrad12

Der eine Reifen kann verschoben werden. Mit gedrückter Strg-Taste wird er dupliziert. Mit gleichzeitig gedrückter Shift-Taste bleibt er auf der gleichen Horizontalen.

20160730Motorrad13

Das fertige Ergebnis

20160730Motorrad14

Fast wie das Original …

Action im ShapeSheet

Manchmal entgehen mir Dinge.
Ich gestehe, ich habe übersehen, dass Visio 2010 im ShapeSheet im Abschnitt „Action“ die beiden Spalten „BeginGroup“ und „FlyoutChild“ eingeführt hat. Die erste Spalte ist eigentlich nicht nötig, denn man kann auch mit einem Unterstrich im Menu arbeiten:
_Top
fügt vor dieser Zeile eine Trennlinie ein.
Praktisch ist jedoch „FlyoutChild – damit lassen sich Untermenüs erstellen. Visio hat bei den Shapes der Schablone „Zeitachsen-Shapes“ dies vorgemacht. Ein Blick ins Shapesheet zeigt, wie es funktioniert.
   20160428Action0120160428Action0220160428Action0320160428Action04

Timer

20161104Uhr

Hallo Herr Martin,

danke für Ihre letzte Antwort.!
Um in der Angelegenheit große Schritte zu tun (oder sie bleiben zu lassen, was ich erst einmal bevorzugt habe) müssten wir wohl über das Schreiben hinausgehen.

Momentan treibt mich eine andere Angelegenheit um:
Inzwischen nutze ich ja das visio2010.
Ein Kollege, dem ich eine kleine Simulation zugeschickt habe, benutzt ein visio 2013.

Nun brauche ich für meine Routine einen genauen 20ms Zeittakt. (oder auch 30ms, …)
Die Rechnerzeit hole ich mir mit GetTime aus

Private Declare Function GetTime Lib „winmm.dll“ Alias „timeGetTime“ () As Long

Dabei überwache ich, ob mein Arbeitszyklus auch nicht länger als die 20ms ist.
Seit langem funktioniert bei mir die Routine. (auch gemütliche PC’s) Die Überwachung habe ich sichtbar gestaltet.

Jetzt, bei meinem Kollegen, braucht der PC, wie soll ich sagen, „mehr Zeit“ (auch 30ms reichen nicht)….

Frage:
– Ist Ihnen ein besserer Zugriff auf die Systemzeit des PC’s im Rahmen in visio bekannt?
– Hätten Sie ein Erklärung parat ?

zur Info das kleine Programmstück

If (M_GetTime – Ticker) > Taktzeit Then ‚ in Abstand von z.B. 20ms wird getaktet
Schleife = True ‚ für den Aufruf eines Programmes
If (M_GetTime – Ticker) > 2 * Taktzeit Then ‚ Kontrolle, ob Überlauf!
Taktueberlauf = Taktueberlauf + 1
End If
Normaltakt = Normaltakt + 1 ‚ Zähler für den Takt
Ticker = Ticker + Taktzeit
End If

….im Programm dann „Schleife = false“
####
Hallo Herr F.,
Hätten Sie mich gefragt, wie man einen Timer ansteuert , hätte ich Ihnen geantwortet – mit einer API-Funktion. Nein , Visio hat, anders als Word oder Access, keinen integrierten Timer.
Dass diese Funktion nicht richtig arbeitet, oder sich je nach Rechner oder Prozessor oder Betriebssystem unterschiedlich verhält – dazu kann ich nichts sagen .
Also doch Visual Studio als Überbau?
Sorry – da kann ich leider nicht weiterhelfen.
Schöne Grüße
Rene Martin
#####
Hallo Herr Martin,

vielen Dank für Ihre Antwort!
Und Sie waren eigentlich meine einzige große Hoffnung, etwas Licht in die Dunkelheit zu bringen!

Es ist schon verrückt! Ich habe zu Hause 2 PC’s , einen zum Arbeiten und einen alten, der nur noch herumsteht. Und einen kleinen Laptop.
Auf allen 3 Rechnern (ob W7 oder XP) läuft die genannte Routine (quasi unabhängig von der Leistungsfähigkeit) recht ähnlich.
Das Nutzerprogramm braucht halt ein paar Millisekunden. Der Hauptanteil dürfte aber für VB-visio bei der Bildschirmbehandlung (Verschieben von Rechtecken) verschwendet werden. Hat man z.B einen bunten Hintergrund braucht die Routine mehr Zeit…

Nun mache ich die Erfahrung, dass mit einem (sicher) leistungsfähigem Rechner, aber eben mit visio 2013, das gleiche Programm erheblich mehr Zeit kostet.
Nun, ich werde auf die Ferne mit den Kollegen einige Test’s versuchen , um der Sache etwas näher zu kommen.
Gern informiere ich Sie über das Ergebnis. Vielleicht gibt es auch noch andere Nutzer, die ähnliche Erfahrungen brauchen könnten. Und Sie sind ja der wohl einzige Fachmann, der sich mit visio voll auskennt.

Aus meiner Sicht ist es eigentlich schade, dass MS das Produkt „visio“ so verkommen lässt. ( oder so modernisiert…)
In meiner frühen Zeit habe ich noch maschinennahe Programme geschrieben (Z80). Da es Mangel an Speicher gab, war es oft das Ziel, überlegt zu programmieren…..
Noch bin ich begeistert, dass man z.B. mit 300kB visio-Programm bewegte Bilder mit wichtigem techn. Hintergrund zusammenstellen kann.
Allerdings ist für Viele das meist gar kein Argument… – eben schade!

Eingebettete Objekte

Ich gestehe – es hat mich etwas Mühe gekostet.
Das Einbetten eines Objektes (Exceltabelle) nach Visio ist per Programmierung nicht sehr schwierig – der Makrorekorder hilft dabei:
vsBlattDaten.InsertFromFile Dateiname, visInsertAsEmbed
oder
vsBlattDaten.InsertFromFile Dateiname, visInsertAsEmbed + visInsertIcon
Das kann man leicht mit Hilfe des Makrorekorders herausfinden.
Objekte
20160313Objekte02 Objekte
Der umgekehrte Weg jedoch: wie kann man dieses Objekt auf die Festplatte speichern oder: wie kann man auf die Daten zugreifen, ohne sie zu öffnen, ist etwas kniffliger. Es geht folgendermaßen:
1. ActiveDocument.Pages(Blattname).OLEObjects(1).Object.SaveAsDateiname
Will man die Exceldatei mit Makros speichern, muss man noch einen Parameter hinzufügen:
ActiveDocument.Pages(Blattname).OLEObjects(1).Object.SaveAsDateiname, xlOpenXMLWorkbookMacroEnabled
2. Der Zugriff funktioniert analog:
ActiveDocument.Pages(Blattname).OLEObjects(1).Object.Sheets(1).Range(„A1“).Value
Wenn man es weiß, ist es ganz einfach.

Erstellen Sie eine Linie!

Der versierte Anwender schmunzelt, der Anfänger tut sich schwer.
Heute in der Schulung habe ich einige Male gesagt: Erstellen Sie eine Linie. Sie finden das Werkzeug in der Registerkarte „Start“. Und natürlich habe einige Teilnehmer auf das Symbol für Linienformatierung geklickt. Und nicht auf das Werkzeug „Linie“. Zugegeben – die Gruppe ist beschriftet mit „Formenarten“ – nicht sehr glücklich.

Welche Linie?
Welche Linie?

Umzug

Eine hübsche Fingerübung gestern in der Visio-Schulung:
Eine Teilnehmerin erhält vom Architekten Zeichnungen der Geschosse ihres Gebäudes. Die dxf-Dateien werden importiert und konvertiert.
Der Raum
Der Raum
Da es um die Möbelstücke darin geht, wird die Zeichnung auf ein Hintergrundblatt gelegt – ein Vordergrundblatt verwendet das Hintergrundblatt als Hintergrund.
Ein Shape für die Mitarbeiter wird erstellt. Beim Herausziehen werden die Informationen Zimmernummer, Abteilung, Quadratmeterzahl, Mitarbeitername und Durchwahl in einem Datenfenster abgefragt. Diese Informationen werden auf dem Shape angezeigt.
Mitarbeiterinformationen werden abgefragt.
Mitarbeiterinformationen werden abgefragt.
Die kleine Besonderheit: Wenn drei Mitarbeiter in einem Zimmer sitzen, wird das Shape größer und zeigt nun statt zwei eben die drei Namen an. Ein bisschen Shapesheet wird benötigt – auch zum Durchreichen der Daten von dem Gruppenshape an die Mitgliedsshapes, wo sie angezeigt werden.
Variable Höhe
Variable Höhe
Und schließlich noch ein paar Möbelstücke. Auch hier die Besonderheit: Beim Herausziehen wird abgefragt, ob sie neu sind (das heißt, ob sie angeschafft werden müssen). Wird die Frage bejaht, färbt sich das Shape ein (damit man die neuen Möbelstücke schneller finden kann).
Die Möbelstücke
Die Möbelstücke
Und schließlich wird ein Bericht generiert: Sammle alle Möbelstücke (alle Shapes, die auf dem Layer Möbel liegen) ein, die neu sind (deren Datenfeld bisduneu = WAHR); liste sie auf, gruppiere sie und zähle sie.
Und so wird die Liste für den Einkauf erstellt.
Wirklich ein schönes Beispiel.

Fehler

Ich gestehe: Es ist mir erst letzte Woche, beim Erstellen eines Handbuches, aufgefallen: Wenn man mit der Maus einen Knoten eines Verbinders verschiebt, wird er zur Seite gezogen. Das ist hinlänglich bekannt. Drückt man dabei die [Umschalt]-Taste, wird er „aus der Mitte herausgezogen – ein Rechteck entsteht. Wird jedoch die [Strg]-Taste gedrückt, wird nur der Punkt herausgezogen – die Linien verlaufen nicht mehr rechtwinklig, sondern schräg zur ursprünglichen Linie. Ach ja: bei gedrückter [Alt]-Taste wird das Gitter übergangen.

Seltsamer Fehler
Seltsamer Fehler

Zeichenblattlayout

Layout - geändert
Layout – geändert

Sehr geehrte Damen und Herren, ich habe mit großem Interesse die Schulung über Visio 2010 Programmierung angesehen. Dabei habe ich leider nicht gefunden, wie man per VBA die untergeordneten Elemente eines Shapes neu anordnet. Wenn ich programmtechnisch „user.thislayoutstyle“ auf einen anderen Wert ändere, ist dies im Shape-Sheet zwar sichtbar, aber die Anordnung ändert sich trotz eines doevents nicht. Was muss ich programmieren, damit sich die Anordnung sichtbar ändert? Vielen Dank für Ihre Hilfe und freundliche Grüße aus Berlin
####
Hallo Herr V.,

der Makrorekorder verrät es 😉 (ich hätte es auch nicht
gewusst).

Wenn Sie in die Zellen des ShapeSheets des Blattes beispielsweise folgende Formeln eintragen :
ActivePage.PageSheet.Cells(„PlaceStyle“).FormulaU = „3“
ActivePage.PageSheet.Cells(„RouteStyle“).FormulaU = „1“
müssen Sie diese mit der Methode Layout beenden – sonst werden sie nicht
durchgeführt:
ActivePage.Layout

schöne Grüße und viel Spaß mit Visio

Rene Martin

PS: Das habe ich einige Mal „per Hand“ programmiert: das manuelle Platzieren von Shapes – fürchterliche Rechenarbeit – aber das wissen Sie sicherlich selbst.

Dynamische Shapes

Hallo Herr Martin,
ich sitze heute im HomeOffice und wollte mir eine vermeintlich einfache Aufgabe stellen.
Ich möchte mir ein Shape bauen das ich als „Rahmen verwenden möchte“ Das Shape soll so aussehen.
Ich will das als Sammelplatz für andere Shapes nutzen (ähnlich einem Container)
______________________
Überschrift hat eine Zeile
______________________

______________________
Überschrift hat eine Zeile
und noch eine
______________________

______________________
Ich möchte das die Überschrift immer so Hoch ist wie der Text (Also nur der obere Kasten soll wachsen die Größe des unteren ergibt sich dadurch das ich sie durch ziehen einstelle)
Der Kasten soll nach oben wachsen und auch die Schrift soll immer nach oben verschoben werden.
Ich habe das bisher so gelöst das ich zwei Vierecke miteinander gruppiert habe. Ohne Gruppierung bekomme ich das hin aber so wie die beiden Vierecke gruppiert sind verhält sich das Kästchen Überschrift anders.
ich sehe im shapesheet das sich die Bezüge verändern aber irgendwie komme ich nicht dahinter wie ich es machen muss.
Mir ist zum Beispiel nicht klar wie ich die einzelnen Betsandteile einer Gruppe ansprechen kann. In diesem Fall vermute ich das wir 3 Elemente haben.
Das Shape der ersten Viereck, das Shape des zweiten Viereck und das Shape der Gruppe.
Es wäre toll wenn sie mir eine Visiodatei mit einem Beispiel schicken könnten. Ich habe leider ihre Unterlagen nicht zu Hause, da steht die Lösung eventuell drinn.
Danke Ihnen
Gruß AT.
Hallo Herr T.,
Gruppe ist klasse; mit einer Gruppe kommt man gut hin. Ich nehme zwei Rechtecke; gruppiere sie. Jedes der drei Shapes hat einen Namen (Develloper / Shape-Name). Bei mir: Sheet.5, Sheet.6 und Sheet.7. Bitte nicht ändern! (Kleiner bug im Shapesheet)
Ich habe den Pin des oberen Shapes auf Mitte / oben gesetzt, den Pin des unteren auf Mitte / unten (über View / Task-Pane / Size & Position)
Ich schreibe Text in das obere Shape. Die Height im Shapesheet lege ich fest: =GUARD(TEXTHEIGHT(TheText,1)) – also: Höhe so groß wie die Texthöhe.
Außerdem achte ich darauf, dass PinY auf: =Sheet.7!Height*1 liegt, also Oberkante an Oberkante.
Beim unteren Kästchen stelle ich im Shapesheet ein:
Height: =Sheet.7!Height-Sheet.5!Height
Ebenso: Unterkante an Unterkante, also: PinY: = =Sheet.7!Height*0
Okay. Ganz dolle ist es noch nicht – am Verhältnis Höhe und Breite und Schriftgröße müsste man noch arbeiten.
Hilft Ihnen das?
schöne Grüße
Rene Martin
Hallo Herr Martin,
danke für die Antwort. Ich hatte mich mühsam rangetastet und es letzten ende hinbekommen.
Ein Frage:
Visio benennt die Shapes selbst numerisch. Shape.97 etc.
Kann ich den Shapes Sinnvolle Namen geben. Beispiel:
Shape.Oberertext
Shape.Unterertext
und so weiter?
Das würde es einfacher machen wenn man darauf referenziert
Danke und Gruß
Hallo Herr T,

wenn Sie Visio programmieren, dann bemerken Sie, dass Visio innerhalb einer Datei jedem Shape eine eindeutige ID zuweist. Das ist sinnvoll. Die wird im Shapesheet nicht verwendet. Steht aber auch im Dialog Shape-Name
Darüber hinaus bekommt jedes Shape einen Namen. Den kann man ändern, um leichter darauf zugreifen zu können. Nur: Im Shapesheet wird leider der von Visio vergebene Name verlangt (ich weiß, ich weiß, ist blöde … ich habe mich auch schon geärgert).
Aber das Konzept ist wichtig, weil: Wenn Sie das Shape in eine Schablone ziehen und nun wieder aufs Zeichenblatt zurück, bekommt das Shape (oder die Shapes bei einer Gruppe) neue Namen, d.h. Nummern zugewiesen. Sonst würde es zu Konflikten kommen mit
=Sheet.77!Height

Wenn Sie dem Teilchen in der Schablone einen Namen geben (also aus Master.1 bspw. „Server“ machen), dann heißt das erste Shape, das aus der Schablone gezogen wird: Server, das zweite Server.2, das dritte Server.3, …

Und: Wenn Sie das Fenster Size & Position öffnen, dann sehen Sie dort in der Titelzeile den Namen.

Wie auch bei einigen anderen Fragen von Ihrer Seite: Schulterzucken meinerseits; hat sich jemand so ausgedacht; man hätte es auch anders machen können. Immerhin, wenn Sie einen falschen Namen im Shapesheet tippen (bspw.: =Sheet.104!) dann hilft Intellisense nicht mehr weiter. So erkenne ich, ob der Name korrekt ist.

schöne Grüße

Rene Martintroester

Neues Shape

Natürlich kann man Shapes in Schablonen abspeichern. Aber vielleicht möchte ich nicht, dass Anwender solche Shapes sehen und sich dann fragen, zu welchem Zwecke sie in der Schablone liegen. Und wo sie benötigt werden.
Manchmal ist es einfacher ein Shape per Code zu erzeugen. Beispielsweise diese „Kreuzug“, die jemand haben wollte. Ein paar Zeilen Code und fertig ist das Shape:
Dim vsShapeNeu As Shape
 
Set vsShapeNeu = ActivePage.DrawRectangle(100, 200, 300, 400)
 
vsShapeNeu.Cells(„LineWeight“).FormulaU = „=1.5 pt“ ‚ Linienstärke
vsShapeNeu.Cells(„Geometry1.Y1“).FormulaU = „=Height*0.5“
vsShapeNeu.Cells(„Geometry1.Y2“).FormulaU = „=Height*0.5“
vsShapeNeu.Cells(„Geometry1.Y3“).FormulaU = „=Height*0.5“
vsShapeNeu.Cells(„Geometry1.Y4“).FormulaU = „=Height*0.5“
 
vsShapeNeu.AddSection visSectionFirstComponent + 1
vsShapeNeu.AddRow visSectionFirstComponent + 1, visRowComponent, visTagComponent
vsShapeNeu.AddRow visSectionFirstComponent + 1, visRowVertex, visTagLineTo
vsShapeNeu.AddRow visSectionFirstComponent + 1, visRowVertex, visTagMoveTo
 
vsShapeNeu.Cells(„Geometry2.X1“).FormulaU = „=Width*0.5“
vsShapeNeu.Cells(„Geometry2.Y1“).FormulaU = „=Height*0“
vsShapeNeu.Cells(„Geometry2.X2“).FormulaU = „=Width*0.5“
vsShapeNeu.Cells(„Geometry2.Y2“).FormulaU = „=Height*1“
 
vsShapeNeu.AddSection visSectionFirstComponent + 2
vsShapeNeu.AddRow visSectionFirstComponent + 2, visRowComponent, visTagComponent
vsShapeNeu.AddRow visSectionFirstComponent + 2, visRowVertex, visTagLineTo
vsShapeNeu.AddRow visSectionFirstComponent + 2, visRowVertex, visTagLineTo
vsShapeNeu.AddRow visSectionFirstComponent + 2, visRowVertex, visTagLineTo
vsShapeNeu.AddRow visSectionFirstComponent + 2, visRowVertex, visTagLineTo
vsShapeNeu.AddRow visSectionFirstComponent + 2, visRowVertex, visTagMoveTo
 
vsShapeNeu.Cells(„Geometry3.X1“).FormulaU = „=Width*0.5“
vsShapeNeu.Cells(„Geometry3.Y1“).FormulaU = „=Height*0.25“
vsShapeNeu.Cells(„Geometry3.X2“).FormulaU = „=Width*0.75“
vsShapeNeu.Cells(„Geometry3.Y2“).FormulaU = „=Height*0.5“
vsShapeNeu.Cells(„Geometry3.X3“).FormulaU = „=Width*0.5“
vsShapeNeu.Cells(„Geometry3.Y3“).FormulaU = „=Height*0.75“
vsShapeNeu.Cells(„Geometry3.X4“).FormulaU = „=Width*0.25“
vsShapeNeu.Cells(„Geometry3.Y4“).FormulaU = „=Height*0.5“
vsShapeNeu.Cells(„Geometry3.X5“).FormulaU = „=Width*0.5“
vsShapeNeu.Cells(„Geometry3.Y5“).FormulaU = „=Height*0.25“

Form20151208