194 82 11MB
German Pages 668
visual basic 6 referenz rudolf huttary
new technology Markt+Technik Verlag
Die Deutsche Bibliothek – CIP-Einheitsaufnahme Ein Titeldatensatz für diese Publikation ist bei Der Deutschen Bibliothek erhältlich. Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt. Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollständig ausgeschlossen werden. Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag und Herausgeber dankbar.
Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig. Fast alle Hardware- und Softwarebezeichnungen, die in diesem Buch erwähnt werden, sind gleichzeitig auch eingetragene Warenzeichen oder sollten als solche betrachtet werden. Umwelthinweis: Dieses Buch wurde auf chlorfrei gebleichtem Papier gedruckt. Die Einschrumpffolie – zum Schmutz vor Verschmutzung – ist aus umweltverträglichem und recyclingfähigem PE-Material.
10 9 8 7 6 5 4 3 2 1 03 02 01 00
ISBN 3-8272-5588-0
© 2000 by Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH, Martin-Kollar-Straße 10–12, D 81829 München/Germany Alle Rechte vorbehalten Lektorat: Erik Franz, [email protected] Herstellung: Claudia Bäurle, [email protected] Satz: reemers publishing services gmbh, Krefeld Druck und Verarbeitung: Media Print, Paderborn Printed in Germany
Inhaltsverzeichnis Vorwort
15
Lesebuch und Nachschlagewerk Gut verwurzelt: traditionelles Basic vs. Visual Basic Zielgruppe
15 16 18
Teil I: Referenzteil
21
Grundlegendes
23
Programme und Module in Visual Basic Programm Modul Projekt Arten von Modulen in einem Projekt Literale und Konstanten Anweisungen Bezeichner und Namensraum Kontrollstrukturen Unbedingte und bedingte Verzweigung, Subroutinen Fallunterscheidung Schleifen Fehlerbehandlung
23 23 24 24 25 27 33 34 36 36 38 40 43
Datentypen und ihre Operationen
49
Elementare Datentypen Der Datentyp Variant Die Datentypen Integer, Long, Single und Double Die Datentypen Boolean und Byte Die Datentypen Currency und Date Der Datentyp Decimal Operatoren für elementare Datentypen und logische Bedingungen Arrays Typumwandlung Benutzerdefinierte Datentypen Type-Datentypen Enum-Aufzählungen Funktionen und Anweisungen für Zeichenfolgen Asc-, AscB- und AscW-Funktion Chr-, ChrB- und ChrW-Funktion Filter-Funktion Format-Funktion FormatCurrency-Funktion FormatDateTime-Funktion FormatNumber-Funktion
49 50 51 52 52 53 54 55 57 60 61 62 63 66 67 68 69 73 74 75
5
Inhaltsverzeichnis
FormatPercent-Funktion 75 Hex-Funktion 76 InStr- und InStrB-Funktion 76 InStrRev-Funktion 77 Join-Funktion 78 LCase-Funktion 79 Left- und LeftB-Funktion 79 Len- und LenB-Funktion 79 LSet-Anweisung 80 LTrim-Funktion 81 Mid- und MidB-Funktion 81 Mid- und MidB-Anweisung 82 MonthName-Funktion 82 Oct-Funktion 82 Option Compare-Anweisung 83 Replace-Funktion 84 Partion-Funktion 85 Right- und RightB-Funktion 85 RSet-Anweisung 86 RTrim-Funktion 86 Space-Funktion 86 Split-Funktion 87 Str-Funktion 87 StrComp-Funktion 88 StrConv-Funktion 89 String-Funktion 90 StrReverse-Funktion 90 Trim-Funktion 90 UCase-Funktion 91 Val-Funktion 91 WeekdayName-Funktion 92 Mathematische und finanzmathematische Funktionen und Anweisungen 92 Abs-Funktion 94 Atn-Funktion 95 Cos-Funktion 95 DDB-Funktion 96 Exp-Funktion 97 Fix-Funktion 97 FV-Funktion 98 Int-Funktion 99 IPmt-Funktion 99 IRR-Funktion 100 Log-Funktion 101 MIRR-Funktion 102 NPer-Funktion 103 NPV-Funktion 104
6
Inhaltsverzeichnis
Pmt-Funktion PPmt-Funktion PV-Funktion Randomize-Anweisung Rate-Funktion Rnd-Funktion und Rnd-Anweisung Round-Funktion Sgn-Funktion Sin-Funktion SLN-Funktion Sqr-Funktion SYD-Funktion Tan-Funktion Funktionen und Anweisungen für Datums-/Zeitwerte CDate-Funktion Date-Funktion und Date-Anweisung DateAdd-Funktion DateDiff-Funktion DatePart-Funktion DateSerial-Funktion DateValue-Funktion Day-Funktion FileDateTime-Funktion FormatDateTime-Funktion Hour-Funktion Minute-Funktion Month-Funktion MonthName-Funktion Now-Funktion Second-Funktion Time-Funktion und Time-Anweisung Timer-Funktion TimeSerial-Funktion TimeValue-Funktion Weekday-Funktion WeekdayName-Funktion Year-Funktion Dateiorientierte Funktionen und Anweisungen ChDir-Anweisung ChDrive-Anweisung Close-Anweisung CurDir-Funktion Dir-Funktion Environ-Funktion EOF-Funktion FileAttr-Funktion
105 106 106 107 108 109 110 110 112 112 113 113 114 114 116 116 116 117 118 119 120 121 121 121 121 121 122 122 122 122 123 124 124 125 125 126 126 126 131 132 133 134 135 136 137 138
7
Inhaltsverzeichnis
FileCopy-Anweisung FileDateTime-Funktion FileLen-Funktion FreeFile-Funktion Get-Anweisung GetAttr-Funktion Input- und InputB-Funktion Input #-Anweisung Kill-Anweisung Line Input #-Anweisung Loc-Funktion Lock-Anweisung LOF-Funktion LSet-Anweisung MkDir-Anweisung Name-Anweisung Open-Anweisung Print #-Anweisung Put-Anweisung Reset-Anweisung RmDir-Anweisung Seek-Anweisung und Seek-Funktion SetAttr-Anweisung Shell-Anweisung Unlock-Anweisung Write #-Anweisung
Variablen Variablendeklaration Typkennzeichen und Bezeichnerbereiche für Typen Variableninitialisierung Geltungsbereiche von Variablen
Funktionen und Prozeduren Parameterübergabe an Funktionen und Prozeduren Funktionen selbst definieren Prozeduren selbst definieren Routinen aus DLLs und der Windows-API einsetzen
Objekte und Klassen Klassen als Datentypen für Objektvariablen Ereignisroutinen Standardereignisse Activate-Ereignis und Deactivate-Ereignis Change-Ereignis Click-Ereignis DblClick-Ereignis
8
138 139 139 139 140 142 142 143 144 145 146 146 147 148 148 148 149 151 153 154 155 156 157 158 159 159
161 162 167 168 173
175 178 181 183 185
195 196 204 207 212 214 215 217
Inhaltsverzeichnis
DragDrop-Ereignis DragOver-Ereignis GotFocus-Ereignis und LostFocus-Ereignis Initialize-Ereignis KeyDown-Ereignis und KeyUp-Ereignis KeyPress-Ereignis LinkClose-Ereignis LinkError-Ereignis LinkExecute-Ereignis LinkNotify-Ereignis LinkOpen-Ereignis Load-Ereignis MouseDown-Ereignis und MouseUp-Ereignis MouseMove-Ereignis OLECompleteDrag-Ereignis OLEDragDrop-Ereignis OLEDragOver-Ereignis OLEGiveFeedback-Ereignis OLESetData-Ereignis OLEStartDrag-Ereignis Paint-Ereignis QueryUnload-Ereignis Resize-Ereignis Terminate-Ereignis Unload-Ereignis Validate-Ereignis Global-Objekt App-Objekt CallByName-Methode Clipboard-Objekt Command-Methode CreateObject-Methode DeleteSetting-Methode DoEvents-Methode Err-Objekt Forms-Auflistung GetAllSettings-Methode GetObject-Methode GetSetting-Methode InputBox-Methode Load-Methode LoadPicture-Methode LoadResData-Methode, LoadResPicture-Methode, LoadResString-Methode Printer-Objekt Printers-Auflistung
218 221 222 224 225 228 230 231 232 233 233 236 237 239 241 242 245 247 248 250 253 256 257 258 259 260 261 264 269 270 273 273 275 276 277 279 279 280 281 281 282 283 284 284 297
9
Inhaltsverzeichnis
QBColor-Methode RGB-Methode SavePicture-Methode SaveSetting-Methode Screen-Objekt Sendkeys-Methode Unload-Methode Auflistungen und Collection-Objekte Formulare Form-Objekt (Basisobjekt für Formulare) MDIForm-Objekt Selbst definierte Klassen ClassModul-Schnittstelle
Steuerelemente Gemeinsame Eigenschaften Alignment-Eigenschaft Appearance-Eigenschaft AutoSize-Eigenschaft BackColor-Eigenschaft und ForeColor-Eigenschaft BackStyle-Eigenschaft BorderStyle-Eigenschaft Caption-Eigenschaft Container-Eigenschaft CausesValidation-Eigenschaft DataChanged-Eigenschaft DataField-Eigenschaft DataFormat-Eigenschaft DataMember-Eigenschaft DataSource-Eigenschaft DisabledPicture-Eigenschaft DownPicture-Eigenschaft DragIcon-Eigenschaft DragMode-Eigenschaft DrawMode-Eigenschaft DrawStyle-Eigenschaft Enabled-Eigenschaft FillColor-Eigenschaft FillStyle-Eigenschaft Font-Eigenschaft ForeColor-Eigenschaft HasDC-Eigenschaft hDC-Eigenschaft Height-Eigenschaft und Width-Eigenschaft HelpContextID-Eigenschaft und WhatsThisHelpID-Eigenschaft hWnd-Eigenschaft Image-Eigenschaft
10
298 299 299 300 300 302 303 304 306 307 313 318 320
321 323 327 328 329 330 331 332 334 335 335 336 336 338 339 339 341 341 342 343 344 346 347 348 349 349 350 350 351 351 353 354 354
Inhaltsverzeichnis
Index-Eigenschaft Left-Eigenschaft und Top-Eigenschaft MaskColor-Eigenschaft MouseIcon-Eigenschaft MousePointer-Eigenschaft MultiLine-Eigenschaft Name-Eigenschaft OLEDropAllowed- und OLETypeAllowed-Eigenschaften OLEDropMode-Eigenschaft Parent-Eigenschaft Picture-Eigenschaft RightToLeft-Eigenschaft ScaleLeft-Eigenschaft und ScaleTop-Eigenschaft ScaleHeight-Eigenschaft und ScaleWidth-Eigenschaft ScaleMode-Eigenschaft ShowTips-Eigenschaft Style-Eigenschaft TabIndex-Eigenschaft TabStop-Eigenschaft Tag-Eigenschaft ToolTipText-Eigenschaft UseMaskColor-Eigenschaft Visible-Eigenschaft WhatsThisHelp-Eigenschaft WhatsThisHelpID-Eigenschaft Width-Eigenschaft Gemeinsame Methoden Drag-Methode LinkExecute-Methode LinkPoke-Methode LinkRequest-Methode LinkSend-Methode Move-Methode OLEDrag-Methode Refresh-Methode SetFocus-Methode ShowWhatsThis-Methode ZOrder-Methode Standardsteuerelemente Anzeige-Steuerelement (Image) Befehlsschaltfläche-Steuerelement (CommandButton) Bezeichnungsfeld-Steuerelement (Label) Bildfeld-Steuerelement (PictureBox) Bildlaufleisten-Steuerelemente (HScrollBar, VScrollBar) Dateilistenfeld-Steuerelement (FileListBox) Data-Datensteuerelement (Data)
356 357 358 359 360 361 361 362 363 364 365 366 366 368 369 371 372 375 376 376 377 377 378 378 378 379 379 379 380 381 382 382 383 383 384 385 386 386 387 390 392 393 395 398 400 402
11
Inhaltsverzeichnis
Figur-Steuerelement (Shape) Kombinationsfeld-Steuerelement (ComboBox) Kontrollkästchen-Steuerelement (CheckBox) Laufwerklistenfeld-Steuerelement (DriveListBox) Linie-Steuerelement (Line) Listenfeld-Steuerelement (ListBox) OLE-Container-Steuerelement (OLE) Optionsfeld-Steuerelement (OptionButton) Rahmen-Steuerelement (Frame) Textfeld-Steuerelement (TextBox) Verzeichnislistenfeld-Steuerelement (DirListBox) Zeitgeber-Steuerelement (Timer) ActiveX-Steuerelemente (OCX) – Windows-Standardsteuerelemente Abbildungsliste-Steuerelement (ImageList) Weitere ActiveX-Steuerelemente Bildausschnitt-Steuerelement (PictureClip) Standarddialoge-Steuerelement (CommonDialog)
Teil II: Praxisteil
451
Ältere Basic-Programme nach Visual Basic portieren
453
Wie importiert man den Quelltext? Einfache Programme Implementation einer eigenen Input-Routine Anspruchsvollere Programme Implementation von Inkey$ Implementation von LOCATE, POS, CSRLIN und COLOR Koordinatensystem und Grafikmodus Zusammenfassung der Emulation als Standardmodul Von WANKEL.BAS zur WankelAnimation Die portierte Fassung
454 454 456 457 459 460 461 463 468 472
Mathematik und Algorithmen ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge Implementation des Apfelmännchen-Algorithmus Optimierung Ereignisbehandlung mit DoEvents, ein komplexes Problemfeld Benutzerschnittstelle Der Stack Einzelbilder speichern
Formulare und Ansichten Ereignisbehandlung Gummiband – Bereiche interaktiv auswählen DDE-Verbindungen OLE-Drag&Drop
12
406 407 409 410 411 412 415 424 426 427 431 432 433 436 439 442 444
477 478 484 485 485 487 488 489
491 491 492 495 501
Inhaltsverzeichnis
DiaProjektor – SDI-Formulare synchronisieren Das Programmdesign Info-Dialog als gebundenes Formular aufrufen Ereignisse delegieren und Instanziierung durch One-Shot-Logik Programmstart und Auswahl der Bilddateien im Standarddialog Öffnen Das Anzeigesystem Bilder einlesen und in maximaler Größe zeichnen Vollbildanzeige Menü und Kontextmenü Benutzerschnittstelle Bildlaufleisten für Ansichten einsetzen und auf Größenänderungen reagieren Bildlauf – ein kleiner Betrachter für große Bilder HexView – eine schnelle Textansicht für große Dateien Registrierung RegTest – Sitzungen wieder aufnehmen
Objektorientiertes Basic Klassen selbst definieren Ring – eine einfache Klasse demonstriert Grundlegendes 3DAnimation – Drahtgittermodelle frei im Raum gedreht Point3D – ein Punkt im Raum Line3D – eine Linie aus zwei Punkten ActiveX-Steuerelemente und Benutzersteuerelemente LongTimer – der Timer mit Ausdauer Transparenz und Drag&Drop MemoryEdit – das Textfeld mit Gedächtnis Kurzreferenz der Schlüsselwörter mit Vergleich zu QBasic
Tabellenindex
511 514 525 525 527 530 535 536 538 542 544 545 551 561 562
567 567 568 577 582 586 599 599 606 615 642
659
13
Vorwort Wer heute nicht täglich mit einem bestimmten Produkt, etwa einem Entwicklungssystem wie Visual Basic, einer Tabellenkalkulation oder einer Textverarbeitung arbeitet, sondern eher sporadisch, dem bleibt nichts anderes übrig, als erst einmal erhebliche Mengen an wertvoller Zeit schlicht damit zu vergeuden, sich und sein System immer wieder auf den neuesten Stand des jeweiligen Produkts zu bringen. Der Effizienzvorsprung, den der neueste Stand des Produkts verspricht, muss oft sehr teuer mit Lernaufwand und der Umgestaltung bestehender Lösungen erkauft werden. Die Hersteller wollen nicht nur, dass ein Produkt in der neuen Version äußerlich anders erscheint, die zusätzlichen Features sowie die Anpassung an eine sich ständig ändernde Umgebung (Benutzeroberfläche, Betriebssystem, Entwicklungsplattform, Vernetzung, verwandte Produkte) erzwingen in den meisten Fällen auch Änderungen des inneren Aufbaus, eingeführter Daten- und Kommunikationsstrukturen und nicht zuletzt auch erhebliche Änderungen in der Dokumentation. Damit wären wir bereits beim Thema.
Lesebuch und Nachschlagewerk Dieses Buch reiht sich mit seinem Titel in die 1999 neu ins Leben gerufene Referenzreihe des Markt+Technik-Verlags ein. Maßgeblich für das Erscheinen dieser neuen Reihe war der Wunsch vieler semi- wie professioneller Programmierer nach verdichteten Referenzinformationen mit ineinander greifender theoretischer und praktischer Aufarbeitung, mit anderen Worten, der schnelle und gleichzeitig kompetente Überblick über ein Sprachprodukt mit nichttrivialen praktischen Anregungen – als Nachschlagewerk für den Einstieg, Umstieg sowie die Auffrischung für die konkrete Arbeit mit dem Produkt. Die Titel in dieser Reihe geben Antwort auf die Fragen »Was ist das?« und »Wie geht das?« – und dies in einer für den Einzelnen noch überschaubaren Weise. Das Buch soll dem Käufer als Lesebuch und als Nachschlagewerk dienen, es soll ihm also das nötige Know-how für seine Programmiertätigkeit vermitteln und ihm gleichzeitig Anregungen und Lösungen anbieten, die er in seine Programmierarbeit einfließen lassen kann. Schaltstelle und Garant für die gute gegenseitige Durchdringung der Themen im Referenz- und Praxisteil ist der zentrale Tabellenindex im Anhang, dessen themen- und sachbezogene Einträge überwiegend in beiden Teilen Fundstellen ausweisen. Heutige Online-Hilfen zu Produkten können dies aus verschiedenen Gründen eher schlecht als recht bzw. immer häufiger gar nicht mehr leisten. So, weil sie sich über die Versionen hinweg immer weiter aufgeblasen haben, ohne strukturell überarbeitet worden zu sein, weil sie aufgrund schlechter und unvollständiger Aufarbeitungen teilweise bereits in sich widersprüchlich geworden sind, weil sie aufgrund erbärmlicher Indizes nur sehr zeitraubend zu handhaben sind und nicht zuletzt, weil sie in ihrem enzyklopädischen Charakter keinerlei Gewichtung der Informationen nach Kriterien der Brauchbarkeit und dem Wissensstand des Lesers mehr enthalten. Ein wirklich pathologisches Beispiel einer solchen Online-Hilfe ist die MSDN Library für Visual Studio 6.0. Der monumentale Fundus dieses in seinem Format inzwischen auf den Internet Explorer zugeschnittenen Hilfesystems ist auf zwei CDs verteilt und stellt einen Rundschlag an Informationen über die wichtigeren Sprachprodukte von Microsoft dar – darunter zu Visual Basic, Visual C++, Visual J++, Visual FoxPro sowie die SDK- und die DDK-Dokumentation. Die Benutzbarkeit des Systems lässt jedoch extrem zu wünschen übrig. Erstens wurden Text und Index teilweise eingedeutscht, was für den Index eine echte Katastrophe darstellt, teilweise im amerikanischen Original belassen, und zweitens wurde bei der indexikalischen Suche schlicht vergessen, die Produktzugehörigkeit der einzelnen Themen mit anzugeben. Die Volltextsuche leistet dies zwar, erschlägt einen aber schier mit der Fülle der Fundstellen. Wer dieser Hilfe in annehmbarer Zeit etwas halbwegs Vernünftiges über Visual Basic entlocken will, tut
15
Gut verwurzelt: traditionelles Basic vs. Visual Basic
Gut verwurzelt:
traditionelles
Bas ic
vs.
Visual Basic
gut daran, sich über das Menü ANSICHT/UNTERMENGE DEFINIEREN als Erstes eine Quellenauswahl in Form einer Untermenge zusammenzustellen und diese für die weitere Arbeit als Filter zu benutzen. Eine gedruckte Referenz zu Visual Basic im Umfang des vorliegenden Buches kann es sich nicht leisten, ausgiebigst auf allen Hochzeiten zu tanzen – das sei der Online-Hilfe vorbehalten. Vielmehr stellt sich die gedruckte Referenz der Aufgabe, die Ecken und Kanten abzuschleifen, die ein Verständnis der Sprache oder spezifische Problemlösungen erschweren, indem sie Zusammenhängendes als solches aufzeigt, begreiflich darstellt und in seinen relevanten Dimensionen exemplarisch erläutert. Entscheidend ist dabei die Auswahl und Verdichtung der behandelten Thematiken, die zwar nicht in jedem Fall, so doch aber in der Mehrzahl der Fälle eine Vertiefung der eher lax gehaltenen Online-Hilfe zu Visual Basic erreicht. Der vorliegende Band enthält eine umfassende Darstellung der Konzepte, Funktionen und Objekte von Visual Basic als Programmiersprache und Entwicklungsplattform, beschränkt sich aber in seiner Themenauswahl auf die »Innensicht der Sprache«, ohne sich allzu weit in der Welt des ActiveX, der Automatisierung, der Datenbankprogrammierung sowie generell des COM (bzw. DCOM) zu verlieren. Grob gesehen deckt der Band das gesamte Instrumentarium von Visual Basic inklusive aller Standardsteuerelemente sowie ausgewählter Windows-Standardsteuerelemente und die Programmierung eigener Benutzersteuerelemente ab.
Gut verwurzelt: traditionelles Basic vs. Visual Basic Keiner anderen Programmiersprache haftet so stark das Etikett an, in Hunderte verschiedener Dialekte zerfallen zu sein, wie Basic. Das liegt zum einen daran, dass Basic über lange Zeit hinweg, insbesondere für die ersten in ihren Möglichkeiten massiv beschränkten Mikrocomputer und später für den PC die mit dem Betriebssystem ausgelieferte Standardsprache darstellte – wenn es nicht gar, wie etwa für den Commodore C64 zur Kommandosprache für das Betriebssystem selbst avanciert war. Zum anderen liegt es aber auch daran, dass die Sprache in ihrer Entwicklung einer weniger rigiden Kontrolle durch Standardisierungskomitees und -gremien ausgesetzt war als die anderen – vielleicht wegen des Buchstabens »B« im Akronym, der ja bekanntlich für »Beginners« steht. Unterschwellig mag dabei freilich auch noch das Vorurteil mitgeschwungen haben, Basic werde aufgrund seiner Begrenztheit als Entwicklungssprache für ernst zu nehmende Anwendungen sowieso nie taugen. Ein großes Veränderungspotential geht aber auch mit einem großen Entwicklungspotential und der Fähigkeit zur schnellen Adaption einher. In der Tat haben im letzten Jahrzehnt die Philosophien für Benutzeroberflächen und Betriebssysteme einen massiven Wandel durchgemacht. Das gilt in besonders krasser Weise für den PC. Da ist es nicht verwunderlich, wenn sich auch die Anforderungen verlagert haben, denen eine Programmiersprache bei der Anwendungsentwicklung für moderne Benutzeroberflächen genügen muss. Eine wichtige Rolle spielen heute Objektorientierung, Modularisierung und Prozesskommunikation. Mit anderen Worten, das monolithische Programm, das isoliert von anderen Anwendungen den ihm zugedachten Aufgaben nachkommt, indem es seine eigenen Datenformate und Algorithmen strickt, seine eigene Benutzerschnittstelle parat hält und vielleicht noch so tut, als gehöre ihm die Maschine alleine, hat unwiderruflich ausgedient. Gefragt sind überschaubare, möglichst allgemein einsetzbare Komponenten, die im Dienste der Allgemeinheit das Ihre zum Großen Ganzen beitragen. Dieser neue Zeitgeist hört auf den Namen COM (Component Object Model), eine sprachübergreifende Spezifikation, die die Implementation und das Miteinander von Objekten in dieser Welt regelt. Microsoft hat seinen Beitrag an der technologischen Umsetzung dieser Konzeption (mit Blick auf die Internet-Programmierung) unter der Bezeichnung ActiveX zusammengefasst. Einer Anwendung, gleich in welcher Sprache sie realisiert wird, stehen damit vonseiten des Betriebssystems komplexe, allgemein gehaltene Bausteine in Form von Komponenten (Steuerelemente,
16
Gut verwurzelt:
traditionelles
Basic
vs.
Visual Basic
●
●
●
●
Module – der Modulbegriff deckt sich nicht mehr mit dem Programmbegriff, sondern erweitert die Strukturierungsfähigkeit der Sprache nach oben hin. Die Sprache vermag damit insbesondere Bibliotheken (Klassen- und Komponentenbibliotheken) konzeptuell zu integrieren Objekte – der Objektbegriff ist inzwischen sprachlich-syntaktisch verwurzelt. Neben den einfachen Datentypen stehen nun auch komplexe, verkapselte Datentypen samt zugehöriger Operationen zur Disposition. Der Sprache eröffnet sich damit unter anderem die vollständige Anbindung an alle Dienste des Betriebsystems inklusive der grafisch orientierten Benutzerschnittstelle, des gesamten Dateiwesens, der Kommunikationseinrichtungen und der Datenbankschnittstellen. Ereignisse – die Sprache adaptiert das Modell der ereignisgesteuerten Anwendungsprogrammierung von Windows über den Objektbegriff. So gestatten vordefinierte Klassen und interaktiv definierte Objekte dieser Klassen eine umfassende Repräsentation der Benutzerschnittstelle mit all ihren Elementen (Fenster, Menüs, Symbol- und Statusleisten, Steuerelemente, Komponenten) und Aktionen. ActiveX – die vom COM geforderte Codeabstraktion ermöglicht es der Sprache nicht nur, von existierenden Komponenten zu profitieren, sondern auch selbst Komponenten beizusteuern, von denen wiederum andere Anwendungen profitieren können.
Erst mit Integration dieser Konzepte besitzt Visual Basic das nötige Rüstzeug, um in der Welt der modernen Windows-Programmierung Schritt halten zu können. Das gilt mit gleichem Vorzeichen für den Programmierer: Wer auch nur halbwegs ernst zu nehmende Anwendungen mit Visual Basic zu Stande bringen will, dem bleibt nichts anderes übrig, als sein Basic-Repertoire (und sein Denken) auf den Stand dieser Neuerungen zu bringen. Dabei spielt in erster Linie der Objektbegriff eine zentrale Rolle. Wer den Objektbegriff einmal soweit verinnerlicht hat, dass er nicht mehr über die Nahtstelle zwischen dem »alten Basic« und dem »Basic mit Objekten« stolpert, dem wird auch die modulare Programmierung mit Code- und Klassenbibliotheken, ActiveX-Komponenten keine allzu großen Rätsel mehr aufgeben. Damit wären wir bereits bei der Zielgruppe dieses Buchs.
17
Gut verwurzelt: traditionelles Basic vs. Visual Basic
Schnittstellen, Player, Filter etc.) mit verkapselter Funktionalität und Implementation zur Verfügung, derer sie sich nach Belieben und ohne großes Brimborium bedienen kann. Angesichts dieser Entwicklungen scheint es etwa bei Betrachtung der Linie von BasicA über QuickBasic/QBasic nach Visual Basic beinahe schon verblüffend, wie treu sich die Sprache in ihren Wurzeln doch geblieben ist und wie viel sie von ihren ursprünglichen Konzepten in die neue Objekt-dominierte Welt retten konnte. Mehr noch, die Adaption ist so erstaunlich gut gelungen, dass sich der mit Visual Basic vorliegende Basic-Dialekt mit Fug und Recht inzwischen zu den ernst zu nehmenden Sprachen für die Anwendungsentwicklung zählen darf. Aber auch damit noch nicht genug. Microsoft hat Visual Basic vielmehr die Rolle des Flagschiffs zugedacht: In Form von VBA (Visual Basic für Anwendungen) stellt das neue Basic zudem die Automatisierungssprache für die wichtigsten Anwendungen der Microsoft Office Suite, und in der stark eingeschränkten Form von VBScript ist das neue Basic auch gleich noch zur neuen Kommandosprache des Betriebssystems Windows avanciert. Wer nun darauf beharrt, Visual Basic habe nicht mehr viel mit dem traditionellen Basic zu tun, dem kann natürlich genauso wenig widersprochen werden. Die objektorientierte Fassung von C ist C++ und von Pascal ist Modula oder Delphi, und keiner wird Letztere als Dialekte Ersterer bezeichnen wollen, obwohl die Kenntnis von C bzw. Pascal doch sehr beim Verständnis ihrer objektorientierten Nachfolger von Vorteil ist. Nehmen Sie es so: Basic war schon immer mehr ein Oberbegriff, denn ein kohärentes Gebilde, und als Oberbegriff ist es durchaus in der Lage, auch den Übergang in die objektorientierte Programmierung unter sich zu subsumieren. Die wesentlichen in Visual Basic zu findenden Neuerungen sind:
Zielgruppe
Zielgruppe Was das Vorwissen des Lesers betrifft, so wurde bei der Gestaltung der einzelnen Themen größter Wert auf eine Steigerung vom Einfachen zum Komplexen und vom Allgemeinen zum Speziellen gelegt. Der Eine liest so weit, wie er kommt, der Andere beginnt da zu lesen, wo es für ihn interessant wird. Damit ist, wie für eine Referenz üblich, die Zielgruppe dieses Buchs naturgemäß recht breit anzusetzen. Sie umfasst:
Zielgruppe
●
●
●
●
●
den unerfahrenen Programmierer, der die ersten Schritte und Hürden der Visual-BasicProgrammierung zwar hinter sich gebracht hat, aber weder den inneren Zusammenhang der Sprache so recht durchdrungen hat, noch eine Vorstellung von der Fülle ihrer Möglichkeiten bei der Bewältigung praktischer Problemfelder besitzt. Programmierer dieser Gruppe finden in diesem Buch nicht nur einen übersichtlichen Grundlagenteil, der auf die Elemente und Konzepte der Sprache genauer eingeht und gleichermaßen eine Vertiefung des Objektbegriffs vermittelt, sondern auch Anregungen für die eigene Programmiertätigkeit in Form einfacher Programmbeispiele, die Lösungen zu typischen Fragestellungen vorstellen. den Alten Hasen, der Basic seit langem kennt, die Sprache aber vernachlässigt hat und mit Visual Basic den schnellen Wiedereinstieg in die heutige objektorientierte Basic-Programmierung sucht. Programmierer dieser Gruppe werden in der Referenz nützliche Gegenüberstellungen und Anmerkungen finden, die gerade auf die Veränderung der Sprache im Vergleich zu QBasic abzielen. den ambitionierten Anwendungsentwickler, der sein Repertoire erweitern will, nach Ansätzen für neue Lösungen sucht und sich vom Griff zur Referenz nicht nur Auskunft, sondern auch Inspiration erwartet. Als Referenz bemüht sich das Buch, Licht in möglichst viele Winkel der Visual-Basic-Programmierung zu bringen. Programmierer dieser Gruppe werden daher in der Fülle der vorgestellten Programmiertechniken und Problemlösungen schnell Ansatzpunkte für die Lösung der eigenen Fragestellungen finden. den versierten Programmierer, der in vielen Programmiersprachen zu Hause ist und gezielte Hilfestellung in der einen oder anderen Fragestellung sucht. Die problemrelevante Auswahl der Einzelthemen und die Anwendungen unterschiedlicher Schwierigkeitsgrade und Komplexität umfassende Beispielsammlung dürfte das Buch für diesen Programmierertyp zu einer Fundgrube bei der Suche nach speziellen Lösungen werden lassen. den Entwickler spezifischer Datenbanklösungen, der Visual Basic unter anderem als Plattform für die Front-End-Programmierung benutzt
Auch wenn im Text vielfach nur »Visual Basic« zu lesen ist, ist der Inhalt des Buches vor dem Hintergrund der bei Drucklegung aktuellsten Version von Visual Basic zu interpretieren. Die in diesem Buch aufgeführten Thematiken und Beispiele wurden daher unter Visual Basic 6.0 (SP3) sowie der dazu von Microsoft bereitgestellten Dokumentation sorgfältig ausgearbeitet und auch getestet. Da Microsoft die Entwicklungszyklen seiner Produkte inzwischen scheinbar zunehmend auf Release-Versionen ausdehnt und eine weitgehende Fehlerfreiheit meist erst mit dem zweiten oder dritten Service-Pack erreicht wird, bietet diese Version eine hinreichend stabile Plattform für die Anwendungsentwicklung.
Die CD zum Buch Dem Buch ist eine CD beigelegt, auf der Sie die im Text explizit als Projekte bezeichneten Beispiele in je eigenen Unterverzeichnissen der Verzeichnisse Referenz und Praxis vorfinden. Zur einfacheren Orientierung tragen die Unterverzeichnisse die Namen der Projekte. Um die nicht
18
Zielgruppe
kompilierten Programme auszuführen, öffnen Sie die jeweilige VBP-Projektdatei oder VBG-Projektgruppendatei in der Visual-Basic-Entwicklungsumgebung und starten die Ausführung mittels der Taste (F5). Für Kommentare, Verbesserungen und Anregungen mit Bezug auf den Inhalt dieses Buchs bin ich jederzeit dankbar. Richten Sie Zuschriften bitte an: [email protected]
München im August, 2000
Rudolf Huttary
Zielgruppe 19
Teil 1: Referenzteil
21
Grundlegendes Bei der prozeduralen Programmierung erfolgt die Strukturierung des Quellcodes traditionell durch Kontrollstrukturen, Funktionen/Prozeduren und Module. Während Kontrollstrukturen als Muss für jede Programmiersprache schon immer zum Kern von Basic zählten, hielten der Funktions- und Prozedurbegriff und das damit verbundene Konzept des Namensraums nur sehr zögerlich Einzug in die Sprache. Der Modulbegriff war als solcher zwar schon immer vorhanden, er implizierte bis zur Entwicklung von Visual Basic jedoch nicht mehr als die schiere Möglichkeit, von einem ersten Programm aus die Kontrolle zusammen mit gegebenenfalls speziell für den Export deklarierten Werten an ein zweites Programm abzugeben. Da das erste Programm dadurch beendet wurde und seine gesamte Umgebung verlorenging, war dieses Konzept als zusätzliche Strukturebene wenig geeignet. Brauchbare Adaptionen für Funktionen/Prozeduren gibt es seit QuickBasic und QBasic, wenngleich die etwas seltsam anmutenden Regeln für den Namensraum aus heutiger Sicht den Eindruck erwecken, als seien den Funktionen/Prozeduren Teile eines Modulkonzepts untergemischt worden. Erst die mit Visual Basic vollzogene Öffnung zur objektorientierten Programmierung brachte der Sprache ein ausgewogenes Verhältnis dieser drei Strukturebenen, wie es heute in allen modernen Programmiersprachen zu finden ist: Kontrollstrukturen sind (unverändert) bedingte Verzweigungen und Schleifen, die eine Steuerung der Programmausführung ermöglichen. Prozeduren/Funktionen fassen als Unterprogramme umfangreiche Anweisungsfolgen zu kompakten Einheiten zusammen, wobei Funktionen aufgrund des Funktionswerts, den sie verkörpern, noch der spezielle Aspekt der Auswertung komplexer Ausdrücke zufällt. Module haben Bibliothekscharakter und kombinieren Code und Datenstrukturen zu eigenständigen Programmeinheiten. Damit erfüllen sie die strukturelle Voraussetzung für die Implementation von Objektdatentypen (Klassen).
Programme und Module in Visual Basic Dieser Abschnitt diskutiert den Programm- und Modulbegriff von Visual Basic und stellt die verschiedenen Ausprägungen vor.
Programm Ein Programm ist eine Folge von Befehlen, die auf einem Computer ausführbar ist und im weitesten Sinne eine spezifische Anleitung für die spezifische Verarbeitung spezifischer Daten darstellt. Das hier etwas strapazierte Wort »spezifisch« soll deutlich machen, dass bei der Datenverarbeitung die Repräsentation eine enorme Rolle spielt und Programm nicht gleich Programm ist, selbst wenn es das Gleiche tut. Basic war ursprünglich als Interpretersprache konzipiert, was nichts anderes heißt, als dass zur Ausführung eines Basic-Programms ein Interpreter (also ein weiteres Programm) erforderlich war, das vergleichbar einem Dolmetscher die Basic-Befehle nacheinander in Maschinenbefehle übersetzte. Darüber hinaus musste der Interpreter während des Übersetzens auch noch darauf achten, dass der Programmtext keine Fehler syntaktischer oder sonstiger Natur enthielt. Das hatte zwar den Vorteil, dass die Programmentwicklung sehr einfach – weil vollständig interaktiv – vonstatten gehen konnte, aber auch den Nachteil, dass die Ausführungsgeschwindigkeit zu wünschen übrig ließ. Basic hatte daher immer schon den Ruf, »nicht gerade der schnellsten einer« zu sein. Im Gegensatz zu Basic sind andere Sprachen wie C oder Pascal von vornherein als Compilersprachen konzipiert, das heißt, Programmtexte werden einmalig (sowie nach jeder Änderung) von einem Compiler (Übersetzungsprogramm) auf syntaktische und sonstige Fehler hin untersucht und dann in eine ausführbare Version übersetzt, die aus nichts weiter als aus Maschinenbefehlen besteht und vom Prozessor direkt verarbeitet werden kann. (In der Praxis muss der vom Compiler gelieferte Code allerdings zur Auflö-
23
Programme und Module in Visual Basic
Programme und Module in Visual Basic
sung von Bibliotheksverweisen noch einem Bindevorgang unterzogen werden – dafür ist der so genannte Linker zuständig). Der Geschwindigkeitsvorteil liegt dabei natürlich auf der Hand. Visual Basic vereint heute die Vorteile einer Interpretersprache mit der einer Compilersprache. Für die interaktive Programmentwicklung stellt die Entwicklungsumgebung von Visual Basic einen Interpreter (genau genommen handelt es sich dabei um einen inkrementellen Compiler) mit integriertem Debugger bereit, und zur Fertigstellung einen Compiler, der direkt ausführbaren Code erzeugen kann. Dieser Code ist allerdings noch auf eine oder mehrere zu Visual Basic gehörende Laufzeitbibliotheken angewiesen, die in Form von DLLs bereitstehen. Neben der Übersetzung in Maschinencode bietet Visual Basic auch die Übersetzung in den so genannten PCode an, ein im Schnitt etwa um 40 Prozent kompakterer und syntaktisch fehlerfreier Zwischencode. In P-Code vorliegende Programme besitzen einen kleinen ca. 9 KB umfassenden Maschinencode-Anteil, den so genannten P-Code-Interpreter, der ein primitives Laufzeitsystem darstellt und den P-Code (mit weitaus geringeren Geschwindigkeitsverlusten als ein Basic-Interpreter) in Maschinencode entfaltet.
Modul Ein Blick auf die Entwicklung von Basic zeigt weiterhin, dass sich die Sprache von einer schwach strukturierenden Sprache, deren einzige Strukturelemente Kontrollstrukturen und (inzwischen völlig verpönte) Subroutinen bildeten, zu einer stark strukturierenden Sprache gemausert hat, die sich dem Vorwurf, sie würde Spagetti-Code fördern, nicht mehr gefallen lassen muss. So baut sich die Funktionseinheit Programm heute nicht mehr als schlichte Folge von Anweisungen, Verzweigungen und Sprüngen auf, sondern als Sammelsurium sich gegenseitig in streng hierarchischer Organisation aufrufender Funktionen und Prozeduren, also in sich abgeschlossener und gekapselter Untereinheiten mit eng begrenzten und überschaubaren Funktionalitäten. Damit aber nicht genug. Um als Programmiersprache in einer zunehmend objektorientiert gestalteten Systemumgebung noch mitmischen zu können, muss auch die Möglichkeit einer Strukturierung »nach oben hin« gegeben sein. Dies bringt den Begriff des Moduls ins Spiel. Ein Modul vereinigt im Wesentlichen das unter sich, was traditionell als Basic-Programm begriffen wurde: einen als Datei vorliegenden Programmtext, der vom Basic-Laufzeitsystem als eigenständige Programmeinheit behandelt wird. Charakteristikum des Moduls ist, dass es einen eigenen Namensraum darstellt, mithin also Variablen bereitstellen kann, die global in allen Prozeduren des Moduls bekannt sind (Deklaration mit Dim oder Private). Darüber hinaus ist auch ein Export globaler Variablen und Prozeduren an andere Module (Deklaration mit Public) möglich. Auf diese Weise lässt sich in Visual Basic die Gesamtfunktionalität eines Programms als Ansammlung kleinerer »Programme« bzw. Module mit definierten Schnittstellen begreifen. Das einzelne Modul kann im Zusammenspiel mit anderen Modulen einem höheren Zwecke dienen, aber auch für sich genommen ein vollständiges Programm sein. Mit Blick auf die Objektorientierung hat das Modul in Visual Basic eine noch weitere sehr wichtige Funktion: Es kann als eigenständiger komplexer Datentyp (Klasse) auftreten und stellt dafür die Implementation. Eine ausführliche Diskussion dieses Aspekts finden Sie im Teil »Objekte und Klassen« (S. 195).
Projekt Der Visual-Basic-Programmierer legt für jedes neue Programm ein Projekt an, welches als organisatorischer Rahmen für die verschiedenen Module seines Programms fungiert. Damit das Programm für sich lauffähig ist, muss eines (und nur eines) dieser Module ein Startobjekt bereitstellen, das unter PROJEKTEIGENSCHAFTEN auf der Seite ALLGEMEIN anzugeben ist. Der Name »Objekt« ist hier ein wenig unglücklich gewählt, weil nicht nur Objekte mit eigenständiger Nachrichtenbehandlung (wie Formulare), sondern auch eine Prozedur mit dem speziellen Bezeichner Main zur Auswahl stehen. Ist für ein Projekt kein Startobjekt definiert, kann der resultierende Code nur als Bibliothek für andere Programme oder Bibliotheken fungieren. (Eine
24
Arten von Modulen in einem Projekt
Bibliothek kann allerdings gleichfalls ein Startobjekt benötigen, wenn noch vor dem Aufruf der ersten Bibliotheksroutine gegebenenfalls notwendige Initialisierungen durchzuführen sind.) So ergibt sich, dass in Visual Basic geschriebene Programme aus unterschiedlichen Teilen zusammengesetzt sind, die jeweils unterschiedliche Gestalten haben bzw. annehmen können: ●
Arten von Modulen in einem Projekt Visual Basic unterscheidet mehrere Arten von Modulen. Um einem bestehenden Projekt ein weiteres Modul hinzuzufügen, finden sich im Menü PROJEKT der Entwicklungsumgebung entsprechende Einträge. Mit Ausnahme von Standardmodulen des Typs Modul sowie allgemeinen Klassenmodulen setzt sich ein Modul aus einer Codekomponente und einer Objektkomponente (lies: sichtbare Repräsentation) zusammen. Die Bearbeitung der Codekomponente erfolgt im ASCII-Editor und die Bearbeitung der Objektkomponente im Designerfenster der integrierten Entwicklungsumgebung Visual Studio. Standardmäßiges Modul für die Programmierung kleiner Anwendungen mit Ein- und Ausgabefunktionalität ist das Formular. Sein Charakteristikum ist, dass seine Funktionalität im Wesentlichen auf ein einzelnes Fenster ausgerichtet ist, das ihm als Eingabe- und Ausgabemedium dient. Nachdem ein Formularmodul zur Laufzeit durch ein Formularobjekt mit eigenständiger Nachrichtenbehandlung repräsentiert wird, kann jedes Formularmodul formal zum Startobjekt erklärt werden. (Natürlich muss dann auch das Design sowie die Logik des Formulars auf diese Eigenschaft zugeschnitten sein.) Somit kann ein aus einem einzelnen Formularmodul bestehendes Projekt bereits als vollständiges, interaktives Visual-Basic-Programm auftreten. Sie erhalten ein solches Minimalprojekt (mit geeignet definiertem Startobjekt), wenn Sie ein Projekt des Typs »Standard-EXE« anlegen. Mit dieser Konstellation kommt das Formularmodul dem traditionellen Basic-Programm am weitesten entgegen, auch wenn die Programmiertechniken für die Ein- und Ausgabe unter Windows doch erheblich anders aussehen als vergleichsweise noch unter DOS. Eine Anleitung, wie ältere, noch mit QBasic geschriebene Basic-Programme unter Visual Basic zum Laufen gebracht werden, findet sich zu Anfang des Praxisteils. Eine andere, gleichfalls auf die Arbeit mit Fenstern ausgerichtete Modulart ist das MDI-Formular. Es unterscheidet sich vom gewöhnlichen Formularmodul darin, dass es das Rüstzeug für die Programmierung mit einem Hauptfenster und beliebig vielen weiteren, ersterem untergeordneten Fenstern sozusagen bereits mitbringt. MDI-Formularmodule kommen dementsprechend dann zum Einsatz, wenn es um die Darstellung und Verwaltung mehrerer Dokumente (Formularmodule) »unter einem gemeinsamen Dach« (MDI-Formularmodul) geht. Weitere Informationen hierzu im Abschnitt »Selbst definierte Klassen« auf Seite 318. Die schlichte Bezeichnung Modul für die dritte Modulart verrät bereits, dass es sich hierbei um ein unspezifisches Standardmodul handelt. Ein solches Modul kann beispielsweise die Logik für die Koordination weiterer Module enthalten oder schlicht als Bibliothek für von allen Modulen eines Projekts gemeinsam genutzte Funktionen, Prozeduren, Variablen, Typen und Konstanten fungieren.
25
Programme und Module in Visual Basic
●
Quelltext oder Interpretercode – liegt im ASCII-Format vor und kann die Dateierweiterungen .frm (Formular und MDI-Formular), .bas (Programmmodul), .ctl (ActiveXSteuerelement) oder .cls (Klassenmodul, ActiveX-Komponente) haben. Zur Ausführung des Quelltextes im Visual-Basic-Interpreter sind darüber hinaus je Quelltext eine Projektdatei (.vbp) und bei Gruppierung mehrerer Projekte zu einem Ganzen eine Gruppierungsdatei (.vbg) vonnöten. Compilercode – liegt als ausführbarer Maschinencode oder P-Code vor und kann die Dateierweiterungen .exe (Ausführbare Datei oder prozessexterne ActiveX-Komponente), .dll (dynamische Bibliothek oder prozessinterne ActiveX-Komponente) oder .ocx (ActiveX-Steuerelement) tragen.
Programme und Module in Visual Basic
Programme und Module in Visual Basic
Geheimnisvoller ist die Bezeichnung Klasse für die vierte Modulart. Sie ist dafür gedacht, die neu mit Visual Basic hinzugekommene Seite der objektorientierten Programmierung aktiv zu bedienen, sprich, eigene Objekte zu implementieren. Sieht man ein Objekt als Kombination aus einem benutzerdefinierten Datentyp und den zugehörigen Operationen über diesem Datentyp an, wird die Rolle des Klassenmoduls schnell deutlich. Es beherbergt die Beschreibung des Objektdatentyps hinsichtlich seiner Repräsentation und seiner Methoden (lies: Funktionen und Prozeduren). Weitere Informationen hierzu im Abschnitt »Selbst definierte Klassen« auf Seite 318. Die Modulart Benutzersteuerelement ist dem Bereich der ActiveX-Programmierung zuzurechnen. Sie erlaubt die Bereitstellung eigener Steuerelemente im OCX-Format, deren Funktionalität im (allerdings recht reichhaltigen) Angebot der unter Windows allgemein verfügbaren Steuerelemente nicht enthalten ist. Anders als ein Formular ist ein Benutzersteuerelement im Allgemeinen nicht dazu da, ein komplettes Fenster darzustellen, sondern – wie der Name schon sagt – nur ein Steuerelement, das sich auf einem Formular platzieren lässt. Aus diesem Grund besitzt ein Benutzersteuerelement für gewöhnlich weder Menüleisten, Symbolleisten und andere Dinge, die bei Formularen anzutreffen sind, noch ein feste Größe. Vergleichbar mit den Standardsteuerelementen, werden die sichtbaren Abmessungen eines Benutzersteuerelements erst bei Platzierung des fertigen Steuerelements im Verlauf des Formularentwurfs oder programmgesteuert festgelegt. Das Benutzersteuerelementmodul enthält die gesamte Logik eines Benutzersteuerelements sowie die Schnittstellendefinition für den Datenaustausch (Eigenschaften). Wie das Formular Minimalbestandteil des Projekttyps »Standard-EXE« ist, so ist das Benutzersteuerelement Minimalbestandteil des Projekttyps »ActiveX-Steuerelement«. Auch die Modulart Eigenschaftsseite fällt in den Bereich der ActiveX-Programmierung. ActiveX-Steuerelemente haben oft komplexe Eigenschaften (so etwa zusammengesetzte Datentypen oder Objekte), deren Darstellung im standardmäßigen Fenster Eigenschaften der Entwicklungsoberfläche nicht mehr erfolgen kann. Für diesen Fall besteht die Möglichkeit, eine oder mehrere Eigenschaftsseiten für die Eingabe der Eigenschaften bereitzustellen. Da ein ActiveX-Steuerelement, das beim Entwurf eines Formulars, eines anderen Steuerelements oder einer anderen Komponente in den Entwurfbereich gezogen wird, standardmäßig (als Entwurfsinstanz) zur Ausführung kommt, steht insbesondere auch der hinter einer Eigenschaftsseite steckende Code zur Verfügung. Eine Eigenschaftsseite lässt sich wie ein Formular unter Verwendung von Steuerelementen im Designerfenster der Entwicklungsumgebung zusammenstellen und im Code-Editor mit der entsprechenden Logik für den Datenaustausch mit einem ActiveX-Steuerelement, aber auch mit mehreren ActiveX-Steuerelementen (bei Mehrfachauswahl von ActiveXSteuerelementen im Designerfenster, denen die gleiche Eigenschaftsseite zugeordnet ist) versehen. Die letzte Modulart, Designer, ist mehr oder weniger ein Sammelbecken für die verschiedensten Objekte. Visual Basic hält für jedes dieser Objekte ein Designer-Werkzeug bereit, das ähnlich dem Formulardesigner die interaktive visuelle Gestaltung der Objektkomponente ermöglicht. Wie beim Formular wird in der Codekomponente eines solchen Objekts seine spezifische Reaktion auf bestimmte Ereignisse festgelegt. Unter den Werkzeugen finden sich der DHTML-Designer für den Entwurf und die Programmierung dynamischer HTML-Seiten, der Data-ReportDesigner für den Entwurf und die Programmierung von Datenberichten, der Data-Environment-Designer für die interaktive Gestaltung und das Management der Datenumgebung für Datenbankverbindungen mit programmgesteuerten Datenzugriffen sowie der WebClass-Designer für die Bereitstellung von Active Server Pages (.asp-Dateien) im Zusammenhang mit verteilten Anwendungen im Internet oder Intranet und dem Internet Information Server. Tipp
................................................... Tipp
Module sind ein sehr geeignetes Mittel für die Strukturierung von Programmcode hinsichtlich seiner Wiederverwendbarkeit. Die Vielfalt der unter Visual Basic vorhandenen Modularten för-
26
Literale und Konstanten
dert zwar bereits von sich aus die modulare Programmierung, ersetzt aber verständlicherweise nicht die bewusste Aufteilung des Codes in spezifische und allgemein verwendbare Programmtexte. Wer sich beizeiten vernünftige Bibliotheken anlegt, kann später um so mehr davon profitieren. Beispiele
................................................... Beis piele
' Projekt: Modultest ' vollständiger Code von Module1 Sub Main() ' Main ist Startobjekt des Projekts Dim f As New Form1 f.Caption = "Erster Aufruf" ' Lädt Formular Form1 in Hauptspeicher f.Show 1 ' Zeigt Formular an und wartet, bis dieses endet f.Caption = "Zweiter Aufruf" f.Show 1 ' Zeigt Formular an und wartet, bis dieses endet End Sub ' vollständiger Code von Form1 ' Formular enthält Schaltfläche "Beenden" Private Sub Beenden_Click() Unload Me End Sub
Das in den folgenden beiden Abbildungen gezeigte Projekt EuroDMTestprojekt besteht aus zwei Modulen, einem einfachen Formularmodul und einem Benutzersteuerelementmodul. Das Programm testet ein Benutzersteuerelement namens EuroDM, welches die Ein- und Ausgabe von Geldbeträgen wahlweise in DM oder Euro gestattet. Der Einfachheit halber wurde auf eine Rundung und eine Korrektur der Punkt-/Komma-Problematik verzichtet. Das aus zwei Textund zwei Bezeichnungsfeldern bestehende Benutzersteuerelement rechnet Eingaben in der einen Währung automatisch in die andere um und erlaubt die Definition und Abfrage seiner beiden Textfelder über die Eigenschaften Euro und DM. Da die Textfelder eine gegenseitige Wertänderung im Rahmen ihrer Change-Behandlung vornehmen, sind ein wenig Logik und die globale Zustandsvariable Changing nötig, um eine Endlosschleife zu verhindern.
Literale und Konstanten [Public | Private] Const ConstName [As Typ] = Literal [Public | Private] Const ConstName [As Typ] = LiteralerAusdruck
27
Literale und Konstanten
Das einfache Projekt Modultest besteht aus zwei Modulen, einem gewöhnlichen Modul Module1 und einem Formularmodul Form1. Module1 enthält eine Startprozedur namens Main, die im Dialog PROJEKTEIGENSCHAFTEN als Startobjekt spezifiziert ist. Form1 enthält dagegen nichts weiter als eine Schaltfläche Beenden zum Beenden des Formulars. In diesem Programm ruft Main als Startobjekt Form1 zweimal hintereinander als gebundenes Formular auf und passt dazu den Fenstertitel entsprechend an. Wählt man Form1 als Startobjekt, erfolgt nur ein Aufruf des Formulars, während das Modul Module1 gar nicht erst zur Ausführung kommt:
Literale und Konstanten
Literale und Konstanten
Testprojekt für das Benutzersteuerelement EuroDM im Entwurfsmodus
Das Benutzersteuerelement EuroDM im Einsatz Beschreibung
................................................... Bes c hreibung
Die elementarste Unterscheidung bei der Datenverarbeitung, an der selbst einfachste Taschenrechner nicht vorbeikommen, ist die zwischen Daten und Befehlen. Als Datum bezeichnet man die Repräsentation eines Werts in einem spezifischen Datenformat (Datentyp). Ein Datum kann als Literal, als Konstante oder als Variable vorliegen. Im Falle des Literals steht der Wert für sich selbst, etwa wie 42 für die Zahl Zweiundvierzig oder »Rudolf« für den Vornamen des Autors dieses Buches. Im Falle der Konstanten hat man es genau genommen gleichfalls mit einem Literal zu tun, da der Interpreter bzw. Compiler jedes Vorkommen einer Konstanten im Quelltext automatisch durch ihren literalen Wert ersetzt. Variablen sind dagegen auf ein bestimmtes Datenformat (Datentyp) zugeschnittene Behälter, die einen Bezeichner (lies: einen Namen) tragen und einen (in dem bestimmten Datenformat gehaltenen) Wert enthalten. Während sich der Wert eines Literals oder einer Konstanten im Programmverlauf nicht ändern kann, weil – wenn man so will – Bezeichner und Wert identisch sind, kann eine Variable (im
28
Literale und Konstanten
Anwendung
................................................... Anwendung
Ein Literal kann überall dort stehen, wo ein Wert erforderlich ist – so bei Zuweisungen als Rechtswert (lies: rechts von Gleichheitszeichen), in Ausdrücken als Operand, bei Funktionsund Prozeduraufrufen als Argument für einen Parameter. Für die Notation literaler Größen gibt es feste Regeln, die sich auch von Datentyp zu Datentyp unterscheiden können. So sind Zeichenfolgenliterale in doppelte Anführungszeichen einzuschließen, und damit es zu keiner Verwechslung zwischen dem doppelten Anführungszeichen als Zeichen und dem Zeichenfolgenende kommt, muss das Anführungszeichen doppelt notiert werden, wenn es als Zeichen auftritt. strMyName = "Rudolf Huttary" Position$ = "Das Schiff liegt 2° 3' und 42"" Ost"
Zahlenliterale können Sie in dezimaler Schreibweise, wie gewohnt: Const cMaxSize = 255
in hexadezimaler Schreibweise durch Voranstellen von &H: Const cMaxSize = &HFF
' dezimaler Wert 255
oder in oktaler Schreibweise durch Voranstellen von &O notieren: Const cMaxSize = &O377
' dezimaler Wert 255
Die dezimale Notation von Zahlenliteralen mit Nachkommastellen erfolgt mit Dezimalpunkt. (Achtung: In Zeichenfolgen, die später implizit oder mittels einer Funktion wie Val umgewandelt werden, gelten jedoch die Ländereinstellungen, so dass hier auf einem deutschen System ein Komma zu notieren ist.) Etwaige Zehnerpotenzen sind, durch ein »E« abgetrennt, an die Dezimaldarstellung anzuhängen. Positive Vorzeichen können Sie weglassen; negative Vorzeichen stellen Sie jeweils dem Wert voran, für den sie gelten. Const delta = -2.14E-27
' Minus 2 Komma 14 mal 10 hoch Minus 27
29
Literale und Konstanten
Rahmen ihres Datenformats) unter Beibehaltung ihres Namens jederzeit ihren Wert ändern. Anders gesagt: Ein Literal ist ein Wert, eine Konstante steht für einen Wert und eine Variable enthält einen Wert. Ein Befehl ist eine allgemeine Vorschrift für die Manipulation von Daten im weitesten Sinne und wird in Visual Basic häufig mit der so genannten Anweisung gleichgesetzt (vgl. »Anweisungen«, S. 33). So ist beispielsweise die Zuweisung eines Werts an eine Variable, die so genannte Zuweisungsoperation mit »=« ebenso ein Befehl wie die Ausgabe einer Grafik mit automatischer Größenanpassung in ein Bildfeld, das auf einem Formular gelegen ist. Als Operationen bezeichnet man dagegen eine besondere Art von Befehlen, bei der ein Operator (lies: Rechenvorschrift) auf einen oder mehrere Operanden (lies: Werte einer bestimmten Art) angewendet wird und einen neuen Wert (gleicher Art) produziert – so etwa die Bildung der Summe zweier Zahlen, die Verkettung von Zeichenfolgen, die Restwertdivision (Modulo-Rechnung) oder, wie gesagt, die Zuweisung eines Werts an eine Variable. Ist ein Wert so notiert, dass er erst durch Anwendung von Operatoren auf Operanden berechnet werden muss, spricht man von einem Ausdruck. Sind die Operanden als Literale notiert, spricht man genauer von einem literalen Ausdruck.
Literale und Konstanten
Der standardmäßige Datentyp von Zahlenliteralen ist Integer bzw. – bei vorhandenen Nachkommastellen – Single. Um einen anderen Datentyp zu erzwingen, können Sie dem literalen Wert ein Typkennzeichen anhängen.
Literale und Konstanten
Const cAlpha = 100& Const cBeta = 100! Const cGamma = 100#
' cAlpha ist vom Typ Long ' cBeta ist vom Typ Single ' cGamma ist vom Typ Double
Nicht ganz so eingängig sind die Regeln für die Notation von Datumsliteralen. Werte dieses Typs repräsentiert Visual Basic als 64-Bit-Gleitkommazahlen (8 Bytes) nach IEEE und kann somit Datumsangaben im Bereich zwischen dem 1. Januar 100 und dem 31. Dezember 9999 sowie Uhrzeiten im Bereich von 0:00:00 bis 23:59:59 unterscheiden. Datumsliterale können Datumsangaben und Zeitangaben kombinieren, aber auch je einzeln ausdrücken. Der Notation literaler Datums- und Zeitangaben liegt das amerikanische Format zugrunde, das heißt, in Datumsangaben wird der Monat vor dem Tag notiert und die Abtrennung erfolgt durch das Zeichen »/«, und Zeitangaben sind in 12-Stunden-Darstellung gefolgt von »PM« oder »AM« zu treffen. Zudem ist die Darstellung durch ein führendes und abschließendes Zeichen »#« einzuschließen. (Der Editor erkennt übrigens auch andere Darstellungen, so etwa #1 Feb 99#, und korrigiert diese beflissen in das erwünschte Format.) Dim a = b = c =
a As Date, b As Date, c As Date #2/1/1996 1:12:01 PM# #12:01:00 PM# #2/1/1996#
Konstanten lassen sich – wie Literale – überall dort einsetzen, wo ein Wert erforderlich ist. Gegenüber Literalen bieten sie den Vorteil, dass der Wert, für den sie stehen, an zentraler Stelle definiert und fortan formal durch Angabe des Konstantenbezeichners notiert werden kann. Die Definition einer Konstanten erfolgt zur Entwurfszeit im Rahmen einer Const-Anweisung durch Zuweisung eines Literals oder eines literalen Ausdrucks an einen Konstantenbezeichner. Bei der Wahl des Konstantenbezeichners gelten die üblichen Vorschriften für die Bezeichnerwahl (vgl. »Bezeichner und Namensraum«, S. 34). Es ist legitim, bei der Definition von Konstanten, andere, bereits definierte Konstanten als Rechtswerte oder als Operanden in Ausdrücken zu verwenden. Const MinSize = 8 Const MaxSize = MinSize + 2741
' MinSize steht für den Wert 8 ' MaxSize steht für den Wert 2749
................................................... Warnung
Warnung
Wer denkt, dass die Konstantendeklarationen Const a = 65535
und Const b = &HFFFF
identisch sind, der irrt. a steht für die Zahl 65535 (wie notiert), b jedoch für -1. Das liegt daran, dass Visual Basic a implizit den Datentyp Long und b den Datentyp Integer zuordnet und der Wert -1 aufgrund der Repräsentation negativer Zahlen durch Zweierkomplementbildung die hexadezimale Darstellung &HFFFF hat. Damit beide Konstanten den gleichen Wert erhalten, ist die hexadezimale Darstellung so zu notieren: Const b = &H0FFFF
30
Literale und Konstanten
In Basic existiert nur formal ein Unterschied zwischen der bitweisen Operation und der logischen Operation, da die Repräsentation logischer Werte genau so gewählt ist, dass eine bitweise Operation die jeweilige logische Operation hervorbringt. Const a = Not 2
' a steht für -3 (Zweierkomplement)
und s% = -3 And 42 Or 1 ' s% erhält den Wert 41
Tipps
................................................... Tipps Vermeiden Sie im Programmtext nach Möglichkeit die Verwendung von Literalen und arbeiten Sie mit Konstanten, die Sie jeweils zu Anfang des Moduls im Bereich ALLGEMEIN (seltener: zu Anfang einer Prozedur) definieren. Auf diese Weise können Sie den Wert eines Literals an zentraler Stelle mit globaler Wirkung für den gesamten Programmtext ändern. Const cMaxSize = 255 ... For x = 0 to cMaxSize
Um für Konstanten einen bestimmten Typ zu erzwingen, erklären Sie diesen entweder durch die Angabe eines Typkennzeichens oder durch eine explizite Typdeklaration. Const cMaxSize As Integer = 255
Bildet ein literaler Wert die Grundlage für einen weiteren literalen Wert, so empfiehlt es sich, den zweiten Wert als Ausdruck zu schreiben, der auf den ersten aufbaut, oder anstelle des zweiten Literals eine Variable einzusetzen und deren Wert rechnerisch aus dem ersten Literal zu ermitteln. Const cMinSize = 100 ' Const cMaxSize = 199 Const cMaxSize = 2 * cMinSize – 1 Const cVerschlüsseltesKennWort = "2XVf5uhf" ' Const KennwortLänge = 8 ... Dim KennwortLänge As Integer KennwortLänge = Len(cVerschlüsseltesKennwort)
' falsch ' richtig
' falsch
' richtig
Visual Basic besitzt eine sehr reichhaltige Fülle an vordefinierten Konstanten (auch Objektkonstanten), deren Einsatz nicht nur ein Garant für Kompatibilität ist, sondern auch (gerade im Zusammenhang mit Objektkonstanten) zu Laufzeitverbesserungen führt. Einen Überblick über diese Konstanten gibt der Objektkatalog (aufzurufen über ANSICHT/OBJEKTKATALOG oder (F2)). Beispiel
................................................... Beis piel
Das folgende vollständige Programm Apfelmann, eine stark vereinfachte Version des mehrfach in diesem Buch diskutierten Apfelmännchens, demonstriert den Umgang mit literalen Werten. Da das Programm während der Berechnung keine Aktualisierung der Anzeige vornimmt, erscheint das Bild erst nach Abschluss aller Berechnungen – es sei denn, man fügt einen ShowAufruf in die Load-Routine ein und setzt die AutoRedraw-Eigenschaft des Formulars auf False.
31
Literale und Konstanten
Die von Visual Basic verwendete interne Repräsentation für Datumswerte kann mit folgender Kapriole aufwarten: Der 30. Dezember 1899 ist nicht darstellbar. Visual Basic interpretiert diesen Tag vielmehr als reine Zeitangabe #12:00:00 AM#.
Literale und Konstanten
Literale und Konstanten
' Bereich Allgemein Const cx1 As Double = -2.1 Const cy1 As Double = -1.2 Const cx2 As Double = 0.7 Const cy2 As Double = 1.2 Const cFenster_x = 4000 Const cFenster_y = 3600 Const cMaxIterat As Integer = 200 Const cGrenze As Double = 100
' Bildausschnitt des Apfelmännchens
' Fensterabmessungen nicht zu groß ' sonst dauert es zu lange
Private Sub Apfel(m_x1, m_x2, m_y1, m_y2, step_x, step_y) Dim r1 As Double, re As Double, im As Double Dim zr As Double, zi As Double, it As Integer For zr = m_x1 To m_x2 Step step_x ' alle Spalten in x-Richtung For zi = m_y1 To m_y2 Step step_y ' alle Punkte in Spalte zr re = 0 ' Realteil initialisieren im = 0 ' Imaginärteil initialisieren For it = 0 To cMaxIterat ' Iteration für Punkt r1 = re * re – im * im + zr im = 2 * re * im + zi re = r1 If re < -cGrenze Or re > cGrenze Or _ im < -cGrenze Or im > cGrenze Then PSet (zr, zi), it * 16 ' Punkt ausgeben Exit For End If Next it Next zi Next zr End Sub Private Sub Form_Load() Dim step_x As Double, step_y As Double Width = cFenster_x ' Fensterabmessungen anpassen Height = cFenster_y ' AutoRedraw = False ' Show ScaleMode = vbPixels ' Ab jetzt Bildpunkte als Einheit step_x = (cx2 – cx1) / ScaleWidth ' Breite eines Bildpunkts step_y = (cy2 – cy1) / ScaleHeight ' Höhe eines Bildpunkts Scale (cx1, cy1)-(cx2, cy2) ' Koordinatensystem vorgeben Apfel cx1, cx2, cy1, cy2, step_x, step_y ' Apfelmännchen berechnen End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
Dim, Public, Private, ReDim Verwandte Themen
................................................... Verwandte Them en
Datentypen und ihre Operationen (S. 49); Operatoren für elementare Datentypen und logische Bedingungen (S. 54); Anweisungen (S. 33); Bezeichner und Namensraum (S. 34)
32
Anweisungen
Anweisungen _ (Operator für Übertrag in nächste Zeile) : (Operator für Aneinanderreihung von Anweisungen) [Let] Var = Wert Rem Kommentar ' Kommentar
Beschreibung
................................................... Bes c hreibung
Der Quelltext eines Visual-Basic-Moduls setzt sich aus einer Folge von Anweisungen zusammen. Unter einer Anweisung versteht man in Visual Basic alles, was einen Befehl darstellt, ohne selbst einen Wert zu verkörpern. Man unterscheidet zwischen einfachen Anweisungen, die in einer einzelnen Zeile stehen können, und Kontrollstrukturen, die als zusammengesetzte Anweisungen ihrerseits Anweisungsfolgen strukturieren und auf höherer Ebene zu einer logischen Einheit zusammenfassen. Eine besondere Anweisungsform stellen Compileranweisungen dar, denen das Zeichen # vorangeht (#If Then...#Else...#End If). Sie werden nicht erst zur Laufzeit, sondern bereits zur Übersetzungszeit interpretiert und führen dazu, dass bestimmte Teile des Codes gar nicht erst übersetzt werden. Ausdrücke in solchen Anweisungen dürfen nur aus Literalen und Konstanten zusammengesetzt sein. Visual Basic definiert in diesem Zusammenhang die Boolean-Konstanten Win16 und Win32, deren (jeweils gegensätzlicher) Wahrheitswert ausdrückt, ob die Übersetzung auf einer 16-Bit- oder 32-Bit-Plattform erfolgt. Anwendung
................................................... Anwendung
Zu den einfachen Anweisungen zählen Zuweisungsoperationen (Let, Set, LSet, RSet Mid), Prozeduren (vordefinierte und benutzerdefinierte), Deklarationen (Const, Dim, Private, Public, Declare) und Definitionen (Function, Sub) aller Art. Alles, was Visual Basic als einfache Anweisungen betrachtet, kann als eigenständige Programmzeile stehen. Überlange einfache Anweisungen lassen sich mittels des Übertragsoperators _ (Unterstrich) in zwei oder mehrere Zeilen aufteilen. Dabei muss der Übertragsoperator durch ein Leerzeichen getrennt als letztes Zeichen in der Zeile notiert sein – und darf insbesondere keine Zeichenfolgenliterale trennen. Mehrere Anweisungen lassen sich in eine Zeile stellen, wenn zwischen den Anweisungen der Aneinanderreihungsoperator : (Doppelpunkt) notiert ist. Eine Kontrollstruktur ist eine zusammengesetzte Anweisung, die sich über mehrere Zeilen hinweg erstrecken kann und eine Rahmung untergeordneter Anweisungsfolgen mittels Schlüsselwörtern vorsieht, entsprechend den die Kontrollstruktur geltenden syntaktischen Regeln. Im Falle der If-Anweisung akzeptiert Visual Basic sowohl die kompakte Zeilenform als auch eine mehrzeilige Form. Rem-Anweisungen sind nur aus formaler Sicht Anweisungen. Eigentlich stellen sie Kommentare dar, da sie der Compiler bei der Übersetzung ebenso ignoriert wie Kommentare, die durch ein Hochkomma ' eingeleitet sind.
33
Anweisungen
#If Ausdruck Then Anweisungsfolge1 [#Else | ElseIf AusdruckN AnweisungsfolgeN #End If
Bezeichner und Namensraum
Bezeichner und Namensraum Bezeichner, Namensraum, Schlüsselwörter Private, Public, Dim Beschreibung
Bezeichner und Namensraum
................................................... Bes c hreibung
Bezeichner fungieren in Visual Basic als formale Namen für verschiedenen Größen: Konstanten, Variablen und Objekte, Funktionen und Prozeduren (Methoden) sowie Module. Bei der Wahl eines Bezeichners für eine bestimmte Größe genießt der Programmierer weitestgehende Freiheiten. Er muss lediglich die formalen Regeln zur Bezeichnerbildung einhalten und auf Eindeutigkeit im jeweiligen Namensraum achten. Zudem verbietet sich die Verwendung der von Visual Basic reservierten Schlüsselwörter, die von der Sprache selbst mit einer festen Bedeutung belegt sind. Die formalen Regeln für die Bezeichnerbildung in Visual Basic sind: ● ●
●
●
Bezeichner dürfen zwischen ein und 255 Zeichen lang sein Bezeichner müssen mit einem Buchstaben beginnen, wobei auch deutsche Umlaute und Sonderzeichen (genau genommen sogar alle ANSI-Zeichen mit einem Code zwischen 128 und 255) erlaubt sind. Für alle weiteren Zeichen sind darüber hinaus auch die Ziffern »0« bis »9« und der Unterstrich »_« erlaubt. Visual Basic unterscheidet in der Notation von Bezeichnern nicht zwischen Groß- und Kleinschreibung. MyVar und Myvar bezeichnen somit dasselbe. (Der Editor der integrierten Entwicklungsumgebung setzt allerdings auf Modulebene eine konsistente Schreibweise durch, indem er jeweils die bei der Deklaration eines Bezeichners verwendete Schreibweise erzwingt und bei implizit deklarierten Bezeichnern jeweils die zuletzt verwendete Schreibweise für alle Vorkommen des Bezeichners übernimmt.)
Als Namensraum eines Bezeichners wird der Bereich bezeichnet, innerhalb dessen ein Bezeichner bekannt ist. Der größte Namensraum ist der so genannte globale Namensraum oder die Programmebene. Bezeichner, die diesem Namensraum angehören, sind in allen Modulen eines Programms bekannt und somit global ansprechbar. Jeweils kleinere Namensräume sind die Modulebene und Prozedurebene. Bezeichner, deren Namensraum auf die Modulebene beschränkt ist, sind nur innerhalb des Moduls bekannt, in dem sie deklariert wurden, und Bezeichner, deren Namensraum auf die Prozedurebene beschränkt ist, sind nur innerhalb der Prozedur (bzw. Funktion) bekannt, in dem sie deklariert wurden. Bei Bezeichnerkonflikten, die durch die Wahl gleicher Bezeichner für unterschiedliche Größen in überlappenden Namensräumen unterschiedlicher Stufe entstehen, ist im kleineren Namensraum immer nur der in diesem Namensraum deklarierte Bezeichner sichtbar. Anwendung
................................................... Anwendung
Während Modulbezeichner von vornherein dem globalen Namensraum angehören, müssen Prozeduren, Funktionen und Methoden explizit mit dem Zusatz Public deklariert werden, damit ihr Bezeichner im globalen Namensraum sichtbar wird. Geschieht die Deklaration dagegen mit dem Zusatz Private oder ohne Zusatz, ist ihr Bezeichner jeweils immer nur innerhalb des Moduls bekannt, das den Quelltext enthält. Die vielfältigsten Möglichkeiten für die Gestaltung des Namensraums bieten Konstanten, Variablen und Objekte. Bei impliziter oder expliziter Deklaration in einem Prozedur- oder Funktionskörper erstreckt sich der Namensraum des Bezeichners ab Deklaration bis zum Endes des Körpers. Findet die Deklaration dagegen auf Modulebene (im Bereich ALLGEMEIN) ohne Zusatz oder unter Angabe von Dim oder Private statt, ist der Bezeichner fortan im restlichen Teil des Modulkörpers bekannt und insbesondere
34
Bezeichner und Namensraum
auch in allen Funktionen und Prozeduren (bzw. Methoden) sichtbar. Während sich der Namensraum einer Konstanten grundsätzlich nicht über mehrere Module erstrecken kann, sondern maximal auf die Modulebene beschränkt bleibt, unterliegen Variablen und Objekte dieser Einschränkung nicht. Damit eine Variable oder ein Objekt im globalen Namensraum bekannt wird, muss eine Public-Deklaration auf Modulebene erfolgen. Warnung
................................................... Wa rnung
Dim x As Single, y As Single ... Sub BerechneMatrix(a(), b()) ... For x = 1 To 100 For y = 1 To 200 ... Next x, y End Sub
Die Variablen x und y werden hier leichtfertig und im Vertrauen auf die implizite Deklaration als Zählvariablen eingesetzt. Eine solche findet aber nicht statt, da unter diesen Bezeichnern globale Variablen bekannt sind. Diese verlieren durch die Schleifen leider ihren Wert, was an völlig anderer Stelle seltsame Nebeneffekte hervorbringen kann. Deshalb immer fleißig deklarieren und auf globaler Ebene keine nichtssagenden 08/15-Bezeichner vergeben. Tipp
................................................... Tipp
Wer die Wahl hat, hat die Qual. Dieser Spruch bewahrheitet sich insbesondere, wenn es darum geht, sich immer wieder neue Bezeichner auszudenken. Eine gute Hilfe ist es, sich dabei von formalen Kriterien leiten zu lassen und bei der Auswahl darauf zu achten, dass ein Bezeichner möglichst viel über die Größe aussagt, für die er steht. Um Konstanten, Variablen und Prozeduren besser auseinander halten zu können, folgen viele Programmierer daher bei der Bildung von Bezeichnern bestimmten Konventionen. So hat es sich beispielsweise bewährt, Konstanten immer in Großschreibung zu notieren, Variablen mit einem Kleinbuchstaben beginnen zu lassen und Prozeduren mit einem Großbuchstaben. Sehr verbreitet ist zudem die so genannte ungarische Notation, die durch Bezeichnerpräfixe den zu einem Bezeichner gehörigen Datentyp zum Ausdruck bringt. Variablen vom Typ Integer würden mit einem »i« beginnen, Variablen vom Typ String mit einem »s« oder »str« usw. Der restliche Teil des Bezeichners kann dann noch in gemischter Groß- und Kleinschreibung notiert werden, um seine Funktion mnemonisch besser zum Ausdruck zu bringen. (Diese Schreibweise wird inzwischen der früher weit verbreiteten Zusammensetzung mit Unterstrichen »_« vorgezogen.) Bei sehr enger Verwandtschaft zweier Größen leistet oft auch die Abzählung durch Anhängen von Ziffern als Suffix gute Dienste.
35
Bezeichner und Namensraum
Visual Basic betrachtet es nicht als Fehler, wenn Sie ein und denselben Bezeichner in verschiedenen Namensräumen vergeben. Solange die Namensräume nichts miteinander zu tun haben, wird dies keine allzu große Verwirrung stiften, ja, vielfach sogar Vorteile bringen. Problematisch wird es allerdings, wenn ein Namensraum den anderen umfasst, wie etwa die Modulebene eine Prozedurebene. In diesem Fall wird die auf Modulebene deklarierte Variable in der Prozedurebene unsichtbar, weil ihr Bezeichner durch die lokal in der Prozedur deklarierte Variable »verdeckt« ist. Dies ist meist zu verschmerzen, oft sogar auch gewollt. Fehlerträchtig wird es allerdings, wenn der Programmierer auf eine implizite Deklaration auf Prozedurebene setzt und unwissentlich oder fahrlässig den Bezeichner einer global deklarierten Variable erwischt. So führt beispielsweise der folgende Code zu unangenehmen Nebeneffekten:
Kontrollstrukturen
Beispiel
................................................... Beis piel
Kontrollstrukturen
' Unterscheidung der Notation durch Klein und Großschreibung Const MAXSIZE = 10 ' Konstanten in Großschreibung Private anzahl As Integer ' Variable in Kleinschreibung Private ergebnis As Single, werte(MAXSIZE) As Single Function StandardAbweichung(a() As Single) As Single ' Ungarische Notation Const cMaxSize = 10 ' Präfix "c" für Konstante Private iElemAnzahl As Integer ' Präfix "i" für Integer Private bChanging As Boolean ' Präfix "b" für Boolean Private frmAnmeldung As Form1 ' Präfix "frm" für Formular Private sErgebnis1 As Single ' Präfix "s" für Single, Abzählung Private sErgebnis2 As Single ' Präfix "s" für Single, Abzählung Function sStandardAbweichung(a() As Single) As Single Verwandte Befehle
................................................... Verwa ndte Befehle
DefType Verwandte Themen
................................................... Verwandte Them en
Datentypen und ihre Operationen (S. 49); Typkennzeichen und Bezeichnerbereiche für Typen (S. 167); Geltungsbereiche von Variablen (S. 173)
Kontrollstrukturen Aufgabe einer Kontrollstruktur ist die Steuerung der Programmausführung in Abweichung von der im Quelltext notierten Anweisungsfolge.
Unbedingte und bedingte Verzweigung, Subroutinen GoTo {Marke | Zeile} ... Marke: GoSub SubRoutine ... SubRoutine: ... Return If Bedingung Then Anweisung [Else Anweisung] If Bedingung Then [ThenAnweisungsBlock] [ElseIf Bedingung1 [ElseIfAnweisungsBlock]] ... [Else [ElseAnweisungsBlock]] End If
36
Unbedingte und bedingte Verzweigung,
Subroutinen
Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Der unbedingte Sprung mit GoTo, aber auch die GoSub-Unterprogramme, zählen zu den Erblasten von Basic, denen die Sprache in ihrer Anfangszeit das Attribut »Spagetti-Code« zu verdanken hatte. In der modernen, strukturierten Programmierung findet in seltenen Fällen nur noch die GoTo-Anweisung Anwendung, nämlich im Zusammenhang mit der Fehlerbehandlung, wo der Befehl im Zusammenspiel mit On Error gezielte Sprünge zu Fehlerbehandlungsroutinen ermöglicht. Anstelle von GoSub-Unterprogrammen benutzt man heute ausschließlich benutzerdefinierte Funktionen und Prozeduren. Anders die If-Anweisung. Sie hat an Wichtigkeit im Laufe der Zeit nichts eingebüßt. In der mehrzeiligen Form eignet sie sich bei Verwendung von ElseIf-Zweigen für umfangreichere Fallunterscheidungen, auch wenn die Select-Anweisung hier oft die bessere Wahl darstellt. IfAnweisungen können natürlich auch vollständig verschachtelt werden, von der Laufzeit her sind ElseIf-Formulierungen jedoch überlegen. Warnung
................................................... Wa rnung
Aufrufe parameterloser Prozeduren und schlichte Sprungmarken kann Visual Basic von der Notation her nicht unterscheiden, wenn der Doppelpunkt-Operator zur Anreihung mehrerer Anweisungen in einer Programmzeile ins Spiel kommt. Visual Basic zieht in diesem Fall die Interpretation »Sprungmarke« der anderen vor. Setzen Sie parameterlose Prozeduraufrufe daher besser in eigene Zeilen (ohne nachfolgenden Doppelpunkt) oder benutzen Sie die CallAnweisung für den Aufruf. Beispiel
................................................... Beis piel
Die folgenden Zeilen zeigen, wie die Logik für die Berechnung der Sgn-Funktion aussieht:
37
Kontrollstrukturen
Die einfachste (inzwischen aber verpönte) Möglichkeit, die Kontrolle einem anderen Programmteil weiterzugeben, ist der unbedingte Sprung mittels GoTo zu einer Sprungmarke oder Zeilennummer. Die Anweisung GoSub ermöglicht den Aufruf eines Unterprogramms (auch verschachtelt), das an der Sprungmarke oder Zeilennummer SubRoutine beginnt und bis zur nächsten Return-Anweisung (auf gleicher Ebene) reicht. Sprungmarken und Zeilennummern müssen jeweils innerhalb der gleichen Funktion/Prozedur liegen und am Zeilenanfang stehen. Eine Sprungmarke ist ein beliebiger Bezeichner gefolgt von einem Doppelpunkt. Die wichtigste Kontrollstruktur zur Steuerung des Programmablaufs ist die bedingte Verzweigung in Form der If-Anweisung, für die zwei unterschiedliche Notationen zulässig sind. In der kürzeren Schreibweise (Zeilenform) muss die Anweisung – gegebenenfalls samt Else-Teil – in einer Zeile und ohne abschließendes End If notiert sein. In der mehrzeiligen Schreibweise ist dagegen das abschließende End If unerlässlich. Die Syntax erlaubt in dieser Form zudem ElseIf-Fallunterscheidungen. Die If-Anweisung führt den im Then-Zweig gelegenen ThenAnweisungsblock aus, wenn die – meist als logischer Ausdruck formulierte – Bedingung Bedingung einen Wert ungleich 0 ergibt. Ist der Wert 0, kommt der ElseAnweisungsblock des Else-Zweiges zur Ausführung. Der Else-Zweig kann durch Einfügung von ElseIf-Zweigen weiter aufgespreizt sein, wobei ein ElseIf-Zweig nichts anderes als die optimierte Form einer verschachtelten If-Anweisung im Else-Zweig ist. Ergibt sich für die Bedingung eines ElseIf-Zweiges ein Wert ungleich 0, kommt der ElseIfAnweisungsblock zur Ausführung. Bei vorhandenen ElseIfZweigen kommt ein ElseAnweisungsblock nur zur Ausführung, wenn alle bis dahin geprüften Bedingungen den Wert 0 ergeben haben.
Kontrollstrukturen
If a > 0 Then a = 1 ElseIf a < 0 Then a = -1 End If ' für den Fall a = 0 hat a bereits den richtigen Wert! Verwandte Befehle
................................................... Verwa ndte Befehle
On Error, Select, On ... GoSub
Kontrollstrukturen
Verwandte Themen
................................................... Verwandte Them en
Operatoren für elementare Datentypen und logische Bedingungen (S. 54); Fallunterscheidung (S. 38); Fehlerbehandlung (S. 43)
Fallunterscheidung Select Case TestAusdruck [Case Fall1 [AnweisungsBlock1]] ... [Case FallN [AnweisungsBlockN]] [Case Else [ElseAnweisungsBlock]] End Select Function Switch(Ausdruck1, Wert1,[Ausdruck2, Wert2[, ...]]) As Variant Function Choose(Index As Integer, Wert1[, Wert2[,... WertN]]) As Variant On Ausdruck GoSub SprungzielListe On Ausdruck GoTo Sprungzielliste Function IIf(Kriterium As Boolean, ThenWert, ElseWert) As Variant Beschreibung
................................................... Bes c hreibung
Die Select Case-Kontrollstruktur führt eine Fallunterscheidung auf Basis des Werts von TestAusdruck durch. Für jeden zu unterscheidenden Fall ist ein Case-Zweig mit der Anweisungsfolge AnweisungsblockN zuständig. Der Case-Ausdruck Fall kann als Konstante/Literal, Is-Vergleich (offener Bereich), To-Bereich (geschlossener Bereich) oder als Fall-Aufzählung formuliert sein: Fall Fall Fall Fall
= = = =
Zahl | Zeichenfolge Is VglOperator VglWert Fall1 To FallN Fall1, ..., FallN
In einer Select-Struktur kommt maximal ein, bei vorhandenem Else-Zweig genau ein Zweig zur Ausführung. Die Switch-Funktion führt eine Fallunterscheidung auf Basis ihrer in Paaren zu je einem Ausdruck und einem potentiellen Funktionswert organisierten Parameterliste durch. Den Funktionswert WertN eines solchen Paares gibt die Funktion zurück, wenn der Ausdruck AusdruckN von links beginnend der erste Ausdruck ist, der einen von 0 verschiedenen Wert hat, also den Wahrheitswert True besitzt. Falls keiner der Ausdrücke ungleich 0 ist, liefert die Funktion den Wert Null.
38
Fallunterscheidung
Anwendung
................................................... Anwendung
Obwohl sich Fallunterscheidungen prinzipiell gesehen genauso gut über If-Anweisungen (verschachtelt oder mit ElseIf-Zweigen) formulieren lassen, sind Select Case-Formulierungen im Allgemeinen eleganter und übersichtlicher – vor allem, wenn viele Fälle zu unterscheiden sind. Die Syntax für die Formulierung der einzelnen Fälle ist reichhaltig. Der Compiler nimmt allerdings keine Überprüfung auf Überlappung vor, so dass auf eine disjunkte Formulierung der Fall-Ausdrücke geachtet werden sollte. In einfachen Fällen, wenn sich die Fallunterscheidung (wie bei Arrays) auf die indexorientierte Auswahl eines Werts aus einer Werteliste zurückführen lässt, sollte die Choose-Funktion das Mittel der Wahl sein. Dieselbe Funktionalität lässt sich allerdings mittels der Array-Funktion erzielen, wie das Beispiel am Ende des Abschnitts zeigt. Für Fallunterscheidungen, die auf die Auswahl eines Werts in Abhängigkeit verschiedener Bedingungen hinauslaufen, ist die Switch-Funktion meist das eleganteste Mittel. Die Anwendung der Funktion widerspricht aber in gewisser Hinsicht der Intuition, da es grundsätzlich zur Auswertung aller Ausdrücke kommt. In der Praxis hat das zwei Auswirkungen: Erstens muss jeder Ausdruck für jeden Fall wohldefiniert sein (kein Überlauf, keine Division durch 0 etc.), sonst kommt es zu einem Laufzeitfehler, und zweitens hat die Funktion unabhängig vom unterschiedenen Fall immer die gleichen Seiteneffekte. Von einem Gebrauch der On-Anweisung (jenseits von On Error) ist abzuraten, weil GoTo-Sprünge und GoSub-Unterprogramme angesichts der reichhaltigen Ausstattung von Visual Basic für die strukturierte Programmierung nicht mehr zeitgemäß sind. Diese Befehle werden nur noch für die Abwärtskompatibilität unterstützt. Warnung
................................................... Wa rnung
Da in Select-Strukturen immer nur ein Case-Zweig zur Ausführung kommt, ist im Falle der Überlappung von Case-Ausdrücken die Reihenfolge der Case-Aufzählung relevant. Visual Basic wertet bei Abarbeitung der Switch-Funktion immer alle Ausdrücke aus, so dass eventuelle Seiteneffekte vom Funktionswert unabhängig bleiben. Beispiel
................................................... Beis piel
Der folgende Code zeigt die eine Select-Fallunterscheidung für den von einem Textfeld gemeldeten Tastaturcode: Private Sub Text1_KeyUp(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeyDelete, vbKeyBack ' wg. Überschreibmodus Case vbKeyUp, vbKeyDown ' Nächste Zeile in Textfeld AktualisiereZeile(sZeile) ' Änderungen zurückschreiben
39
Kontrollstrukturen
Die Choose-Funktion liefert den an der Position Index in der Werteliste stehenden Wert – der Wert 1 wählt Wert1, der Wert 2 wählt Wert2 usw. Die On-Kontrollstruktur ermöglicht eine Fallunterscheidung durch Auswahl eines Sprungziels aus der Liste SprungzielListe in Abhängigkeit von Ausdruck. Der Wert von Ausdruck darf zwischen 0 und 255 liegen. Ist er 0 oder größer als die Anzahl der Sprungziele in der Liste, findet kein Sprung bzw. Unterprogrammaufruf statt, ansonsten benennt er die Listenposition des anzusteuernden Sprungziels. Als Sprungziele können wahlweise Zeilennummern oder Sprungmarken genannt sein, die in der gleichen Funktion/Prozedur definiert sind. Eine Fallunterscheidung der besonderen Art stellt die Funktion IIf dar. Sie wird mit drei Parametern aufgerufen und liefert in Abhängigkeit vom Wahrheitswert des ersten Parameters den zweiten Parameter (erster Parameter ist True) oder dritten Parameter (erster Parameter ist False) als Funktionsergebnis.
Kontrollstrukturen
Kontrollstrukturen
Case vbKeyEscape List1_Click ' Ursprüngliche Fassung holen Case vbKeyEnd Start = LineLen – 1 Case vbKeyLeft Start = LinePos – 1 Case vbKeyRight Start = LinePos + 1 Case vbKeyHome Start = 0 Case Else ' Sonstige Tasten VerarbeiteTaste(KeyCode, sZeile) End Select Text1.SelStart = Start ' Position in Puffer aktualisieren Text1.SelLength = 1 ' Überschreibmodus End Sub
Hier verschiedene Formulierungen für die Zuordnung eines numerischen Werts zu einer Zeichenfolge: sZahl = Choose(a + 1, "Null", "Eins", "Zwei", "Drei", "Vier", "Fünf") sZahl = Switch(a = 0, "Null", a = 1, "Eins", a = 2, "Zwei", a = 3, _ "Drei", a = 4, "Vier", a = 5, "Fünf") sZahl = Array("Null", "Eins", "Zwei", "Drei", "Vier", "Fünf")(a)
IIf macht die Min-/Max-Berechnung leicht: Min = IIF(a < b, a, b) Max = IIF(a > b, a, b) Verwandte Befehle
................................................... Verwa ndte Befehle
If, GoTo, GoSub Verwandte Themen
................................................... Verwandte Them en
Unbedingte und bedingte Verzweigung, Subroutinen (S. 36)
Schleifen For CountVar = StartVal To EndVal [Step StepVal] [Anweisungsfolge] [Exit For] [Anweisungsfolge] Next [CountVar[, CountVar1]] For Each IteratVar In Liste [Anweisungsfolge] [Exit For] [Anweisungsfolge] Next [IteratVar[, IteratVar1 ...]] While Bedingung [Anweisungsfolge] [Exit While]
40
Schleifen
[Anweisungsfolge] Wend Do [{While | Until} Bedingung] [Anweisungsfolge] [Exit Do] [Anweisungsfolge] Loop
Beschreibung
................................................... Bes c hreibung
Schleifen sind Kontrollstrukturen, die es gestatten, einen Anweisungsblock oder Schleifenkörper in Abhängigkeit eines Kriteriums – einer logischen Bedingung oder dem Wert einer Zählvariablen – mehrmals zu durchlaufen. Das klassische Programmiermodell unterscheidet zwischen abweisenden Schleifen, die das Schleifenkriterium im Schleifenkopf vor dem ersten Durchlaufen des Schleifenkörpers prüfen (und selbst die einmalige Ausführung des Schleifenkörpers unterbinden können), und nicht abweisenden Schleifen, die ihr Kriterium nach Abarbeitung des Schleifenkörpers prüfen. Visual Basic weicht diese Unterscheidung allerdings auf, indem es sprachliche Mittel für den Schleifenabbruch an beliebiger Stelle vorsieht. Darüber hinaus lässt sich zwischen Schleifen unterscheiden, bei denen eine Berechnung der benötigten Schleifendurchläufe noch vor dem ersten Eintritt in die Schleife möglich ist (Zählschleifen), und solchen, bei denen diese Berechnung nicht möglich ist (Schleifen mit implizitem Abbruchkriterium). Schleifen, deren Kriterium sich nie erfüllt, heißen Endlosschleifen. Falls der Schleifenkörper einer Schleife eine weitere Schleife enthält, spricht man von verschachtelten Schleifen. Anwendung
................................................... Anwendung
Der Einsatzbereich von Schleifen ist derartig breit, dass es wohl nur wenige auch nur halbwegs anspruchsvolle Programme geben wird, die ohne dieses Mittel auskommen. Abweisende Schleifen werden in Visual Basic als For-, While- oder Do-Schleifen und nicht abweisende Schleifen ausschließlich als Do-Schleifen formuliert. Als Zählschleife ist die starre Form der For-Schleife am besten geeignet. Schleifen lassen sich beliebig verschachteln, solange gewährleistet ist, dass eine äußere Schleife den Schleifenkörper einer inneren Schleife jeweils vollständig enthält.
Die For...Next- Schleife Eine For-Schleife kann in einer von zwei Formen benutzt werden. In der ersten Form verlangt sie die Bekanntgabe einer Zählvariablen (CountVar) eines beliebigen numerischen Typs, eines Startwerts (StarVal), eines Endwerts (EndVal) und gegebenenfalls einer Schrittweite, wenn diese von der standardmäßigen Schrittweite 1 abweicht. Der Ablauf ist: 1. Beim ersten Eintritt der Programmausführung in den Schleifenkopf initialisiert die ForSchleife die Zählvariable mit dem Startwert. 2. Unmittelbar vor jedem Durchlaufen des Schleifenkörpers prüft die Schleife, ob die Zählvariable den Endwert bereits überschritten hat. Falls ja, endet die Schleife, und die Ausführung überspringt den Schleifenkörper. 3. Nach jedem Durchlaufen des Schleifenkörpers erfolgt automatisch die Aktualisierung der Zählvariablen unter Beachtung der geltenden Schrittweite.
41
Kontrollstrukturen
Do [Anweisungsfolge] [Exit Do] [Anweisungsfolge] Loop [{While | Until} Bedingung]
Kontrollstrukturen
Kontrollstrukturen
Beachten Sie, dass Sie zwar den Wert der Zählvariablen jederzeit ändern und somit das Verhalten der Schleife von innerhalb des Schleifenkörpers manipulieren können, nicht jedoch den geltenden Endwert oder die Schrittweite. Von einer solchen Manipulation ist aber generell eher abzuraten, da der Code dann nicht mehr übersichtlich ist. Um eine For-Schleife verfrüht abzubrechen, bedienen Sie sich besser des Befehls Exit For. Als Datentyp für die Zählvariable kommen ganzzahlige Typen wie Integer oder Long in Betracht, ebenso aber auch Fließkommatypen wie Single oder Double. Das beste Laufzeitverhalten hat eine Schleife, wenn die Zählvariable vom Typ Long ist. Um eine Schleife zum Rückwärtszählen zu bewegen, geben Sie StepVal mit einer negativen Schrittweite an sowie einen Endwert, der kleiner als der Startwert ist. Dim i As Long For i = 10 to 2 Step -2 Print i, i+1 Next i
In Form der For Each-Schleife ermöglicht die For-Schleife das Durchlaufen aller Elemente einer Auflistung Liste. An die Stelle der Zählvariable tritt die Aufzählvariable IterateVar, die bei jedem Schleifendurchlauf den Wert des jeweils nächsten Elements von Liste annimmt, bis das Ende der Auflistung erreicht ist. Eine Modifikation der Aufzählvariable innerhalb des Schleifenkörpers hat keine Auswirkung auf die Aufzählung. Einzig der vorzeitige Abbruch mittels Exit For ist möglich. Als Voraussetzungen für die Anwendung dieser Form sind zu beachten: Liste muss eine Auflistung (Collection-Objekt) oder ein Array sein, und IterateVar muss den Datentyp Variant oder einen Objektdatentyp tragen. Dim a(20) As Integer Dim i As Variant For Each i In a i = 2 Next i
' Array elementweise initialisieren
Die Nennung der Zähl- bzw. Aufzählvariablen nach dem Schlüsselwort Next ist optional. Als Abschluss verschachtelter For-Schleifen ist auch die Nennung mehrerer Zähl- bzw. Aufzählvariablen nach dem Schlüsselwort Next zulässig.
Die While...Wend- Schleife Als Standardlösung für abweisende Schleifen bietet sich die While-Schleife an. Schleifen dieser Art prüfen unmittelbar vor jedem Eintritt in den Schleifenkörper, ob das Kriterium Bedingung einen Wert ungleich 0 hat. Falls dem so ist, bricht die Schleife ab und die Ausführung überspringt den Schleifenkörper. While-Schleifen lassen sich jederzeit auch von innerhalb des Schleifenkörpers mittels einer Exit While-Anweisung abbrechen. While Not EOF(1) Line Input #1, a MyList.AddItem a Wend
' Zeilen aus Datei in Auflistung einlesen
Die Do...Loop- Schleife Am meisten Flexibilität bietet die Do-Schleife. Sie lässt sich als abweisende, als nicht abweisende Schleife und als Endlosschleife formulieren. In der abweisenden Form wird das Schleifenkriterium mit einem While- oder Until-Zusatz hinter das Schlüsselwort Do, in der nicht abweisenden Form hinter das Schlüsselwort Loop gesetzt. Ein While-Kriterium bricht die Schleife ab, wenn es den Wert 0 hat, während ein Until-Kriterium mit einem Wert ungleich 0 den Abbruch bedingt. Wie die anderen Schleifen lässt sich auch die Do-Schleife jederzeit von innerhalb des Schleifen-
42
Fehlerbehandlung
körpers mittels einer Exit Do-Anweisung abbrechen. Endlosschleifen sind in Wirklichkeit halbabweisende Schleifen, da sie mittels Exit Do irgendwo mitten im Schleifenkörper abgebrochen werden müssen. Do Line Input #1, a Loop While a = "" MyList.AddItem a
' Leerzeilen überlesen
' Zeile in Auflistung einfügen
Warnung
................................................... Wa rnung
Tipps
................................................... Tipps Als Faustregel lässt sich sagen, dass Schleifen in einem Programm ca. zwischen 80 und 99 Prozent der Ausführungszeit absorbieren. Es lohnt sich daher, wenn es um die Einsparung von Laufzeit geht, insbesondere innere Schleifen zu optimieren, die besonders oft durchlaufen werden. Rekursive Aufrufe von Funktionen/Prozeduren lassen sich in der Regel ohne große Schwierigkeiten mittels Schleifen in iterative Aufrufe überführen. Iterative Fassungen dienen insbesondere der Vermeidung des Fehlers 28, »Nicht genügend Stapelspeicher« und sind von der Laufzeit her meist überlegen. Endlosschleifen nicht kompilierter Programme lassen sich innerhalb der Entwicklungsumgebung mittels (Strg)+(Untbr) abbrechen. Schwieriger ist der Abbruch von endlosen Ereignisschleifen unter Windows 9x. Aber auch hierzu gibt es einen Trick, den unter Windows 9x allfälligen Reset zu vermeiden. Das Problem ist, dass der Task-Scheduler von Windows 9x der aus dem Rahmen fallenden Anwendung nach gewisser Zeit nahezu die gesamte Rechenzeit zur Verfügung stellt, weil die Nachrichtenflut die Priorität so weit hochschraubt, dass keine Hintergrundanwendung mehr Nachrichten zugestellt bekommt (noch nicht einmal der Task-Switcher). Der Trick: Man muss die Visual-Basic-Anwendung durch den impliziten Start einer Vordergrundanwendung in den Hintergrund verbannen. Für einen solchen impliziten Start reicht bereits das Einlegen einer CD (gegebenenfalls mit Autorun-Anwendung) oder der Empfang eines Faxes. Windows NT ist gegen endlose Ereignisschleifen unempfindlich, da die Ereigniswarteschlange in diesem Betriebssystem anders implementiert ist. Beispiele
................................................... Beis piele
Für die For-Anweisung vgl. das Beispiel zu »Literale und Konstanten« (S. 23). Für die Do-Anweisung vgl. das Beispiel zu »InStrRev-Funktion« (S. 79). Für die While-Anweisung vgl. die Beispiele zu »Dir-Funktion« (S. 148). Komplexer ist das Beispiel des Bubble-Sort-Algorithmus im Abschnitt »Prozeduren selbst definieren« (S. 204).
Fehlerbehandlung Sub Error(lFehlerNr As Long)
43
Kontrollstrukturen
Da Schleifen die Reaktionen eines Windows-Programms auf Benutzereingaben sehr beeinträchtigen können, empfiehlt es sich, in Schleifen mit zeitaufwändigen Berechnungen etwa jede Zehntelsekunde die Anweisung DoEvents aufzurufen. Beachten Sie jedoch, dass es zur Rekursion kommt, wenn bei der Ereignisverarbeitung die so unterbrochene Funktion/Prozedur erneut aufgerufen wird. Achtung! Endlosschleifen entstehen häufig auch ungewollt durch Ereignisse, die sich gegenseitig oder selbst auslösen. Ereignisfluten dieser Art können das System destabilisieren.
Kontrollstrukturen
Sub Err.Raise(Number As Long[, Source As String, _ Description As String, Helpfile As String, _ Helpcontext As String]) Function Error(lFehlerNr As Long) As String
Kontrollstrukturen
On Error Resume Next On Error GoTo Marke ... [On Error GoTo 0] ... Exit {Function | Sub} Marke: ... Resume [Next] Function CVErr(FehlerNummer As Long) As Error Funktion IsError(VarWert) As Boolean Beschreibung
................................................... Bes c hreibung
Die Vielfalt der möglichen Ursachen für das Fehlverhalten eines Systems steigt mit der Komplexität des Systems. Es ist nicht nur aus theoretischen Gründen unmöglich, die Logik eines Programms so zu gestalten, dass dieses vor jedem Schritt jede Fehlermöglichkeit ausschließt – schließlich könnte sich eine Fehlerbedingung im zeitlichen Verlauf auch erst unmittelbar nach der Prüfung einstellen –, auch aus praktischen Erwägungen heraus ist es unsinnig, Laufzeit für die Überprüfung selbst halbwegs wahrscheinlicher Fehlerbedingungen aufzuwenden. Anstatt umfangreicher und letztlich doch unzulänglicher Fehlerprüfungen setzt sich daher in den Programmiersprachen zunehmend das Konzept der Ausnahmebehandlung bzw. der Behandlung von Laufzeitfehlern durch. Zu einem Laufzeitfehler kommt es, wenn eine Routine ihrer Aufgabe aufgrund einer Fehlerbedingung nicht nachkommen kann und dies als Laufzeitfehler mit einer bestimmten Nummer signalisiert. Das Signal für einen Laufzeitfehler kann von einer Routine des Betriebssystems, einer Komponente oder einem sonstigen Objekt gesetzt werden (die entsprechenden Fehlernummern sind im Hilfesystem dokumentiert), aber auch von einer Visual-Basic-Routine selbst, wenn diese die Anweisung Error unter Angabe einer Fehlernummer, lFehlerNr, oder die RaiseMethode des vordefinierten Err-Objekts ausführt. Die Funktion Error liefert die zu einer Fehlernummer gehörige textuelle Fehlermeldung. Zur Behandlung eines Laufzeitfehlers – gleich welcher Natur dieser ist – lässt sich mittels einer On Error GoTo-Anweisung eine vorbereitete Fehlerbehandlungsroutine auf Funktions-/Prozedurebene installieren. Die Anweisung On Error Resume Next installiert dagegen eine standardmäßige Fehlerbehandlungsroutine für die Inline-Fehlerbehandlung, deren Strategie darin besteht, den für den Laufzeitfehler verantwortlichen Befehl zu überspringen und die Fehlerbehandlung unmittelbar im Anschluss an den Befehl durch Auswertung der Fehlernummer durchzuführen. Für die De-installation einer Fehlerbehandlungsroutine sorgt On Error GoTo 0. Ein anderes Konzept für die Signalisierung von Fehlern eröffnet die Funktion CVErr. Sie liefert einen Wert von Typ Variant mit dem Untertyp Error zurück und ermöglicht die Implementation von Funktionen/Prozeduren, die als Ergebniswert auch eine Fehlernummer zurückgeben können. Ob ein Variant-Wert den Untertyp Error hat, lässt sich mittels der IsError-Funktion in Erfahrung bringen. Aufgerufen mit einem Variant-Wert, liefert Sie den Wert True, wenn dieser eine Fehlernummer repräsentiert.
44
Fehlerbehandlung
Anwendung
................................................... Anwendung
45
Kontrollstrukturen
Die Anweisungen Error bzw. Err.Raise werden im Allgemeinen zur Simulation von Fehlern eingesetzt, um den Code für die Behandlung von Laufzeitfehlern zu testen. Darüber hinaus eignen sich die Befehle auch für die Realisierung programminterner Fehlerbehandlungsmechanismen. (Einzelheiten über den Einsatz des Fehlerobjekts für die Signalisierung von Laufzeitfehlern finden Sie im Abschnitt »Err-Objekt«, S. 277). Die Fehlernummer 0 sowie Fehlernummern größer als 65535 sind nicht zulässig, sondern führen ihrerseits zu einem Laufzeitfehler 5, »Ungültiger Prozeduraufruf oder ungültiges Argument«. Die Fehlernummern zwischen 1 und 1000 sind für das Laufzeitsystem von Visual Basic reserviert, wenn auch derzeit noch nicht alle mit einer Bedeutung versehen sind. Die anderen Fehlernummern sind frei verfügbar und lassen sich für programmspezifische Zwecke nutzen. Für die reservierten Fehlernummern von Visual Basic stehen textuelle Fehlermeldungen zur Verfügung, die sich mittels der Funktion Error – jeweils auf den letzten Fehler bezogen – abfragen lassen. Bei Einsatz des Err-Objekts lässt sich diese Fehlermeldung für jede Fehlernummer Number frei gestalten, da Error nichts weiter als den Wert der Description-Eigenschaft dieses Objekts liefert. Wenn der Vorgabetext des Systems für die Signalisierung programmspezifischer Fehler nicht angemessen ist, ist nur der Wert dieser Eigenschaft anzupassen – bzw. der Text als Wert bei Aufruf der Raise-Methode für den zweiten Parameter anzugeben. Um Laufzeitfehler abzufangen und darauf reagieren zu können, installiert man mittels On Error GoTo Marke eine Fehlerbehandlungsroutine, wobei Marke (am Zeilenanfang gefolgt von einem Doppelpunkt zu notieren) eine innerhalb derselben Routine befindliche Sprungmarke darstellt, die den Beginn des Fehlerbehandlungscodes kennzeichnet. Die für die genauere Analyse des Fehlers erforderliche Fehlernummer liefert die Eigenschaft Err.Number des vordefinierten Fehlerobjekts. Nachdem es sich dabei um die Standardeigenschaft des Objekts handelt, ergibt sich der Wert bereits durch schlichte Nennung des Objektbezeichners – was insbesondere die Kompatibilität mit älterem Basic-Code sicherstellt. Der zur Fehlernummer gehörige Fehlertext liefert die Error-Funktion oder die Eigenschaft Err.Description. Der Befehl Resume beendet die Fehlerroutine nach erfolgreicher Behandlung des Fehlers mit einem Rücksprung und bewirkt die erneute Ausführung jenes Befehls, der den Laufzeitfehler ausgelöst hatte. Falls eine Wiederholung dieses Befehls nicht in Frage kommt, lässt sich die Ausführung mit Resume Next beim nächstfolgenden Befehl wieder aufnehmen. Bei Fehlern, die sich nicht erfolgreich behandeln lassen oder für die die Fehlerroutine nicht ausgelegt ist, bleibt der Routine nur der Ausweg, ihrerseits einen Fehler auszulösen, der dann auf der Ebene des Aufrufers behandelt wird – und somit den gleichen Weg nimmt wie ein Fehler, für den keine Fehlerbehandlung auf aktueller Aufrufebene eingerichtet ist. Anders herum: Kommt während der Behandlung eines Fehlers eine Funktion/Prozedur zum Aufruf, die eine eigene Fehlerbehandlung vornimmt, ist deren Fehlerbehandlungsroutine für alle auf dieser Ebene ausgelösten Fehler zuständig. Hat die Funktion/Prozedur keine eigene Fehlerbehandlung, fällt die Fehlerbehandlung der Fehlerbehandlungsroutine des Aufrufers zu. Damit besteht die Möglichkeit, dass eine Fehlerbehandlungsroutine während der Behandlung eines Fehlers erneut zum Aufruf kommt, was von der Sache her nicht unbedingt mit Schwierigkeiten verbunden sein wird, logisch aber ein wenig verzwickt sein kann. Wenn ein Laufzeitfehler bereits durch Überspringen des jeweiligen Befehls behoben ist, kann die Fehlerbehandlungsroutine auch inline mittels On Error Resume Next installiert werden. In diesem Fall ist kein weiterer Code erforderlich. Die Zuständigkeit der jeweils aktuellen Fehlerbehandlungsroutine in einer Funktion/Prozedur erlischt mit dem Befehl On Error GoTo 0. Fehlt dieser Befehl, endet Zuständigkeit mit der Rückgabe der Kontrolle an den Aufrufer.
Kontrollstrukturen
Bei Signalisierung eines Fehlers ermittelt das Laufzeitsystem jeweils die nächste zuständige Fehlerbehandlungsroutine. Eine auf gleicher Ebene (Prozedurebene) gelegene Fehlerbehandlungsroutine kommt als Erstes zum Zuge, ansonsten wandert der Fehler in umgekehrter Aufruffolge von Aufrufer zu Aufrufer, bis sich eine zuständige Fehlerbehandlungsroutine findet oder das Laufzeitsystem schließlich eine standardmäßige Behandlung vornimmt. Warnung
Kontrollstrukturen
................................................... Wa rnung
Die Logik von Fehlerbehandlungsroutinen ist meist komplizierter als man denkt. So ist erstens davon auszugehen, dass jeder zwischen einer On Error GoTo Marke-Anweisung und einer On Error GoTo 0-Anweisung auftretende Laufzeitfehler zum Aufruf der Routine führen kann: falsche Argumente bei Prozedur-/Funktionsaufrufen ebenso wie Laufzeitfehler, die von einer aufgerufenen Prozedur oder Funktion signalisiert werden, weil sie dort keine Behandlung erfahren oder eine Behandlung nicht möglich ist. Zweitens ist aber auch davon auszugehen, dass ein Fehler immer wieder auftritt, weil er nicht korrekt behoben ist. Der unbedachte Einsatz von Resume ohne den Zusatz Next kann dann zu lästigen Endlosschleifen führen, die sich in der Entwicklungsumgebung nur noch mittels (Strg)+(Untbr) oder in der kompilierten Fassung des Programms nur noch über den Task-Manager abbrechen lassen. Ein häufiger Fehler im Zusammenhang mit Fehlerbehandlungsroutinen ergibt sich aus einer Nachlässigkeit: Die Ausführung durchläuft die Routine auch ohne Vorliegen eines Laufzeitfehlers, weil diese nicht durch den Befehl Exit Sub oder Exit Function vom gewöhnlichen Code abgesetzt ist. Tipp
................................................... Tipp
Testen Sie jede Fehlerbehandlungsroutine auf Herz und Nieren, indem Sie Testcode einsetzen, der alle Fehler – also auch solche, die die Routine nicht behandeln kann – mittels Error-Anweisungen oder Aufrufen der Methode Err.Raise simuliert. Beispiel
................................................... Beis piel
Das folgende Codebeispiel demonstriert die Fehlerbehandlung, wenn das Öffnen einer Datei mit vorangehender Abfrage des Dateinamens fehlschlägt. Da es keinen Sinn macht, die OpenAnweisung ohne erneute Eingabe des Dateinamens (hier über ein Standarddialoge-Objekt CommonDialog1 gelöst) zu wiederholen, ist der betreffende Code in einer eigenen Funktion zusammengefasst, der die Dateinummer zurückliefert. Die in der aufrufenden Routine installierte Fehlerbehandlungsroutine bietet dem Benutzer die Wahl zwischen der Wiederholung des gesamten Funktionsaufrufs oder einem Abbruch der aktuellen Routine. Der Abbruch wird seinerseits durch Auslösung eines Laufzeitfehlers bewerkstelligt. (Hinweis: Der FreeFile-Aufruf liefert nach einem Fehlschlag wieder die gleiche Dateinummer, da Open keine Reservierung der angebotenen Dateinummer vornimmt.) ... Dim Handle As Integer Dim Meldung As String ... On Error GoTo OpenFehler ' Routine installieren Handle = OpenBinary ' Funktion aufrufen On Error GoTo 0 ' Routine de-installieren ... Exit Sub ' Hier nicht weiter! OpenFehler: Meldung = "Fehler" + Str(Err) + ": " + Error(Err)
46
Fehlerbehandlung
If MsgBox(Meldung, vbRetryCancel) = vbRetry Then Resume ' Funktionsaufruf wiederholen Else ' Fehler an Aufrufer weitermelden Err.Raise(1001, "Binärdatei lässt sich nicht öffnen") End If ...
Vgl. auch das Beispiel zu »Open-Anweisung« (S. 166). Verwandte Themen
................................................... Verwa ndte Them en
Dateiorientierte Funktionen und Anweisungen (S. 126); Err-Objekt (S. 277); Standarddialoge-Steuerelement (CommonDialog) (S. 444)
47
Kontrollstrukturen
Function OpenBinary() As Integer OpenBinary = FreeFile ' freie Dateinummer ermitteln CommonDialog1.ShowOpen Open CommonDialog1.FileName For Binary As FreeFile End Function
Datentypen und ihre Operationen Wie alle Programmiersprachen, deren Wurzeln in der prozeduralen Programmierung liegen, verfügt Basic über ein Typkonzept, das im Laufe der Sprachentwicklung zunehmend reichhaltiger geworden ist. Das ursprüngliche Typsystem von Basic war geschlossen. Es gab vier numerische Datentypen mit unterschiedlichen Wertebereichen, über denen sich Ganzzahl- und Fließkommaarithmetik und ein wenig Boolsche Algebra betreiben ließ, sowie einen Zeichenfolgendatentyp mit vielen komfortablen Funktionen. QuickBasic und QBasic brachten der Sprache eine »Pascalisierung«, die sich nicht nur in einem verallgemeinerten Prozedur- und Funktionsbegriff bemerkbar machte, sondern auch in der Öffnung des Typsystems für benutzerdefinierte Datentypen. Darüber hinaus erhielt die Sprache auch einen flexiblen Datentyp, der jeden elementaren Datentyp (nicht jedoch benutzerdefinierte Datentypen) vertreten konnte und aufgrund impliziter Typumwandlungen eine gewisse Typtoleranz mit sich brachte. Seit die Sprache mit Visual Basic in den Bereich der objektorientierten Programmierung vorgedrungen ist, hat das Typsystem der Sprache in Form der in Typbibliotheken vorliegenden Objektdatentypen eine explosive Verbreiterung erfahren.
Elementare Datentypen Byte, Boolean, Integer, Long, Single, Double, Currency, Decimal, Date, Object, String, Variant True, False, Empty, Nothing, Null, Error Function IsEmpty(Var) As Boolean Function IsError(Var) As Boolean Function IsNull(Var) As Boolean Function IsNumeric(Var) As Boolean Function IsObject(Var) As Boolean Beschreibung
................................................... Bes c hreibung
Elementare Datentypen sind die Grundelemente einer Sprache für die Darstellung und Interpretation von Informationen. Die einzelnen Datentypen unterscheiden sich hinsichtlich ihrer Darstellung, ihrer Wertebereiche und der für sie definierten grundlegenden Operationen. Visual Basic kennt elementare Datentypen für die Repräsentation logischer Werte (Boolean), binärer Werte (Byte), numerischer Ganzzahlwerte (Integer und Long), numerischer Fließkommawerte (Single und Double), Datumsgaben (Date), Zeichenfolgen (String) und die Referenz auf Objekte (Object). Anwendung
................................................... Anwendung
Mit Hilfe der elementaren Datentypen lassen sich Konstanten und Variablen für die Handhabung der in Programmen anfallenden Daten deklarieren. Jeder dieser Datentypen mit Ausnahme von Variant steht für eine ganz bestimmte Art der Repräsentation und Interpretation von Information. Die folgende Tabelle gibt einen Überblick über ihre Wertebereiche.
49
Elementare Datentypen
Elementare Datentypen
Datentyp
Bytes
Beschreibung und Wertebereich
Byte
1
Kurze vorzeichenlose Ganzzahl zwischen 0 bis 255
Boolean
2
Logischer Wert, True oder False
Integer
2
Ganzzahl zwischen –32.768 bis 32.767
Long
4
Lange Ganzzahl zwischen –2.147.483.648 und 2.147.483.647
Single
4
Gleitkommazahl einfacher Genauigkeit von –3,402823E38 bis –1,401298E–45 für negative Werte und von 1,401298E-45 bis 3,402823E38 für positive Werte
Double
8
Gleitkommazahl mit doppelter Genauigkeit: –1,79769313486232E308 bis –4,94065645841247E-324 für negative Werte und 4,94065645841247E–324 bis 1,79769313486232E308 für positive Werte
Currency
8
Ganzzahl mit Skalierung in 10.000stel zwischen –922.337.203.685.477,5808 und 922.337.203.685.477,5807
Decimal
14
29stellige Dezimalzahl ohne Exponent, als Ganzzahl zwischen ±79.228.162.514.264.337.593.543.950.335 mit Abstand 1, als Zahl mit 28 Nachkommastellen zwischen ±7,9228162514264337593543950335 mit Abstand ±0,0000000000000000000000000001
Date
8
Datum zwischen 1. Januar 100 und 31. Dezember 9999
Object
4
Referenz auf ein Objekt, eine gültige Adresse oder Nothing
String
10 + Länge Zeichenfolge mit variabler Länge. 0 bis theoretisch 231-1 Zeichen. In der Praxis ist je nach Speicherausbau des Systems aber bereits bei einer Länge von ca. 100 Millionen Zeichen Schluss, wegen »Überlauf des Zeichenfolgenspeichers»
String *
Länge
Zeichenfolge mit fester Länge zwischen 1 und 65.535 (216-1)
Variant
16
Standardtyp, bei numerischem Untertyp wie der Datentyp Double
Variant
22 + Länge Standardtyp, bei Zeichenfolge als Untertyp, wie Datentyp String mit variabler Länge
Die elementaren Datentypen von Visual Basic
Der Datentyp Variant Der Typ Variant bildet eine Hülle für alle anderen Datentypen und kann alle durch elementare Datentypen darstellbaren Werte repräsentieren (außer Zeichenfolgen fester Länge) sowie die Werte Empty, Nothing, Null und Error. Variablen vom Typ Variant müssen nicht eigens deklariert werden, da Visual Basic diesen Datentyp als Standardtyp für alle nicht explizit oder via Typkennzeichen deklarierten Variablen einsetzt. Es ist aber kein Fehler (ja sogar guter Programmierstil), Variablen vom Typ Variant explizit zu deklarieren. In diesem Fall erhält die Variable Empty als Initialisierungswert. Man kann einer Variant-Variablen auch den Wert Null zuweisen, was üblicherweise signalisiert, dass die Variable absichtlich keinen gültigen Wert enthält. Bei Zuweisung eines typgebundenen Werts speichert die Variable nicht nur den Wert an sich, sondern auch seinen Typ. Man spricht in diesem Zusammenhang vom Untertyp eines
50
Die Datentypen Integer,
Long,
Single und Double
Die Datentypen Integer, Long, Single und Double Die Datentypen Integer und Long setzt man üblicherweise für Zählvariablen, Indizierungen oder Berechnungen im Bereich der Ganzzahlarithmetik ein. Sie unterscheiden sich von einander allein durch ihren Wertebereich. Single und Double eignen sich dagegen speziell für die Darstellung gebrochen-rationaler Werte (lies: Dezimalzahlen mit Nachkommaanteil). Die zugehörige Gleitkommaarithmetik entspricht der üblichen Dezimalrechnung mit Rundung auf eine feste Anzahl von Dezimalstellen. Das bedingt, dass benachbarte Werte in den jeweiligen Wertebereichen keinen festen Abstand zueinander aufweisen (der bei den Datentypen Integer und Long ja 1 ist), sondern ihren Abstand mit wachsendem Betrag vergrößern (bzw. gegen 0 hin verkleinern). Double weist gegenüber Single die doppelte Genauigkeit sowie einen erheblich größeren Wertebereich auf. Visual Basic initialisiert diese Datentypen mit dem Wert 0 bzw. 0,0. ' Vollständige Deklaration Const cDelta As Double = 2.71364234E-123 Dim iGanzzahl As Integer Dim lGanzzahl As Long Dim sFlKommazahl As Single Dim dFlKommazahl As Double ' Deklaration mit Typkennzeichen Const ci# = 1.2 Dim i% Dim l&
51
Elementare Datentypen
Variant-Werts. Um die Sonderwerte abzufragen, lassen sich die eigens dafür definierten Boolean-Funktionen IsEmpty, IsError und IsNull verwenden – ein expliziter Vergleich mit den Werten Empty, Nothing, Null und Error tut es natürlich auch. Bei der Operation mit typgebundenen Werten kann es passieren, dass der Wertebereich des aktuellen Untertyps einer Variant-Variablen für die Darstellung eines Wert nicht mehr ausreicht. In diesem Fall nimmt Visual Basic eine implizite Typumwandlung im Sinne einer Wertebereichserweiterung vor. Implizite Typumwandlungen finden auch statt, wenn ein VariantWert mit numerischem Untertyp einer String-Variable oder ein Variant-Wert mit Untertyp String einer Variable mit numerischem Typ zugewiesen werden soll. Im ersten Fall wandelt Visual Basic den Variant-Wert in eine adäquate Zeichendarstellung um und im zweiten Fall in eine adäquate numerische Darstellung. Der Sonderwert Error in einer Variablen vom Datentyp Variant ist dafür vorgesehen, in Prozeduren erkannte Fehlerbedingungen anzuzeigen, wenn keine On Error-Fehlerbehandlung durch die Anwendung stattfindet. In diesem Fall muss die rufende Prozedur selbst den Fehler auswerten und nötige Maßnahmen ergreifen. Gesetzt wird der Sonderwert gewöhnlich mittels der Funktion CVErr, die eine Fehlernummer entgegennimmt und einen entsprechenden Error-Wert vom Typ Variant liefert. Trägt ein Variant-Wert den Untertyp Object, drückt der Wert Nothing aus, dass auf kein Objekt referiert wird. Um in Erfahrung zu bringen, ob ein Variant-Wert den Untertyp Object trägt, lässt sich die Boolean-Funktion IsObject verwenden. Nach all dem dürfte offensichtlich sein, welch enorme Flexibilität der Datentyp Variant mit sich bringt und wie sehr er die Programmierung vereinfachen kann, indem er die Typenvielfalt auf einen einzigen Datentyp zurückführt. Allerdings verhält es sich bei der Programmierung mit diesem Datentyp anders als im richtigen Leben: Hier sollten die einfachen Dinge eher den Profis vorbehalten bleiben. Ungeübten Programmierern mit einem noch nicht vollständig ausgeprägten Verständnis für die elementaren Datentypen spielt das verborgene Wirken von Visual Basic gerne mal den einen oder anderen Streich.
Elementare Datentypen
Dim s! Dim d# For n% = 1 to 100
' Deklaration mit Typkennzeichen durch Nennung
Elementare Datentypen
Die Datentypen Boolean und Byte Der mit Visual Basic neu zu Basic hinzugekommene Datentyp Boolean weist einen sehr kleinen Wertebereich auf, nämlich nur die als Konstanten vordefinierten Wahrheitswerte True und False. In Basic entspricht der Wahrheitswert True traditionell dem Wert -1 und False dem Wert 0. Bei Typumwandlungen in den Datentyp Boolean wird jeder Wert ungleich 0 als True interpretiert und nur der Wert 0 als False. Boolean leistet vornehmlich in Kontrollstrukturen für die Programmsteuerung sowie bei der Berechnung logischer Funktionen auf Grundlage der Booleschen Algebra gute Dienste. Visual Basic initialisiert Variablen vom Typ Boolean mit False. Dim bLogValue As Boolean bLogValue = True ... If bLogValue Then ... End If
Gleichfalls ein neues Mitglied im Club ist der Datentyp Byte. Er dient insbesondere dem Umgang mit binären Inhalten, denen keine feste Interpretation zukommt. (Traditionell wurden für Inhalte dieser Art Zeichenfolgen benutzt.) Dieser Datentyp wird zwar noch als numerischer Datentyp gehandelt, das heißt, er wird mit 0 initialisiert, und man kann mit ihm ganz normal rechnen, solange der Wertebereich nicht überschritten wird. Er ist aber als einziger vorzeichenlos. Dim MyByte(256) As Byte ... For i = 0 to 255 Print #1, MyByte(i); Next i
Die Datentypen Currency und Date Der eng mit den ganzzahligen Typen Integer und Long verwandte Datentyp Currency wurde speziell zur Erleichterung finanzmathematischer Berechnungen mit in die elementaren Datentypen aufgenommen. Die Werte in seinem Wertebereich sind ein ganzzahliges Vielfaches von 0,0001. Damit stellt der Datentyp noch vier Stellen hinter dem Komma dar und seine Arithmetik entspricht der üblichen Dezimalrechnung mit Kaufmannsrundung an der vierten Stelle hinter dem Komma. Visual Basic initialisiert Currency-Variablen mit 0,0000. Interessanter ist der gleichfalls neue Datentyp Date, der nicht zuletzt im Schatten des Jahr-2000Problems eine ebenso zweifelhafte wie steile Karriere hinter sich hat. Visual Basic repräsentiert Werte dieses Typs als 64-Bit-Gleitkommazahlen (8 Bytes) nach IEEE und kann somit Datumsangaben im Bereich zwischen dem 1. Januar 100 und dem 31. Dezember 9999 sowie Uhrzeiten im Bereich von 0:00:00 bis 23:59:59 unterscheiden. Sie können mit diesem Datentyp Datumsangaben und Zeitangaben in Kombination, aber auch einzeln als Werte darstellen. Der Notation literaler Datums- und Zeitangaben liegt das amerikanische Format zugrunde, das heißt, in Datumsangaben wird der Monat vor dem Tag notiert und die Abtrennung erfolgt durch das Zeichen »/«, während Zeitangaben in 12-Stunden-Darstellung gefolgt von »PM« oder »AM« zu treffen sind. Zudem ist die Darstellung durch ein führendes und abschließendes Zeichen »#« einzuschließen. (Der Editor erkennt übrigens auch andere Darstellungen, so etwa #1 Feb 99#, und korrigiert diese beflissen in das erwünschte Format.)
52
Der Datentyp Decimal
Dim a = b = c =
a As Date, b As Date, c As Date #2/1/1996 1:12:01 PM# #12:01:00 PM# #2/1/1996#
Der Datentyp Decimal Der gleichfalls neue Datentyp Decimal ist kein eigenständiger Datentyp, sondern kann nur als Untertyp eines Variant-Werts auftreten. Um einen Wert dieses Typs zu erzeugen, bedarf es der Typumwandlungsfunktion CDec. Dim vDez1 vDez1 = CDec(100.00000021)
' aus Double erzeugt
Werte vom Typ Decimal haben eine 29-stellige dezimale Repräsentation mit Komma ohne Exponent im BCD-Code. Den Typen Single und Double liegt dagegen eine binäre Repräsentation zugrunde, die nicht mehr als 8 bzw. 15 dezimale Stellen erfasst. Um Decimal-Werte mit mehr als 15 Stellen (mehr erlaubt der Datentyp Double nicht) noch direkt definieren zu können, ist der Funktion CDec eine entsprechende Zeichenfolgendarstellung des Werts zu übergeben. Beachten Sie, dass dabei die auf dem jeweiligen System geltenden Ländereinstellungen eine Rolle spielen. So legt die Einstellung Deutsch (Standard) als Dezimalzeichen ein Komma fest. Dim vDez2 vDez2 = CDec("100,000000000000000021")
' aus String erzeugt
Warnung
................................................... Wa rnung
Visual Basic vereinbart jede Variable standardmäßig als Variant, wenn sie nicht explizit im Rahmen einer Variablendeklaration oder implizit durch eine DefType-Anweisung bzw. durch eines der traditionellen Typkennzeichen von Basic ($, %, &, !, #) eine feste Typzuweisung erfährt. Tipp
................................................... Tipp
Beobachten Sie bei der Fehlersuche in Programmen besonders Werte vom Typ Variant, insbesondere wenn Seltsames und Absurdes mit im Spiel zu sein scheint. Entlaufene Variant-Werte waren schon Ursache so manchen Übels. Vereinbaren Sie Variablen besser explizit, um einen bestimmten Datentypen zu erzwingen, das verbessert die Übersicht. Wenn Sie das Tippen länglicher Typdeklarationen scheuen, verwenden Sie doch DefType oder die Typkennzeichen ($, %, &, !, #). Oft entlarvt eine Option Explicit-Anweisung den Übeltäter bereits. Verwandte Befehle
................................................... Verwa ndte Befehle
Dim, Public, Private, Function, DefType Verwandte Themen
................................................... Verwandte Them en
Literale und Konstanten (S. 27); Typumwandlung (S. 57); Typkennzeichen und Bezeichnerbereiche für Typen (S. 167); Variablendeklaration (S. 162)
53
Elementare Datentypen
Beim Umwandeln anderer numerischer Datentypen in Werte des Datentyps Date repräsentieren die Vorkommastellen das Datum und die Nachkommastellen die Uhrzeit. Mitternacht entspricht dem Wert 0,0 und 12 Uhr Mittags dem Wert 0,5. Negative ganze Zahlen repräsentieren ein Datum vor dem 30. Dezember 1899, positive ein Datum nach dem 30. Dezember 1899. Den 30. Dezember 1899 selbst kennt Visual Basic dagegen überhaupt nicht, sondern interpretiert ihn als #12:00:00 AM#.
Operatoren für elementare Datentypen und logische Bedingungen
Operatoren für elementare Datentypen und logische Bedingungen +, –, *, /, \, MOD, ^, Not, And, Or, Xor, Eqv, Imp, , =, >=,
a > b
Logische Bedingung: »größer als« (bei Zeichenfolgen von Option Compare abhängig)
Numerische Werte, logische Werte, Zeichenfolgen, Datums-/Zeitwerte
= b
Logische Bedingung: »größer Numerische Werte, logische Werte, gleich« (bei Zeichenfolgen: von Zeichenfolgen, Datums-/Zeitwerte Option Compare abhängig)
a b
Logische Bedingung: »ungleich«
Numerische Werte, logische Werte, Zeichenfolgen, Datums-/Zeitwerte
Is TypeOf
a Is b TypeOf a Is b
Testet, ob Operanden auf gleiches Objekt verweisen bzw. gleichen Objekttyp tragen
Objektvariablen
Operationen der elementaren Datentypen
Arrays Dim StatArray({iDimension1 | Untergrenze1 To Obergrenze1}[, _ {Dimension2 | Untergrenze2 To Obergrenze2}[, _ ... {DimensionN | Untergrenze2 To Obergrenze2}]]) _ [As Typ] Dim DynArray() [As Typ] ReDim [Preserve] DynArray [As Typ] Function Array([Wert1[, Wert2[, ... WertN]]]) As Variant Function UBound(Array[, iDimension As Integer = 1]) As Long Function LBound(Array[, iDimension As Integer = 1]) As Long Function IsArray(Var) As Boolean Option Base {0 | 1}
55
Arrays
Operator
Arrays
Beschreibung
Arrays
................................................... Bes c hreibung
Ein Array stellt eine ein- oder mehrdimensionale Struktur dar, die eine Menge von Werten gleichen Typs unter einem gemeinsamen Variablenbezeichner zusammenfasst. Visual Basic unterscheidet zwischen statischen und dynamischen Arrays. Die (endgültige) Deklaration statischer Arrays erfolgt im Rahmen einer Dim-Anweisung. Für die Deklaration sind neben dem Array-Bezeichner StatArray auch ein oder mehrere Indexbereiche anzugeben – je nachdem, wie viele Dimensionen das Array besitzt – sowie optional ein Elementtyp Typ. Wird ein Indexbereich durch Nennung einer Obergrenze iDimensionN angegeben, beginnt die Zählung der Array-Elemente standardmäßig bei 0 (Option Base 0 ist die Voreinstellung von Visual Basic), es sei denn, das betreffende Modul enthält die Anweisung Option Base 1. Es lassen sich aber auch Indexbereiche mit beliebigen Grenzen durch explizite Nennung unterer und oberer Grenzen (UntergrenzeN To ObergrenzeN) vereinbaren. Die formale Deklaration eines dynamischen Arrays kann durch Vereinbarung einer Array-Variablen im Rahmen einer Dim-Anweisung geschehen, muss aber nicht. Dabei notiert man den Bezeichner DynArray gefolgt von einem leeren Klammerpaar und vereinbart optional einen Elementdatentyp. Die konkrete Definition kann dann an passender Stelle vermittels der ReDimAnweisung unter Angabe von Dimensionen und Array-Grenzen geschehen – auch mehrmals mit unterschiedlichen Grenzen und Dimensionen, aber gleichem Datentyp. ReDim eignet sich auch zur Vergrößerung eines bereits definierten dynamischen Arrays unter Beibehaltung der Dimensionen und Elementwerte. In diesem Fall muss das Schlüsselwort Preserve angegeben werden. Der Zugriff auf den Wert eines Array-Elements erfolgt durch Angabe des Array-Bezeichners gefolgt von einem Index oder einer Indexliste (bei mehrdimensionalen) Arrays in Klammern). Anwendung
................................................... Anwendung
Arrays eignen sich hervorragend zur Verwaltung großer Mengen von gleichartigen, aber auch ungleichartigen (wenn als Datentyp Variant vereinbart wird) Daten, auf die ein effizienter indexsequenzieller Zugriff erfolgen soll. Seien es Matrixelemente bei der numerischen Vektorrechnung, Messwerte, Adressenstämme, Datensätze oder auch Ansammlungen gleichartiger Steuerelemente, die Array-Struktur bietet sich hervorragend für die einfache und schnelle Handhabung von variablen Werten an. Als Elementtyp für Arrays sind alle elementaren und komplexen Datentypen erlaubt, insbesondere auch benutzerdefinierte Datentypen, Objekte und der Typ Variant. Da ein Wert vom Typ Variant seinerseits ein Array sein kann, sind also auch implizit verschachtelte Arrays mit individueller Tiefe je Element möglich. Eine Array-Variable lässt sich wie eine gewöhnliche Variable verwenden – sie erhält ihren »Wert« durch Zuweisung oder durch (partielle) Initialisierung im Zuge einer ReDim-Anweisung. Im Gegensatz zu anderen Programmiersprachen (vgl. C/C++) beschränkt sich Visual Basic bei der Zuweisung eines Arrays an eine Array-Variable nicht auf eine reine Adresszuweisung, sondern erstellt eine physikalische Kopie des gesamten Arrays, wie folgender Code beweist: Dim a(0), b() a(0) = 10 b = a a(0) = 11 Print b(0), a(0)
' Ausgabe: 10
11
Diese Aussage ist allerdings mit Vorsicht zu genießen, sie gilt nämlich nur, wenn die Elemente einfache Datentypen tragen. Von Objekten fertigt Visual Basic keine Kopien an. Das liegt daran, dass der Wert einer Objektvariablen einen Verweis auf das tatsächliche Objekt darstellt und die einfache Zuweisungsoperation (im Gegensatz zur Set-Anweisung) sich auf eine Kopie des Verweises beschränkt, wie folgender Code zeigt:
56
Typumwandlung
Dim a(0) As Object, b() As Object Set a(0) = Me ' Formular wird zugewiesen b = a b(0).Caption = "Dieser " a(0).Caption = "oder jener?" Print b(0).Caption ' Ausgabe: "oder jener?"
Array- Funktionen
Beispiel
................................................... Beis piel
Dim StatArray(-10 To 10, -10 To 10) As Integer ' statisch, zweidim. Dim DynArray() As String ' dynam. deklarieren ... Redim DynArray(10) As String ' dynam. definieren ... Redim Preserve DynArray(UBound(DynArray) + 1) As String 'erweitern Verwandte Themen
................................................... Verwandte Them en
Auflistungen und Collection-Objekte (S. 304); Get-Anweisung (S. 140); Elementare Datentypen (S. 49)
Typumwandlung Function CBool(Ausdruck) As Boolean Function CByte(Ausdruck) As Byte Function CCur(Ausdruck) As Currency Function CDate(Ausdruck) As Date Function CDbl(Ausdruck) As Double Function CDec(Ausdruck) As Decimal Function CInt(Ausdruck) As Integer
57
Typumwandlung
Visual Basic unterstützt Array-Konstanten ebenso wenig wie literale Arrays. Während bei statischen Arrays die Wertzuweisung elementweise erfolgen muss, kann im Falle von dynamischen Arrays eine Zuweisung auch auf Array-Ebene erfolgen. Das macht ein kompakte Initialisierung mittels der Array-Funktion möglich, die ihre als Aufrufparameter übergebene Werteliste als Array zurückliefert. Um die obere bzw. untere Indexgrenze eines Arrays in Erfahrung zu bringen, gibt es die Funktionen UBound bzw. LBound. Falls das Array mehr als eine Dimension besitzt, lässt sich die Dimension als Wert iDimension spezifizieren (die Zählung beginnt bei 1). Variablen des Typs Variant können bekanntlich Werte verschiedenster Datentypen annehmen, darunter auch Arrays. Die Funktion IsArray liefert eine Aussage in Form eines Wahrheitswerts darüber, ob es sich bei einer Variablen um eine Array-Variable handelt oder nicht. Leider kennt Visual Basic keine Funktion, die den kompletten Speicherbedarf für das Speichern eines Arrays ermittelt. Dieser Wert muss vielmehr aus dem Elementdatentyp, der Dimensionenzahl, der Dimensionsgrenzen und gegebenenfalls mitzuspeichernder Deskriptoren »zu Fuß« errechnet werden (vgl. »Get-Anweisung«, S. 140), da Arrays in den unterschiedlichen Dateimodi unterschiedlich repräsentiert werden.
Typumwandlung
Function CLng(Ausdruck) As Long Function CSng(Ausdruck) As Single Function CVar(Ausdruck) As Variant Function CVDate(Ausdruck) As Variant Function CStr(Ausdruck) As String Function IsDate(Ausdruck) As Variant
Typumwandlung
Function IsNumeric (Ausdruck) As Boolean Beschreibung
................................................... Bes c hreibung
Die explizite Typumwandlung wird bei Visual Basic zwar nicht so groß geschrieben wie bei manch anderer Programmiersprache, da der Visual Basic Compiler von sich aus implizite Typanpassungen nach Bedarf vornimmt, vermeidbar ist sie aber nicht in allen Fällen. Die folgende Tabelle gibt einen Überblick über die auf die einzelnen Datentypen zugeschnittenen Konvertierungs- und Typumwandlungsfunktionen. Funktion
Beschreibung
CBool
Konvertiert Ausdruck nach Möglichkeit (bei Zeichenfolgen ohne Unterscheidung der Großschreibung) in einen Wert vom Typ Boolean; Interpretiert die Zeichenfolgen "Wahr", "True" sowie numerische Werte ungleich 0 als True und die Zeichenfolgen "Falsch", "False" sowie den Wert 0 als False. Bei anderen Zeichenfolgen liefert die Funktion einen Laufzeitfehler.
CByte
Liefert Ausdruck als Wert vom Typ Byte. Fließkommawerte mit einem Nachkommaanteil von exakt 0,5 werden zur nächsten geraden Zahl hin gerundet (0,5 wird zu 0 und 1,5 zu 2), ansonsten gilt die Kaufmannsrundung. Liegt der Wert von Ausdruck nicht im Bereich zwischen 0 und 255 oder ist Ausdruck von Typ String, löst die Funktion einen Laufzeitfehler aus.
CCur
Liefert Ausdruck als Wert vom Typ Currency. Rundet numerische Werte auf vier Stellen hinter dem Komma und interpretiert Zeichenfolgen im gebietsspezifischen Währungsformat. Für das Gebietsschema »Deutsch (Standard)« gilt: Komma ist Dezimalzeichen, Punkt ist Tausendertrennzeichen, »DM« als führendes oder nachgestelltes Währungssymbol ist erlaubt, sonstige nicht zur Notation von Zahlenliteralen gehörende Zeichen führen zu einem Laufzeitfehler. Der zulässige Wertebereich für Ausdruck geht von -922.337.203.685.477,5808 bis 922.337.203.685.477,5807.
CDate
Liefert Ausdruck als Wert vom Typ Date. Interpretiert numerische Werte und Zeichenfolgen als Zeit-/Datumswert. Bei numerischen Werten ist ein Vorkommaanteil zwischen -657.434 und 2.958.465 zulässig – er wird als Tage-Offset bezogen auf das Datum 1.1.1899 interpretiert – und ein Nachkommaanteil von nicht mehr als sechs Stellen – er wird als Sekunden-Offset bezogen auf das Datum interpretiert. Bei der Interpretation von Zeichenfolgen erkennt die Funktion das kurze, mittlere oder lange gebietsspezifische Datumsformat (das lange Datumsformat jedoch nur, wenn kein Wochentag notiert ist). Die Funktion IsDate erlaubt eine Vorabprüfung, ob ein gegebener Wert in einen Zeit-/Datumswert wandelbar ist.
Konvertierungs- und Typumwandlungsfunktionen
58
Typumwandlung
Beschreibung
CDbl
Liefert Ausdruck als Wert vom Typ Double. Bei der Konvertierung aus Decimal und Currency werden nicht darstellbare Stellen gegebenenfalls gerundet, alle anderen numerischen Datentypen lassen sich ohne Genauigkeitsverlust überführen. Bei der Konvertierung von Zeichenfolgen erwartet die Funktion das gebietsspezifische Zahlenformat. Für das Gebietsschema »Deutsch (Standard)« gilt: Komma ist Dezimalzeichen, Punkt ist Tausendertrennzeichen. Der Wertebereich geht von -1,79769313486232E308 bis -4,94065645841247E-324 für negative Werte und von 4,94065645841247E-324 bis 1,79769313486232E308 für positive Werte.
CDec
Liefert Ausdruck als Wert vom Typ Decimal, der jedoch (ohne erneute Typumwandlung) nur Variablen des Typs Variant zugewiesen werden kann. Bei der Konvertierung von Zeichenfolgen erwartet die Funktion das gebietsspezifische Zahlenformat. Für das Gebietsschema »Deutsch (Standard)« gilt: Komma ist Dezimalzeichen, Punkt ist Tausendertrennzeichen. Der Wert selbst darf im Bereich ±79.228.162.514.264.337.593.543.950.335 liegen, wobei das Komma fließen darf.
CInt
Liefert Ausdruck als Ganzzahlwert vom Typ Integer. Fließkommawerte mit einem Nachkommaanteil von exakt 0,5 werden zur nächsten geraden Zahl hin gerundet (0,5 wird zu 0 und 1,5 zu 2) ansonsten gilt die Kaufmannsrundung. Der Wertebereich geht von -32.768 bis 32.767.
CLng
Liefert Ausdruck als Ganzzahlwert vom Typ Long. Fließkommawerte mit einem Nachkommaanteil von exakt 0,5 werden zur nächsten geraden Zahl hin gerundet (0,5 wird zu 0 und 1,5 zu 2), ansonsten gilt die Kaufmannsrundung. Der Wertebereich geht von -2.147.483.648 bis 2.147.483.647.
CSng
Liefert Ausdruck als Wert vom Typ Single. Bei der Konvertierung aus Double, Decimal und Currency werden nicht darstellbare Stellen gegebenenfalls gerundet, alle anderen numerischen Datentypen lassen sich ohne Genauigkeitsverlust überführen. Bei der Konvertierung von Zeichenfolgen erwartet die Funktion das gebietsspezifische Zahlenformat. Für das Gebietsschema »Deutsch (Standard)« gilt: Komma ist Dezimalzeichen, Punkt ist Tausendertrennzeichen. Der Wertebereich geht von -1,79769313486232E308 bis -4,94065645841247E-324 für negative Werte und von 4,94065645841247E-324 bis 1,79769313486232E308 für positive Werte.
CVar
Konvertiert numerische Werte in den Untertyp Double (vgl. CDbl) und alle anderen in den Untertyp String
CVDate
Konvertiert einen numerischen Wert oder eine Zeichenfolge Ausdruck in das von älteren Visual-Basic-Versionen benutzte Datumsformat Variant mit Untertyp Date. Da Date inzwischen als elementarer Datentyp verfügbar ist, dient diese Funktion nur noch dem Erhalt der Kompatibilität mit älteren Programmen. Dieselbe Funktionalität ergibt sich auch implizit, wenn der Funktionswert eines CDate-Aufrufs einer Variablen vom Typ Variant zugewiesen wird. Umgekehrt lässt sich aufgrund der impliziten Typanpassung des Compilers auch der Funktionswert eines CVDate-Aufrufs einer Variablen vom Typ Date zuweisen, so dass zwischen CDate und CVDate praktisch gesehen kein Unterschied besteht.
Konvertierungs- und Typumwandlungsfunktionen
59
Typumwandlung
Funktion
Benutzerdefinierte Datentypen
Benutzerdefinierte Datentypen
Funktion
Beschreibung
CStr
Liefert literale Darstellung von Ausdruck als Zeichenfolge im gebietsspezifischen Format. Wahrheitswerte erscheinen als "Wahr" und "Falsch", numerische Werte ohne Tausendertrennzeichen jedoch mit Komma als Dezimalzeichen und erforderlichenfalls in Fließkommanotation mit Exponentenanteil. Der Wert Empty entspricht der leeren Zeichenfolge, während Null einen Laufzeitfehler auslöst. Datumswerte erhalten das für das Gebietsschema geltende kurze Datumsformat. Die literale Darstellung eines Objekts ist die seiner Standardeigenschaft – so liefert CStr(Err) die zuletzt gesetzte Fehlernummer Err.Number.
Konvertierungs- und Typumwandlungsfunktionen Anwendung
................................................... Anwendung
Wer viel mit dem flexiblen Datentyp Variant arbeitet oder von einer streng typisierenden Programmiersprache her kommt, wird in so manchem Fall die Typumwandlungsfunktionen von Visual Basic zu schätzen wissen. Obwohl der Visual-Basic-Compiler weitgehend tolerant ist, was die implizite Typanpassung bei der Zuweisung, der Parameterübergabe und der Ausdrucksberechnung betrifft, lässt sich die Flexibilität im Miteinander von Datentypen durch explizite Typumwandlungen noch weiter verbessern, insbesondere wenn die länderspezifische Darstellung entlang des in der Systemsteuerung eingestellten Gebietsschemas bei der Umwandlung aus Zeichenfolgen ins Spiel kommt. So ist beispielsweise die explizite Typumwandlung in Visual Basic 6.0 der einzige Weg, um Werte des nur als Untertyp von Variant existierenden Datentyps Decimal zu generieren, denn eine Deklaration mit diesem vergleichsweise neuen Datentyp ist in der Version 6.0 noch nicht möglich. Auch greift der Compiler nur dann zum Mittel der impliziten Typumwandlung, wenn eine Verengung oder Erweiterung des gegebenen Typs unvermeidbar ist. Tipps
................................................... Tipps Um festzustellen, ob ein Wert als Zahl ausgewertet werden kann, steht die Boolean-Funktion IsNumeric zur Verfügung. Die Typumwandlung von einem benutzerdefinierten Typ in einen elementaren Typ ist nicht so ohne Weiteres möglich. Einen Schleichweg eröffnet jedoch die LSet-Anweisung (vgl. S. 80). Verwandte Befehle
................................................... Verwa ndte Befehle
Asc, Chr, ChrB, Date, DateSerial, Fix, Format, FormatCurrency, FormatDateTime, FormatNumber, FormatPercent, Int, Round, Str, StrConv Time, TimeSerial, Val Verwandte Themen
................................................... Verwandte Them en
Elementare Datentypen (S. 49)
Benutzerdefinierte Datentypen Visual Basic kennt drei verschiedene Arten von benutzerdefinierten Datentypen: in TypeKonstrukten vereinbarte Datenstrukturen; in Enum-Konstrukten vereinbarte Aufzählungsdatentypen; in Klassenmodulen definierte Klassen (Objektdatentypen). Letztere werden ausführlicher im objektorientierten Teil vorgestellt, wenn es um »Selbst definierte Klassen« (S. 318) geht. Ein Vergleich zwischen Type-Datentypen und Objektdatentypen findet sich in der Tabelle auf Seite 197.
60
Type- Datentypen
Type- Datentypen {Private | [Public]} Type BDT ElementName [([Indizes])] As Typ [ElementName1 [([Indizes])] As Typ] ... End Type With bdtVar .ElementName = Wert End With
................................................... Bes c hreibung
Die Type-Struktur ermöglicht die Definition eines eigenen Datentyps BDT, der aus Elementen ElementName bereits bekannter Datentypen zusammengesetzt ist. Die Private-Vereinbarung des Datentyps ist für beliebige Modularten auf Modulebene möglich und beschränkt den Geltungsbereich der Definition auf das jeweilige Modul. Fehlt der Spezifizierer Private, behandelt der Compiler die Definition als Public-Vereinbarung, die jedoch nur in einem Standardmodul zulässig ist. Ein Public-Datentyp ist in allen Modulen des gegebenen Projekts sowie in allen Projekten einer gegebenenfalls existierenden Projektgruppierung bekannt. Anwendung
................................................... Anwendung
Im Gegensatz zu älteren Basic-Versionen sind in Visual Basic statische und dynamische Arrays als Feldelemente für benutzerdefinierte Datentypen ebenso zulässig wie Objektvariablen. Auch einer Verschachtelung benutzerdefinierter Datentypen durch Verwendung bereits definierter Datentypen als Feldtyp steht nichts im Wege. Die Vereinbarung eines benutzerdefinierten Datentyps BDT für eine Variable weist formal keine Besonderheiten gegenüber der Vereinbarung eines elementaren Datentyps auf. Der einzige Unterschied zu den vordefinierten Datentypen von Visual Basic besteht darin, dass die PublicVereinbarung von Variablen benutzerdefinierter Typen nur in einem Standardmodul erfolgen darf, während in allen anderen Modularten eine Private-Deklaration erforderlich ist. An Operationen für benutzerdefinierte Datentypen gibt es nur den Punktoperator und den Zuweisungsoperator. Der Punktoperator ermöglicht den Zugriff auf die einzelnen Felder des benutzerdefinierten Datentyps für die Arbeit mit einzelnen Feldwerten nach dem Schema Var.Feld. Der Zuweisungsoperator ermöglicht die Zuweisung eines Werts mit einem benutzerdefinierten Datentyp an eine Variable gleichen Typs. Dabei kopiert Visual Basic alle Feldwerte en bloc, selbst wenn Arrays mit im Spiel sind. Zur Vereinfachung der Notation beim Zugriff auf Elementwerte eines benutzerdefinierten Datentyps (aber auch auf Eigenschaften und Methoden von Objekten, mit Ausnahme von Print, Circle und Line) kann die With-Struktur benutzt werden. Dabei führt die With-Anweisung den genannten Bezeichner als Qualifizierungskontext ein. Innerhalb eines Moduls benutzt Visual Basic von sich den Modulbezeichner als Qualifizierungskontext. Mit jeder With-Anweisung (Verschachtelung ist erlaubt) verengt sich der bestehende Qualifizierungskontext. Warnung
................................................... Wa rnung
Vom Prinzip her besteht zwar die Möglichkeit, LSet-Zuweisungen zwischen benutzerdefinierten Datentypen mit unterschiedlichen Strukturen vorzunehmen, von einem Gebrauch dieses Hintertürchens ist aber generell eher abzuraten, da dabei unvorhergesehene Effekte auftreten können (vgl. »LSet-Anweisung«, S. 80).
61
Benutzerdefinierte Datentypen
Beschreibung
Benutzerdefinierte Datentypen
Tipp
................................................... Tipp
Anstelle benutzerdefinierter Datentypen können Sie eigene Datentypen auch über Klassenmodule implementieren. Der dahinter stehende objektorientierte Ansatz verschmilzt das Konzept des benutzerdefinierten Datentyps mit den zu dem Datentyp gehörigen Manipulationsoperationen und bietet somit den Vorteil der Datenabstraktion. Beispiel
Benutzerdefinierte Datentypen
................................................... Beis piel
' Bereich (Allgemein) eines Moduls Private Type BDT lFeld As Long sFeld As String lDynArray() As Long sStatArray(10) As String End Type ... Dim bdtVar1 As BDT, bdtVar1 As BDT ... bdtVar1.lFeld = 10 ' numerischen Wert zuweisen bdtVar1.sFeld = "Wert des String-Feldes" ' Zeichenfolge zuweisen ReDim bdtVar1.lDynArray(10) As Long ' dyn. Array dimensionieren bdtVar2 = bdtVar1 ' Struktur en bloc zuweisen ' Schreibweise bei Qualifizierung mit With With bdtVar1 .lFeld = 10 ' numerischen Wert zuweisen .sFeld = "Wert des String-Feldes" ' Zeichenfolge zuweisen ReDim .lDynArray(10) As Long ' dyn. Array dimensionieren End With bdtVar2 = bdtVar1 ' Struktur en bloc zuweisen Verwandte Befehle
................................................... Verwa ndte Befehle
LSet Verwandte Themen
................................................... Verwandte Them en
Elementare Datentypen (S. 49); Routinen aus DLLs und der Windows-API einsetzen (S. 185); Objekte und Klassen (S. 195); Klassen als Datentypen für Objektvariablen (S. 196)
Enum- Aufzählungen {Private | [Public]} Enum MeineAufzählung Element1 = LiteralerWert1 [Element2 = LiteralerWert2] ... End Enum Beschreibung
................................................... Bes c hreibung
Eine Enum-Aufzählung ist eine Sammlung von Konstanten des Typs Long, die formal in einem Aufzählungsdatentyp zusammengefasst sind. Die einzelnen Konstanten sind jedoch auch jede für sich im Rahmen des jeweiligen Geltungsbereichs bekannt. Ein Aufzählungsdatentyp lässt
62
Funktionen und Anweisungen für Zeichenfolgen
sich wie jeder andere Datentyp für die Vereinbarung von Variablen, Parametern und Funktionswerten heranziehen, eine Überprüfung auf Einhaltung des über die Aufzählung definierten Wertebereichs findet jedoch nicht statt; auch unterscheidet der Compiler nicht zwischen unterschiedlichen Aufzählungsdatentypen, vielmehr behandelt er jeden Aufzählungsdatentyp als Long. Anwendung
................................................... Anwendung
Beispiel
................................................... Beis piel
Public Enum VbTest vbA1 = &H11111111 vbA2 = 101 vbA3 = 105 vbA4 = 103 vbA5 = 104 End Enum ... ' innerhalb einer Prozedur/Funktion Dim a As VbTest a = vbA3 Print TypeName(a) ' Ausgabe: "Long"
Funktionen und Anweisungen für Zeichenfolgen Der unkomplizierte Umgang mit Zeichenfolgen war schon immer die ureigenste Domäne der Programmiersprache Basic. Darüber hinaus hat sich die Ausstattung für die Manipulation von Zeichenfolgen mit jeder Neuauflage von Basic noch einmal verbessert, so dass dem Programmierer unter Visual Basic 6.0 ein ausgesprochen reichhaltiges Angebot an vordefinierten Funktionen und Anweisungen für die Arbeit mit Zeichenfolgen zur Verfügung steht. Während in früheren Versionen von Visual Basic so manche Zeichenfolgenfunktion in zwei Varianten implementiert war – eine mit $-Suffix und eine ohne –, von denen diejenige mit $-Suffix »echte« Zeichenfolgen lieferte und diejenige ohne $-Suffix Werte des Typs Variant, unterstützt Visual Basic 6.0 die Varianten mit $-Suffix zwar noch zur Wahrung der Kompatibilität, kommt aber grundsätzlich ohne sie aus. Beschreibung
................................................... Bes c hreibung
Seit Einführung der 32-Bit-Version mit Visual Basic 4.0 legt Visual Basic intern allen Zeichenfolgen die Unicode-Darstellung zugrunde. Im Gegensatz zu dem bis dahin verwendeten ANSICode, der zur Repräsentation eines Zeichens gerade mal ein Byte vorsieht (und somit nicht mehr als 256 Zeichen unterscheiden kann), umfasst die Repräsentation eines Zeichens im Unicode zwei Bytes. In Unicode gibt es daher bis zu 65.535 unterschiedliche Zeichen, die von der
63
Funktionen und Anweisungen für Zeichenfolgen
Obwohl es möglich ist, Variablen zu vereinbaren, die einen Aufzählungsdatentyp tragen, und der Editor der Entwicklungsumgebung bei der Notation von Rechtswerten dieses Typs eine Liste mit den vereinbarten Konstanten einblendet, sind Aufzählungsdatentypen faktisch nichts weiter als eine Umbenennung des Datentyps Long und somit reine Fassade. Sie verwenden Aufzählungsdatentypen, um Konstanten zu gruppieren und Symbolvorräte formal als endliche Wertebereiche ausdrücken zu können. Ein Blick in den Objektkatalog (Taste (F2)) zeigt, dass Visual Basic in seinen Bibliotheken massiv von diesem Konzept Gebrauch macht.
Funktionen und Anweisungen für Zeichenfolgen
Funktionen und Anweisungen für Zeichenfolgen
ISO international festgelegt wurden. Zeichen mit Unicode kleiner als 256 entsprechen den Zeichen des ANSI-Codes, so dass beispielsweise das Zeichen »A« mit dem ANSI-Code 65 (oder &H40) in Unicode die Darstellung »0, 65« (oder &H0040) hat. Neben Unicode gibt es noch einen weiteren Zeichencode namens DBCS (Double-Byte Character Set), dessen Darstellung zwei Bytes je Zeichen vorsieht. Dieser Code ist in erster Linie im asiatischen Sprachraum verbreitet und dazu gedacht, die Vielfalt der in diesen Sprachen verwendeten Schriftzeichen ausdrücken zu können. Er hat weder etwas mit ANSI-Code noch mit Unicode gemeinsam, stellt also einen völlig eigenständigen Zeichensatz dar. All dies heißt für den Visual-Basic-Programmierer, dass er es potenziell mit allen drei, sicherlich jedoch mit zwei unterschiedlichen Repräsentationsarten für Zeichenfolgen zu tun bekommen kann – so etwa beim Lesen von Datensätzen aus Dateien mit älteren und neueren Datenformaten. Damit aber nicht genug: Es gilt auch systembedingte Unterschiede zu beachten, die sich aufgrund unterschiedlicher Versionen für Objektbibliotheken und Windows selbst einschleichen. Die folgende Tabelle zeigt eine Aufstellung, welche Umgebung mit welcher Zeichendarstellung einhergeht. Umgebung
Verwendete Zeichensätze
Windows-9x-API
ANSI und DBCS
16-Bit-Objektbibliotheken
ANSI und DBCS
Visual Basic
Unicode
32-Bit-Objektbibliotheken
Unicode
Windows-NT-API
Unicode
Automatisierung in Windows NT
Unicode
Automatisierung in Windows 9x
Unicode
Zeichendarstellung in verschiedenen Windows- Komponenten
Um den Programmierer gegen alle Fälle zu wappnen, unterhält Visual Basic daher für die traditionellen Zeichenfolgenfunktionen Asc, Chr, Len, InStr, Left, Right und Mid unterschiedliche Varianten, deren Funktionsweise spezifisch auf die eine oder andere Repräsentation ausgerichtet ist. Varianten mit Suffix B (so etwa AscB) gehen von einer ANSI-Darstellung und Varianten mit Suffix W (so etwa ChrW) von einer Unicode- oder DBCS-Darstellung aus. Die folgende Tabelle gibt eine Übersicht über die unter Visual Basic 6.0 verfügbaren Funktionen und Prozeduren, die im engeren oder weiteren Sinne etwas mit der Manipulation von Zeichenfolgen zu tun haben. Bezeichner
Kurzbeschreibung
Asc
Liefert den ANSI-Code des ersten Zeichens einer Zeichenfolge (auf DBCSSystemen DBCS-Code)
AscB
Liefert den ANSI-Code des ersten Bytes einer Zeichenfolge
AscW
Liefert den Unicode des ersten Doppel-Bytes einer Zeichenfolge
Chr
Liefert das zu einem ANSI-Code gehörige Unicode-Zeichen
ChrB
Liefert das zu einem ANSI-Code gehörige ANSI-Zeichen
ChrW
Liefert das zu einem Unicode gehörige Unicode-Zeichen
Zeichenfolgenfunktionen und - prozeduren von Visual Basic
64
Funktionen und Anweisungen für Zeichenfolgen
Kurzbeschreibung
Filter
Durchsucht alle Elemente eines Zeichenfolgen-Arrays nach einer bestimmten Zeichenfolge und liefert die Array-Elemente, in denen diese enthalten ist
Format
Liefert Zeichenfolgendarstellung eines Werts im spezifizierten Format
FormatCurreny
Liefert die Darstellung eines Währungswerts im spezifizierten Format
FormatDateTime
Liefert die Darstellung eines Datumswerts im spezifizierten Format
FormatNumber
Liefert die Darstellung eines Zahlenwerts im spezifizierten Format
FormatPercent
Liefert die Darstellung eines Prozentwerts im spezifizierten Format
Hex
Liefert die hexadezimale Notation eines Werts
InStr
Liefert die Startposition einer Zeichenfolge in einer anderen Zeichenfolge
InStrB
Liefert die Startposition einer ANSI-Zeichenfolge in einer anderen ANSIZeichenfolge
InStrRev
Wie InStr, beginnt die Suche aber von hinten
Join
Umkehrfunktion zu Split, setzt die Zeichenfolgen eines String-Arrays zu einer einzigen Zeichenfolge zusammen (Trennzeichen optional)
LCase
Liefert die Kopie einer Zeichenfolge in Kleinschreibung
Left
Liefert den linken Teil einer Zeichenfolge
LeftB
Liefert den linken Teil einer ANSI-Zeichenfolge
Len
Liefert die Anzahl der Zeichen in Zeichenfolge – trägt der im Parameter übergebene Wert nicht den Typ String, liefert die Funktion die Anzahl der zum Speichern dieses Werts erforderlichen Bytes.
LenB
Liefert die Anzahl der Bytes, die für die Darstellung des Werts (zum Beispiel bei Speichern) erforderlich sind; liefert damit auch die Länge einer ANSI-Zeichenfolge
LSet
Byteorientierte, linksbündige Zuweisungsoperation für beliebige Datentypen, ohne Längenanpassung des Linkswerts. Elementare Datentypen unterliegen einer Typüberprüfung, benutzerdefinierte nicht.
LTrim
Liefert eine Kopie der Zeichenfolge ohne führende Leerzeichen zurück
Mid
Liefert den mittleren Teil einer Zeichenfolge
Mid
Zuweisungsoperation für den mittleren Teil einer Zeichenfolge
MidB
Liefert den mittleren Teil einer Zeichenfolge als ANSI-Zeichenfolge
MidB
Zuweisungsoperation für mittleren Teil einer ANSI-Zeichenfolge
MonthName
Liefert für eine Zahl zwischen 1 und 12 den Monatsname als Zeichenfolge
Oct
Liefert die oktale Notation eines Werts
Option Compare
Standardvorgabe für Zeichenfolgenvergleiche auf binären Vergleich oder Textvergleich (ohne Beachtung der Großschreibung) setzen
Zeichenfolgenfunktionen und - prozeduren von Visual Basic
65
Funktionen und Anweisungen für Zeichenfolgen
Bezeichner
Funktionen und Anweisungen für Zeichenfolgen
Funktionen und Anweisungen für Zeichenfolgen
Bezeichner
Kurzbeschreibung
Partition
Liefert das Intervall, in das eine Zahl fällt, als Zahlenbereich der Form »IntervallAnf: IntervallEnde«. Der Aufruf der Funktion erfolgt unter Angabe eines Startwerts für das erste Intervall, eines Endwerts für das letzte Intervall und einer Intervallbreite.
Replace
Sucht Vorkommen einer Suchzeichenfolge in Zeichenfolge, ersetzt dieses gegen Ersatzzeichenfolge und liefert resultierende Zeichenfolge
Right
Liefert den rechten Teil einer Zeichenfolge
RightB
Liefert den rechten Teil einer ANSI-Zeichenfolge
RSet
Rechtsbündige Zuweisungsoperation für Zeichenfolgen ohne Längenänderung des Linkswerts; füllt mit Leerzeichen auf oder schneidet ab
RTrim
Liefert die Kopie einer Zeichenfolge ohne abschließende Leerzeichen
Space
Liefert eine Zeichenfolge mit der gewünschten Anzahl von Leerzeichen
Split
Umkehrfunktion zu Join, durchsucht eine Zeichenfolge nach Trennzeichen und liefert die Zeichenfolgenabschnitte als Array
Str
Liefert standardmäßige Repräsentation eines Zahlenwerts als Zeichenfolge
StrComp
Führt alphanumerischen Zeichenfolgenvergleich durch und unterscheidet dabei vier Fälle
StrConv
Konvertiert eine Zeichenfolge nach einem von sieben möglichen Konvertierungsschemata und liefert die konvertierte Version als Kopie
String
Liefert Zeichenfolge mit der gewünschten Anzahl eines einzelnen Zeichencodes
StrReverse
Liefert die Kopie einer Zeichenfolge mit verkehrter Reihenfolge der Zeichen
Trim
Liefert Zeichenfolge ohne führende und abschließende Leerzeichen
UCase
Liefert die Kopie einer Zeichenfolge in Großschreibung
Val
Liefert den Zahlenwert einer Zeichenfolge
WeekdayName
Liefert für eine Zahl zwischen 1 und 7 den Wochentag als Zeichenfolge
Zeichenfolgenfunktionen und - prozeduren von Visual Basic
................................................... Warnung
Warnung
Eine notorische Ursache für Ungereimtheiten im Programmverhalten ist die auf die länderspezifische Zahlendarstellung (Gebietseinstellungen des Systems) zurückzuführende Punkt-/KommaProblematik im Zusammenhang mit Zeichenfolgen. Wer mit Ländereinstellung »Deutsch (Standard)« auf seinem System einen Zahlenwert als literale Zeichenfolge spezifiziert, muss darauf achten, das Komma als echtes Komma zu schreiben, während in »echten« numerischen Literalen der Punkt als Dezimalsymbol notiert werden muss.
Asc- , AscB- und AscW- Funktion Function Asc (s As String) As Integer Function AscB (s As String) As Integer Function AscW (s As String) As Integer
66
Chr- ,
ChrB-
und ChrW - Funktion
Beschreibung
................................................... Bes c hreibung
Die Funktion Asc liefert den Code des ersten Zeichens der Zeichenfolge s entsprechend dem auf dem System geltenden Zeichensatz als Ganzzahl. Die beiden anderen Varianten der Funktion liefern (ohne Rücksicht auf den geltenden Zeichensatz) den ANSI-Code des ersten Bytes der Zeichenfolge (AscB) bzw. den Unicode des ersten Doppel-Bytes der Zeichenfolge (AscW). Beispiel
................................................... Beis piel
Die Funktion StrToHex wandelt eine Zeichenfolge beliebiger Länge byteweise in eine hexadezimale Repräsentation der Form "hh hh ..." um.
Funktionen und Anweisungen für Zeichenfolgen
' Funktion wandelt beliebig lange Byte-Strings in Hex-String um Function StrToHex(sByteString As String) As String Dim i As Integer, iByte As Integer Dim sLow As String, sHigh As String For i = 1 To LenB(sByteString) ' byteweise analysieren iByte = AscB(MidB(sByteString, i, 1)) If iByte \ 16 > 9 Then ' Ziffer oder Buchstabe? sHigh = Chr(iByte \ 16 + 55) ' Buchstabe Else sHigh = Chr(iByte \ 16 + 48) ' Ziffer End If If iByte Mod 16 > 9 Then sLow = Chr(iByte Mod 16 + 55) Else sLow = Chr(iByte Mod 16 + 48) End If StrToHex = StrToHex + sHigh + sLow + " " ' Zusammensetzen Next i End Function Verwandte Befehle
................................................... Verwa ndte Befehle
Chr, Str Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
Chr- , ChrB- und ChrW- Funktion Function Chr (iANSICode As Integer) As String Function ChrB (iANSICode As Integer) As String Function ChrW (iUnicode As Integer) As String Beschreibung
................................................... Bes c hreibung
Die Funktion Chr liefert das Unicode-Zeichen zu einem ANSI-Code als Unicode-Zeichenfolge der Länge 1. ChrB liefert dagegen zu einem ANSI-Code das ANSI-Zeichen als ANSI-Zeichenfolge der Länge 1 und ChrW das Unicode-Zeichen zu einem Unicode als Unicode-Zeichenfolge der Länge 1.
67
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
................................................... Beis piel
Funktionen und Anweisungen für Zeichenfolgen
Die Funktion HexToStr ist die Umkehrfunktion zu der Funktion StrToHex (vgl. Beispiel zu Asc). Sie wandelt beliebig lange Hexadezimaldarstellungen der Form "hh hh ..." in Bytefolgen des Typs String um. Public Function HexToStr(sHexString As String) As String Dim i As Integer, iHigh As Integer, iLow As Integer Dim sHexChar As String Dim sLow As String, sHigh As String If LenB(" ") = Len(" ") Then ' Unicode-System? HexToStr = Space(Len(sHexString) / 3) Else HexToStr = Space(Len(sHexString) / 6) End If For i = 1 To Len(sHexString) Step 3 ' iHigh = Asc(Mid(sHexString, i, 1)) – 48 ' If iHigh > 15 Then iHigh = iHigh – 7 ' iLow = Asc(Mid(sHexString, i + 1, 1)) – 48 If iLow > 15 Then iLow = iLow – 7 MidB(HexToStr, (i + 2) \ 3) = ChrB(iHigh * Next i End Function
aus 3 Zeichen wird 1 Byte! Annahme: Ziffer War es etwa ein Buchstabe?
16 + iLow) ' Zusammensetzen
Verwandte Befehle
................................................... Verwa ndte Befehle
Asc, Str Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
Filter- Funktion Function Filter( _ StringPool() As String, _ SuchString As String, _ [bVorkommenLiefern As Boolean = True], _ [vgl As vbCompareMethod = vbBinaryCompare]) _ As String() Beschreibung
................................................... Bes c hreibung
Die Funktion Filter durchsucht die Elemente des Zeichenfolgenarrays StringPool nach dem Vorkommen der Zeichenfolge SuchString und liefert die entsprechenden Array-Elemente als Zeichenfolgenarray. Hat der optionale Parameter VorkommenLiefern den Wert True oder fehlt er, enthält das Ergebnisarray alle Elemente, die SuchString enthalten, andernfalls (False) alle Elemente, die SuchString nicht enthalten. Hat der optionale Parameter vgl den Wert vbBinaryCompare oder fehlt er, ist die Vergleichsoperation ein zeichenweiser Unicode-Vergleich; hat vgl den Wert vbTextCompare, legt die Funktion der Vergleichsoperation die standardmäßige Sortierordnung der für die auf dem System geltenden Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung.
68
Format- Funktion
Warnung
................................................... Wa rnung
Das Standardverhalten der Funktion bei fehlendem Parameter vgl kann sich durch eine Option Compare-Anweisung ändern. Beispiel
................................................... Beis piel
Das Programm benutzt die Funktion Filter, um herauszufinden, welche Wochentage (hierfür gilt die Ländereinstellung) ohne Unterscheidung der Großschreibung die Zeichenfolge "TAG" nicht enthalten.
Verwandte Befehle
................................................... Verwa ndte Befehle
Join, Split
Format- Funktion Function Format( _ vData, _ sFormat As String], _ [FirstDayOfWeek As VbFirstDayOfWeek = vbSunday], _ [FirstWeekOfYear As VbFirstWeekOfYear = vbFirstJan1]) _ As String Beschreibung
................................................... Bes c hreibung
Die Funktion Format liefert für den Wert vData eine formatierte Darstellung als Zeichenfolge. Fehlt der optionale Parameter sFormat, folgt die Darstellung den auf dem jeweiligen System geltenden Ländereinstellungen, und das Ergebnis entspricht bis auf das fehlende führende Leerzeichen bei der Darstellung positiver Zahlen dem von Str. Ansonsten drückt sFormat unter Beachtung der Syntax für Formatausdrücke ein benutzerdefiniertes Darstellungsformat aus. Die optionalen Parameter FirstDayOfWeek und FirstWeekOfYear beziehen sich auf exotische Formen der Datumsdarstellung und können im Allgemeinen getrost weggelassen werden. Anwendung
................................................... Anwendung
Für den Formatausdruck sFormat gelten folgende Regeln: 1. Der Formatausdruck kann den Namen eines benannten Formats enthalten. Die folgenden drei Tabellen geben einen Überblick über die benannten Formate.
69
Funktionen und Anweisungen für Zeichenfolgen
Private Sub Form_Load() Dim sWochenTage(7) As String, sErgebnis() As String AutoRedraw = True For i = 0 To 6 ' Wochentage generieren sWochenTage(i) = WeekdayName(i + 1) Next i sErgebnis = Filter(sWochenTage, "TAG", False, vbTextCompare) For i = 0 To UBound(sErgebnis) – 1 ' es kommt nur der Mittwoch Print sErgebnis(i) Next i End Sub
Funktionen und Anweisungen für Zeichenfolgen
Formatname
Beschreibung
Funktionen und Anweisungen für Zeichenfolgen
"General Date" Übliche Datums-/Zeitdarstellung mit zweistelliger Jahreszahl – bei Angabe von Datum und Zeit: 01.01.00 13:00:00; bei Angabe von Zeit: 13:00:00; bei Angabe von Datum: 01.01.00 "Long Date"
Ausgeschriebenes Datum, entsprechend der Systemeinstellungen: Samstag, 1. Januar 2000
"Medium Date"
Mittleres Datumsformat (von Host-Anwendung definierbar): 1. Jan. 00
"Short Date"
Kurzes Datum, entsprechend der Systemeinstellungen: 01.01.00
Benannte Datumsformate
Formatname
Beschreibung
"Long Time"
Zeitangabe enthält auch Sekunden: 13:00:00
"Medium Time"
Zeitangabe im 12-Stunden-Format, ohne Sekunden: 1:00
"Short Time"
Zeitangabe im 24-Stunden-Format, ohne Sekunden: 13:00
Benannte Zeitformate
Formatname
Beschreibung
"General Number"
Zahlen werden ohne Tausendertrennzeichen notiert.
"Currency"
Zahlen werden mit Tausendertrennzeichen und zwei Nachkommastellen sowie unter Beachtung der auf dem System geltenden Gebietsschema-Einstellungen notiert.
"Fixed"
Festkommadarstellung unter Beachtung der auf dem System geltenden Gebietsschema-Einstellungen, ohne Tausendertrennzeichen und gerundet auf zwei Stellen hinter dem Komma: 10001,34
"Standard"
Wie "Fixed", jedoch mit Tausendertrennzeichen: 10.001,34
"Percent"
Wie "Fixed", jedoch mit Faktor 100 multipliziert und angehängtem Prozentzeichen %
"Scientific"
Wissenschaftliches Standardformat mit einer Stelle vor dem Komma, zwei Stellen nach dem Komma und Zehnerpotenz: 1,00E34
"Yes/No"
Ausgabe von »Nein« anstatt 0, »Ja« für jeden anderen Wert
"True/False"
Ausgabe von »False« anstatt 0, »True« für jeden anderen Wert
"On/Off"
Ausgabe von »Aus« anstatt 0, »Ein« für jeden anderen Wert
Benannte Zahlenformate
2. Der Formatausdruck kann ein benutzerdefiniertes Format enthalten. Die folgende Tabelle gibt einen Überblick über die Bedeutung der Symbole, die für die Zusammenstellung benutzerdefinierter Formate eine feste Interpretation haben.
70
Format- Funktion
Bedeutung
0
Platzhalter für Ziffer (vor und nach dem Dezimalzeichen). Auch Platzhalter für Ganzzahlanteil vor dem Dezimalzeichen. Platzhalterpositionen, die die Dezimaldarstellung nicht bedient, erhalten das Füllzeichen 0. Das Format "0.000" für 1234,12 ergibt "1234,120" und das Format "000000" für 1234,12 ergibt "001234".
#
Wie Symbol 0, es gibt jedoch kein Füllzeichen
.
Platzhalter für Dezimalzeichen
%
Zahlenwert wird mit 100 multipliziert und als Prozentwert mit anhängendem Prozentzeichen % dargestellt. Das Format "0.000%" für 1234,12 ist "123412,000%".
,
Die Position dieses Zeichens im Formatausdruck ist ausschlaggebend für seine Bedeutung. Steht es zwischen zwei Ziffernplatzhaltern links vom Dezimalzeichenplatzhalter erfolgt die Darstellung mit Tausendertrennzeichen. Steht es dagegen links vom ersten Ziffernplatzhalter in einer Zahlendarstellung, erscheint es als gewöhnliches Komma. Steht es bei fehlendem Dezimalzeichenplatzhalter rechts vom letzten Ziffernplatzhalter oder unmittelbar links neben dem Dezimalzeichenplatzhalter, wird der Zahlenwert durch 1000 dividiert. So bewirkt "#," für 123.4123.456 die Darstellung "1234123" und "#,,.0" für 1234.887.654 die Darstellung "1234,9".
E- oder e-
Wissenschaftliche Darstellung ohne Ausgabe des Pluszeichens im Exponenten
E+ oder e+
Wissenschaftliche Darstellung mit Ausgabe des Pluszeichens im Exponenten
- + $ ( )
Diese Symbole stehen für sich selbst. Sie erscheinen als Zeichen. Alle anderen bedeutungsbeladenen Symbole müssen einen umgekehrten Schrägstrich vorangestellt bekommen, um sie als einfaches Zeichen darzustellen.
\
Dieses Symbol kann einem anderen bedeutungsbeladenen Symbol vorangestellt werden, um dieses als Zeichen darzustellen. "\\" bewirkt die Ausgabe des Symbols selbst als Zeichen. Um ein Anführungszeichen auszugeben, muss es doppelt und in Kombination mit diesem Symbol notiert werden. Die Zahl 30405 wird mit "#0\°##\'##\"" \N\o\r\d" zu "3°04'05"" Nord".
"Nord"
Zeigt die Zeichenfolge in Anführungszeichen an. Die Regeln für Zeichenfolgenliterale fordern die doppelte Notation von Anführungszeichen. Die Zahl 30405 wird mit "#0\°##\'##\"" ""Nord""" gleichfalls zu "3°04'05"" Nord".
Symbole für benutzerdefinierte Zahlenformate
Symbol
Bedeutung
:
Platzhalter für Zeittrennzeichen zwischen Stunden, Minuten und Sekunden
/
Platzhalter für Datumstrennzeichen zwischen Tagen, Monaten und Jahren
C
Zeigt Datumsanteil in der Form ddddd und Zeitanteil in der Form ttttt an
d
Tag erscheint als Zahl ohne führende Null (1 bis 31)
dd
Tag erscheint als Zahl mit führender Null (01 bis 31)
ddd
Tag erscheint als abgekürzter Wochentag (Mo bis So)
Symbole für benutzerdefinierte Datums- und Zeitformate
71
Funktionen und Anweisungen für Zeichenfolgen
Symbol
Funktionen und Anweisungen für Zeichenfolgen
Funktionen und Anweisungen für Zeichenfolgen
Symbol
Bedeutung
dddd
Tag erscheint als ausgeschriebener Wochentag (Montag bis Sonntag)
ddddd
Datum erscheint vollständig im kurzen Datumsformat (vgl. benanntes Format "Short Date")
dddddd
Datum erscheint vollständig im langen Datumsformat (vgl. benanntes Format "Long Date")
w
Wochentag erscheint als Zahl ohne führende Null (1 bis 7)
ww
Woche erscheint als Kalenderwoche (1 bis 54)
m
Monat erscheint als Zahl ohne führende Null (1 bis 12)
mm
Monat erscheint als Zahl mit führender Null (01 bis 12)
mmm
Monat erscheint als abgekürzter Monatsname (Jan bis Dez)
mmmm
Monat erscheint als ausgeschriebener Monatsname (Januar bis Dezember)
q
Quartal erscheint als Zahl (1 bis 4)
y
Kalendertag erscheint als Zahl (1 bis 366)
yy
Jahr erscheint als zweistellige Zahl (00 bis 99)
yyyy
Jahr erscheint als vierstellige Zahl (100 bis 9999)
h
Stunde erscheint als Zahl ohne führende Null (0 bis 23)
hh
Stunde erscheint als Zahl mit führender Null (00 bis 23)
n
Minute erscheint als Zahl ohne führende Null (0 bis 59)
nn
Minute erscheint als Zahl mit führender Null (00 bis 59)
s
Sekunde erscheint als Zahl ohne führende Null (0 bis 59)
ss
Sekunde erscheint als Zahl mit führender Null (00 bis 59)
ttttt
Zeit erscheint als vollständiges langes Zeitformat mit Stunden, Minuten und Sekunden (vgl. benanntes Format "Long Time")
AM/PM
Zeit erscheint im 12-Stunden-Format mit Anhang »AM« für Stunden zwischen 0 und 12 und mit Anhang »PM« für Stunden zwischen 13 und 23. Das amerikanische Zeitformat ist somit "hh.nn.ss AM/PM".
am/pm
Wie AM/PM, jedoch mit kleingeschriebenem Anhang »am« bzw. »pm»
Symbole für benutzerdefinierte Datums- und Zeitformate
Symbol
Bedeutung
@
Platzhalter für alphanumerisches Zeichen; Füllzeichen ist das Leerzeichen
&
Platzhalter für alphanumerisches Zeichen; kein Füllzeichen
Erzwingt Großschreibung
!
Erzwingt Auswertung der Platzhalter von links nach rechts (standardmäßig werden Platzhalter von rechts nach links ausgewertet)
Symbole für benutzerdefinierte Zeichenfolgenformate
72
FormatCurrency- Funktion
Warnung
................................................... Wa rnung
Leider ist die Format-Funktion von Visual Basic 6.0 nicht fehlersicher implementiert, und liefert im Zusammenhang mit der Print-Anweisung gerne mal den obskuren Fehler 480, »Anwendungs- oder objektdefinierter Fehler«, wenn der Formatausdruck syntaktisch nicht korrekt ist oder einfach nicht zum Typ oder Wert von vData passt. Da dieser Fehler danach selbst bei Angabe korrekter Argumente nicht mehr weg zu bekommen ist, hilft in diesem Fall nur ein Neustart von Visual Basic. Beispiel
................................................... Beis piel
' Projekt FormatDemo Private Sub Form_Load() Const cJahr = 2001 ' Jahr Const cHalbjahr = 2 AutoRedraw = True For iMonat = 1 To 6 ' erstes Halbjahr Dat = DateSerial(cJahr, iMonat + (cHalbjahr – 1) * 6, 1) Print Format(Dat, "mmmm yyyy") Print "Kal.-Woche", For i = 0 To 6 ' Wochentage ausgeben Print Format(Dat + i, "dddd"), Next Print ' Anzahl der Tage in Monat berechnen Tage = Day(DateSerial(Year(Dat), Month(Dat) + 1, Day(Dat) – 1)) For i = 1 To Tage ' Kalenderwoche und Tage ausgeben If (i – 1) Mod 7 = 0 Then Print Format(Dat + i – 1, "ww"), Print Format(i, "00"), If i Mod 7 = 0 Then Print Next Print Next End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
FormatCurrency, FormatDateTime, FormatNumber, FormatPercent, Str Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
FormatCurrency- Funktion Function FormatCurrency( _ vData, _ [NachkommaStellen As Long = -1], _ [NullVorKommaErgänzen As VbTriState = vbUseDefault], _ [WennNegativKlammernSetzen As VbTriState = vbUseDefault], _ [TausenderTrennzVerwenden As VbTriState = vbUseDefault]) _ As String
73
Funktionen und Anweisungen für Zeichenfolgen
Das Projekt FormatDemo gibt einen Halbjahreskalender auf einem gewöhnlichen Formular aus:
Funktionen und Anweisungen für Zeichenfolgen
Beschreibung
................................................... Bes c hreibung
Die Funktion FormatCurrency ist eine spezialisierte Variante der Funktion Format. Sie liefert unter Verwendung der in der Systemsteuerung definierten Währung eine als Währungswert formatierte Zeichenfolge. Mittels der vier optionalen Parameter lassen sich Vorgaben für die Anzahl der Nachkommastellen, die Ergänzung einer führenden Null bei Werten kleiner eins, die Klammerung negativer Zahlen sowie die Ergänzung eines Tausendertrennzeichens treffen. Beispiel
Funktionen und Anweisungen für Zeichenfolgen
................................................... Beis piel
' Ausgabe: "(-14.345,13 DM)" Print FormatCurrency(-14345.1253, , , vbTrue) ' Ausgabe: "-14345,125 DM" Print FormatCurrency(-14345.1253, 3, vbFalse, vbFalse, vbFalse) Verwandte Befehle
................................................... Verwa ndte Befehle
Format, FormatDateTime, FormatNumber, FormatPercent, Str, CStr Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
FormatDateTime- Funktion Function FormatDateTime( _ vData, _ BenanntesFormat As VbDateTimeFormat = vbGeneralDate]) _ As String Beschreibung
................................................... Bes c hreibung
Die Funktion FormatDateTime ist eine spezialisierte Variante der Funktion Format. Sie liefert unter Verwendung des in der Systemsteuerung definierten Datums- und Zeitformats eine als Datums- und/oder Zeitangabe formatierte Zeichenfolge. Mittels des optionalen Parameters BenanntesFormat lässt sich das zu verwendende Format vorgeben. Zur Auswahl stehen je ein kurzes und ein langes Format für Zeitangaben und Datumsangaben. Beispiel
................................................... Beis piel
Print FormatDateTime(14345.1223, vbShortTime) ' Ausgabe: "02:56" Print FormatDateTime(14345.1223, vbLongTime) ' Ausgabe: "02:56:07" Print FormatDateTime(14345.1223, vbShortDate) ' Ausgabe: "10.4.39" ' Ausgabe: "Montag, 10 April 1939" Print FormatDateTime(14345.1223, vbLongDate) ' Ausgabe: "10.4.39 02:56:07" Print FormatDateTime(14345.1223, vbGeneralDate) Print FormatDateTime(14345.1223) ' Ausgabe: "10.4.39 02:56:07" Verwandte Befehle
................................................... Verwa ndte Befehle
Format, FormatCurrency, FormatNumber, FormatPercent, Str
74
FormatNumber- Funktion
Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
FormatNumber- Funktion
Beschreibung
................................................... Bes c hreibung
Die Funktion FormatNumber ist eine spezialisierte Variante der Funktion Format. Sie liefert eine Zahlendarstellung in Form einer Zeichenfolge. Der einzige Unterschied zu FormatCurrency besteht darin, dass die Funktion ihre Darstellung ohne Währungssymbol vornimmt. Mittels der fünf optionalen Parameter lassen sich Vorgaben für die Anzahl der Nachkommastellen, die Ergänzung einer führenden Null bei Werten kleiner eins, die Klammerung negativer Zahlen sowie die Ergänzung eines Tausendertrennzeichens treffen. Beispiel
................................................... Beis piel
Print FormatNumber(-143.1253) ' Ausgabe:"-143,13" Print FormatNumber(-143.1253, 3, , vbTrue) ' Ausgabe:"(143,125)" Print FormatNumber(-143.1253, 0, vbFalse, vbFalse) ' Ausgabe:"-143)" Verwandte Befehle
................................................... Verwa ndte Befehle
Format, FormatCurrency, FormatDateTime, FormatNumber, Str Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
FormatPercent- Funktion Function FormatPercent( _ vData, _ [NachkommaStellen As Long = -1], _ [NullVorKommaErgänzen As VbTriState = vbUseDefault], _ [WennNegativKlammernSetzen As VbTriState = vbUseDefault], _ [TausenderTrennzVerwenden As VbTriState = vbUseDefault], _ [ZiffernGruppieren As VbTriState = vbUseDefault)] _ As String Beschreibung
................................................... Bes c hreibung
Die Funktion FormatPercent ist eine spezialisierte Variante der Funktion Format. Sie multipliziert vData mit 100 und liefert das Ergebnis als Prozentangabe mit Prozentzeichen in Form einer Zeichenfolge. Mittels der fünf optionalen Parameter lassen sich Vorgaben für die Anzahl der Nachkommastellen, die Ergänzung einer führenden Null bei Werten kleiner eins, die Klammerung negativer Zahlen sowie die Ergänzung eines Tausendertrennzeichens treffen.
75
Funktionen und Anweisungen für Zeichenfolgen
Function FormatNumber( _ vData, _ [NachkommaStellen As Long = -1], _ [NullVorKommaErgänzen As VbTriState = vbUseDefault], _ [WennNegativKlammernSetzen As VbTriState = vbUseDefault], _ [TausenderTrennzVerwenden As VbTriState = vbUseDefault]) _ [ZiffernGruppieren As VbTriState = vbUseDefault)] _ As String
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
................................................... Beis piel
Print FormatPercent(-143.1253) ' Ausgabe: "-14.312,53%" Print FormatPercent(-143.1253, , , vbTrue) ' Ausgabe: "(14.312,53%)" Print FormatPercent(-143.1253, 0, vbFalse, vbFalse) 'Ausgabe:"-14.313%)" Verwandte Befehle
................................................... Verwa ndte Befehle
Format, FormatCurrency, FormatDateTime, FormatNumber, Str
Funktionen und Anweisungen für Zeichenfolgen
Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
Hex- Funktion Function Hex(vZahl) As String Beschreibung
................................................... Bes c hreibung
Die Funktion Hex interpretiert den Wert vZahl als Ganzzahl und liefert deren hexadezimale Repräsentation als Zeichenfolge. Die Darstellung enthält nicht mehr Stellen als nötig, mithin also keine führenden Nullen oder Leerzeichen. Beispiel
................................................... Beis piel
Print Hex(255) ' Ausgabe: "FF" lWert = 10 Print "&H" Right("0000000"+Hex(lWert) , 8) ' Ausgabe: "&H0000000A" Verwandte Befehle
................................................... Verwa ndte Befehle
Oct
InStr- und InStrB- Funktion Function InStr( [lStart As Long = 1,] _ sDurchsuchterString As String, _ sSuchString As String,_ [vgl As VbCompareMethode = vbBinaryCompare]) _ As Long Function InStrB( [lStart As Long = 1,] _ sDurchsuchterANSIString As String, _ sANSISuchString As String,_ [vgl As VbCompareMethode = vbBinaryCompare]) _ As Long Beschreibung
................................................... Bes c hreibung
Die Funktion InStr durchsucht die Zeichenfolge sDurchsuchterString ab der Zeichenposition lStart (optional mit Vorgabewert 1) nach dem nächsten Vorkommen der Zeichenfolge sSuchString. Ist die Suche erfolgreich, liefert die Funktion ihre Startposition in der durchsuchten Zeichenfolge, ansonsten den Wert 0. Hat der optionale Parameter vgl den Wert vbBinary-
76
InStrRev- Funktion
Compare oder fehlt er, ist die Vergleichsoperation ein zeichenweiser Unicode-Vergleich; hat vgl den Wert vbTextCompare, legt die Funktion der Vergleichsoperation die standardmäßige Sortierordnung der für die auf dem System geltenden Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung. Die Variante InStrB dieser Funktion ist für Zeichenfolgen im ANSI-Code zuständig. Hinweis
................................................... Hinweis
Warnung
................................................... Wa rnung
Das Standardverhalten der Funktion bei fehlendem Parameter vgl kann sich durch eine Option Compare-Anweisung ändern. Beispiel
................................................... Beis piel
Der folgende Code zählt mittels der Zählvariablen iCount, wie oft die Zeichenfolge s1 innerhalb der Zeichenfolge s2 vorkommt. iCount = 0 lPos = 0 Do lPos = InStr(lPos + 1, s1, s2) If lPos Then iCount = iCount +1 Loop While lPos ... ' iCount enthält nun die Anzahl der Vorkommen Verwandte Befehle
................................................... Verwa ndte Befehle
Filter, InStrRev, StrComp
InStrRev- Funktion Function InStrRev( sDurchsuchterString As String, _ sSuchString As String,_ [lStart As Long = -1,] _ [vgl As VbCompareMethod = vbBinaryCompare]) _ As Long Beschreibung
................................................... Bes c hreibung
Die Funktion InStrRev vollbringt die gleiche Aufgabe wie InStr, mit dem feinen Unterschied, dass sie die Zeichenfolge sDurchsuchterString ab der Zeichenposition lStart (optional, mit Vorgabewert -1) rückwärts, also von rechts nach links, durchsucht. Hat der optionale Parameter vgl den Wert vbBinaryCompare oder fehlt er, ist die Vergleichsoperation ein zeichenweiser Unicode-Vergleich; hat vgl den Wert vbTextCompare, legt die Funktion der Vergleichsoperation die standardmäßige Sortierordnung der für die auf dem System geltenden Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung.
77
Funktionen und Anweisungen für Zeichenfolgen
Die mit Visual Basic 6.0 vorliegende Implementation dieser Funktion hat kein Problem damit, wenn Start größer ist als die Länge der durchsuchten Zeichenfolge. Negative Werte sowie ein Wert von 0 führen dagegen zu einem Laufzeitfehler.
Funktionen und Anweisungen für Zeichenfolgen
Hinweis
................................................... Hinweis Die mit Visual Basic 6.0 vorliegende Implementation dieser Funktion hat kein Problem damit, wenn lStart größer ist als die Länge der durchsuchten Zeichenfolge. Werte kleiner gleich 0 (außer dem Sonderwert -1) führen dagegen zu einem Laufzeitfehler. Warnung
................................................... Wa rnung
Das Standardverhalten der Funktion bei fehlendem Parameter vgl kann sich durch eine Option Compare-Anweisung ändern.
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
................................................... Beis piel
Der folgende Code zählt mittels der Zählvariablen iCount, wie oft die Zeichenfolge s1 innerhalb der Zeichenfolge s2 vorkommt. iCount = 0 lPos = -1 Do lPos = InStrRev(s1, s2, lPos) – 1 If lPos >= 0 Then iCount = iCount + 1 Loop While lPos > 0 ... ' iCount enthält nun die Anzahl der Vorkommen Verwandte Befehle
................................................... Verwa ndte Befehle
Filter, InStr, StrComp
J oin- Funktion Function Join( _ StringArray() As String, _ [TrennZeichen As String] = " ") _ As String Beschreibung
................................................... Bes c hreibung
Die Funktion Join ist die Umkehrfunktion zu Split. Sie verkettet die Elemente des Zeichenfolgenarrays StringArray zu einer einzelnen Zeichenfolge und liefert diese zurück. Fehlt der optionale Parameter TrennZeichen, fügt die Funktion zwischen den Elementen ein Leerzeichen ein. Durch Angabe eines Werts lassen sich auch andere Trennzeichenfolgen vorgeben, so etwa die leere Zeichenfolge "", das Tabulatorzeichen vbTab oder Zeilenvorschübe vbCrLf. Beispiel
................................................... Beis piel
Das Projekt JoinDemo initialisiert ein Zeichenfolgenarray mit den Namen der Wochentage und gibt das Ergebnis des nachfolgenden Join-Aufrufs aus: ' Projekt: JoinDemo Private Sub Form_Load() Dim sWochenTage(7) As String, sErgebnis() As String AutoRedraw = True For i = 0 To 6 ' Wochentage generieren sWochenTage(i) = WeekdayName(i + 1) Next i Print Join(sWochenTage, vbCrLf) End Sub
78
LCase- Funktion
Verwandte Befehle
................................................... Verwa ndte Befehle
Filter, Split
LCase- Funktion Function LCase(s As String) As String Beschreibung
................................................... Bes c hreibung
Beispiel
................................................... Beis piel
if LCase(sTest1) = LCase(sTest2) Then
' Schreibweise egal
Verwandte Befehle
................................................... Verwa ndte Befehle
UCase
Left- und LeftB- Funktion Function Left(sUnicode As String, lZeichenAnz As Long) As String Function LeftB(sANSI As String, lZeichenAnz As Long) As String Beschreibung
................................................... Bes c hreibung
Die Funktion Left liefert die ersten lZeichenAnz Zeichen der Zeichenfolge sUnicode als Unicode-Zeichenfolge und die Funktion LeftB die ersten lZeichenAnz Bytes der Zeichenfolge sANSI als ANSI-Zeichenfolge. Ist der Wert von lZeichenAnz größer oder gleich der Länge der Zeichenfolge, gibt die Funktion die vollständige Zeichenfolge zurück. Mit 0 als Wert für lZeichenAnz gibt die Funktion die leere Zeichenfolge zurück. Beispiel
................................................... Beis piel
Die folgende Ausgabeanweisung gibt die Zeichenfolge s linksbündig in einem Feld aus. Ist die Länge der Zeichenfolge s kleiner als 8, werden von rechts her Leerzeichen ergänzt (linksbündige Prokrustes-Zuweisung, vgl. auch »LSet-Anweisung«, S. 80). Const cFeldBreite = 8 Print Left(s + Space(cFeldBreite), cFeldBreite) Verwandte Befehle
................................................... Verwa ndte Befehle
Right, RightB, Mid, MidB, LTrim, RTrim, Trim
Len- und LenB- Funktion Function Len(sUnicode As String) As Long Function LenB(Var As Type) As Long Beschreibung
................................................... Bes c hreibung
Die Funktion Len liefert die Anzahl der Zeichen in der Zeichenfolge sUnicode. Die leere Zeichenfolge Null hat die Länge 0. Die Funktion LenB gibt die Anzahl der Bytes zurück, die zum Speichern des Werts von Var benötigt werden.
79
Funktionen und Anweisungen für Zeichenfolgen
Die Funktion LCase liefert eine Kopie der im Parameter s übergebenen Zeichenfolge in Kleinschreibung zurück. Null wird wieder als Null zurückgegeben.
Funktionen und Anweisungen für Zeichenfolgen
Anwendung
................................................... Anwendung
Wie es die Beschreibung bereits vermuten lässt, verbirgt sich hinter der Funktion LenB so etwas wie der »Längenoperator« der Sprache Visual Basic, den Sie benutzen können, wann immer Sie wissen wollen, wie viele Bytes für die Repräsentation eines bestimmten Werts von einem bestimmten Datentyp erforderlich sind. Achtung jedoch, die Längenangaben von Zeichenfolgen enthalten nicht den Längenbedarf des Deskriptors (vgl. auch »Get-Anweisung«, S. 140). Auf Arrays lässt sich diese Funktion gar nicht anwenden. Beispiel
Funktionen und Anweisungen für Zeichenfolgen
................................................... Beis piel
Siehe Beispiel zu »Chr-, ChrB- und ChrW-Funktion« (S. 67) Verwandte Befehle
................................................... Verwa ndte Befehle
VarType
LSet- Anweisung LSet sString1 = sString2 LSet bdtVar = bdtWert Beschreibung
................................................... Bes c hreibung
Die Anweisung LSet nimmt eine linksbündige Prokrustes-Zuweisung für Zeichenfolgen und benutzerdefinierte Datentypen vor. Auf Zeichenfolgen angewendet, überträgt sie den Wert von sString2 linksbündig in die Variable sString1, ohne deren Länge anzupassen. Dabei wird der Wert von sString2 gegebenenfalls zurechtgestutzt oder um Leerzeichen ergänzt (vgl. Beispiel in »Left- und LeftB-Funktion«, S. 79). Auf benutzerdefinierte Datentypen angewendet, überträgt LSet den Wert bdtWert Byte-weise und linksbündig in die Variable bdtVar, ohne deren Länge anzupassen. Ist bdtWert kürzer als der Wert, den bdtVar erwartet, ergänzt die Anweisung Nullbytes, ist er länger, wird zurechtgestutzt. Anwendung
................................................... Anwendung
Der ursprüngliche Sinn dieser Anweisung war die Bereitstellung einer blockorientierten Zuweisungsoperation für zusammengesetzte bzw. benutzerdefinierte Datentypen. Solche Werte lassen sich im Rahmen einer gewöhnlichen Let-Zuweisung en bloc nämlich nicht mehr übertragen. Ein sehr wichtiger Einsatzbereich von LSet ist daher die Überführung traditionell via Get oder Input gelesener Datensätze in Datensatzvariablen mit benutzerdefinierter Struktur bzw. die Vorbereitung von Datensatzvariablen für die Put-Operation. Aus diesem Grund ist die Typüberprüfung, die Visual Basic LSet angedeihen lässt, nicht sehr rigide. Warnung und Tipp
................................................... Wa rnung
»Nachtigall, ick hör dir trapsen«. Ja, mit LSet lassen sich auf dem Umweg über benutzerdefinierte Datentypen implizite Typumwandlungen ausführen, wie das Beispiel zu diesem Befehl zeigt. Von einer ernsthaften Anwendung im Zusammenhang mit disparaten Datentypen, die über eine Analyse von Repräsentationen bestimmter Datentypen oder Werte hinausgeht, ist jedoch abzuraten, da für gewöhnlich nicht klar ist, welche Speicherausrichtung die Felder benutzerdefinierter Datentypen vom Compiler erhalten.
80
LTrim- Funktion
Beispiel
................................................... Beis piel
Wer die Speicherdarstellung eines spezifischen Werts zu Gesicht bekommen will, muss schon ein wenig tricksen, um der rigiden Typkontrolle von Visual Basic zu entrinnen. Der folgende Code benutzt die als Beispiel zu Chr vorgestellte Funktion StrToHex, um die hexadezimale Repräsentation eines Double-Werts nach einer LSet-Zuweisung zu erhalten. Beachten Sie bei der Interpretation der Hexadezimaldarstellung, dass Intel-Prozessoren mit verkehrter Bytereihenfolge arbeiten und in einem aus mehreren Bytes bestehenden Wert das erste Byte das niederwertige Byte ist. erster benutzerdefinierter Typ
zweiter benutzerdefinierter Typ
bdt2 wie sieht die Repräsentation dieses Werts aus? Zuweisung unter Umgehung der Typprüfung Ausgabe der hexadezimalen Darstellung
Verwandte Befehle
................................................... Verwa ndte Befehle
Get, Let, Put, RSet Verwandte Themen
................................................... Verwandte Them en
Typumwandlung (S. 57)
LTrim- Funktion Function LTrim(s As String) As String Beschreibung
................................................... Bes c hreibung
Die Funktion liefert eine Kopie der Zeichenfolge s zurück, die keine führenden Leerzeichen mehr enthält. Beispiel
................................................... Beis piel
Dim i As Integer i = 121 Print LTrim(Str(i))
' schneidet Leerstelle für Vorzeichen ab
Verwandte Befehle
................................................... Verwa ndte Befehle
RTrim, Trim
Mid- und MidB- Funktion Function Mid(sUnicode As String, lStart As Long _ [, lAnz As Long]) As String Function MidB(sANSI As String, lStart As Long _ [, lAnz As Long]) As String
81
Funktionen und Anweisungen für Zeichenfolgen
Private Type bdt1 ' f As Double End Type Private Type bdt2 ' s As String * 4 End Type Private Sub Form_Load() AutoRedraw = True Dim bt1 As bdt1, bt2 As bt1.f = 2.234E-23 ' LSet bt2 = bt1 ' Print StrToHex(bt2.s) ' End Sub
Funktionen und Anweisungen für Zeichenfolgen
Beschreibung
................................................... Bes c hreibung
Die Funktion Mid liefert lAnz Zeichen der Zeichenfolge sUnicode ab der Position lStart als Unicode-Zeichenfolge zurück. In gleicher Weise liefert die MidB-Funktion lAnz Bytes der Zeichenfolge sANSI ab der Byteposition lStart als Zeichenfolge. Fehlt der optionale Parameter lAnz, liefern beide Funktionen den gesamten Rest der Zeichenfolge ab der Position lStart. Beispiel
................................................... Beis piel
Funktionen und Anweisungen für Zeichenfolgen
Vgl. die Beispiele in »Chr-, ChrB- und ChrW-Funktion« (S. 67) und »Asc-, AscB- und AscW-Funktion« (S. 66).
Mid- und MidB- Anweisung Mid s, lStart [, lAnz] = sErsatz MidB s, lStart [, lAnz] = sErsatz Beschreibung
................................................... Bes c hreibung
Die Mid-Zuweisung kopiert die ersten lAnz Zeichen der Zeichenfolge sErsatz in die Zeichenfolge s ab Position lStart. Ist lAnz größer als die Länge von sErsatz oder fehlt lAnz, wird die gesamte Zeichenfolge sErsatz kopiert. MidB unterscheidet sich von Mid nur darin, dass sie lAnz als Byteanzahl interpretiert und Byte-weise kopiert. Beispiel
................................................... Beis piel
Siehe Beispiel zu »Chr-, ChrB- und ChrW-Funktion« (S. 67) Verwandte Befehle
................................................... Verwa ndte Befehle
Left, LeftB, Right, RightB, LTrim, RTrim, Trim
MonthName- Funktion Function MonthName(lMonat As Long[, bAbk As Boolean = False]) As String Beschreibung
................................................... Bes c hreibung
Die Funktion MonthName liefert den zur Monatszahl lMonat gehörigen Monatsnamen als Zeichenfolge. Hat der optionale Parameter bAbk den Wert False oder fehlt er, gibt die Funktion den vollen Namen zurück, ansonsten seine Abkürzung (drei Buchstaben). Monatszahlen, die nicht zwischen 1 und 12 liegen, führen zu einem Laufzeitfehler. Beispiel
................................................... Beis piel
Print MonthName(Month(Date))
' Name aktueller Monat, ausgeschrieben
Verwandte Befehle
................................................... Verwa ndte Befehle
WeekdayName
Oct- Funktion Function Oct(vOctWert) As Double
82
Option Compare- Anweisung
Beschreibung
................................................... Bes c hreibung
Die Funktion Oct zählt wie Hex nur mittelbar zu den Typumwandlungsfunktionen. Während Hex die hexadezimale Notation seines als Ganzzahl interpretierten Arguments als Zeichenfolge liefert, liefert Oct dessen oktale Notation. Anwendung
................................................... Anwendung
Die Umwandlung in das oktale Zahlensystem mittels Oct findet heutzutage eher selten Anwendung. Sie ist ein Relikt aus vergangenen Zeiten, als das hexadezimale Zahlensystem im Computerbereich noch nicht die alles dominierende Rolle spielte.
................................................... Beis piel
Print Oct(77) Print Oct(&o1234)
' 64+8+5 = "115" ' Oktales Literal: "1234"
Verwandte Befehle
................................................... Verwa ndte Befehle
Hex
Option Compare- Anweisung Option Compare Binary Option Compare Text Beschreibung
................................................... Bes c hreibung
Die Anweisung Option Compare legt fest, welche Art von Zeichenfolgenvergleich bestimmte Zeichenfolgenfunktionen laut Vorgabe (das heißt ohne Angabe des jeweiligen optionalen Parameters) durchführen. Der Vergleichsart Binary liegt ein schlichter Vergleich der binären Repräsentation (zeichenweiser Unicode-Vergleich), der Vergleichsart Text dagegen die standardmäßige Sortierordnung der für die auf dem System geltende Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung. Diese Anweisung darf in einem Modul nicht mehrfach gegeben werden, das heißt, sie gilt immer für das gesamte Modul und muss auf Modulebene stehen. Fehlt die Anweisung, gilt für das jeweilige Modul die Voreinstellung Binary. Eine Option Compare-Anweisung wirkt sich auf die Zeichenfolgenoperatoren , =, = und aus. Weiterhin kann sie sich bei Fehlen des entsprechenden optionalen Parameters auch auf die Funktionen: Filter, InStr, InStrB, InStrRev, Replace, Split, StrComp auswirken. Beispiel
................................................... Beis piel
Option Compare Text ... Print (StrComp("ö", "u", vbBinaryCompare) = -1) = ("ö" < "ü") ' Ausgabe: Falsch
aber Option Compare Binary ' Standardvergleichsart ... Print (StrComp("ö", "u", vbBinaryCompare) = -1) = ("ö" < "ü") ' Ausgabe: Wahr
83
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
Funktionen und Anweisungen für Zeichenfolgen
Verwandte Befehle
................................................... Verwa ndte Befehle
Option Base, Option Explicit, Option Private
Funktionen und Anweisungen für Zeichenfolgen
Replace- Funktion Function Replace( _ sDurchsuchterString As String, _ sSuchString As String,_ sErsatzString As String,_ [lStart As Long = 1], _ [lAnz As Long = -1], [vgl As VbCompareMethode = vbBinaryCompare]) _ As Long Beschreibung
................................................... Bes c hreibung
Die Funktion Replace durchsucht die Zeichenfolge sDurchsuchterString ab der Zeichenposition lStart nach maximal lAnz Vorkommen der Zeichenfolge sSuchString und liefert eine Kopie von sDurchsuchterString ab der Zeichenposition lStart, in der all diese Vorkommen gegen die Zeichenfolge sErsatzString ersetzt sind. Fehlt der optionale Parameter lStart, beginnt die Kopie beim ersten Zeichen. Fehlt der Parameter lAnz, ersetzt die Funktion beliebig viele Vorkommen von sSuchString. Hat der optionale Parameter vgl den Wert vbBinaryCompare oder fehlt er, ist die Vergleichsoperation ein zeichenweiser Unicode-Vergleich; hat vgl den Wert vbTextCompare, legt die Funktion der Vergleichsoperation die standardmäßige Sortierordnung der für die auf dem System geltenden Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung. Hinweis
................................................... Hinweis Die mit Visual Basic 6.0 vorliegende Implementation dieser Funktion hat kein Problem damit, wenn Start größer ist als die Länge der durchsuchten Zeichenfolge; negative Werte sowie ein Wert von 0 führen dagegen zu einem Laufzeitfehler. Warnung
................................................... Wa rnung
Das Standardverhalten der Funktion bei fehlendem Parameter vgl kann sich durch eine Option Compare-Anweisung ändern. Beispiel
................................................... Beis piel
Dim s Print Print Print Print
As String Replace("12222223", Replace("12222223", Replace("12222223", Replace("abbbbbbc",
"22", "22", "22", "BB",
"3") "3", 2, 2) "3", 2 ,0) "C", 2, , vbTextCompare)
Vergleiche auch das Beispiel zu »Print #« (S. 151). Verwandte Befehle
................................................... Verwa ndte Befehle
Filter, InStr, StrComp
84
' ' ' '
"13333" "33223" "2222223" "CCCc"
Partion- Funktion
Partion- Funktion Function Partition(Number As Long, Start As Long, Stop As Long, _ Interval As Long) As String Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Der Einsatzbereich dieser ziemlich spezialisierten Funktion liegt hauptsächlich im Bereich der Datenbankprogrammierung, wo sie für die Berechnung der Datensatzgruppierung verwendbar ist. Beispiel
................................................... Beis piel
Print Print Print Print
Partition(1, 2, 100, 23) Partition(24, 2, 100, 23) Partition(25, 2, 100, 23) Partition(101, 2, 100, 23)
' ' ' '
Ausgabe: Ausgabe: Ausgabe: Ausgabe:
": 2" "2: 24" "25: 47" "101: "
Right- und RightB- Funktion Function Right(sUnicode As String, lZeichenAnz As Long) As String Function RightB(sANSI As String, lZeichenAnz As Long) As String Beschreibung
................................................... Bes c hreibung
Die Funktion Right liefert die letzten lZeichenAnz Zeichen der Zeichenfolge sUnicode als Unicode-Zeichenfolge und die Funktion RightB die letzten lZeichenAnz Bytes der Zeichenfolge sANSI als ANSI-Zeichenfolge. Ist der Wert von lZeichenAnz größer oder gleich der Länge der Zeichenfolge, gibt die Funktion die vollständige Zeichenfolge zurück. Mit 0 als Wert für lZeichenAnz gibt die Funktion die leere Zeichenfolge Null zurück. Beispiel
................................................... Beis piel
Die folgende Ausgabeanweisung gibt die Zeichenfolge s rechtsbündig in einem Feld aus. Ist die Länge der Zeichenfolge s kleiner als 8, werden von links her Leerzeichen ergänzt (rechtsbündige Prokrustes-Zuweisung, vgl. auch »RSet-Anweisung«, S. 86). Const cFeldBreite = 8 Print Right(Space(cFeldBreite) + s , cFeldBreite) Verwandte Befehle
................................................... Verwa ndte Befehle
Right, RightB, Mid, MidB, LTrim, RTrim, Trim
85
Funktionen und Anweisungen für Zeichenfolgen
Die Funktion Partition ordnet eine gegebene Zahl Number in das zugehörige Intervall einer Intervallfolge ein und liefert dann eine Beschreibung des Intervalls in der Form »UntereGrenze: ObereGrenze«. Die Intervallfolge ist über Start (untere Grenze des ersten Intervalls), Stop (obere Grenze des letzten Intervall) und Interval (Breite der einzelnen Intervalle in der Folge) definiert und enthält die halboffenen (nach oben offen) Intervalle, die sich durch wiederholte Addition der Intervalllänge zum Startwert ergeben. Ist Number kleiner als Start, beschreibt die Funktion das Intervall in der Form: »: UntereGrenze », ist Number größer als Stop, in der Form: »ObereGrenze: «.
Funktionen und Anweisungen für Zeichenfolgen
RSet- Anweisung RSet sString1 = sString2 Beschreibung
................................................... Bes c hreibung
Die Anweisung RSet nimmt eine rechtsbündige Prokrustes-Zuweisung für Zeichenfolgen vor, das heißt, sie kopiert den Wert von sString2 rechtsbündig in die Variable sString1, ohne deren Länge anzupassen. Dabei wird der Wert von sString2 gegebenenfalls vorne zurechtgestutzt oder um Leerzeichen ergänzt.
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
................................................... Beis piel
Dim s As String * 20 RSet s = FormatCurrency(vWert, 2) Verwandte Befehle
................................................... Verwa ndte Befehle
Get, Let, LSet, Put
RTrim- Funktion Function RTrim(s As String) As String Beschreibung
................................................... Bes c hreibung
Die Funktion liefert eine Kopie der Zeichenfolge s zurück, die keine Leerzeichen am Ende enthält. Beispiel
................................................... Beis piel
Dim sFix As String * 100 Dim sVariable As String sFix = "Literaler Wert" ' Prokrustes-Zuweisung sVariable = sFix Print RTrim(sVariable) Verwandte Befehle
................................................... Verwa ndte Befehle
LTrim, Trim
Space- Funktion Function Space(lAnz As Long) As String Beschreibung
................................................... Bes c hreibung
Die Funktion Space liefert eine Unicode-Zeichenfolge der Länge lAnz, die mit Leerzeichen gefüllt ist. Beispiel
................................................... Beis piel
Siehe die Beispiele zu »Chr-, ChrB- und ChrW-Funktion« (S. 67), »Left- und LeftB-Funktion« (S. 79 ) und »Right- und RightB-Funktion« (S. 85). Verwandte Befehle
................................................... Verwa ndte Befehle
LTrim, RTrim
86
Split- Funktion
Split- Funktion Function Split(_ sKombination As String, _ [sTrennzeichen As String = " "], _ [lAnz As Long = -1], _ [vgl As vbCompareMethod = vbBinaryCompare]) _ As String() Beschreibung
................................................... Bes c hreibung
Warnung
................................................... Wa rnung
Das Standardverhalten der Funktion bei fehlendem Parameter vgl kann sich durch eine Option Compare-Anweisung ändern. Beispiel
................................................... Beis piel
cVornamen = "Audra, Petra, Jennifer, Maria, Magdalena" Dim sVornamen() As String sVornamen = Split(cVornamen, ", ") For i = 0 To UBound(sVornamen) ' zeilenweise ausgeben Print sVornamen(i) Next i Print cVornamen = Join(sVornamen, ", ") ' Ausgabe: Wahr Verwandte Befehle
................................................... Verwa ndte Befehle
Filter, Join
Str- Funktion Function Str(lZahl As Long) As String Function Str(dZahl As Double) As String Beschreibung
................................................... Bes c hreibung
Die Funktion Str liefert den Wert von lZahl bzw. dZahl als Unicode-Zeichenfolge im standardmäßigen amerikanischen Zahlenformat. Warnung
................................................... Wa rnung
Leider ist die Str-Funktion von Visual Basic 6.0 nicht fehlersicher implementiert und liefert im Zusammenhang mit der Print-Anweisung gerne mal den Fehler 480, wenn dZahl als literaler Wert angegeben wird. Da dieser Fehler danach selbst bei Angabe korrekter Argumente nicht mehr weg zu bekommen ist, hilft in diesem Fall nur ein Neustart von Visual Basic.
87
Funktionen und Anweisungen für Zeichenfolgen
Als Umkehrfunktion zu Join unterteilt die Funktion Split die Zeichenfolge sKombination in mehrere Zeichenfolgen und gibt diese als Zeichenfolgenarray zurück. Fehlt der optionale Parameter sTrennzeichen, wertet die Funktion standardmäßig jedes erscheinende Leerzeichen als Trennzeichen zwischen zwei Zeichenfolgen, ansonsten den Wert von sTrennzeichen. Fehlt der optionale Parameter lAnz, nimmt die Funktion so viele Unterteilungen vor, wie sie Trennzeichen findet, ansonsten nicht mehr als lAnz. Hat der optionale Parameter vgl den Wert vbBinaryCompare oder fehlt er, ist die Vergleichsoperation ein zeichenweiser Unicode-Vergleich; hat vgl den Wert vbTextCompare, legt die Funktion der Vergleichsoperation die standardmäßige Sortierordnung der für die auf dem System geltenden Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung.
Funktionen und Anweisungen für Zeichenfolgen
Wird die Funktion mit einer literalen Zeichenfolge bzw. einer Konstante als Argument aufgerufen, verwandelt Visual Basic die Zeichenfolge zunächst implizit in eine Zahl vom Typ Long oder Double, um mit Str daraus wieder eine Zeichenfolge zu machen. In Systemen mit deutschem Zahlenformat (Ländereinstellungen) passiert dabei dummerweise Folgendes: Print Str("1234,1234") Print Str(Str("1234,1234"))
' Ausgabe: 1234,1234 ' Ausgabe: 12341234
Fehler, die aus dieser Ungereimtheit heraus entstehen, sind meist recht schwer zu finden (vgl. auch Variableninitialisierung, S. 168).
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
................................................... Beis piel
Der folgende Code geht von einem Formular mit zwei Textfeldern namens Text1 und Text2 aus und übersetzt Eingaben in die Standardnotation. Private Sub Text1_Change() Text2 = Str(Val(Text1)) End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
Val, Round
StrComp- Funktion Function StrComp( _ s1 As String, _ s2 As String, _ [vgl As vbCompareMethod = vbBinaryCompare]) _ As Integer Beschreibung
................................................... Bes c hreibung
Die Funktion StrComp unterzieht die beiden Zeichenfolgen s1 und s2 einer Vergleichsoperation und unterscheidet dabei die vier in der folgenden Tabelle aufgelisteten Fälle. Hat der optionale Parameter vgl den Wert vbBinaryCompare oder fehlt er, ist die Vergleichsoperation ein zeichenweiser Unicode-Vergleich; hat vgl den Wert vbTextCompare, legt die Funktion der Vergleichsoperation die standardmäßige Sortierordnung der für die auf dem System geltenden Landessprache zugrunde – ohne Unterscheidung der Groß- und Kleinschreibung. Funktionswert
Ergebnis des Vergleichs (hängt von Vergleichsoperation ab)
-1
s1 ist »kleiner als« s2
1
s1 ist »größer als« s2
0
s1 ist »gleich« s2
Null
Einer der beiden Vergleichswerte ist Null
Warnung
................................................... Wa rnung
Das Standardverhalten der Funktion bei fehlendem Parameter vgl kann sich durch eine Option Compare-Anweisung ändern.
88
StrConv- Funktion
Beispiel
................................................... Beis piel
Print StrComp("Blöd", "Blut") ' Ausgabe: 1 Print StrComp("Blöd", "Blut", vbTextCompare) ' Ausgabe: -1 Print StrComp("BlOnD", "blond", vbTextCompare) ' Ausgabe: 0 Verwandte Befehle
................................................... Verwa ndte Befehle
Option Compare, =
Function StrConv( _ s As String, _ KonvSchema As VbStrConv, _ [lGebietsschemaID As Long) _ As String Beschreibung
................................................... Bes c hreibung
Die Funktion StrComp liefert eine konvertierte Variante der Zeichenfolge s. Der Wert von KonvSchema (siehe Tabelle) bestimmt, welches Konversionsschema die Funktion der Konversion zugrunde legt. Bestimmte Konversionen sind allerdings nur möglich, wenn im System ein entsprechendes Gebietsschema eingestellt oder im optionalen Parameter lGebietsschemaID spezifiziert ist. Wert für KonvSchema
Verwendetes Konversionsschema
vbUpperCase (1)
Umwandlung in Großschreibung
vbLowerCase (2)
Umwandlung in Kleinschreibung
vbProperCase (3)
Umwandlung in gemischte Groß-/Kleinschreibung, Wortanfang groß, Rest klein
vbWide (4)
Umwandlung von Ein-Byte-Zeichen in Zwei-Byte-Zeichen (DBCS)
vbNarrow (8)
Umwandlung von Zwei-Byte-Zeichen (DBCS) in Ein-Byte-Zeichen
vbKatakana (16)
Umwandlung Hiragana-Zeichen in Katagana-Zeichen
vbHiragana (32)
Umwandlung Katagana-Zeichen in Hiragana-Zeichen
vbUnicode (64)
Umwandlung von systemspezifischem ANSI-Zeichensatz in Unicode unter Verwendung der Zeichenumsetzungstabelle des Systems
vbFromUnicode (128)
Umwandlung von Unicode in systemspezifischen ANSI-Zeichensatz unter Verwendung der Zeichenumsetzungstabelle des Systems
Hinweis
................................................... Hinweis Sie können die in der Tabelle genannten Konstanten für KonvSchema auch kombinieren. Allerdings hängen die sinnvollen Kombinationsmöglichkeiten stark vom geltenden Gebietsschema ab. Der Wert vbUnicode + vbProperCase bewirkt beispielsweise die Umwandlung einer ANSIZeichenfolge in Unicode mit gemischter Groß-/Kleinschreibung. Folgende Zeichen wertet die Funktion als Trennzeichen zwischen Wörtern: Chr(0), Chr(9), Chr(10), Chr(11), Chr(12), Chr(13), Chr(32) – das gilt aber nicht für alle Gebietsschemata.
89
Funktionen und Anweisungen für Zeichenfolgen
StrConv- Funktion
Funktionen und Anweisungen für Zeichenfolgen
Beispiel
................................................... Beis piel
LSET s = StrConv(s, vbFromUnicode) ' ANSI-String für Ausgabe vorbereiten Print StrConv(s1, vbUnicode + vbProperCase) Verwandte Befehle
................................................... Verwa ndte Befehle
Chr, CStr
Funktionen und Anweisungen für Zeichenfolgen
String- Funktion Function String(lAnz As Long, iANSI As Integer) As String Function String(lAnz As Long, sVorgabe As String) As String Beschreibung
................................................... Bes c hreibung
Die Funktion String gibt es in zwei unterschiedlichen Varianten. Beide Varianten liefern eine Unicode-Zeichenfolge der Länge lAnz, die mit einem einzelnen Zeichen aufgefüllt ist. Für die erste Variante wird das Zeichen als ANSI-Code iANSI spezifiziert. Ist iANSI größer als 255, bildet die Funktion den Wert mittels einer Restwertdivision in das Intervall zwischen 0 und 255 ab. Die zweite Variante von String arbeitet mit beliebigen Unicode-Zeichen. In dieser Syntax verwendet die Funktion das erste Unicode-Zeichen der Zeichenfolge sVorgabe. Beispiel
................................................... Beis piel
Print StrToHex(String(2, 300)) ' Ausgabe: "2C 00 2C 00" Print StrToHex(String(2, ChrW(300))) ' Ausgabe: "2C 01 2C 01" Verwandte Befehle
................................................... Verwa ndte Befehle
LTrim, RTrim
StrReverse- Funktion Function StrReverse(s As String) As String Beschreibung
................................................... Bes c hreibung
Die Funktion StrReverse liefert eine Zeichenfolge, in der alle Zeichen der Zeichenfolge s in umgekehrter Reihenfolge enthalten sind. Bei Aufruf mit einer leeren Zeichenfolge ist das Ergebnis des Funktionsaufrufs gleichfalls eine leere Zeichenfolge. Ein Aufruf der Funktion mit Null führt dagegen zu einem Laufzeitfehler. Beispiel
................................................... Beis piel
Print StrReverse("ABCD")
' Ausgabe: "DCBA"
Trim- Funktion Function Trim(s As String) As String Beschreibung
................................................... Bes c hreibung
Die Funktion liefert eine Kopie der Zeichenfolge s zurück, die weder am Anfang noch am Ende Leerzeichen enthält.
90
UCase- Funktion
Beispiel
................................................... Beis piel
Print RTrim(LTrim(" Test ")) = Trim(" Test ") ' Gibt "Wahr" aus Verwandte Befehle
................................................... Verwa ndte Befehle
LTrim, RTrim
UCase- Funktion Function UCase(s As String) As String
................................................... Bes c hreibung
Die Funktion UCase liefert eine Kopie der im Parameter s übergebenen Zeichenfolge in Großschreibung zurück. Die leere Zeichenfolge Null wird wieder als Null zurückgegeben. Beispiel
................................................... Beis piel
If UCase(sTest1) = UCase(sTest2) Then
' Schreibweise egal
Verwandte Befehle
................................................... Verwa ndte Befehle
LCase
Val- Funktion Function Val(sZahl As String) As Double Beschreibung
................................................... Bes c hreibung
Die Funktion Val ist die Umkehrfunktion zu Str. Sie interpretiert die Zeichenfolge sZahl als Zahl in Standardnotation (mit Dezimalpunkt, nicht mit Dezimalkomma, da die Funktion keine Ländereinstellungen berücksichtigt) und liefert den Wert dieser Zahl. Anwendung
................................................... Anwendung
Val liefert auch einen Zahlenwert als Ergebnis, wenn sZahl mit einer Ziffernfolge beginnt und danach Zeichen folgen, die nichts mehr mit der Zahlendarstellung zu tun haben – so macht Val aus »12.34 Abfahrt Hamburg HBF« den Wert 12.34, aus »12,34 Abfahrt Hamburg HBF« jedoch 12. Um festzustellen, ob ein Wert vollständig als Zahl ausgewertet werden kann, steht die Boolean-Funktion IsNumeric zur Verfügung – sie liefert für beide Beispielzeichenfolgen False. Warnung
................................................... Wa rnung
Anders als die anderen Zeichenfolgenfunktionen arbeitet Val nicht mit der länderspezifischen Zahlendarstellung und will einen Punkt als Dezimalsymbol sehen. Dennoch ergeben sich im Zusammenspiel mit Str »seltsame Effekte«: Print Print Print Print
Val("10,1") Val("10.1") Str(10.1) Val(Str(10.1))
' ' ' '
Ausgabe: Ausgabe: Ausgabe: Ausgabe:
10 10,1 "10,1" 10,1 (seltsam,nicht?)
91
Funktionen und Anweisungen für Zeichenfolgen
Beschreibung
Mathematische und finanzmathematische Funktionen und Anweisungen
Beispiel
................................................... Beis piel
Private Sub Text1_Change() Text2.Text = Sqr(Val(Text1.Text)) End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
Mathematische und finanzmathematische Funktionen und Anweisungen
LCase
WeekdayName- Funktion Function WeekdayName( _ lTag As Long, _ [bAbk As Boolean = False], _ [FirstDayOfWeek As VbFirstDayOfWeek = vbUseSystemDayOfWeek]) _ As String Beschreibung
................................................... Bes c hreibung
Die Funktion WeekdayName liefert den zur Tageszahl lTag gehörigen Wochentag als Zeichenfolge. Hat der optionale Parameter bAbk den Wert False oder fehlt er, gibt die Funktion den vollen Namen zurück, ansonsten seine Abkürzung (zwei Buchstaben). Über den optionalen Parameter FirstDayOfWeek lässt sich zudem vorgeben, mit welchem Wochentag die Zählung beginnen soll. Fehlt er, beginnt die Zählung mit dem im System festgelegten Tag, und das ist der Montag. Tageszahlen, die nicht zwischen 1 und 7 liegen, führen zu einem Laufzeitfehler. Beispiel
................................................... Beis piel
Print WeekdayName(Weekday(Date))
' aktueller Wochentag ausgeschrieben
Verwandte Befehle
................................................... Verwa ndte Befehle
MonthName
Mathematische und finanzmathematische Funktionen und Anweisungen Wenn bei den Zeichenfolgen zuvor die Rede davon war, dass die Manipulation derselben schon immer eine der ureigensten Domänen der Programmiersprache Basic war, dann sollte das nicht etwa heißen, dass die Sprache in puncto Mathematik wenig zu bieten habe. Auch für die Formulierung mathematischer und numerischer Problematiken war die Sprache für sich genommen immer schon recht reichhaltig ausgestattet. Insbesondere bot die weitgehend interaktive Programmentwicklung eine enorme Flexibilität bei der Programmierung von On-the-fly-Anwendungen für die Lösung minder komplexer Problematiken, die nicht auf das überlegene Laufzeitverhalten von Compilersprachen angewiesen waren. Als problematisch erwiesen sich allerdings die fehlenden Mittel für eine geeignete Modularisierung und eine Anbindung an bereits bestehende mathematische Bibliotheken. Was die Modularisierbarkeit von Code betrifft, so hat sich Basic mit Visual Basic inzwischen zu einer wahrlich vorbildlichen Programmiersprache entwickelt. Die Möglichkeiten der Anbindung an bestehende mathematische Bibliotheken sind aber nach wie vor eher als lau einzustufen, da solche Bibliotheken (sofern sind nicht in Visual Basic selbst, als ActiveX-Bibliotheken
92
Mathematische und finanzmathematische Funktionen und Anweisungen
Bezeichner
Kurzbeschreibung
Abs
Liefert den Absolutwert (vorzeichenlosen Wert) einer Zahl
Atn
Liefert den Arcustangens einer Zahl als Winkel im Bogenmaß
Cos
Liefert den Cosinus zu einem Winkel im Bogenmaß
DDB
Liefert den Abschreibungswert eines Vermögenswerts über einen bestimmten Zeitraum bei geometrisch degressiver Abschreibung
Exp
Liefert den Wert der Exponentialfunktion (mit Basis e) zu einer Zahl
Fix
Liefert den Vorkommaanteil einer Dezimalzahl als Ganzzahl
FV
Liefert den künftigen Wert einer Annuität (Ansparung oder Kredit) bei konstanter Zahlung, konstantem Zins und fester Laufzeit
Int
Liefert den nächsten ganzzahligen Wert kleiner oder gleich einer Zahl
IPmt
Liefert den Zinsanteil für eine bestimmte Periode bei Abzahlung oder Ansparung mit konstanten Raten und konstantem Zinssatz
IRR
Liefert den internen Ertragssatz für eine Folge regelmäßiger Ein- und Auszahlungen
Log
Liefert den natürlichen Logarithmus einer Zahl
MIRR
Liefert den modifizierten internen Ertragssatz für eine Folge regelmäßiger, mit unterschiedlichen Zinssätzen behafteten Ein- und Auszahlungen
NPer
Liefert die Anzahl der Zeiträume für eine Annuität (Ansparung oder Kredit) bei konstanter Zahlung und konstantem Zins
NPV
Liefert den Nettobarwert einer Investition bei regelmäßigen Aus- und Einzahlungen und konstantem Diskontsatz
Pmt
Liefert den Auszahlungswert (Höhe der Rate bei Kredit) für eine Annuität mit einer festen Anzahl von Zeiträumen, konstanter Zahlung und konstantem Zins
PPmt
Liefert den Kapitalanteil (bei Kredit: Tilgung) eines bestimmten Zeitraums für eine Annuität (Ansparung oder Kredit) mit einer festen Anzahl von Zeiträumen, konstanter Zahlung und konstantem Zins
Mathematische und finanzmathematische Funktionen und Anweisungen
93
Mathematische und finanzmathematische Funktionen und Anweisungen
oder in C implementiert sind, und das sind Bibliotheken aus dem Bereich der Numerischen Mathematik auch heutzutage noch eher nicht, weil da immer noch FORTRAN herumgeistert) von ihrem Aufrufmodell her meist nicht kompatibel sind. Auch wenn es Visual Basic wohl nicht mehr zur lingua franca der numerischen Mathematik bringen wird, ihre mathematische und auch finanzmathematische Grundausstattung ist reichhaltig genug für die meisten Fragestellungen im naturwissenschaftlichen, wirtschaftlichen und informationstechnologischen Bereich, und es spricht inzwischen absolut nichts mehr gegen die Entwicklung eigener mathematischer Bibliotheken als solide Basis für künftige Projekte. Bei einer solchen Bibliothek kann es sich um eine Klassenbibliothek für abstrakte Datentypen handeln, so etwa für die Vektor- und Matrizenrechnung, oder um ein gewöhnliches Bibliotheksmodul, das spezifische Funktionen und Prozeduren etwa für den Bereich Statistik bereitstellt. Nichtsdestoweniger bleibt jede eigene Implementation von Datentypen und Operationen auf das mathematische Inventar der Sprache selbst angewiesen. Die folgende Tabelle gibt einen Überblick über die mathematischen und finanzmathematischen Funktionen und Anweisungen von Visual Basic.
Mathematische und finanzmathematische Funktionen und Anweisungen
Mathematische und finanzmathematische Funktionen und Anweisungen
Bezeichner
Kurzbeschreibung
PV
Liefert den Barwert für eine Annuität (Ansparung oder Kredit) bei konstanter Zahlung, konstantem Zins und fester Laufzeit
Randomize
Initialisiert den Zufallsgenerator mit einem Startwert
Rate
Liefert den Zinssatz zu einer Annuität (Anzahlung oder Kredit) mit einer festen Anzahl von Zeiträumen, konstanter Zahlung und konstantem Zins
Rnd
Liefert eine gleich verteilte Zufallszahl zwischen 0 und 1
Round
Liefert den Wert einer Zahl auf eine bestimmte Dezimalstelle gerundet
Sgn
Liefert das Vorzeichen eines Werts als Faktor (-1, 0 oder 1)
Sin
Liefert den Sinus zu einem Winkel im Bogenmaß
SLN
Liefert den periodischen Abschreibungswert eines Vermögenswerts bei linearer Abschreibung über einen bestimmten Zeitraum
Sqr
Liefert die Quadratwurzel eines positiven Zahlenwerts
SYD
Liefert den Abschreibungswert eines Vermögenswerts für eine bestimmte Periode nach dem Modell der Jahressummengewichtung
Tan
Liefert den Tangens zu einem Winkel im Bogenmaß
Mathematische und finanzmathematische Funktionen und Anweisungen Warnung
................................................... Wa rnung
Die mit Visual Basic 6 (SP3) vorliegende Implementation der finanzmathematischen Funktionen ist alles andere als fehlersicher. So erhält man in nicht klar zu bestimmenden Situationen oder bei Angabe falscher Parameterwerte gerne mal den lästigen Laufzeitfehler 480, »Anwendungsoder objektdefinierter Fehler«, den man im Lauf der aktuellen Visual-Basic-Sitzung nicht mehr los wird – selbst bei Angabe korrekter Parameterwerte. In diesem Fall hilft nur noch ein Neustart von Visual Basic. Tipp
................................................... Tipp
Aufgrund der internen Darstellung gewöhnlicher Zahlenwerte im hexadezimalen Format kommt es bei verschiedenen Funktionen zu Rundungsfehlern, die gerade im finanzmathematischen Bereich, aber auch anderswo für peinliche Fehler (so genannte »Pfennigfuchser-Fehler«) im Bereich der letzten Nachkommastelle sorgen können. Sie vermeiden solche Fehler, indem Sie für Währungsbeträge konsequent den Datentyp Currency und für dezimale Berechnungen mit nachfolgenden Rundungsoperationen den Datentyp Decimal einsetzen. Gegebenenfalls erforderliche Typumwandlungen nimmt Visual Basic dann implizit vor.
Abs- Funktion Function Abs(dZahl As Double) As Double Beschreibung
................................................... Bes c hreibung
Die Funktion Abs liefert den Absolutwert zu der Zahl dZahl, das heißt den Zahlenwert mit positivem Vorzeichen.
94
Atn- Funktion
Beispiel
................................................... Beis piel
DeltaX = Abs(MouseX – X) DeltaY = Abs(MouseY – Y) Verwandte Befehle
................................................... Verwa ndte Befehle
Sgn
Atn- Funktion Beschreibung
................................................... Bes c hreibung
Die zu den trigonometrischen Umkehrfunktionen zählende Arcustangensfunktion Atn ist die Umkehrfunktion der Tangensfunktion (Tan). Sie liefert den Arcustangens zu der Zahl d als Winkel im Bogenmaß. Das Ergebnis der Funktion liegt immer im offenen Intervall ]-π/2; π/2[. Für die Umwandlung in Grad ist der Wert mit 180/π = 57,2957795130823 zu multiplizieren. Anwendung
................................................... Anwendung
Diese Funktion berechnet den Winkel zwischen Hypothenuse und Ankathete eines rechtwinkligen Dreiecks, wenn deren Längen bekannt sind, bzw. den zu einem Tangenswert (Steigung) gehörigen Winkel. Tipp
................................................... Tipp
Da Visual Basic die Zahl π nicht als Konstante kennt, muss ein anderer Weg gefunden werden, an ihren Wert zu kommen. Ein sehr eleganter Weg ist die Berechnung des Werts über die Funktion Atn. Dim Pi As Double Pi = Atn(1) * 4
' 3.14159265358979
Beispiel
................................................... Beis piel
Print Atn(1)
' Ausgabe: 0,785398163397448
Verwandte Befehle
................................................... Verwa ndte Befehle
Cos, Sin, Tan
Cos- Funktion Function Cos(dWinkel As Double) As Double Beschreibung
................................................... Bes c hreibung
Die zu den trigonometrischen Funktionen zählende Cosinusfunktion Cos liefert den Cosinus zu dem im Bogenmaß angegebenen Winkel dWinkel. Das Ergebnis der Funktion liegt immer im Intervall [-1; 1]. Für die Umwandlung eines Gradwerts in das Bogenmaß ist der Wert mit π/180 = 1,74532925199433E-02 zu multiplizieren. Anwendung
................................................... Anwendung
Diese Funktion berechnet aus dem Winkel zwischen Ankathete und Hypothenuse die Ankathete eines rechtwinkligen Dreiecks mit Hypothenuse 1.
95
Mathematische und finanzmathematische Funktionen und Anweisungen
Function Atn(d As Double) As Double
Mathematische und finanzmathematische Funktionen und Anweisungen
Beispiel
................................................... Beis piel
Dim Pi As Double Pi = Atn(1) * 4 Print Cos(Pi / 3)
' 3.14159265358979 ' Ausgabe: 0,5
Verwandte Befehle
................................................... Verwa ndte Befehle
Mathematische und finanzmathematische Funktionen und Anweisungen
Atn, Sin, Tan
DDB- Funktion Function DDB( _ dKosten As Double, _ dRestwert As Double, _ dNutzungsDauer As Double, _ dPeriode As Double, _ [vFaktor As Variant = 2]) _ As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion DDB ermöglicht die Berechnung der Abschreibung einer Investition dKosten mit dem Restwert dRestwert nach der angenommenen Nutzungsdauer dNutzungsDauer für eine bestimmte Periode dPeriode. Fehlt der optionale Parameter vFaktor oder hat er den Wert 2, berechnet die Funktion den Abschreibungswert nach der geometrisch degressiven Methode, ansonsten mit der gleichen Formel, jedoch mit vFaktor als Degressionsfaktor. Anwendung
................................................... Anwendung
dNutzungsDauer und dPeriode muss die gleiche Einheit (Monate oder Jahre) zugrunde liegen. Diese Funktion berücksichtigt den Parameter dRestwert nur insofern, als sie 0 zurückliefert, wenn der Restwert für eine Periode bereits erreicht ist. Mit anderen Worten, die Funktion rechnet nicht mit der üblichen Formel ( Wert(Periode) – Restwert ) ⋅ Faktor DDB = -----------------------------------------------------------------------------------------------Nutzungszeit sondern nach der schlichteren Formel Wert(Periode) ⋅ Faktor DDB = ------------------------------------------------------------Nutzungszeit Das kann zwar verwirren, gestattet aber einen Test, nach wie vielen Perioden eine Investition einen bestimmten Restwert erreicht hat. Beispiel
................................................... Beis piel
Das folgende Codefragment zeigt, wie sich ein Wert von 10.000 € bei Abschreibung nach der geometrisch degressiven Methode und einer Laufzeit von 10 Jahren entwickelt: Laufzeit = 10 AnschaffungsWert = 10000 RestWert = 2000 For Per = 1 to Laufzeit – 1 Print DDB(AnschaffungsWert, RestWert, Laufzeit, Per) Next
96
Exp- Funktion
Verwandte Befehle
................................................... Verwa ndte Befehle
SLN, SYD
Exp- Funktion Function Exp(dZahl As Double) As Double Beschreibung
................................................... Bes c hreibung
Beispiel
................................................... Beis piel
Print Exp(1) Print Exp(Log(10))
' Ausgabe: 2,71828182845905 ' Ausgabe: 10
Verwandte Befehle
................................................... Verwa ndte Befehle
Log
Fix- Funktion Function Fix(dZahl As NumTyp) As NumTyp Beschreibung
................................................... Bes c hreibung
Die Rundungsfunktion Fix liefert den Ganzzahlanteil von dZahl, indem sie alle Nachkommastellen abschneidet. Sie weist damit die gleiche Funktionalität wie CInt auf. Im Gegensatz zu CInt richtet die Funktion den Datentyp des Rückgabewerts aber nach dem Datentyp des Parameters. Warnung
................................................... Wa rnung
Wie das Beispiel zeigt, ist die Dezimalrechnung mit den Datentypen Single und Double nicht immer exakt. Das liegt daran, dass die Repräsentation dieser Werte intern im hexadezimalen bzw. echten binären Zahlenformat erfolgt und viele endliche Dezimalbrüche im binären Zahlensystem nur als unendliche Binärbrüche darstellbar sind. Wenn Sie Exaktheit benötigen, müssen Sie mit einem der Datentypen Currency oder Decimal rechnen! Beispiel
................................................... Beis piel
a = 27.003 Print Fix(a) Print (a – Fix(a))
' Ausgabe: 27 ' Ausgabe: 3,00000000000011E-03
Dim b As Variant b = CDec(a) Print Fix(b) Print (b – Fix(b))
' Ausgabe: 27 ' Ausgabe: 0,003
Verwandte Befehle
................................................... Verwa ndte Befehle
CInt, Int, Round
97
Mathematische und finanzmathematische Funktionen und Anweisungen
Die Wachstumsfunktion Exp ist die Umkehrfunktion zur natürlichen Logarithmusfunktion Log. Sie liefert den Wert der Eulerschen Konstante (2,71828182845905) hoch dZahl.
Mathematische und finanzmathematische Funktionen und Anweisungen
FV- Funktion Function FV( _ dZins As Double, _ dLaufzeit As Double, _ dRate As Double, _ [vJetztWert], _ [vTermin]) _ As Double
Mathematische und finanzmathematische Funktionen und Anweisungen
Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion FV liefert den zukünftigen Wert einer Annuität mit einer Laufzeit von dLaufzeit Zahlungsperioden, konstantem Zins dZins und der Rate dRate. Der optionale Parameter vJetztWert ermöglicht die Angabe eines Ausgangswerts bei bereits erfolgter Ansparung. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Anwendung
................................................... Anwendung
Beachten Sie, dass die Werte für die Parameter dZins und dLaufzeit auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Funktion lässt sich sowohl zur Berechnung von Krediten als auch von Ansparungen verwenden, wird aber vorzugsweise für die Kreditberechnung eingesetzt, da der zukünftige Wert bei Ansparungen meist einen Ausgangswert darstellt. Bei der Kreditberechnung sind dRate und dJetztWert als negative Werte anzugeben, bei der Ansparberechnung als positive Werte. Tipp
................................................... Tipp
Die Funktionen PV und FV liefern mit vertauschten Vorzeichen für dRate und dJetztWert die gleichen Ergebnisse. Beispiel
................................................... Beis piel
Das folgende Codefragment zeigt, wie sich eine Ansparung mit einer monatlichen Rate von 100 € und einem Zinssatz von 10% p.a. mit und ohne eine Starteinlage von 10.000 € über zehn Jahre hin entwickelt: Laufzeit = 10 * 12 MonatsRate = 100 Zins = 0.1 / 12 Starteinlage = 10000 Print FV(Zins, Monatsrate, Laufzeit) ' -18619,84 Print FV(Zins, Monatsrate, Laufzeit, Starteinlage) ' -41550,28
Das gleiche als Kredit: Laufzeit = 10 * 12 MonatsRate = -100 Zins = 0.1 / 12 Starteinlage = -10000
98
Int- Funktion
Print FV(Zins, Monatsrate, Laufzeit) Print FV(Zins, Monatsrate, Laufzeit, Starteinlage)
' 8120,14 ' 12481,15
Verwandte Befehle
................................................... Verwa ndte Befehle
IPmt, IRR, NPer, NPV, Pmt, PPmt, PV
Int- Funktion Function Int(dZahl As NumTyp) As NumTyp Beschreibung
Die Rundungsfunktion Int liefert die nächste Ganzzahl kleiner gleich dZahl. Im Gegensatz zu Fix schneidet die Funktion nicht nur die Nachkommastellen ab, sondern rundet echt. Die Funktion richtet den Datentyp des Rückgabewerts nach dem Datentyp des Parameters. Warnung
................................................... Wa rnung
Wie das Beispiel zeigt, ist die Dezimalrechnung mit den Datentypen Single und Double nicht immer exakt. Das liegt daran, dass die Repräsentation dieser Werte intern im hexadezimalen bzw. echten binären Zahlenformat erfolgt und viele endliche Dezimalbrüche im binären Zahlensystem nur als unendliche Binärbrüche darstellbar sind. Wenn Sie Exaktheit benötigen, müssen Sie mit einem der Datentypen Currency oder Decimal rechnen. Beispiel
................................................... Beis piel
a = -27.002 Print Int(a) Print (a – Int(a))
' Ausgabe: -28 ' Ausgabe: 0,998000000000001
Dim b As Variant b = CDec(a) Print Int(b) Print (b – Int(b))
' Ausgabe: -28 ' Ausgabe: 0,998
Verwandte Befehle
................................................... Verwa ndte Befehle
CInt, Fix, Round
IPmt- Funktion Function IPmt( _ dZins As Double, _ dPeriode As Double, _ dLaufzeit As Double, _ dBarwert As Double, _ [vZukünftigerWert], _ [vTermin]) _ As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion IPmt (engl.: Interest Payment) liefert den Zinsanteil in der Periode dPeriode zu einer Annuität mit einer Laufzeit von dLaufzeit Zahlungsperioden, konstantem Zins dZins und dem Barwert dBarwert (vgl. »PV-Funktion«,
99
Mathematische und finanzmathematische Funktionen und Anweisungen
................................................... Bes c hreibung
Mathematische und finanzmathematische Funktionen und Anweisungen
S. 106). Der optionale Parameter vZukünftigerWert (vgl. »FV-Funktion«, S. 98) ermöglicht die Angabe eines zukünftigen Werts, der den nach der letzten Zahlung erreichten Kontostand angibt. Bei einem Kredit ist dieser Wert im Allgemeinen mit 0 anzugeben, was dem Vorgabewert für den Parameter entspricht. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Anwendung
Mathematische und finanzmathematische Funktionen und Anweisungen
................................................... Anwendung
Beachten Sie, dass die Werte für die Parameter dZins, dPeriode und dLaufzeit auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Funktion wird im Allgemeinen zur Berechnung von Krediten verwendet. Für die Kreditberechnung setzen Sie dBarwert auf die Höhe des Kredits (Zahlungsausgang) und vZukünftigerWert auf 0 (Kredit abbezahlt). Tipp
................................................... Tipp
Die Funktion PPmt liefert den Tilgungs- bzw. Kapitalanteil. Die Summe aus Tilgungs- bzw. Kapitalanteil und Zins entspricht der von der Funktion Pmt gelieferten Rate. Beispiel
................................................... Beis piel
Das Projekt ZinsAnteil zeigt, wie sich Zins und Tilgung prozentual für einen Kredit beliebiger Höhe bei einem Zinssatz von 10% p.a. über zehn Jahre hin entwickeln. ' Projekt: Annuität-Zinsanteil Const Laufzeit = 10 * 12 Const Zins = 0.1 / 12 Const mRate = 100
' 100 Prozent(!)
Private Sub Form_Load() AutoRedraw = True BarWert = PV(Zins, Laufzeit, mRate) ' Barwert in Prozent (!) ' Kreditmodalitäten Print "Laufzeit", Laufzeit; "Monate" Print "Zins p.a.", Zins * 12 * 100; "%" Print "Periode", "Zinsanteil (%)", "Tilgungsanteil (%)" Print String(40, "=") ' prozentualen Zins- und Tilgungsanteil ausgeben. For i = 1 To Laufzeit Step 12 Print i, Round(IPmt(Zins, i, Laufzeit, BarWert), 2), Print Round(PPmt(Zins, i, Laufzeit, BarWert), 2) Next i End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
FV, NPer, NPV, Pmt, PPmt, PV
IRR- Funktion Function IRR(dWerte() As Double[, vErwartet As Variant = 0.1)] As Double
1 00
Log- Funktion
Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion IRR (engl.: Internal Rate of Return) liefert den internen Ertragssatz für eine via dWerte() spezifizierte Folge regelmäßiger Ein- und Auszahlungen (Cash Flows). Fehlt der optionale Parameter vErwartet, rechnet die Funktion mit dem Erwartungswert 0,1, ansonsten mit dem angegebenen Wert. Anwendung
................................................... Anwendung
Beispiel
................................................... Beis piel
Das folgende Codefragment zeigt beispielhaft, wie die Analyse eines Unternehmens aussehen kann: Dim dWerte(9) As Double dWerte(0) = -50000 dWerte(1) = -25000 dWerte(2) = 0 dWerte(3) = 5000 dWerte(4) = -1000 dWerte(5) = 7000 dWerte(6) = 21000 dWerte(7) = 45000 dWerte(8) = 60000 dWerte(9) = 110000 Print Round(IRR(dWerte) * 100, 2)
' ' ' ' ' ' ' ' ' ' '
Investition bei Gründung Unternehmensaufbau Break Even Erster Gewinn im vierten Jahr Verlust wg. schwacher Konjunktur Gewinn im sechsten Jahr Gewinn im siebten Jahr Gewinn im achten Jahr Gewinn im neunten Jahr Gewinn im zehnten Jahr 17,32 Prozent
Verwandte Befehle
................................................... Verwa ndte Befehle
MIRR, Rate
Log- Funktion Function Log(dZahl As Double) As Double Beschreibung
................................................... Bes c hreibung
Die natürliche Logarithmusfunktion Log ist die Umkehrfunktion zur Wachstumsfunktion Exp. Sie liefert den Wert, mit dem man die Eulersche Konstante (2,71828182845905) potenzieren muss, um dZahl zu erhalten.
1 01
Mathematische und finanzmathematische Funktionen und Anweisungen
Der interne Ertragssatz ist der Zinssatz für eine Investition, die aus Ein- und Auszahlungen in regelmäßigen Abständen besteht, wobei sich aber das Verhältnis zwischen Ein- und Auszahlungen mit der Zeit verschieben kann (wie bei einem neuen Unternehmen üblich, das zu Beginn große Investitionen tätigt und seine Einnahmen erst mit der Zeit verbessert, bis der Break-even überschritten ist). Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Elemente des Arrays dWerte enthalten die Werte der Cash Flows. Dabei ist die Reihenfolge eine wichtige Größe. IRR wird iterativ berechnet. IRR verwendet vErwartet als Startwert und wiederholt die Berechnung so lange, bis das Ergebnis auf 0,00001 Prozent genau ist. Wenn nach 20 Versuchen kein Ergebnis gefunden werden kann (im Allgemeinen, weil vErwartet zu schlecht ist), generiert IRR den Laufzeitfehler 5.
Mathematische und finanzmathematische Funktionen und Anweisungen
Beispiel
................................................... Beis piel
Print Log(2.71828182845905) Print Exp(Log(10))
' Ausgabe: 1 ' Ausgabe: 10
Verwandte Befehle
................................................... Verwa ndte Befehle
Exp
Mathematische und finanzmathematische Funktionen und Anweisungen
MIRR- Funktion Function MIRR( _ dWerte() As Double, _ dZinsFinanz As Double, _ dZinsReinv As Double) _ As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion MIRR (engl.: Modified Internal Rate of Return) liefert den modifizierten internen Ertragssatz für eine via dWerte() spezifizierte Folge regelmäßiger Ein- und Auszahlungen (Cash Flows). Im Gegensatz zu IRR rechnet MIRR mit unterschiedlichen Zinssätzen für die Finanzierung ungedeckter Ausgaben (dZinsFinanz) und die Reinvestition von Gewinnen (dZinsReinv). Anwendung
................................................... Anwendung
Die beiden Zinswerte, dZinsFinanz und dZinsReinv, sind als Faktoren (Prozentwert dividiert durch 100) anzugeben. Beispiel
................................................... Beis piel
Das folgende Codefragment zeigt beispielhaft, wie die Analyse eines Unternehmens aussehen kann, wenn für Investitionen ein Zins von 10% und für Reinvestitionen der interne Ertragssatz des Unternehmens angesetzt wird: Dim dWerte(9) As Double dWerte(0) = -50000 ' Investition bei Gründung dWerte(1) = -25000 ' Unternehmensaufbau dWerte(2) = 0 ' Break Even dWerte(3) = 5000 ' Erster Gewinn im vierten Jahr dWerte(4) = -1000 ' Verlust wg. schwacher Konjunktur dWerte(5) = 7000 ' Gewinn im sechsten Jahr dWerte(6) = 21000 ' Gewinn im siebten Jahr dWerte(7) = 45000 ' Gewinn im achten Jahr dWerte(8) = 60000 ' Gewinn im neunten Jahr dWerte(9) = 110000 ' Gewinn im zehnten Jahr Print Round(IRR(dWerte) * 100, 2) ' 17,32 Prozent Print Round(MIRR(dWerte, 0.1, IRR(dWerte)) * 100, 2) ' 17,04 Prozent Verwandte Befehle
................................................... Verwa ndte Befehle
IRR, Rate
1 02
NPer- Funktion
NPer- Funktion Function NPer( _ dZins As Double, _ dRate As Double, _ dBarwert As Double, _ [vZukünftigerWert], _ [vTermin]) _ As Double Beschreibung
Die zu den finanzmathematischen Funktionen zählende Funktion NPer (engl.: Number of Periods) liefert die Laufzeit (Anzahl der Zahlungsperioden) einer Annuität mit konstantem Zins dZins und dem Barwert dBarwert (vgl. die Funktion »PV-Funktion« S. 106). Der optionale Parameter vZukünftigerWert (vgl. »FV-Funktion«, S. 98) ermöglicht die Angabe eines zukünftigen Werts, der den nach der letzten Zahlung erreichten Kontostand angibt. Bei einem Kredit ist dieser Wert im Allgemeinen mit 0 anzugeben, was dem Vorgabewert für den Parameter entspricht. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Anwendung
................................................... Anwendung
Beachten Sie, dass die Werte für die Parameter dZins, dRate auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen, wie der von der Funktionen erwartete Wert. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Wird die Funktion zur Berechnung eines Kredits eingesetzt, ist für dBarwert die Kredithöhe als negativer Wert zu spezifizieren. Wird die Funktion zur Berechnung einer Ansparung eingesetzt, ist für dBarwert der augenblickliche Wert der Ansparung als positiver Wert anzugeben und für vZukünftigerWert das Sparziel als negativer Wert. Beispiel
................................................... Beis piel
Das folgende Codefragment berechnet die Laufzeit für einen Kredit über 7.000 € zu 10% p.a. sowie die Laufzeit einer Ansparung zu denselben Bedingungen: Print NPer(0.1 / 12, 100, -7000) Print NPer(0.1 / 12, 100, 0, -7000)
' Laufzeit f. Kredit: 106 ' Laufzeit f. Ansparung: 55
Auf dieselben Ergebnisse kommt man auch mittels: Print -NPer(0.1 / 12, 100, 0, 7000) Print -NPer(0.1 / 12, 100, 7000)
' Laufzeit f. Kredit: 106 ' Laufzeit f. Ansparung: 55
Warnung
................................................... Wa rnung
Die Funktion liefert einen Laufzeitfehler, wenn die Kreditlaufzeit bei gegebenem Zins und gegebener Rate über alle Grenzen wachsen würde, sprich: die Rate zu klein ist, als dass jemals eine Tilgung erfolgen könnte. (Solche Kredite würden Banken natürlich am liebsten geben: Man zahlt ein Leben lang, und die Schulden werden immer größer.) Print NPer(0.1 / 12, 100, -20000)
' Laufzeitfehler
1 03
Mathematische und finanzmathematische Funktionen und Anweisungen
................................................... Bes c hreibung
Mathematische und finanzmathematische Funktionen und Anweisungen
Verwandte Befehle
................................................... Verwa ndte Befehle
FV, IPmt, NPV, Pmt, PPmt, PV
NPV- Funktion Function NPV(dDiskontsatz As Double Werte() As Double) As Double Beschreibung
Mathematische und finanzmathematische Funktionen und Anweisungen
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion NPV (engl.: Net Present Value) liefert den Nettobarwert einer Investition für eine via dWerte() spezifizierte Folge regelmäßiger Ein- und Auszahlungen (Cash Flows) bei festem Diskontsatz dDiskontsatz. Anwendung
................................................... Anwendung
Der Nettobarwert einer Investition ist der aktuelle Wert einer Folge zukünftiger regelmäßiger Aus- und Einzahlungen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Elemente des Arrays dWerte enthalten die Werte der erwarteten Cash Flows. Dabei ist die Reihenfolge eine wichtige Größe. Die Investition beginnt mit dem Zeitraum des ersten CashFlow-Werts und endet mit dem Auftreten des letzten Cash-Flow-Werts. Im Gegensatz zur Funktion PV, die den Barwert einer Folge von Zahlungen unveränderlicher Höhe bei konstantem Zins und konstanter Laufzeit berechnet, erlaubt NPV Zahlungen unterschiedlicher Höhe (und Vorzeichen) und ermittelt die Laufzeit selbstständig aus der Anzahl der Werte. Die Funktion geht davon aus, dass die Zahlungen jeweils zum Ende der Zahlungsperioden erfolgen. Bezieht sich der erste Cash Flow auf den Beginn des ersten Zeitraums, so muss die Folge mit der zweiten Zahlung beginnen und die erste Zahlung gesondert zum Ergebnis von NPV addiert werden. Beispiel
................................................... Beis piel
Das folgende Codefragment zeigt beispielhaft, wie die NPV-Analyse für ein Unternehmen aussehen kann: Dim dWerte(9) As Double dWerte(0) = -50000 dWerte(1) = -25000 dWerte(2) = 0 dWerte(3) = 5000 dWerte(4) = -1000 dWerte(5) = 7000 dWerte(6) = 21000 dWerte(7) = 45000 dWerte(8) = 60000 dWerte(9) = 110000 Print NPV(0.1, dWerte) Verwandte Befehle
' ' ' ' ' ' ' ' ' ' '
................................................... Verwa ndte Befehle
MIRR, Rate
1 04
Investition bei Gründung Unternehmensaufbau Break Even Erster Gewinn im vierten Jahr Verlust wg. schwacher Konjunktur Gewinn im sechsten Jahr Gewinn im siebten Jahr Gewinn im achten Jahr Gewinn im neunten Jahr Gewinn im zehnten Jahr 40254
Pmt- Funktion
Pmt- Funktion Function Pmt( _ dZins As Double, _ dLaufzeit As Double, _ dBarwert As Double, _ [vZukünftigerWert], _ [vTermin]) _ As Double Beschreibung
Die zu den finanzmathematischen Funktionen zählende Funktion Pmt (engl.: Payment) liefert die zu zahlende Rate zu einer Annuität mit einer Laufzeit von dLaufzeit Zahlungsperioden, konstantem Zins dZins und dem Barwert dBarwert (vgl. die Funktion »PV-Funktion«, S. 106). Der optionale Parameter vZukünftigerWert (vgl. die Funktion »FV-Funktion«, S. 98) ermöglicht die Angabe eines zukünftigen Werts, der den nach der letzten Zahlung erreichten Kontostand angibt. Bei einem Kredit ist dieser Wert im Allgemeinen mit 0 anzugeben, was dem Vorgabewert für den Parameter entspricht. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Anwendung
................................................... Anwendung
Beachten Sie, dass die Werte für die Parameter dZins und dLaufzeit auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Für die Kreditberechnung setzen Sie dBarwert auf die Höhe des Kredits (Zahlungsausgang) und vZukünftigerWert auf 0 (Kredit abbezahlt). Tipp
................................................... Tipp
Die Funktionen IPmt und PPmt liefern den Zinsanteil und den Kapitalanteil zu einer bestimmten Periode. Die Summe aus Kapitalanteil und Zinsanteil entspricht der von Pmt gelieferten Rate. Beispiel
................................................... Beis piel
Sie wollen einen Kredit über 250.000 € mit einer Laufzeit von 20 Jahren und einem festen Zinssatz von 8,3% aufnehmen. Die monatliche Rate berechnet sich dann zu: Print Pmt(.083 / 12, 20 * 12, -250000)
' Ausgabe: 2138
Die gleichen 250.000 € im Rahmen einer Lebensversicherung mit 4,6% Kapitalverzinsung angespart, ergibt eine monatliche Rate von: Print Pmt(.046 / 12, 20 * 12, 0, -250000)
' Ausgabe: 636,82
Man sieht, Geben ist eben doch billiger denn Nehmen. Verwandte Befehle
................................................... Verwa ndte Befehle
FV, IPmt, NPer, NPV, PPmt, PV
1 05
Mathematische und finanzmathematische Funktionen und Anweisungen
................................................... Bes c hreibung
Mathematische und finanzmathematische Funktionen und Anweisungen
PPmt- Funktion
Mathematische und finanzmathematische Funktionen und Anweisungen
Function PPmt( _ dZins As Double, _ dPeriode As Double, _ dLaufzeit As Double, _ dBarwert As Double, _ [vZukünftigerWert], _ [vTermin]) _ As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion PPmt (engl.: Principal Payment) liefert den Kapitalanteil in der Periode dPeriode zu einer Annuität mit einer Laufzeit von dLaufzeit Zahlungsperioden, konstantem Zins dZins und dem Barwert dBarwert (vgl. »PVFunktion«, S. 106). Der optionale Parameter vZukünftigerWert (vgl. »FV-Funktion«, S. 98) ermöglicht die Angabe eines zukünftigen Werts, der den nach der letzten Zahlung erreichten Kontostand angibt. Bei einem Kredit ist dieser Wert im Allgemeinen mit 0 anzugeben, was dem Vorgabewert für den Parameter entspricht. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Anwendung
................................................... Anwendung
Beachten Sie, dass die Werte für die Parameter dZins, dPeriode und dLaufzeit auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Funktion wird im Allgemeinen zur Berechnung von Krediten eingesetzt und liefert dann den Tilgungsanteil zu einer bestimmten Periode. Für die Kreditberechnung setzen Sie dBarwert auf die Höhe des Kredits (Zahlungsausgang) und vZukünftigerWert auf 0 (Kredit abbezahlt). Tipp
................................................... Tipp
Die Funktion IPmt liefert den Zinsanteil. Die Summe aus Tilgungs- bzw. Kapitalanteil und Zins entspricht der von der Funktion Pmt gelieferten Rate. Beispiel
................................................... Beis piel
Vgl. das Beispiel in »IPmt-Funktion« (S. 99). Verwandte Befehle
................................................... Verwa ndte Befehle
FV, IPmt, NPer, NPV, Pmt, PV
PV- Funktion Function PV( _ dZins As Double, _ dLaufzeit As Double, _ dRate As Double, _ [vJetztWert], _ [vTermin]) _ As Double
1 06
Randomize- Anweisung
Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion PV (engl.: Payment Value) liefert den Barwert einer Annuität mit einer Laufzeit von dLaufzeit Zahlungsperioden, konstantem Zins dZins und der Rate dRate. Der optionale Parameter vJetztWert ermöglicht die Angabe eines Ausgangswerts bei bereits erfolgter Ansparung. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Anwendung
Beachten Sie, dass die Werte für die Parameter dZins und dLaufzeit auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Funktion lässt sich sowohl zur Berechnung von Krediten als auch von Ansparungen verwenden, wird aber vorzugsweise für die Ansparberechnung eingesetzt, da der Barwert bei Krediten üblicherweise einen Ausgangswert darstellt. Bei der Kreditberechnung sind dRate und dJetztWert als positive Werte anzugeben, bei der Ansparberechnung als negative Werte. Tipp
................................................... Tipp
Die Funktionen PV und FV liefern mit vertauschten Vorzeichen für dRate und dJetztWert die gleichen Ergebnisse. Beispiel
................................................... Beis piel
Das folgende Codefragment ermittelt den Barwert einer auf 100.000 € abgeschlossenen Lebensversicherung mit einer Laufzeit von 35 Jahren und einem Zinssatz von 4,45%: Zins = 0.045/12 Laufzeit = 35 * 12 Ansparung = -100000 Raten = Pmt(Zins, Laufzeit, 0, Ansparung) Barwert = PV(Zins, Laufzeit, Raten) ZukWert = FV(Zins, Laufzeit, Raten)
' 99,33 ' 21126,98 ' 100000 Probe stimmt!
Verwandte Befehle
................................................... Verwa ndte Befehle
FV, IPmt, IRR, NPer, NPV, Pmt, PPmt
Randomize- Anweisung Sub Randomize ([vSeed]) Beschreibung
................................................... Bes c hreibung
Die Anweisung Randomize initialisiert den Zufallsgenerator mit einem Startwert (engl.: Seed). Ausgehend von diesem Startwert lässt sich mittels der Zufallsfunktion Rnd eine gleich verteilte Sequenz von Zufallszahlen berechnen. Zu einem bestimmten Startwert liefert der Zufallsfunktion Rnd immer die gleiche Folge. Dabei benutzt sie jeweils den zuletzt gelieferten Wert als neuen Startwert. Fehlt vSeed, nimmt die Anweisung den von der Funktion Timer gelieferten Wert als Startwert.
1 07
Mathematische und finanzmathematische Funktionen und Anweisungen
................................................... Anwendung
Mathematische und finanzmathematische Funktionen und Anweisungen
Anwendung
................................................... Anwendung
Mathematische und finanzmathematische Funktionen und Anweisungen
Eine wirklich zufällige Initialisierung des Zufallsgenerators lässt sich erreichen, indem man den Wert der Funktion Timer als Startwert benutzt, der die Anzahl der seit Mitternacht (Systemzeit) vergangenen Sekunden liefert. Wird Randomize in einem Programm dagegen gar nicht ausgeführt, arbeitet Visual Basic mit dem Vorgabewert 0 als Startwert. Um im gleichen Programmlauf mehrere Folgen von Zufallszahlen mit deterministischem Startwert zu erzeugen, übergeben Sie der Funktion Rnd jeweils bei Berechnung des letzten Folgenelements einen negativen Wert und rufen danach Randomize mit dem Startwert der nächsten Folge auf. Beispiel
................................................... Beis piel
Der Startwert 10 sorgt dafür, dass Rnd reproduzierbar die folgende »Zufallsfolge« {0,5749933; 0,2375866; 0,5295308; 0,2520258} generiert: Randomize 10 Print Rnd(1), Rnd(1), Rnd(1), Rnd(1) Rnd(-1) Randomize Timer Print Rnd(1), Rnd(1), Rnd(1), Rnd(1)
' Folge für Startwert 10 ' Randomize vorbereiten ' wirklich zufällige Folge
Verwandte Befehle
................................................... Verwa ndte Befehle
Rnd
Rate- Funktion Function Rate( _ dLaufzeit As Double, _ dRate As Double, _ dBarWert As Double, _ [vZukünftigerWert], _ [vTermin]) _ [vSchätzung As Variant = 0.1] As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion Rate liefert den Zinssatz einer Annuität mit dem Barwert (vgl. »PV-Funktion«, S. 106) dBarWert, einer Laufzeit von dLaufzeit Zahlungsperioden und der Zahlungsrate dRate. Der optionale Parameter vZukünftigerWert (vgl. »FV-Funktion«, S. 98) ermöglicht die Angabe eines zukünftigen Werts, der den nach der letzten Zahlung erreichten Kontostand angibt. Bei einem Kredit ist dieser Wert im Allgemeinen mit 0 anzugeben, was dem Vorgabewert für den Parameter entspricht. Umgekehrt ist bei einer Ansparung dBarWert mit 0 anzugeben. Fehlt der optionale Parameter vTermin oder ist er 0, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Ende einer Periode erfolgt; ist der Wert dagegen 1, geht die Funktion davon aus, dass die Ratenzahlung jeweils zu Beginn einer Periode erfolgt. Da die Funktion das Ergebnis mit einem iterativen Verfahren berechnet, benötigt sie für den Start der Iteration einen Schätzwert vSchätzung. Fehlt dieser optionale Parameter, arbeitet die Funktion mit dem Vorgabewert 0,1.
1 08
Rnd- Funktion und Rnd- Anweisung
Anwendung
................................................... Anwendung
Beachten Sie, dass die Werte für die Parameter dRate und dLaufzeit auf denselben Einheitszeitraum (meist Monat oder Jahr) bezogen sein müssen. Für alle finanzmathematischen Funktionen gilt, dass Zahlungsausgänge durch negative Zahlen und Zahlungseingänge durch positive Zahlen dargestellt werden. Die Funktion lässt sich sowohl bei der Berechnung von Krediten als auch von Ansparungen verwenden. Bei der Kreditberechnung ist dBarwert als negativer Wert anzugeben, bei der Ansparberechnung dBarwert als 0 und dZukünftigerWert als negativer Wert. Beispiel
................................................... Beis piel
dLaufzeit = 35 * 12 dZukWert = -250000 dRate = 250 Print Rate(dLaufzeit, dRate, 0, dZukWert) * 1200; "%" ' Ausgabe: 4,42 % Verwandte Befehle
................................................... Verwa ndte Befehle
FV, IPmt, NPer, NPV, Pmt, PPmt, PV
Rnd- Funktion und Rnd- Anweisung Function Rnd [(vSchalter)] As Single Sub Rnd ([vSchalter]) Beschreibung
................................................... Bes c hreibung
Rnd lässt sich sowohl als Funktion als auch als Anweisung verwenden. Die Anweisung unterscheidet sich von der Funktion nur insoweit, als sie keinen Wert liefert. Die Zufallsfunktion Rnd ermittelt ausgehend von einem Startwert eine Zufallszahl mit dem Datentyp Single, die dem halboffenen Intervall [0; 1[ entstammt. Die Berechnung ist gleichverteilt, das heißt, jede der im Intervall als Single darstellbaren Zahlen wird mit gleicher Wahrscheinlichkeit ermittelt. Der Wert des optionalen Parameters vSchalter bestimmt, wie die Funktion mit dem Startwert verfährt. Fehlt der Parameter oder ist sein Wert größer als 0, berechnet die Funktion jeweils die nächste Zufallszahl aus der vorangegangenen, indem sie diese als Startwert verwendet. Damit liefert Rnd eine deterministische Folge von Zufallszahlen, die durch den ersten Startwert ausgewählt wird. Standardmäßig initialisiert Visual Basic den Startwert für jeden Programmlauf auf 0, so dass Rnd ohne weitere Vorkehrungen in der Tat die immer gleiche Folge liefert. Um eine andere Folge auszuwählen, muss der Startwert zuvor mittels der Anweisung Randomize explizit gesetzt werden. Hat der Parameter vSchalter den Wert 0, liefert Rnd erneut die vorangegangene Zufallszahl. Ist vSchalter dagegen ein negativer Wert, legt die Funktion dem nächsten Aufruf den durch Randomize (erneut) gesetzten Startwert zugrunde. Anwendung
................................................... Anwendung
Im Allgemeinen wird man vor dem ersten Rnd-Aufruf einen Randomize-Aufruf setzen, der für eine Auswahl der Zufallsfolge sorgt. Eine wirklich zufällige Initialisierung des Zufallsgenerators lässt sich erreichen, indem man den Wert der Funktion Timer, die die Anzahl der seit Mittnacht (Systemzeit) vergangenen Sekunden liefert, als Startwert einsetzt. Dazu reicht es, Randomize ohne Angabe eines Parameters auszuführen. Um im gleichen Programmlauf mehrere Folgen von Zufallszahlen mit deterministischem Startwert zu erzeugen, setzen Sie vor jeden Randomize-Aufruf die Anweisung Rnd(-1).
1 09
Mathematische und finanzmathematische Funktionen und Anweisungen
Das folgende Codefragment ermittelt den Zins in Prozent für eine Ansparung über 250.000 € mit einer Laufzeit von 35 Jahren und einer monatlichen Rate von 250 €:
Mathematische und finanzmathematische Funktionen und Anweisungen
Beispiel
................................................... Beis piel
Vgl. das Beispiel zu »Randomize-Anweisung« (S. 107). Verwandte Befehle
................................................... Verwa ndte Befehle
Randomize Verwandte Themen
................................................... Verwandte Them en
Mathematische und finanzmathematische Funktionen und Anweisungen
Zeitgeber-Steuerelement (Timer) (S. 432)
Round- Funktion Function Round(dZahl As NumTyp, [iDezStellen As Integer = 0]) As NumTyp Beschreibung
................................................... Bes c hreibung
Die Rundungsfunktion Round führt eine Kaufmannsrundung durch. Fehlt der Parameter iDezimalstellen oder hat der den Wert 0, liefert die Funktion die nächste Ganzzahl in der Umgebung von dZahl und führt dabei – im Gegensatz zu Fix und Int – eine echte Kaufmannsrundung durch. Jeder andere positive Wert für iDezimalstellen benennt eine Dezimalstelle hinter dem Komma, an der die Rundung stattfinden soll. Die Funktion richtet den Datentyp des Rückgabewerts nach dem Datentyp des Parameters. Warnung
................................................... Wa rnung
Wie das Beispiel zeigt, ist die Dezimalrechnung mit den Datentypen Single und Double nicht immer exakt. Das liegt daran, dass die Repräsentation dieser Werte intern im hexadezimalen bzw. echten binären Zahlenformat erfolgt und viele endliche Dezimalbrüche im binären Zahlensystem nur als unendliche Binärbrüche darstellbar sind. Im Zusammenhang mit der Funktion Round kann das zu peinlichen Fehlern führen. Wenn Sie Exaktheit benötigen, müssen Sie mit einem der Datentypen Currency oder Decimal rechnen. Beispiel
................................................... Beis piel
Print Print Print Print Print Print
Round(14.005, Round(14.015, Round(14.025, Round(14.035, Round(14.045, Round(14.055,
2) 2) 2) 2) 2) 2)
' ' ' ' ' '
14 14,02 14,02 14,04 14,04 14,06
(erwartet: 14,01) (korrekt) (erwartet 14,03) (korrekt) (erwartet 14,03) (korrekt)
Verwandte Befehle
................................................... Verwa ndte Befehle
CInt, Fix, Int
Sgn- Funktion Function Sgn(dZahl As NumTyp) As Integer Beschreibung
................................................... Bes c hreibung
Die Vorzeichenfunktion Sgn liefert das Vorzeichen des Werts dZahl als Faktor. Das Ergebnis ist 1, wenn dZahl positiv ist, 0, wenn dZahl 0 ist, und -1, wenn dZahl negativ ist.
110
Sgn- Funktion
Anwendung
................................................... Anwendung
Die Funktion Sgn ist zuweilen nützlich, wenn es darum geht, Laufzeitoptimierungen vorzunehmen und If-Anweisungen durch geschicktere Formulierung logischer Ausdrücke zu vereinfachen oder ganz zu vermeiden. Beispiel
................................................... Beis piel
Die folgende Zeile wird erheblich schneller verarbeitet als die auskommentierte If-Anweisung (allerdings haben die beiden Formulierungen nicht die gleiche Semantik, da Nullwerte nicht mitgezählt werden):
In der folgenden, dem Projekt Apfelmann entstammenden Routine führt die Formulierung der zeitaufwändigen If-Abfrage mit den Funktionen Abs und Sgn zu einer Laufzeitverbesserung um immerhin ca. 30 %. Messen Sie es nach, indem Sie einmal die eine und einmal die andere Zeile auskommentieren! Private Sub Apfel(m_x1, m_x2, m_y1, m_y2, step_x, step_y) Dim r1 As Double, re As Double, im As Double Dim zr As Double, zi As Double, it As Long Zeit = Timer For zr = m_x1 To m_x2 Step step_x ' alle Spalten in x-Richtung For zi = m_y1 To m_y2 Step step_y ' alle Punkte in Spalte zr re = 0 ' Realteil initialisieren im = 0 ' Imaginärteil initialisieren For it = 0 To cMaxIterat ' Iteration für Punkt r1 = re * re – im * im + zr im = 2 * re * im + zi re = r1 ' If re < -cGrenze Or re > cGrenze Or im < -cGrenze Or im > cGrenze Then If Sgn(cGrenze – Abs(re)) + Sgn(cGrenze – Abs(im)) = -2 Then PSet (zr, zi), it * 16 ' Punkt ausgeben Exit For End If Next it Next zi Next zr Caption = Timer – Zeit End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
CInt, Fix, Int
111
Mathematische und finanzmathematische Funktionen und Anweisungen
Dim lZähler As Long Zeit = Timer ' Laufzeitmessung beginnen For i = 1 To 1000000 zv = Rnd – 0.5 lZähler = lZähler + Sgn(zv) ' If zv > 0 Then lZähler = lZähler + 1 Else lZähler = lZähler – 1 Next Caption = Timer – Zeit ' Laufzeit als Titelzeile ausgeben
Mathematische und finanzmathematische Funktionen und Anweisungen
Sin- Funktion Function Sin(dWinkel As Double) As Double Beschreibung
................................................... Bes c hreibung
Die zu den trigonometrischen Funktionen zählende Sinusfunktion Sin liefert den Sinus zu dem im Bogenmaß angegebenen Winkel dWinkel. Das Ergebnis der Funktion liegt immer im Intervall [-1; 1]. Für die Umwandlung eines Gradwerts in das Bogenmaß ist der Wert mit π/180 = 1,74532925199433E-02 zu multiplizieren.
Mathematische und finanzmathematische Funktionen und Anweisungen
Anwendung
................................................... Anwendung
Diese Funktion berechnet aus dem Winkel zwischen Ankathete und Hypothenuse die Gegenkathete eines rechtwinkligen Dreiecks mit Hypothenuse 1. Beispiel
................................................... Beis piel
Dim Pi As Double Pi = Atn(1) * 4 Print Sin(Pi / 6)
' 3.14159265358979 ' Ausgabe: 0,5 [= Sin(30°)]
Verwandte Befehle
................................................... Verwa ndte Befehle
Atn, Cos, Tan
SLN- Funktion Function SLN( _ dAnschaffungsKosten As Double, _ dRestwert As Double, _ dNutzungsDauer As Double) _ As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion SLN (engl.: Straight Line Depreciation) berechnet die periodische Abschreibung einer Investition dAnschaffungsKosten mit dem Restwert dRestwert über die Nutzungsdauer dNutzungsDauer nach dem linearen (arithmetischen) Abschreibungsmodell. Anwendung
................................................... Anwendung
Der von SLN gelieferte Wert bezieht sich auf die gleiche Einheit (Monate oder Jahre) wie dNutzungsDauer. Er errechnet sich wie folgt: Anschaffungswert – Endwert SLN = --------------------------------------------------------------------------Nutzungsdauer Beispiel
................................................... Beis piel
Print SLN(10000, 100, 10) Verwandte Befehle
' Ausgabe 990
................................................... Verwa ndte Befehle
DDB, SYD
112
Sqr- Funktion
Sqr- Funktion Function Sqr(dPositiveZahl As Double) As Double Beschreibung
................................................... Bes c hreibung
Die Wurzelfunktion Sqr liefert die Quadratwurzel von dPositiveZahl. Ist der Wert von dPositiveZahl negativ, meldet die Funktion einen Laufzeitfehler. Beispiel
................................................... Beis piel
det = (b * b – 4 * a * c) If det < 0 Then Print "Keine Lösung" If det = 0 Then Print "x1, x2 = "; -b / 2 / a If det > 0 Then Print "x1 = "; (-b + det) / 2 / a Print "x2 = "; (-b – det) / 2 / a End If Verwandte Befehle
................................................... Verwa ndte Befehle
^ (Operator)
SYD- Funktion Function SYD( _ dAnschaffungsKosten As Double, _ dRestwert As Double, _ dNutzungsDauer As Double_ dPeriode As Double) _ As Double Beschreibung
................................................... Bes c hreibung
Die zu den finanzmathematischen Funktionen zählende Funktion SYD (engl.: Sum of Years Depreciation) berechnet die periodische Abschreibung einer Investition dAnschaffungsKosten mit dem Restwert dRestwert über die Nutzungsdauer dNutzungsDauer für die Periode dPeriode nach dem Abschreibungsmodell der Jahressummengewichtung. Beispiel
................................................... Beis piel
Der folgende Code zeigt eine alternative Implementation der Funktion SYD: Function MySYD(Wert, Rest, Nutzung, per) d = Nutzung * (Nutzung + 1) / 2 MySYD = (Wert – Rest) / d * (Nutzung + 1 – per) End Function
Beide Funktionen liefern die gleichen Werte: For per = 1 To 10 Print SYD(10000, 100, 10, per), Print MySYD(10000, 100, 10, per) Next
' 1800, 1620, 1440, 1260,... ' 1800, 1620, 1440, 1260,...
113
Mathematische und finanzmathematische Funktionen und Anweisungen
Das folgende Codefragment berechnet die Lösung(en) der allgemeinen quadratischen Gleichung ax² + bx +c = 0:
Funktionen und Anweisungen für Datums- / Zeitwerte
Verwandte Befehle
................................................... Verwa ndte Befehle
DDB, SLN
Tan- Funktion Function Tan(dWinkel As Double) As Double Beschreibung
Funktionen und Anweisungen für Datums- / Zeitwerte
................................................... Bes c hreibung
Die zu den trigonometrischen Funktionen zählende Tangensfunktion Tan liefert den Tangens zu dem im Bogenmaß angegebenen Winkel dWinkel. Die Umkehrfunktion zu Tan ist Atn. Für die Umwandlung von Grad in das Bogenmaß ist der Wert mit π/180 = 1,74532925199433E-02 zu multiplizieren. Anwendung
................................................... Anwendung
Diese Funktion berechnet aus dem Winkel zwischen Ankathete und Hypothenuse die Steigung der Hypothenuse, welche ihrerseits als Quotient zwischen Ankathete und Gegenkathete definiert ist. Beispiel
................................................... Beis piel
Dim Pi As Double Pi = Atn(1) * 4 Print Sin(Pi / 4) / Cos(Pi / 4) Print Tan(Pi / 4)
' 3.14159265358979 ' 1 ' 1
Verwandte Befehle
................................................... Verwa ndte Befehle
Atn, Cos, Sin
Funktionen und Anweisungen für Datums- / Zeitwerte Mit der zunehmenden Bedeutung von Visual Basic als Programmiersprache für Front-endAnwendungen im Datenbankbereich versteht es sich beinahe von selbst, dass die Sprache insbesondere für solche Datentypen Äquivalente anbietet, die bei der Datenbankprogrammierung gemeinhin als grundlegende Datentypen gehandelt werden. Die Welt der Datums-/Zeitwerte und ihrer Operationen stellt nicht zuletzt aus diesem Grund neben der Welt der Zeichenfolgen und der Welt der numerischen Datentypen eine eigene Kategorie dar, um die Visual Basic die Sprache Basic bereichert hat. Werte des Typs Date repräsentiert Visual Basic als 64-Bit-Gleitkommazahlen (8 Bytes) nach IEEE und kann somit Datumsangaben im Bereich zwischen dem 1. Januar 100 und dem 31. Dezember 9999 sowie Uhrzeiten im Bereich von 0:00:00 bis 23:59:59 unterscheiden. Datumswerte können Datumsangaben und Zeitangaben kombinieren, aber auch je einzeln ausdrücken. Der Notation literaler Datums- und Zeitangaben liegt das amerikanische Format zugrunde, das heißt, in Datumsangaben wird der Monat vor dem Tag notiert, die Abtrennung erfolgt durch das Zeichen »/«, und Zeitangaben sind in 12-StundenDarstellung gefolgt von »PM« oder »AM« zu treffen. Zudem ist die Darstellung durch ein führendes und ein abschließendes #-Zeichen einzuschließen. An Operationen für den Datentyp Date hält Visual Basic eine ganze Latte parat, die mehr oder weniger etwas mit der Konvertierung unter Berücksichtigung verschiedener Notationen oder mit der Extraktion einer bestimmten Teilinformation zu tun haben. Die folgende Tabelle gibt einen Überblick über alle für diesen Datentyp relevanten Funktionen und Anweisungen:
114
Funktionen und Anweisungen für Datums- / Zeitwerte
Kurzbeschreibung
CDate
Interpretiert eine Zeichenfolge oder einen Zahlenwert als Datums-/Zeitwert
Date
Liefert das aktuelle Systemdatum als Datums-/Zeitwert
Date
Setzt den Datumsanteil von Datums-/Zeitwert als aktuelles Systemdatum
DateAdd
Berechnet die Summe aus einem Datums-/Zeitwert und einem Zeitintervall, das wahlweise in Sekunden, Minuten, Stunden, Tage etc. anzugeben ist
DateDiff
Berechnet das Zeitintervall zwischen zwei Datums-/Zeitwerten und liefert das Ergebnis wahlweise in einer der Einheiten Sekunden, Minuten, Stunden, Tage etc.
DatePart
Liefert eine Teilinformation aus einem Datums-/Zeitwert, wahlweise Sekunden, Minuten, Stunden, Tage etc.
DateSerial
Setzt einen Datums-/Zeitwert aus Ganzzahlwerten (Tag, Monat und Jahr) zusammen
DateValue
Interpretiert eine Zeichenfolge oder einen Zahlenwert als Datumsanteil von Datums-/Zeitwert
Day
Liefert den Tag aus einem Datums-/Zeitwert als Zahlenwert (1 bis 31)
FileDateTime
Liefert den Zeitpunkt der Erstellung bzw. letzten Änderung einer Datei als Datums-/Zeitwert
FormatDateTime
Liefert die Darstellung eines Datums-/Zeitwerts als Zeichenfolge im spezifizierten Format
Hour
Liefert die Stunde aus einem Datums-/Zeitwert als Zahlenwert (0 bis 23)
Minute
Liefert die Minute aus einem Datums-/Zeitwert als Zahlenwert (0 bis 59)
Month
Liefert den Monat aus einem Datums-/Zeitwert als Zahlenwert (1 – 12)
MonthName
Liefert für einen Zahlenwert zwischen 1 und 12 den Monatsnamen als Zeichenfolge
Now
Liefert Systemdatum und -zeit als Datums-/Zeitwert
Second
Liefert die Sekunde aus einem Datums-/Zeitwert als Zahlenwert (0 bis 59)
Time
Liefert die aktuelle Systemzeit als Datums-/Zeitwert
Time
Setzt den Zeitanteil von Datums-/Zeitwert als aktuelle Systemzeit
Timer
Liefert den Wert des System-Timers (Sekunden seit Mitternacht)
TimeSerial
Setzt einen Datums-/Zeitwert aus Ganzzahlwerten (Sekunde, Minute, Stunde) zusammen
TimeValue
Interpretiert eine Zeichenfolge oder einen Zahlenwert als Zeitanteil eines Datums-/Zeitwerts
WeekDay
Liefert den Wochentag aus einem Datums-/Zeitwert als Zahl (1 bis 7)
WeekDayName
Liefert den Wochentag als Zeichenfolge für Werte zwischen 1 und 7
Year
Liefert das Jahr aus einem Datums-/Zeitwert als Zahlenwert
Auf Datum und Zeit bezogene Funktionen und Anweisungen
115
Funktionen und Anweisungen für Datums- / Zeitwerte
Bezeichner
Funktionen und Anweisungen für Datums- / Zeitwerte
CDate- Funktion Function CDate(vWert) As Date Siehe »Typumwandlung« (S. 57).
Date- Funktion und Date- Anweisung Function Date() As Date Date = datDatum Beschreibung
Funktionen und Anweisungen für Datums- / Zeitwerte
................................................... Bes c hreibung
Als Funktion liefert Date das aktuelle Systemdatum und als Anweisung setzt Date das aktuelle Systemdatum (dauerhaft). Beispiel
................................................... Beis piel
Immer häufiger spielen sich Shareware-Programme als Timeware-Programme auf, indem sie nach einer gewissen Zeit überraschend die Arbeit einstellen und einen so dazu »überreden« wollen, sich für die Vollversion registrieren zu lassen. Für die Übergangszeit bietet sich ein kleines Visual-Basic-Programm namens SharewareTrick an, das kurz am Systemdatum dreht: Dim datSystem As Date Private Sub Form_Load() datSystem = Date Date = "1.1.00" Zeitware = Shell("notepad.exe", vbNormalFocus) Timer1.Interval = 10000 End Sub Private Sub Timer1_Timer() Timer1.Interval = 0 Date = datSystem End End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
Now, Time
DateAdd- Funktion Function DateAdd(Interval As String, Number As Double, Date) As Date Beschreibung
................................................... Bes c hreibung
Die Funktion DateAdd addiert zu einem gegebenen Datums-/Zeitwert Date ein Zeitintervall Number, dem die Einheit Interval zugrunde gelegt ist. Wert für Interval
Beschreibung
"yyyy"
Die Funktion interpretiert Number als Jahre
"q"
Die Funktion interpretiert Number als Quartale
"m"
Die Funktion interpretiert Number als Monate
116
DateDiff- Funktion
Wert für Interval
Beschreibung
"ww"
Die Funktion interpretiert Number als Wochen
"d", "w", "y"
Die Funktion interpretiert Number als Tage
"h"
Die Funktion interpretiert Number als Stunden
"n"
Die Funktion interpretiert Number als Minuten
"s"
Die Funktion interpretiert Number als Sekunden
Anwendung
Der Datentyp Date verwendet für die interne Darstellung von Datums-/Zeitwerten einen Wert vom Typ Double, der sich nicht so ohne Weiteres in seine Bestandteile (Sekunden, Minuten, Stunden, Tage, Wochen, Monate Jahre) zerlegen lässt. Mit der Funktion DateAdd stellt Visual Basic ein bequemes Mittel für das Rechnen mit Zeitwerten zur Verfügung. Beachten Sie, dass der Wertebereich von Date auf Datums-/Zeitwerte zwischen dem 1.1.100 und dem 31.12.9999 beschränkt ist. Beispiel
................................................... Beis piel
Die folgende Zeile berechnet den Datums-/Zeitwert für ein Ereignis, das NewInterval Sekunden in der Zukunft gelegen ist. m_TriggerTime = DateAdd("s", NewInterval, Now)
Ein praxisnahes Beispiel für die Anwendung dieser Funktion ist das im Praxisteil vorgestellte Projekt LongTimer (vgl. »LongTimer – der Timer mit Ausdauer«, S. 599). Verwandte Befehle
................................................... Verwa ndte Befehle
DateDiff, DatePart, DateSerial, DateValue, TimeSerial
DateDiff- Funktion Function DateDiff(Interval As String, Date1, Date2, [FirstDayOfWeek As VbFirstDayOfWeek = vbSunday], _ [FirstWeekOfYear As VbFirstWeekOfYear = vbFirstJan1]) _ As Long Beschreibung
................................................... Bes c hreibung
Die Funktion DateDiff bildet die Differenz aus den beiden Datums-/Zeitwerten Date2 und Date1 und liefert das Ergebnis als Ganzzahl in der Einheit Interval. Die optionalen Parameter FirstDayOfWeek und FirstWeekOfYear beziehen sich auf exotische Formen der Datumsdarstellung und können im Allgemeinen getrost weggelassen werden. Wert für Interval
Beschreibung
"yyyy"
Funktion liefert das Ergebnis in der Einheit »Jahre»
"q"
Funktion liefert das Ergebnis in der Einheit »Quartale»
"m"
Funktion liefert das Ergebnis in der Einheit »Monate»
"w", "ww"
Funktion liefert das Ergebnis in der Einheit »Wochen»
117
Funktionen und Anweisungen für Datums- / Zeitwerte
................................................... Anwendung
Funktionen und Anweisungen für Datums- / Zeitwerte
Wert für Interval
Beschreibung
"d", "y"
Funktion liefert das Ergebnis in der Einheit »Tage»
"h"
Funktion liefert das Ergebnis in der Einheit »Stunden»
"n"
Funktion liefert das Ergebnis in der Einheit »Minuten»
"s"
Funktion liefert das Ergebnis in der Einheit »Sekunden»
Anwendung
Funktionen und Anweisungen für Datums- / Zeitwerte
................................................... Anwendung
Der Datentyp Date verwendet für die interne Darstellung von Datums-/Zeitwerten einen Wert vom Typ Double, der sich nicht so ohne Weiteres in seine Bestandteile (Sekunden, Minuten, Stunden, Tage, Wochen, Monate Jahre) zerlegen lässt. Mit der Funktion DateDiff stellt Visual Basic ein bequemes Mittel für das Rechnen mit Zeitwerten zur Verfügung. Beachten Sie, dass der Wertebereich von Date auf Datums-/Zeitwerte zwischen dem 1.1.100 und dem 31.12.9999 beschränkt ist. Warnung
................................................... Wa rnung
Die Reihenfolge der Parameter Date1 und Date2 ist leider kontraintuitiv gewählt. DateDiff rechnet: Date2 – Date1. Beispiel
................................................... Beis piel
Die folgende Zeile berechnet die Anzahl der Sekunden, die seit der Geburtsstunde des Autors verstrichen sind: Print DateDiff("s", #3/3/1959 11:32:00 PM#, Now)
Ein praxisnahes Beispiel für die Anwendung dieser Funktion ist das im Praxisteil vorgestellte Projekt LongTimer (vgl. »LongTimer – der Timer mit Ausdauer«, S. 599). Verwandte Befehle
................................................... Verwa ndte Befehle
DateAdd, DatePart, DateSerial, DateValue, TimeSerial
DatePart- Funktion Function DatePart( _ Interval As String, Date, [FirstDayOfWeek As VbFirstDayOfWeek = vbSunday], _ [FirstWeekOfYear As VbFirstWeekOfYear = vbFirstJan1]) _ As Long Beschreibung
................................................... Bes c hreibung
Die Funktion DatePart extrahiert den über den Parameter Interval spezifizierten Bestandteil des Datums-/Zeitwerts Date und liefert ihn als Wert vom Typ Long. Die optionalen Parameter FirstDayOfWeek und FirstWeekOfYear beziehen sich auf exotische Formen der Datumsdarstellung und können im Allgemeinen getrost weggelassen werden.
118
DateSerial- Funktion
Wert für Interval
Beschreibung
"yyyy"
Funktion extrahiert die Information »Jahre»
"q"
Funktion extrahiert die Information »Quartale»
"m"
Funktion extrahiert die Information »Monate»
"ww"
Funktion extrahiert die Information »Wochen»
"w"
Funktion extrahiert die Information »Tag der Woche» Funktion extrahiert die Information »Tag im Jahr» Funktion extrahiert die Information »Tag im Monat»
"h"
Funktion extrahiert die Information »Stunden»
"n"
Funktion extrahiert die Information »Minuten»
"s"
Funktion extrahiert die Information »Sekunden»
Anwendung
................................................... Anwendung
Der Datentyp Date verwendet für die interne Darstellung von Datums-/Zeitwerten einen Wert vom Typ Double, der sich nicht so ohne Weiteres in seine Bestandteile (Sekunden, Minuten, Stunden, Tage, Wochen, Monate Jahre) zerlegen lässt. Mit der Funktion DatePart stellt Visual Basic ein bequemes Mittel für das Zerlegen von Datums-/Zeitwerten zur Verfügung. Beispiel
................................................... Beis piel
Print "Diese Woche ist die " & DatePart("ww", Now) & ". Kalenderwoche" Verwandte Befehle
................................................... Verwa ndte Befehle
Day, Hour, Minute, Month, MonthName, Second, WeekDay, Year
DateSerial- Funktion Function DateSerial( _ iJahr As Integer, iMonat As Integer, iTag As Integer) As Date Beschreibung
................................................... Bes c hreibung
Die Funktion DateSerial generiert aus den Ganzzahlwerten iTag, iMonat und iJahr einen Datums-/Zeitwert. Anwendung
................................................... Anwendung
Die Funktion prüft die Werte der Parameter nicht, das heißt, sie löst auch keinen Laufzeitfehler aus, wenn die Komponenten kein reelles Datum ergeben. Wichtig ist nur das Resultat: Es darf sich kein Datum vor dem 1.1.100 und nach dem 31.12.9999 ergeben. Auf diese Weise gestattet die Funktion sehr schön das Rechnen mit relativen Zeitangaben wie: heute, vor zwei Jahren, drei Monaten, vier Tagen. Wenn Sie versuchen, dies allgemein »zu Fuß« auszurechnen, werden Sie merken, dass Sie schnell in des Teufels Küche geraten, da die Monate unterschiedlich lang sind und unser Gregorianische Kalender eine nicht unkomplizierte Schaltregel hat.
119
Funktionen und Anweisungen für Datums- / Zeitwerte
"y" "d"
Funktionen und Anweisungen für Datums- / Zeitwerte
Beispiel
................................................... Beis piel
Funktionen und Anweisungen für Datums- / Zeitwerte
Mit DateSerial gerät die Lösung des genannten Problems zum Einzeiler. Probieren Sie es aus; für den 1.1.2001 stimmt die alternative Lösung, für den 1.1.2000 dagegen nicht. d = Date Date = "1.1.2000" ' Date = "1.1.2001" Print DateSerial(Year(Date) – 2, Month(Date) – 3, Day(Date) – 4) Print Date – 2 * 365 – 3 * 31 – 4 ' alternative Lösung Date = d
Ein praxisnahes Beispiel für die Anwendung dieser Funktion ist das Projekt FormatDemo (vgl. »Format-Funktion«, S. 69), das einen Halbjahreskalender ausgibt. Verwandte Befehle
................................................... Verwa ndte Befehle
TimeSerial
DateValue- Funktion Function DateValue( sDatum As String) As Date Beschreibung
................................................... Bes c hreibung
Die Funktion DateValue interpretiert die Zeichenfolge sDatum als Datum und generiert daraus einen Datums-/Zeitwert. Falls die Zeichenfolge auch Zeitangaben enthält, werden diese nicht berücksichtigt. Anwendung
................................................... Anwendung
Was die Notation des Datums betrifft, ist DateValue weitgehend tolerant. So ergänzt die Funktion bei fehlendem Jahr das aktuelle Jahr aus dem Systemdatum des Computers und akzeptiert darüber hinaus neben dem kurzen und dem langen Datumsformat (entsprechend den auf dem System geltenden Datumseinstellungen) auch mittlere Datumsformate, in denen der Monat mit mindestens drei Buchstaben abgekürzt ist und Tag und Monat gegebenenfalls vertauscht sind. Tipp
................................................... Tipp
CDate und TimeValue unterscheiden sich insofern, als CDate auch Werte anderer Datentypen als String in einen Datums-/Zeitwert umsetzt und zusätzlich auch einen Zeitanteil berücksichtigt. Beispiel
................................................... Beis piel
Viele Wege führen nach Rom! Print Print Print Print Print Print Print Print Print
1 20
DateValue("1.2") DateValue("1. Feb") DateValue("1. Febr.") DateValue("1. Februar 00") DateValue("Feb, 1 00") DateValue("00, Feb 01 ") DateValue("1.2.00") DateValue("1.2.2000 ") DateValue("1. Feb")
' ' ' ' ' ' ' ' '
"01.02.2000" "01.02.2000" "01.02.2000" "01.02.2000" "01.02.2000" "01.02.2000" "01.02.2000" "01.02.2000" "01.02.2000"
Day- Funktion
Verwandte Befehle
................................................... Verwa ndte Befehle
TimeSerial, CDate
Day- Funktion Function Day(datWert As Date) As Integer Beschreibung
................................................... Bes c hreibung
Beispiel
................................................... Beis piel
Siehe »Format-Funktion« (S. 69) und das dort vorgestellte Projekt FormatDemo. Verwandte Befehle
................................................... Verwa ndte Befehle
DatePart, Hour, Minute, Month, Second, Year
FileDateTime- Funktion Function FileDateTime(sPfad As String) As Date Siehe »FileDateTime-Funktion« (S. 139 ).
FormatDateTime- Funktion Function FormatDateTime(vData, _ BenanntesFormat As VbDateTimeFormat = vbGeneralDate]) _ As String Siehe »FormatDateTime-Funktion« (S. 74 ) und »Format-Funktion« (S. 69).
Hour- Funktion Function Hour(datWert As Date) As Integer Beschreibung
................................................... Bes c hreibung
Die Funktion Hour liefert den Stundenanteil des Datums-/Zeitwerts datWert als Ganzzahl zwischen 0 und 23. Beispiel
................................................... Beis piel
Print "Es ist"; Minute(Time); " Minuten und "; Second(Time); _ "Sekunden nach"; Hour(Time) Verwandte Befehle
................................................... Verwa ndte Befehle
DatePart, Day, Minute, Month, Second, Year
Minute- Funktion Function Minute(datWert As Date) As Integer
1 21
Funktionen und Anweisungen für Datums- / Zeitwerte
Die Funktion Day liefert den Tagesanteil des Datums-/Zeitwerts datWert als Ganzzahl zwischen 1 und 31.
Funktionen und Anweisungen für Datums- / Zeitwerte
Beschreibung
................................................... Bes c hreibung
Die Funktion Minute liefert den Minutenanteil des Datums-/Zeitwerts datWert als Ganzzahl zwischen 0 und 59. Beispiel
................................................... Beis piel
Print "Es ist"; Minute(Time); " Minuten und "; Second(Time); _ "Sekunden nach"; Hour(Time)
Funktionen und Anweisungen für Datums- / Zeitwerte
Verwandte Befehle
................................................... Verwa ndte Befehle
DatePart, Day, Hour, Month, Second, Year
Month- Funktion Function Month(datWert As Date) As Integer Beschreibung
................................................... Bes c hreibung
Die Funktion Month liefert den Monatsanteil des Datums-/Zeitwerts datWert als Ganzzahl zwischen 1 und 12. Beispiel
................................................... Beis piel
Siehe »Format-Funktion« (S. 69) und das dort vorgestellte Projekt FormatDemo. Verwandte Befehle
................................................... Verwa ndte Befehle
DatePart, Day, Hour, Minute, Second, Year
MonthName- Funktion Function MonthName(lMonat As Long, bAbk As Boolean = False) As String Siehe »MonthName-Funktion« (S. 82).
Now- Funktion Function Now() As Date Beschreibung
................................................... Bes c hreibung
Die Funktion Now liefert die aktuelle Systemzeit mit Datums- und Zeitanteil. Beispiel
................................................... Beis piel
Print Now Verwandte Befehle
................................................... Verwa ndte Befehle
Time, Date
Second- Funktion Function Second(datWert As Date) As Integer
1 22
Time- Funktion und Time- Anweisung
Beschreibung
................................................... Bes c hreibung
Die Funktion Second liefert den Sekundenanteil des Datums-/Zeitwerts datWert als Ganzzahl zwischen 0 und 59. Beispiel
................................................... Beis piel
Print "Es ist"; Minute(Time); " Minuten und "; Second(Time); _ "Sekunden nach"; Hour(Time) Verwandte Befehle
DatePart, Day, Hour, Month, Minute, Year
Time- Funktion und Time- Anweisung Function Time() As Date Time = datZeit Beschreibung
................................................... Bes c hreibung
Als Funktion liefert Time die aktuelle Systemzeit und als Anweisung setzt Time den Datums-/ Zeitwert datZeit als aktuelle Systemzeit (dauerhaft). Anwendung
................................................... Anwendung
Wer nicht gerade eine Uhr programmiert, dürfte sehr gut ohne diese Funktion bzw. Anweisung auskommen. Es kommt zwar häufiger vor, dass man die aktuelle Systemzeit ausgeben muss – so etwa beim Drucken oder wenn Datensätze mit Zeitstempeln versehen werden müssen, im Allgemeinen wird dann aber die Funktion Now die bessere Lösung sein, da sie den Zeit- und den Datumsanteil der Systemzeit ermittelt. Wenn es dagegen um die Bestimmung von Zeiträumen innerhalb eines Tages geht, so etwa für Laufzeitmessungen, wird die Funktion Timer die bessere Wahl sein. Anwendung
................................................... Anwendung
Wer kennt das nicht? Das Dokument ist erst in der Nacht fertig geworden, und der Empfänger braucht das nicht unbedingt zu wissen. Anstatt umständlich auf den Zeitstempel der Datei loszugehen, ist es geschickter, der Anwendung eine Zeit lang eine falsche Zeit vorzugaukeln, während sie die Datei abspeichert. Genau das macht das Beispielprojekt ZeitStempel. ' Projekt: Zeitstempel Const cVerzögerung = 10 Const cZivilZeit = #3:59:00 PM# Dim datSysZt As Date
' Sekunden ' Kurz vor Feierabend
Private Sub Form_Load() datSysZt = Time Time = cZivilZeit Timer1.Interval = cVerzögerung * 1000 End Sub
' aktuelle Zeit merken ' Kurz vor Feierabend ... ' Timer setzen
Private Sub Timer1_Timer() Timer1.Interval = 0 t = Time
1 23
Funktionen und Anweisungen für Datums- / Zeitwerte
................................................... Verwa ndte Befehle
Funktionen und Anweisungen für Datums- / Zeitwerte
Time = datSysZt + (t – cZivilZeit) If Time < datSysZt Then Date = Date + 1 End End Sub
' Zeit richtig korrigeren ' Mitternachtskorrektur ' und Tschüss
Verwandte Befehle
................................................... Verwa ndte Befehle
Now, Date
Funktionen und Anweisungen für Datums- / Zeitwerte
Timer- Funktion Function Timer() As Single Beschreibung
................................................... Bes c hreibung
Die Funktion Timer liefert die seit Mitternacht (Systemzeit) vergangene Zeit in Sekunden mit Nachkommaanteil als Fließkommawert einfacher Genauigkeit (Windows 9x: in 18tel Sekundenschritten; Windows NT: in 50stel Sekundenschritten). Beispiel
................................................... Beis piel
Siehe die Beispiele zu »Sgn-Funktion« (S. 110). Verwandte Befehle
................................................... Verwa ndte Befehle
Time, Date
TimeSerial- Funktion Function TimeSerial( _ iStd As Integer, iMin As Integer, iSek As Integer) As Date Beschreibung
................................................... Bes c hreibung
Die Funktion TimeSerial generiert aus den Ganzzahlwerten iStd, iMin und iSek einen Datums-/ Zeitwert. Anwendung
................................................... Anwendung
Die Funktion prüft die Werte der Parameter nicht, das heißt, sie löst auch keine Laufzeitfehler aus, wenn die Komponenten keine reelle Zeit ergeben. Ergibt die akkumulierte Zeit einen Wert größer #23:59:59# oder kleiner #0:00:00#, liefert die Funktion gleichzeitig einen Datumsoffset bezogen auf das Referenzdatum 30.12.1899. Auf diese Weise gestattet die Funktion sehr schön das Rechnen mit relativen Zeitangaben wie: »vor 22 Stunden, 97 Minuten und 123 Sekunden«. Beispiel
................................................... Beis piel
cZt = #11:11:11# For iSek = 0 to 400 Step 10 Print TimeSerial(Hour(cZt), Minute(cZt), Second(cZt) + iSek) next iSek Verwandte Befehle
................................................... Verwa ndte Befehle
DatePart, DateSerial
1 24
TimeValue- Funktion
TimeValue- Funktion Function TimeValue(sZeit As String) As Date Beschreibung
................................................... Bes c hreibung
Die Funktion DateValue interpretiert die Zeichenfolge sZeit als Zeitangabe und generiert daraus einen Datums-/Zeitwert. Falls die Zeichenfolge auch Datumsangaben enthält, werden diese nicht berücksichtigt. Anwendung
................................................... Anwendung
Tipp
................................................... Tipp
CDate und TimeValue unterscheiden sich insofern, als CDate auch Werte anderer Datentypen als String in einen Datums-/Zeitwert umsetzt und zusätzlich einen Datumsanteil berücksichtigt. Beispiel
................................................... Beis piel
Alle Zeitangaben notieren die gleiche Zeit: Print Print Print Print Print Print Print
TimeValue("13:0") TimeValue("13:00:00") TimeValue("1 pm") TimeValue("13 pm") TimeValue("13 am") TimeValue("1 PM") TimeValue("13 AM")
' ' ' ' ' ' '
"13:00:00" "13:00:00" "13:00:00" "13:00:00" "13:00:00" "13:00:00" "13:00:00"
Verwandte Befehle
................................................... Verwa ndte Befehle
DateValue, CDate
Weekday- Funktion Function Weekday( _ datDatum As Date, _ [FirstDayOfWeek As VbDayOfWeek = vbSunday]) _ As Integer Beschreibung
................................................... Bes c hreibung
Die Funktion Weekday interpretiert den Datums-/Zeitwert datDatum als Zeitangabe und liefert dazu den Wochentag als Ganzzahl zwischen 1 und 7. Fehlt der optionale Parameter FirstDayOfWeek oder hat er den Wert vbSunday, interpretiert die Funktion den Sonntag als ersten Tag der Woche, ansonsten den Tag, den die Konstante ausdrückt. Warnung
................................................... Wa rnung
Microsoft hat den Standardwert für den Parameter FirstDayOfWeek nicht richtig gewählt, da der Aufruf Weekday(Now) ein falsches Ergebnis liefert. In unseren Sphären gilt der Montag als erster Tag der Woche – wohl aufgrund der biblischen Devise »und am Siebten Tage ruhte der Herr«. Es empfiehlt sich daher, die Funktion mit dem Wert vbMonday für ErsteTagWoche aufzurufen.
1 25
Funktionen und Anweisungen für Datums- / Zeitwerte
Was die Notation der Zeit betrifft, ist TimeValue weitgehend tolerant, solange nur das Trennzeichen »:« erscheint und die Zeitangabe reell ist. So interpretiert die Funktion fehlende Minutenund Sekundenanteile als »00« und kommt auch mit den Zusätzen »am«, »AM«, »pm« und »PM« zurecht, wenn die Zeit in 12-Stunden-Darstellung notiert ist.
Dateiorientierte Funktionen und Anweisungen
Beispiel
................................................... Beis piel
Alle Zeitangaben notieren die gleiche Zeit: Print WeekdayName(Weekday(Now)) Print WeekdayName(Weekday(Now, vbMonday))
' Falscher Wochentag!!! ' Richtiger Wochentag
Verwandte Befehle
................................................... Verwa ndte Befehle
Dateiorientierte Funktionen und Anweisungen
DatePart, DateValue, CDate
WeekdayName- Funktion Function WeekdayName( _ lTag As Long, _ [bAbk As Boolean = False], _ [FirstDayOfWeek As VbFirstDayOfWeek = vbUseSystemDayOfWeek]) _ As String Siehe »WeekdayName-Funktion« (S. 92).
Year- Funktion Function Year(datWert As Date) As Integer Beschreibung
................................................... Bes c hreibung
Die Funktion Year liefert den Jahresanteil des Datums-/Zeitwerts datWert als Ganzzahl zwischen 100 und 9999. Beispiel
................................................... Beis piel
Siehe »Format-Funktion« (S. 69) und das dort vorgestellte Projekt FormatDemo. Verwandte Befehle
................................................... Verwa ndte Befehle
DatePart, Day, Hour, Minute, Month, Second
Dateiorientierte Funktionen und Anweisungen Um es gleich vorwegzunehmen: Visual Basic weist nicht mehr die ursprüngliche Geschlossenheit der Sprache Basic gegenüber dem Dateisystem und der dateibezogenen Ein- und Ausgabe auf. Die Sache ist komplizierter geworden, denn verloren gegangen ist eher wenig, hinzugekommen dagegen viel. Freilich sind da noch die traditionellen Mittel, wohlbekannte Befehle wie Open, Input, Print#, Get, Put und Close, mit denen sich letztlich jeder Datei zu Leibe rücken lässt und die auch eine gesunde Basis für das delikate Thema der Abwärtskompatibilität darstellen. Zudem sind die dateisystembezogenen Befehle ChDir, ChDrive, MkDir, RmDir, Name weiterhin vorhanden. Ja, sie haben sogar noch Gesellschaft in Form recht nützlicher Befehle wie Dir, FileCopy, FileLen, GetAttr und SetAttr usw. erhalten, die man sich zu Zeiten von QBasic etwa noch als entsprechende DOS-Kommandos mit Zeichenfolgenoperationen selbst zusammenbasteln und über die Shell-Anweisung ausführen musste. Darüber hinaus versteht es sich schon fast von selbst, dass Dateinamen inzwischen lang und Pfadangaben UNC-konform (engl.: Universal Naming Convention, dazu gleich mehr) sein können, was letztlich Tür und Tor für den netzwerkweiten Zugriff auf Dateien öffnet, ohne auf logische Laufwerke oder andere Krücken aus der DOSZeit angewiesen zu sein. Damit lässt sich schon was anfangen.
1 26
Dateiorientierte Funktionen und Anweisungen
Bezeichner
Kurzbeschreibung
ChDir
Ändert das aktuelle Arbeitsverzeichnis
ChDrive
Setzt das aktuelle logische Laufwerk
Auf Dateioperationen bezogene Funktionen und Anweisungen
1 27
Dateiorientierte Funktionen und Anweisungen
Komplett neu ist dagegen alles, was der Sprache von der objektorientierten Seite her an Potenzial zuteil geworden ist. So beispielsweise das FileSystemObject-Objekt, das als operative Grundlage des Windows-Explorers ein wahres Füllhorn an Möglichkeiten darstellt, wenn es darum geht, etwas über das Dateisystem in Erfahrung zu bringen, Manipulationen darin vorzunehmen oder auch nur mit Textdateien zu arbeiten. Zudem ist das Tor weit offen für beliebige Erweiterungen in dieser Richtung – es steht Ihnen frei, Ihre ganz persönliche Klassenbibliothek für dateibezogenene Operationen zu schreiben und fortan alle Dateizugriffe über die darin definierten Objekte abzuwickeln. Das könnte beispielsweise den Vorteil haben, dass diese Objekte Ihren Anwendungen den ganzen Ballast logistischer und formaler Natur abnehmen, den bestimmte Dateiformate so mit sich bringen. Paradebeispiel für diesen Ansatz sind die Anweisungen LoadPicture, SavePicture, Load und Unload. (Wer genau hinsieht, wird erkennen, dass zumindest die ersten drei Anweisungen in BLoad und BSave ihre Vorläufer hatten). So bequem solche Operationen auch sind, ihre Implementation – und da beißt die Maus keinen Faden ab – lebt letztlich wieder von den erwähnten traditionellen Mitteln des Dateizugriffs, es sei denn, man kann dafür von entsprechenden – zumeist in C oder C++ geschriebenen – Bibliotheksroutinen profitieren oder gar von Betriebssystemroutinen aus der reichhaltigen Windows API (vgl. hierzu »Routinen aus DLLs und der Windows-API einsetzen«, S. 185). Ein etwas konsequenterer Ansatz, der der Idee der objektorientierten Programmierung näher steht, besteht darin, die im Programm verwendeten Datenstrukturen selbst als Objekte zu verpacken und ihnen Operationen wie SaveMyObject und LoadMyObject zu spendieren. Ein komplexes Objekt, das seinerseits verschiedene Objekte als Elemente enthält, wird in seiner SaveMethode dann schlicht die Save-Methoden dieser Objekte aufrufen usw. Wann immer aber – und das gilt auf letzter Ebene für alle Objektrepräsentationen – die Werte elementarer Datentypen zu speichern sind, geht es ans »Eingemachte«, und die traditionellen Mittel sind wieder gefragt. Das alles ist aber noch nicht genug. Tatkräftige Unterstützung gibt es auch noch vonseiten der Steuerelemente. Da wären schon mal die Standardsteuerelemente der Klassen FileListBox und DriveListBox, die eine interaktive Auswahl von Dateien und logischen Laufwerken ermöglichen. Da wären die Standarddialoge, die eine große Hilfe beim Öffnen und Speichern von Dateien darstellen und eine Fülle von Operationen so ganz nebenbei und kostenlos mit sich bringen (vgl. »Standarddialoge-Steuerelement (CommonDialog)«, S. 444). Und nicht zuletzt wäre da auch noch die schier unerschöpfliche Fülle an Möglichkeiten, mittels so genannter Datenquellen (Data-Steuerelement, RemoteData-Steuerelement, ADO-Daten-Steuerelement, ADORecordset-Objekte) sowie DAO- und ADO-Objekten mit Daten zu hantieren, die in Datenbanken organisiert sind. Nicht nur weil die historische Entwicklung der Sprache Basic es so hervorgebracht hat, sondern auch weil es der Aufbau dieses Buches so will, geht es erst im Kapitel »Objekte und Klassen« (S. 195) um die Dateioperationen von Objekten – und da eher nur am Rande. Ein wenig über den Umgang mit Datenbanken finden Sie im Abschnitt »Data-Datensteuerelement (Data)« (S. 402). Wer aber die in diesem Abschnitt vorgestellte traditionelle Grundlage aller Dateioperationen kennt und verstanden hat, wird auf der objektorientierten Seite keine Not haben, beides miteinander zu verheiraten. Die folgende Tabelle gibt einen Überblick über die traditionellen Funktionen und Anweisungen, die unmittelbar oder mittelbar etwas mit Dateizugriffen zu tun haben.
Dateiorientierte Funktionen und Anweisungen
Dateiorientierte Funktionen und Anweisungen
Bezeichner
Kurzbeschreibung
Close
Schließt eine oder mehrere zuvor geöffnete Dateien
CurDir
Liefert das aktuelle Arbeitsverzeichnis auf dem angegebenen logischen Laufwerk
Dir
Liefert den nächsten Dateinamen, der auf ein Suchmuster passt
Environ
Liefert eine oder alle Umgebungsvariablen
EOF
Testet, ob das Dateiende erreicht ist
FileAttr
Ermittelt den Öffnungsmodus einer Datei
FileCopy
Kopiert eine Datei
FileDateTime
Liefert den Zeitpunkt der Erstellung bzw. letzten Änderung einer Datei als Datums-/Zeitwert
FileLen
Liefert die Länge einer Datei in Bytes
FreeFile
Liefert die nächste freie Dateinummer
Get
Liest Daten aus einer indexsequenziellen Datei oder Binärdatei
GetAttr
Liefert die Attribute einer Datei oder eines Ordners bzw. Verzeichnisses
Input
Liest die angegebene Anzahl an Zeichen aus einer Datei und liefert diese als Unicode-Zeichenfolge
Input #
Liest den Wert einer oder mehrerer Variablen aus einer Textdatei
InputB
Liest die angegebene Anzahl an Bytes aus einer Datei und liefert diese als Bytearray (ANSI-Zeichenfolge)
Kill
Löscht alle Dateien, die auf das angegebene Suchmuster passen
Line Input #
Liest eine Zeile aus einer geöffneten sequenziellen Datei in eine Variable vom Typ String ein
Loc
Liefert die aktuelle Schreib- bzw. Leseposition (Byte-Nummer) einer geöffneten Datei
Lock
Regelt die Zugriffsmöglichkeiten anderer Programme auf eine bereits geöffnete Datei
LOF
Liefert die Länge einer Datei in Bytes
LSet
Zuweisungsoperation, die Daten beliebiger Datentypen für die Ausgabe in eine Datei als Zeichenfolge aufbereitet
MkDir
Generiert ein neues Verzeichnis
Name
Benennt eine Datei um oder verschiebt diese in ein anderes Verzeichnis
Open
Öffnet eine Datei zum Lesen oder Schreiben
Print#
Schreibt Daten im gebietsspezifischen Format in eine sequenzielle Datei
Put
Schreibt Daten in eine indexsequenzielle Datei oder Binärdatei
Reset
Schließt alle geöffneten Dateien
RmDir
Löscht ein Verzeichnis
Seek
Liefert die aktuelle Schreib- oder Leseposition in einer geöffneten Datei
Auf Dateioperationen bezogene Funktionen und Anweisungen
1 28
Dateiorientierte Funktionen und Anweisungen
Bezeichner
Kurzbeschreibung
Seek
Setzt die aktuelle Schreib- oder Leseposition in einer geöffneten Datei
SetAttr
Setzt ein oder mehrere Attribute für eine Datei oder ein Verzeichnis
Shell
Startet eine andere Anwendung und liefert deren Task-ID
Unlock
Regelt die Zugriffsmöglichkeiten anderer Programme auf eine bereits geöffnete Datei
Write#
Schreibt Daten in standardisiertem Format in eine sequenzielle Datei
UNC- Pfad und Laufwerkspfad Ein wichtige Größe im Umgang mit Dateien ist ihre Position im lokalen Dateisystem respektive im Netzwerk. Um eine irgendwo im Netzwerk (das kann auch auf dem lokalen System sein) gelegene Datei anzusprechen, geben Sie den UNC-Pfad der Datei an, der nach folgendem Schema notiert wird: \\Server\Freigabe\[Verzeichnis ... \]Dateiname.Erw
Liegt die Datei dagegen auf dem lokalen Computer oder existiert für seine im Netzwerk gelegene Position eine Netzlaufwerkverbindung, die der betreffenden Freigabe einen Laufwerksbuchstaben Laufw zuordnet, lässt sie sich auch über ihren traditionellen Laufwerkspfad ansprechen. Laufw:\[Verzeichnis ... \]Dateiname.Erw
Beide Pfadangaben können nach allen Regeln der Kunst absolut oder relativ zum jeweils aktuellen Arbeitsverzeichnis sein; der Unterschied zwischen beiden besteht eigentlich nur darin, dass der absolute Laufwerkspfad einen Laufwerksbuchstaben mit nachfolgenden Doppelpunkt hat, wo der absolute UNC-Pfad einen Servernamen und eine Freigabe enthält.
Fehler und deren Behandlung »Wo gehobelt wird, fallen Späne«. Da Dateioperationen sozusagen aus der geschlossenen Welt eines Programms hinausführen und mit anderen Programmen am Gerangel um Gemeingut (gemeinsam genutzte Ressourcen) teilnehmen, ist es völlig normal, dass zur Laufzeit Fehler auftreten können, die zur Entwurfszeit nicht absehbar waren. Die zu solchen Fehlern führenden Konstellationen sind recht vielfältig, so dass man sich beim Programmentwurf einer stattlichen Anzahl möglicher Laufzeitfehler gegenüber sieht, die es einzukalkulieren gilt. Hier einige der Ursachen für häufige Fehler: Nr.
Fehlermeldung
Mögliche Ursachen
52
Dateiname oder -nummer Der Dateiname einer anzulegenden Datei entspricht nicht falsch der Konvention für Dateinamen. Ihr Programm hat nicht das Recht, die Datei auf einer Freigabe anzulegen, (z.B. weil das Kennwort nicht richtig ist). Die verwendete Dateinummer wurde entweder durch eine Close-Anweisung bereits freigegeben oder nie im Rahmen einer Open-Anweisung vergeben, etwa weil diese gescheitert ist.
Häufige Laufzeitfehler im Zusammenhang mit Dateioperationen
1 29
Dateiorientierte Funktionen und Anweisungen
Auf Dateioperationen bezogene Funktionen und Anweisungen
Dateiorientierte Funktionen und Anweisungen
Dateiorientierte Funktionen und Anweisungen
Nr.
Fehlermeldung
Mögliche Ursachen
53
Datei nicht gefunden
Die Datei kann nicht geöffnet werden, weil sie nicht existiert.
55
Datei bereits geöffnet
Die Datei kann nicht geöffnet werden, weil sie bereits geöffnet ist. Passiert bei Open, Name, FileCopy, SetAttr, Kill.
57
Fehler beim Lesen von/ Schreiben auf Gerät
Das Ein- bzw. Ausgabegerät enthält einen defekten Datenträger oder die Netzwerkverbindung ist während der Dateioperation zusammengebrochen.
58
Datei existiert bereits
Sie versuchen, eine Datei mit Name umzubenennen, der angegebene Dateiname ist aber bereits an eine andere Datei vergeben.
61
Datenträger voll
Der freie Platz auf einer Diskette, Festplatte oder Netzwerkfreigabe reicht für die Durchführung der Operation nicht aus.
62
Einlesen hinter Dateiende
Die Dateioperation passt nicht zu dem Modus, in dem die Datei geöffnet wurde. Beispielsweise dürfen Sie EOF nicht im Modus Binary und die Funktion Input nicht im Modus Input verwenden.
70
Zugriff verweigert
Sie haben versucht, auf eine Datei oder einen Datensatz zuzugreifen, die bzw. der von einem anderen Prozess gesperrt wurde, oder es fehlt das Schreibrecht, um auf dem entsprechenden Datenträger zu schreiben.
71
Datenträger nicht bereit
Im angegebenen Laufwerk befindet sich kein Datenträger oder das Laufwerk wurde nicht verriegelt.
75
Fehler beim Zugriff auf Pfad/Datei
Das Format der Pfadangabe ist nicht korrekt, das Ausgabegerät unterstützt keine Schreiboperationen oder die Datei ist schreibgeschützt.
76
Pfad nicht gefunden
Der angegebene Pfad existiert nicht oder der Server, der ihn freigibt, ist nicht am Netz.
Häufige Laufzeitfehler im Zusammenhang mit Dateioperationen
In Form der On Error GoTo-Anweisung stellt Basic ein Mittel bereit, solchen Laufzeitfehlern zu begegnen. Mehr darüber finden Sie im Abschnitt »Fehlerbehandlung« (S. 43).
Dateien Um in Visual Basic eine Datei mit traditionellen Mitteln bearbeiten zu können, muss sie zunächst durch eine Open-Anweisung geöffnet werden – ein Vorgang, der unter anderem die Zugriffsrechte anderer Prozesse auf diese Datei einschränken kann und ihr eine logische Dateinummer zuordnet. Diese Dateinummer ist für alle folgenden Operationen anzugeben, die mit dieser Datei in Zusammenhang stehen. Die Zugriffsrechte auf die Datei oder Teile der Datei lassen sich auch danach noch mittels Lock- und Unlock-Anweisungen entsprechend den Erfordernissen handhaben. Sobald kein weiterer Zugriff auf die Datei mehr erfolgt, kann sie mittels Close geschlossen werden. Diese Operation schreibt gegebenenfalls noch nicht geschriebene Pufferinhalte und gibt die Dateinummer wieder frei.
1 30
ChDir- Anweisung
ChDir- Anweisung ChDir sPfad Beschreibung
................................................... Bes c hreibung
Windows kennt und pflegt in der Systemumgebung eines Programms für jedes Laufwerk ein aktuelles Arbeitsverzeichnis. Das standardmäßige Arbeitsverzeichnis (vgl. »CurDir-Funktion«, S. 134) ist das aktuelle Arbeitsverzeichnis auf dem standardmäßigen Laufwerk (vgl. »ChDriveAnweisung«, S. 132). Die Anweisung ChDir setzt sPfad als neues aktuelles Arbeitsverzeichnis auf dem in sPfad spezifizierten Laufwerk. Enthält sPfad keine Laufwerksspezifikation, setzt die Funktion das standardmäßige Arbeitsverzeichnis auf sPfad. Anwendung
................................................... Anwendung
Ist der in sPfad spezifizierte Pfad nicht existent, löst die Funktion den Laufzeitfehler 76, »Pfad nicht gefunden« aus. Solange das standardmäßige Arbeitsverzeichnis lokal auf dem Computer liegt, zeigt ChDir bei Angabe eines UNC-Pfads für sPfad keine Wirkung – meldet aber auch keinen Fehler. Ergibt sich dagegen die Situation, dass das standardmäßige Arbeitsverzeichnis auf einem anderen Computer liegt (vgl. »CurDir-Funktion«, S. 134) und somit bereits ein UNCPfad ist, kommt ChDir auch bei Angabe eines UNC-Pfads seiner Aufgabe nach. Warnung
................................................... Wa rnung
Mit dem UNC-Pfad ist das so eine Sache. Wie unter CurDir näher ausgeführt, besteht zwar die Möglichkeit, das standardmäßige Arbeitsverzeichnis von vornherein als UNC-Pfad zu erhalten, Visual Basic sieht aber keine Mittel vor, das standardmäßige Arbeitsverzeichnis, sofern es einmal auf ein lokales Verzeichnis gesetzt wurde, wieder auf einen anderen Computer (etwa einen File Server) im Netzwerk zu verlagern, sprich: in einen UNC-Pfad umzuwandeln. Damit könnte man natürlich leben, wenn sich ChDir darauf beschränken würde, ein UNC-Arbeitsverzeichnis bei Angabe eines UNC-Pfades als UNC-Arbeitsverzeichnis beizubehalten. Leider ist das jedoch
1 31
Dateiorientierte Funktionen und Anweisungen
Was die Dateioperationen betrifft, so ist zu beachten, dass Basic traditionell drei Dateikonzepte unterstützt, die sich darin unterscheiden, welche Art von Information gespeichert wird und wie der Zugriff auf diese Information erfolgt: die sequenzielle Datei (auch Textdatei genannt), die indexsequenzielle Datei und die Binärdatei. Für jede dieser Dateiarten gibt es spezifische Operationen, die speziell auf ihren Zweck zugeschnitten sind. Sequenzielle Dateien enthalten durch spezifische Trennzeichen voneinander abgetrennte Zeichenfolgen, die textuelle Repräsentationen von Werten unterschiedlicher Datentypen darstellen. Zum Schreiben dieser Werte verwendet man die Anweisungen Print# und Write#, wobei erstere die gebietsspezifische Zeichenfolgendarstellung eines Werts generiert und letztere die internationale. Das Lesen besorgt dagegen die Anweisung Input# oder – wenn auch die Trennzeichen gelesen werden sollen – die Funktion Input. Im speziellen Fall von Textdateien ermöglicht die Anweisung Line Input# das zeilenweise Lesen. Indexsequenzielle Dateien enthalten eine Folge von Datensätzen. Da alle Datensätze eine feste Länge aufweisen, kann Basic die Position eines bestimmten Datensatzes aus der Datensatznummer und der Datensatzlänge errechnen, so dass keine Trennzeichen notwendig sind. Das Schreiben von Datensätzen besorgt die Anweisung Get und das Lesen die Anweisung Put. Binärdateien liegt dagegen a priori keine bestimmte Interpretation zugrunde. Sie werden als einfache Aneinanderreihung von Bytes behandelt, und es unterliegt der Verantwortung des Programms, sie zu einzelnen Werten für Variablen der unterschiedlichen Datentypen zu gruppieren. Als Leseoperationen stehen dafür die Funktion Input und die Anweisung Get zur Verfügung und als Schreiboperation die Anweisung Put.
Dateiorientierte Funktionen und Anweisungen
nicht so: ChDir setzt bei Angabe eines UNC-Pfads, der in das Dateisystem des lokalen Computers führt, ungefragt den Laufwerkspfad. Beispiele
................................................... Beis piele
Dateiorientierte Funktionen und Anweisungen
Angenommen das Programm, das den folgenden Code enthält, ist im Verzeichnis C:\VB-Programme gelegen und wird über den Explorer gestartet: Print App.Path Print CurDir ChDir ".." Print CurDir ChDir "Windows" Print CurDir ChDir "C:\VB-Programme" Print CurDir ChDir "D:\Eigene Dateien" Print CurDir ChDrive "D" Print CurDir
' ' ' ' ' ' ' ' ' ' ' '
C:\VB-Programme C:\VB-Programme (wie App.Path) Ein Verzeichnis höher C:\ relativer Pfad C:\Windows absoluter Pfad auf Standardlaufwerk C:\VB-Programme absoluter Pfad auf Nicht-Standardlaufwerk C:\VB-Programme (C ist Standardlaufwerk) erst jetzt ändert sich Standardlaufwerk D:\Eigene Dateien (D ist Standardlaufwerk)
Angenommen das Programm, das den folgenden Code enthält, liegt im Verzeichnis \\Adler\c\VB-Programme\ und wird über die Netzwerkumgebung des Explorers gestartet: Print Print ChDir Print ChDir Print ChDir Print
App.Path CurDir ".." CurDir "Windows" CurDir "C:\VB-Programme" CurDir
' ' ' ' ' ' ' '
\\Adler\c\VB-Programme\ \\Adler\c\VB-Programme\ (wie App.Path) Ein Verzeichnis höher \\Adler\c\ relativer Pfad \\Adler\c\windows UNC-Pfad ist ab jetzt verloren C:\VB-Programme
Verwandte Befehle
................................................... Verwa ndte Befehle
ChDrive, CurDir
ChDrive- Anweisung Sub ChDrive (sLaufw As String) Beschreibung
................................................... Bes c hreibung
Windows kennt und pflegt in der Systemumgebung eines Programms für jedes Laufwerk ein aktuelles Arbeitsverzeichnis. Die Anweisung ChDrive setzt das erste Zeichen von sLaufw als neues aktuelles Laufwerk. Das aktuelle Arbeitsverzeichnis auf diesem Laufwerk wird damit zum standardmäßigen Arbeitsverzeichnis. Anwendung
................................................... Anwendung
Ist sLaufw eine leere Zeichenfolge, ändert ChDrive das aktuelle Laufwerk nicht, meldet aber auch keinen Fehler. Existiert das erste Zeichen von sLaufw nicht als logisches Laufwerk, löst die Funktion den Laufzeitfehler 68, »Gerät nicht verfügbar«, aus.
1 32
Close- Anweisung
Warnung
................................................... Wa rnung
Ergibt sich die Situation, dass das standardmäßige Arbeitsverzeichnis auf einem anderen Computer liegt (vgl. »CurDir-Funktion«, S. 134) und somit durch einen UNC-Pfad beschrieben wird, geht dieser mit dem nächsten Aufruf von ChDrive unwiederbringlich verloren, das heißt, als standardmäßiges Arbeitsverzeichnis lassen sich fortan nur noch Verzeichnisse einstellen, auf die der Zugriff über ein logisches Laufwerk erfolgen kann. Beispiel
................................................... Beis piel
Siehe das Beispiel zu »ChDir-Anweisung« (S. 131).
................................................... Verwa ndte Befehle
ChDir, CurDir
Close- Anweisung Close [#]iDateiNr[, [#]DateiNr1, ...] Beschreibung
................................................... Bes c hreibung
Die Anweisung Close schließt die unter den Dateinummern iDateiNr, iDateiNr1 usw. (mittels Open) geöffneten Dateien oder Geräte. Gegebenenfalls existierende Schreibpuffer werden zuvor herausgeschrieben. Wird der Befehl ohne Parameter aufgerufen, schließt er alle mit Dateinummern assoziierten Dateien und Geräte. Anwendung
................................................... Anwendung
Bevor ein Programm mit traditionellen Mitteln auf eine Datei oder ein Gerät zugreifen kann, muss es eine Open-Anweisung durchführen, die der Datei eine Dateinummer zuordnet und gegebenenfalls Pufferspeicher organisiert. Aus Gründen der Effizienz puffert Visual Basic alle Schreib- und Leseoperationen für Dateien, die im Input-, Output- oder Append-Modus geöffnet wurden, und führt sie blockweise aus. Das hat unter anderem die Folge, dass Schreiboperationen wie Print# ihre Daten nicht direkt auf den Datenträger schreiben, sondern immer erst, wenn der Schreibpuffer voll ist. Der Befehl Close hat nun folgende Funktionen: Er bewirkt für jede genannte Dateinummer ein explizites Herausschreiben gegebenenfalls noch gefüllter Schreibpuffer mit nachfolgender Freigabe des Puffers und der Dateinummer. Die Freigabe einer Dateinummer durch Close hebt gleichzeitig alle Zugriffsbeschränkungen auf, die für die betreffende Datei mittels Open und Lock getroffen wurden. Entgegen anders lautenden Informationen in der Online-Hilfe zu Visual Basic entfernt Close alle Sperren, die mit Lock gesetzt und nicht explizit mit Unlock freigegeben wurden. Tipp
................................................... Tipp
Zwar schließt ein Visual-Basic-Programm bei Beendigung von sich aus alle Dateien und Geräte durch einen impliziten Close-Aufruf, dennoch ist es guter defensiver Programmierstil, eine Datei unmittelbar, nachdem der letzte Zugriff darauf erfolgt ist, wieder zu schließen. Das verkürzt die Einschränkungen, denen andere Programme in Bezug auf diese Datei ausgesetzt sind, auf ein Minimum. Beispiel
................................................... Beis piel
Der folgende Code lässt sich in einem Programm einsetzen, dessen Aufrufe protokolliert werden sollen:
1 33
Dateiorientierte Funktionen und Anweisungen
Verwandte Befehle
Dateiorientierte Funktionen und Anweisungen
Open "Aufrufe.log" For Append As 1 Print #1, "Aufruf am "; Now Close 1 Verwandte Befehle
................................................... Verwa ndte Befehle
Open
CurDir- Funktion
Dateiorientierte Funktionen und Anweisungen
Function CurDir[(sLaufw As String)] As String Beschreibung
................................................... Bes c hreibung
Windows kennt und pflegt in der Systemumgebung eines Programms für jedes Laufwerk ein aktuelles Arbeitsverzeichnis und ein aktuelles Laufwerk. Im Allgemeinen ist das standardmäßige Arbeitsverzeichnis dann das aktuelle Arbeitsverzeichnis auf dem aktuellen Laufwerk. Die Funktion CurDir liefert das aktuelle Arbeitsverzeichnis auf dem Laufwerk sLaufw. Fehlt der optionale Parameter sLaufw, liefert die Funktion das standardmäßige Arbeitsverzeichnis. Anwendung
................................................... Anwendung
Unmittelbar nach Programmstart entspricht das standardmäßige Arbeitsverzeichnis dem Verzeichnis, aus dem heraus der Start erfolgt ist. Erfolgt der Start direkt durch Aufruf der ausführbaren Datei aus einem Fenster des Explorers heraus, deckt sich das Arbeitsverzeichnis mit dem Programmverzeichnis (vgl. »App.Path-Eigenschaft«, S. 264). Wird der Programmstart dagegen von einem anderen Programm veranlasst, erbt das Visual-Basic-Programm schlicht das standardmäßige Arbeitsverzeichnis des Aufrufers. Das ist so, wenn der Aufruf aus einem Kommandozeileninterpreter oder Scripting-Host heraus erfolgt, wenn er von einem anderen Visual-Basic-Programm aus mittels einer Shell-Anweisung erfolgt oder wenn er über eine Verknüpfung führt, in deren Eigenschaften unter AUSFÜHREN IN ein anderer Pfad als das Programmverzeichnis eingetragen ist. Das ist aber auch so, wenn das standardmäßige Arbeitsverzeichnis des Aufrufers auf einem anderen Computer im Netzwerk liegt. In diesem Fall lässt sich das standardmäßige Verzeichnis nur als UNC-Pfad notieren, wenn es kein logisches Laufwerk für die entsprechende Freigabe gibt. Warnung
................................................... Wa rnung
Ist das standardmäßige Verzeichnis einmal ein Laufwerkspfad, lassen sich fortan nur noch solche Verzeichnisse als standardmäßiges Arbeitsverzeichnis setzen, die über ein logisches Laufwerk ansprechbar sind. UNC-Pfade sind nicht mehr möglich. Tipp
................................................... Tipp
Beim Öffnen von Dateien, für die kein absoluter Pfad spezifiziert ist, bezieht sich Visual Basic auf das ererbte Arbeitsverzeichnis. Das aber kann mal so und mal so aussehen, je nach dem, ob das Programm in der Entwicklungsumgebung, als kompilierte Fassung, über eine Verknüpfung oder aus einem Explorer-Fenster heraus gestartet wurde. Als probates Mittel, um einen definierten und situationsunabhängigen Ausgangspunkt für das Laden von Hilfsdateien zu erhalten, empfiehlt es sich, entsprechende Pfadangaben auf die Exe-Datei zu beziehen und das standardmäßige Arbeitsverzeichnis via ChDir auf den Wert von App.Path zu setzen. Beispiel
................................................... Beis piel
Siehe »ChDir-Anweisung« (S. 131)
1 34
Dir- Funktion
Verwandte Befehle
................................................... Verwa ndte Befehle
ChDir, ChDrive
Dir- Funktion Function Dir [(sSuchmuster As String, _ [Attributvkt As VbFileAttribute = vbNormal])] As String Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Die überaus nützliche Funktion Dir vereinigt in sich das Funktionsschema der Win32-APIFunktionen FindFirstFile, FindNextFile und FindClose. Um alle Dateinamen in einem Verzeichnis zu erhalten, die auf ein gegebenes Suchmuster passen und darüber hinaus bestimmte Attribute aufweisen, legen Sie mit dem ersten Aufruf von Dir das Suchmuster und gegebenenfalls den Attributvektor fest und rufen Dir ab dann so oft parameterlos auf, bis die Funktion die leere Zeichenfolge liefert. Das Suchmuster besteht aus einem Pfadanteil (absolut oder relativ notiert) und einem Dateianteil, wobei der Pfadanteil das Verzeichnis spezifiziert, das durchsucht wird, und der Dateianteil ein Dateinamensmuster, das auch die Platzhalter »?« (Zeichen an dieser Stelle wird nicht unterschieden) und »*« (Zeichen ab dieser Stelle werden nicht unterschieden) enthalten kann. Fehlt der Pfadanteil oder ist er relativ notiert, bezieht die Funktion den Pfad auf das standardmäßige Arbeitsverzeichnis (vgl. »CurDir-Funktion«, S. 134). Um den Namen eines Datenträgers zu erfahren, geben Sie das Stammverzeichnis des Laufwerks als Suchmuster an (z.B. C:\) und die Konstante vbVolume als Attributvektor. In anderen Pfaden hat vbVolume keine Wirkung. Die in der VbFileAttribute-Aufzählung enthaltene Konstante vbAlias ist für zukünftige Zwecke definiert. Unter Visual Basic 6.0 (SP3) löst sie einen Laufzeitfehler aus. Warnungen
................................................... Wa rnungen Da diese Funktion in der von Microsoft stammenden Dokumentation recht lieblos abgehandelt wurde, ist viel Falsches darüber zu lesen, insbesondere was den Attributvektor betrifft. Richtig ist: Die Funktion schränkt die Ergebnismenge nicht auf Dateien mit bestimmten Attributen ein, sondern sie erweitert die zu vbNormal gehörige Ergebnismenge um die Dateien, die eines der im Attributvektor genannten zusätzlichen Attribute tragen. Die mit Visual Basic vorliegende Implementation von Dir ist nicht für den rekursiven Aufruf geeignet. Das Beispiel zu »RmDir-Anweisung» (S. 155) zeigt einen Work-around. Ein Beispiel für eine alternative Implementation, die speziell für rekursive Prozeduren geeignet ist, finden Sie im Abschnitt »Routinen aus DLLs und der Windows-API einsetzen« (S. 185).
1 35
Dateiorientierte Funktionen und Anweisungen
Die Funktion Dir kennt zwei unterschiedliche Arbeitsmodi. Wird sie unter Angabe eines Werts für den optionalen Parameter sSuchmuster aufgerufen, interpretiert sie diesen als Suchmuster für Dateinamen und liefert den ersten Dateinamen, der passt. Passt das Suchmuster auf keinen Dateinamen, gibt sie die leere Zeichenfolge zurück. Wird die Funktion Dir, nachdem sie einmal mit Suchmuster aufgerufen wurde, ohne den optionalen Parameter sSuchmuster aufgerufen, liefert sie den jeweils nächsten Dateinamen, der auf das Suchmuster passt. Der zweite optionale Parameter Attributvkt ermöglicht die Angabe eines Attributvektors, der die Ergebnismenge um Dateien mit entsprechenden Attributen erweitert(!).
Dateiorientierte Funktionen und Anweisungen
Tipp
................................................... Tipp
Falls Sie sich nur für Dateien mit bestimmten Attributen interessieren, übergeben Sie Dir diese Attribute als Attributvektor und filtern dann die gewünschten Dateien mittels GetAttr aus der von Dir gelieferten Ergebnismenge selbst heraus. Beispiel
................................................... Beis piel
Dateiorientierte Funktionen und Anweisungen
Das folgende Codefragment liefert alle Dateien im Verzeichnis C:\Eigene Dateien, deren Dateiname mit »T« beginnt, mindestens zwei Zeichen enthält und die Erweiterung »txt« trägt: sDatName = Dir("C:\Eigene Dateien\T?*.txt") While sDatName "" Print sDatName Dir Wend
Und dieses Codefragment liefert nur die Dateien aus dem Verzeichnis C:\, die verborgen und schreibgeschützt sind: Attr = vbHidden + vbReadOnly Pfad = "C:\" sDatName = Dir(Pfad + "*.*", Attr) While sDatName "" If (GetAttr(Pfad + sDatName) And Attr) = Attr Then ' Filter Print sDatName End If sDatName = Dir Wend Verwandte Befehle
................................................... Verwa ndte Befehle
ChDir, CurDir, FileDateTime, GetAttr Verwandte Themen
................................................... Verwandte Them en
Routinen aus DLLs und der Windows-API einsetzen (S. 185)
Environ- Funktion Function Environ(sEnvVar As String) Function Environ(iEnvIndex As Integer) Beschreibung
................................................... Bes c hreibung
Wird die Funktion Environ mit einer Zeichenfolge als Parameter aufgerufen, spezifiziert sEnvVar den Namen einer Umgebungsvariablen. Environ liefert dann den Wert dieser Umgebungsvariablen oder die leere Zeichenfolge, wenn diese nicht bekannt ist. Bei Aufruf der Funktion mit einem Zahlenwert liefert die Funktion dagegen die durch iEnvIndex spezifizierte Zeile aus der Umgebungsdefinition oder die leere Zeichenfolge, falls die Umgebungsdefinition weniger Zeilen umfasst.
1 36
EOF- Funktion
Anwendung
................................................... Anwendung
Auch wenn diese Funktion nicht unmittelbar etwas mit Dateizugriffen zu tun hat, mittelbar hat sie es schon, weil sie Informationen über vordefinierte Pfade (PATH, TEMP, TMP, windir, winbootdir usw.) liefert. Beispiel
................................................... Beis piel
Der folgende Code gibt die gesamte Umgebungsinformation eines Programms aus:
Vgl. auch das Beispiel zu »Kill-Anweisung« (S. 144).
EOF- Funktion Function EOF(iDateiNummer As Integer) As Boolean Beschreibung
................................................... Bes c hreibung
Die Funktion EOF liefert True, wenn das Dateiende einer unter der Nummer iDateiNummer geöffneten Datei beim Lesen erreicht ist, ansonsten False. Anwendung
................................................... Anwendung
Leseoperationen auf Dateien können nur so lange durchgeführt werden, bis das Dateiende erreicht ist. Um festzustellen, ob dies der Fall ist, wird die Funktion EOF eingesetzt. Bei Dateien, die mit dem Zugriffsmodus Input geöffnet wurden, liefert sie False, wenn die letzte Leseoperation (meist Line Input #) durch das Ende der Datei beendet wurde. Im Zusammenhang mit den Zugriffsmodi Binary und Random liefert sie True, wenn die letzte Leseoperation (Input bzw. Get) aufgrund des Dateiendes nicht oder nicht vollständig ausgeführt werden konnte. Warnung
................................................... Wa rnung
Die Online-Hilfe zu EOF bezichtigt diese Funktion, Laufzeitfehler zu produzieren, wenn sie im Zugriffsmodus Binary für die Kontrolle der Input-Funktion benutzt wird. Das ist falsch. Input ist so implementiert, dass es im Modus Binary generell keinen Laufzeitfehler auslöst. Zu einem Laufzeitfehler kann es dagegen kommen, wenn EOF im Zugriffsmodus Input für die Kontrolle der Funktion Input benutzt wird und diese mehr als ein Zeichen je Aufruf liest. Beispiel
................................................... Beis piel
Der folgende Code liest die Textdatei Scandisk.log zeilenweise für die Ausgabe durch Print: Open "c:\scandisk.log" For Input As 1 While Not EOF(1) Line Input #1, sZeile Print sZeile Wend Close 1
1 37
Dateiorientierte Funktionen und Anweisungen
i = 1 While Environ(i) "" Print Environ(i) i = i + 1 Wend
Dateiorientierte Funktionen und Anweisungen
Verwandte Befehle
................................................... Verwa ndte Befehle
LOF, Loc, Get, Input, Line Input, Open, Seek
FileAttr- Funktion Function FileAttr(iDateiNummer As Integer[, iTyp As Integer = 1]) Beschreibung
Dateiorientierte Funktionen und Anweisungen
................................................... Bes c hreibung
Die Funktion FileAttr liefert eine Aussage darüber, in welchem Modus die zu der Dateinummer iDateiNummer gehörige Datei geöffnet wurde. Es sind folgende Funktionswerte möglich: 1 steht für Input, 2 für Output, 4 für Random, 8 für Append und 32 für Binary. Anwendung
................................................... Anwendung
Der zweite, optionale Parameter wird nur noch aus Kompatibilitätsgründen mitgeschleppt. Er hatte eine Bedeutung, als es noch 16-Bit-Systeme gab. Auf 32-Bit-Systemen muss er 1 sein. Beispiel
................................................... Beis piel
Open sDatei For Binary As 2 Print FileAttr(2) Close2
' Ausgabe: 32
Verwandte Befehle
................................................... Verwa ndte Befehle
Open
FileCopy- Anweisung Sub FileCopy(sQuellDatei As String, sZielDatei As String) Beschreibung
................................................... Bes c hreibung
Die Anweisung FileCopy erstellt eine Kopie der Datei sQuellDatei als sZielDatei. Anwendung
................................................... Anwendung
Es versteht sich, dass sQuellDatei einen gültigen Pfad zu einer existierenden Datei und sZielDatei einen gültigen Pfad mit gültigem Dateinamen enthalten müssen. Die Funktion löst verschiedene Laufzeitfehler aus – so den Laufzeitfehler 76, wenn mit den Pfaden etwas nicht in Ordnung ist, den Laufzeitfehler 53, wenn die Datei nicht existiert, und den Laufzeitfehler 55, wenn die Datei zum Schreiben geöffnet wurde. Warnung
................................................... Wa rnung
Sollte unter dem Dateinamen sZielDatei bereits eine andere Datei existieren, wird diese kommentarlos überschrieben. Beispiel
................................................... Beis piel
FileCopy sQuellDatei, sZieldatei Verwandte Befehle
................................................... Verwa ndte Befehle
Kill, Name
1 38
FileDateTime- Funktion
FileDateTime- Funktion Function FileDateTime(sDatei As String) As Date Beschreibung
................................................... Bes c hreibung
Die Funktion FileDateTime liefert das letzte Änderungsdatum bzw. das Erstellungsdatum der Datei oder des Verzeichnisses sDatei als Datums-/Zeitwert. Beispiel
................................................... Beis piel
Print FileDateTime ("C:\Windows")
' Datum der Windows-Installation
................................................... Verwa ndte Befehle
FileLen, GetAttr
FileLen- Funktion Function FileLen(sDatei As String) As Long Beschreibung
................................................... Bes c hreibung
Die Funktion FileDateTime liefert die Länge der Datei sDatei in Bytes. Spezifiziert sDatei ein Verzeichnis, gibt die Funktion den Wert 0 zurück. Anwendung
................................................... Anwendung
Ein Aufruf dieser Funktion für eine zum Schreiben geöffnete Datei liefert die Länge der Datei, bevor diese zum Schreiben geöffnet wurde. Die aktuelle Länge einer bereits geöffneten Datei ermittelt die Funktion LOF. Beispiel
................................................... Beis piel
Print FileLen("C:\Msdos.sys")
' muss größer 1024 Bytes sein
Verwandte Befehle
................................................... Verwa ndte Befehle
FileDateTime, GetAttr, LOF
FreeFile- Funktion Function FreeFile[(iBereich As Integer)] Beschreibung
................................................... Bes c hreibung
Die Funktion FreeFile liefert jeweils die kleinste freie Dateinummer im Block iBereich. Fehlt der optionale Parameter iBereich oder hat er den Standardwert 0, entstammt die gelieferte Dateinummer dem Block 0 bis 255, ansonsten dem Block 256 bis 512. Anwendung
................................................... Anwendung
Nachdem Dateinummern globale Größen in einem Modul sind, ist es in größeren Programmen oft schwierig, den Überblick darüber zu behalten, welche bereits vergeben sind und welche nicht. Indem Sie sich neue Dateinummern von FreeFile zuteilen lassen, entlasten Sie sich von der gesamten Problematik.
1 39
Dateiorientierte Funktionen und Anweisungen
Verwandte Befehle
Dateiorientierte Funktionen und Anweisungen
Beispiel
................................................... Beis piel
iBer = FreeFile Open sDatei For Input As iBer ... Close iBer
Vgl. auch das Beispiel im Abschnitt »Fehlerbehandlung« (S. 43). Verwandte Befehle
Dateiorientierte Funktionen und Anweisungen
................................................... Verwa ndte Befehle
Open
Get- Anweisung Get [#]iDateiNr, [lSatzNr], Variable Beschreibung
................................................... Bes c hreibung
Die Anweisung Get ist das Gegenstück zur Anweisung Put. Sie liest Daten aus der Datei mit der Dateinummer iDateiNr und weist diese der Datensatzvariablen Variable als Wert zu. Bei Angabe einer Satznummer lSatzNr liest die Anweisung im Modus Random den entsprechenden Datensatz unter Berücksichtigung der bei der Open-Anweisung vereinbarten Datensatzlänge und im Modus Binary ab der Byteposition lSatzNr. Fehlt lSatzNr, liest die Anweisung jeweils den nächsten Datensatz (Random) bzw. ab der aktuellen Leseposition (Binary) und aktualisiert danach den Datensatzzeiger bzw. die aktuelle Leseposition. Die Datensatzvariable kann einen beliebigen Typ tragen. Objekte lassen sich mittels Get jedoch nicht en bloc einlesen. Anwendung
................................................... Anwendung
Wenn es um das Schreiben und Lesen von Dateiformaten ging, waren Get und Put schon immer die Arbeitspferde der Sprache Basic. Die Arbeitsweise dieser Anweisungen ist traditionell auf indexsequenzielle Dateien zugeschnitten, deren Bearbeitung im Modus Random erfolgt. Get und Put werden aber auch – jedoch mit leicht modifizierter Arbeitsweise – im Modus Binary eingesetzt.
Der Modus Random Beim Öffnen von Dateien im Modus Random wird normalerweise eine Datensatzlänge in Bytes festgelegt, die fortan bestimmt, wie viele Byte mit jeder Get- bzw. Put-Operation je Datensatz gelesen bzw. geschrieben werden. Die Zählung der Datensätze beginnt bei 1. Den Bytebedarf der elementaren Datentypen entnehmen Sie der Tabelle im Abschnitt »Elementare Datentypen« (S. 49); den von Datentypen mit fester Länge sowie von benutzerdefinierten Datentypen ermittelt man am besten mittels LenB, da die Speicherausrichtung der Datenfelder noch eine zusätzliche Rolle spielt. Trägt die Datensatzvariable einen Typ variabler Länge (bzw. einen Typ, der Felder variabler Länge enthält), muss der Datensatz einen Deskriptor (lies: Längenangabe) enthalten. Dabei gilt, dass ein Deskriptor dem Wert unmittelbar vorausgeht. Mithin muss also der Längenbedarf eines oder mehrerer Deskriptoren bei der Berechnung der Datensatzlänge berücksichtigt werden. Für Zeichenfolgen variabler Länge schlagen dabei 2 Längenbyte (!) zu Buche, für Variant-Variablen gleichfalls zunächst 2 Bytes für den VarType-Typ plus gegebenenfalls weitere Längenbyte für Wertanteile mit variablen Längen. Dynamische Arrays schlagen mit 2 Bytes für den Array-Deskriptor zu Buche plus 8 Bytes je Dimension. Die maximale Datensatzlänge beträgt 32.767.
1 40
Get- Anweisung
Die Wertzuweisung an Variablen mit Datentypen fester Länge erfolgt als linksbündige Prokrustes-Zuweisung (vgl. »LSet-Anweisung«, S. 80), wenn die Datensatzlänge nicht dem Längenbedarf der Variablen entspricht.
Der Modus Binary
Warnung
................................................... Wa rnung
Get liest ANSI-Zeichenfolgen als Unicode und Put schreibt Unicode-Zeichenfolgen als ANSICode. Beispiel
................................................... Beis piel
Der folgende Code schreibt eine Zeichenfolge und einen Double-Wert in eine indexsequenzielle Datei und liest diese Werte dann einmal im Modus Random und einmal im Modus Binary: ' Schreiben der Daten Open "Test.Idx" For Random As 1 Len = 8 Dim sDatenSatz As String ' Zeichenfolge (Unicode!) Dim a As Double ' Double-Wert sDatenSatz = "abc" ' Initialisierung a = 2.1E-122 Put 1, , sDatenSatz ' erster Datensatz wird geschrieben Put 1, 17, a ' 17ter Datensatz Close 1 ' Lesen der Daten im Modus Random sDatenSatz = "" a = 0 Open "Test.Idx" For Random As 1 Len Get 1, , sDatenSatz Print Len(sDatenSatz); sDatenSatz Get 1, 17, a Print a Close 1 ' Lesen der Daten im Modus Binary sDatenSatz = Space(3) a = 0 Open "Test.Idx" For Binary As 1 Get 1, 3, sDatenSatz Print Len(sDatenSatz), sDatenSatz Get 1, (17 – 1) * 8 + 1, a Print a Close 1
' Initialisierung = 8 ' erster Datensatz wird gelesen ' Ausgabe: "3 abc" (Deskriptor!) ' Doublewert braucht 8 Bytes! ' Ausgabe: 2,1E-122
' drei Unicodezeichen sind zu lesen ' Initialisierung ' ' ' '
Deskriptoranteil überspringen! Ausgabe: "3 abc" (Deskriptor!) Datensatzlänge 8 einberechnen Ausgabe: 2,1E-122
1 41
Dateiorientierte Funktionen und Anweisungen
Für den Modus Binary gilt im Wesentlichen dasselbe, mit folgenden Abweichungen: Eine Datensatzlänge wird nicht berücksichtigt, und die Anweisung liest ab der aktuellen Position bzw. der Position lSatzNr so viele Bytes, wie für den Wert der Datensatzvariablen erforderlich sind. Zeichenfolgen variabler Länge behandelt Get daher wie Zeichenfolgen fester Länge und liest nur so viele Zeichen, wie der Wert der String-Variablen aktuell enthält – ein Deskriptoranteil entfällt somit. Analoges gilt auch für Arrays. Im Zusammenhang mit benutzerdefinierten Datentypen finden Deskriptoranteile einzelner Datenfelder jedoch sehr wohl Berücksichtigung.
Dateiorientierte Funktionen und Anweisungen
Verwandte Befehle
................................................... Verwa ndte Befehle
Input, Input#, Line Input#, Open, LenB, LSet, Print#, Put Verwandte Themen
................................................... Verwandte Them en
Elementare Datentypen (S. 49); Benutzerdefinierte Datentypen (S. 60)
GetAttr- Funktion
Dateiorientierte Funktionen und Anweisungen
Function GetAttr(sPfad As String) As Integer Beschreibung
................................................... Bes c hreibung
Die Funktion GetAttr liefert die Attribute der Datei oder des Verzeichnisses sPfad als Attributvektor. Anwendung
................................................... Anwendung
Um festzustellen, ob in dem Attributvektor ein bestimmtes Attribut (als Bit) gesetzt ist, führen Sie eine And-Operation mit dem für das Attribut definierten Wert durch. Als Element des Aufzählungstyps VbFileAttribute ist für ihn eine Konstante definiert. Zur Auswahl stehen: Konstante
Wert
Beschreibung
vbNormal
0
Keines der Bits im Attributvektor ist gesetzt. Es handelt sich um eine gewöhnliche Datei.
vbReadOnly
1
Datei/Verzeichnis ist schreibgeschützt.
vbHidden
2
Datei/Verzeichnis ist verborgen.
vbSystem
4
Datei ist Systemdatei bzw. Verzeichnis ist Systemverzeichnis.
vbVolume
8
Logischer Datenträger (wird von GetAttr nicht geliefert)
vbDirectory
16
Verzeichnis
vbArchive
32
Datei wurde seit der letzten Datensicherung geändert
Konstanten für Dateiattribute Beispiel
................................................... Beis piel
Dim Attribut As VbFileAttribut Attribut = vbHidden If Attribut And GetAttr(sDatei) Then
' Datei ist verborgen
Wie man das Vorhandensein mehrerer Attribute prüft, zeigt das Beispiel zur »Dir-Funktion« (S. 135). Verwandte Befehle
................................................... Verwa ndte Befehle
Dir, FileAttr, SetAttr
Input- und InputB- Funktion Function Input(lZeichenAnz, [#]iDateiNr) As String Function InputB(lBytes, [#]iDateiNr) As String
1 42
Input #- Anweisung Beschreibung
................................................... Bes c hreibung
Die Funktion Input liest lBytes Bytes aus der unter der Dateinummer iDateiNr im Modus Input oder Binary geöffneten Datei und liefert diese als Unicode-Zeichenfolge, wobei aus jedem Byte ein Unicode-Zeichen wird. In Abweichung dazu liefert InputB ein echtes Byte-Array in Form einer ANSI-Zeichenfolge. Anwendung
................................................... Anwendung
Warnung
................................................... Wa rnung
Fallen Sie nicht darauf herein, dass Input einzelne Bytes in Unicode-Zeichen umwandelt – und somit aus einem Byte zwei Bytes macht. Um wirklich die gelesene Bytefolge zu erhalten, müssen Sie mit InputB arbeiten. Wenn Sie Input oder InputB beim Lesen einer Textdatei mittels EOF kontrollieren wollen, riskieren Sie einen Laufzeitfehler, sobald die Funktion mehr als ein Byte auf einmal lesen muss. Man arbeitet in diesem Fall besser mit dem Wert von LOF bzw. der Differenz aus den Werten von LOF und Seek. Beispiel
................................................... Beis piel
Open sTextDatei For Input As 1 sGesamteDatei = Input(LOF(1), 1) Close 1 Open sBinärDatei For Binary As 1 sGesamteDatei = InputB(LOF(1), 1) Close 1
' Textdatei ' Gesamte Datei auf einmal lesen ' Binärdatei ' Gesamte Datei als Bytearray lesen
Verwandte Befehle
................................................... Verwa ndte Befehle
Get, Print#, Put, LOF, EOF
Input #- Anweisung Input #iDateiNr, Variable[, Variable ...] Beschreibung
................................................... Bes c hreibung
Die Anweisung Input# liest den im literalen Standardformat repräsentierten Wert einer oder mehrerer Variablen aus einer sequenziellen Datei, die im Modus Input oder Binary geöffnet wurde. Als Trennzeichen zwischen zwei aufeinander folgenden Werten wertet die Anweisung ein Komma oder ein Wagenrücklaufzeichen Chr(13) bzw. vbCr sowie die Kombination Chr(13)+Chr(10) bzw. vbCrLf. Führende und abschließende Leerzeichen sowie doppelte Anführungszeichen schneidet die Anweisung ab.
1 43
Dateiorientierte Funktionen und Anweisungen
Traditionell ist Input (heute InputB genannt) die Leseoperation für Binärdateien (Modus: Binary), Get die Leseoperation für indexsequenzielle Dateien (Modus: Random) und Input# die Leseoperation für Textdateien (Modus: Input). Binärdateien lassen sich aber genauso gut auch mit Get lesen und Textdateien mit Input. Im Gegensatz zu Input# liefert Input alle gelesenen Zeichen, einschließlich Kommas, Wagenrücklaufzeichen (Chr(13) bzw. vbCr), Zeilenvorschubzeichen (Chr(10) bzw. vbLf), Anführungszeichen und führende Leerzeichen.
Dateiorientierte Funktionen und Anweisungen
Anwendung
................................................... Anwendung
Der traditionelle Zweck der Anweisung Input# ist, Daten aus sequenziellen Dateien zu lesen, denen unterschiedliche Datentypen zugrunde gelegt sind. Die Anweisung nimmt daher beim Lesen des Werts für eine Variable eines bestimmten Datentyps von sich aus eine entsprechende Typumwandlung vor. Warnung
Dateiorientierte Funktionen und Anweisungen
................................................... Wa rnung
Im Unterschied zu Line Input# interpretiert Input# auch Kommas als Trennzeichen, wenn diese nicht von Anführungszeichen eingeschlossen sind. Daher hat die Funktion insbesondere Schwierigkeiten mit dem Einlesen von Dezimalzahlen mit Nachkommaanteil sowie Datumswerten, wenn diese mit Print# geschrieben wurden. Print# legt der textuellen Darstellung von Zahlen- und Datumswerten nämlich das gebietsspezifische Format zugrunde. Für das Gebietsschema »Deutsch (Standard)« ist das Dezimaltrennzeichen ein Komma, und das Datumsformat ist komplett anders als das amerikanische. Sie sollten die Daten daher mit der Write#-Anweisung in die Datei schreiben, weil diese grundsätzlich das internationale Standardformat benutzt, das auch für die Notation von Literalen im Quelltext verwendet wird. Beispiel
................................................... Beis piel
' Daten schreiben Open "test.seq" For Output As 1 Write #1, 270; "Er sagte, ""Hi!""" ' Die Anweisung schreibt 2 Werte (!) Close 1 ' Daten lesen Dim i As Integer, a As String, b As String Open "test.seq" For Input As 1 Print Input(24, 1) ' So steht es in der Datei: 270,"Er sagte, ""Hi!""" Seek 1, 1 ' Lesezeiger wieder an den Anfang Input #1, i, a, b ' Die Anweisung liest drei Werte (!), wegen " Print i, a, b ' Ausgabe: 270 Er sagte, Hi! Verwandte Befehle
................................................... Verwa ndte Befehle
EOF, Get, Line Input#, Input, Print#, Put, Write# Verwandte Themen
................................................... Verwandte Them en
Literale und Konstanten (S. 27)
Kill- Anweisung Sub Kill(sSuchmuster As String) Beschreibung
................................................... Bes c hreibung
Die Anweisung Kill löscht alle Dateien, deren Dateiname auf das Suchmuster sSuchmuster passt. Anwendung
................................................... Anwendung
Das Suchmuster besteht aus einem Pfadanteil (absolut oder relativ notiert) und einem Dateianteil, wobei der Pfadanteil das Verzeichnis spezifiziert, das durchsucht wird, und der Dateianteil ein Dateinamensmuster, das auch die Platzhalter »?« (Zeichen an dieser Stelle wird nicht unter-
1 44
Line Input #- Anweisung schieden) und »*« (Zeichen ab dieser Stelle werden nicht unterschieden) enthalten kann. Fehlt der Pfadanteil oder ist er relativ notiert, bezieht die Anweisung den Pfad auf das standardmäßige Arbeitsverzeichnis (vgl. »CurDir-Funktion«, S. 134). Beispiel
................................................... Beis piel
sPfad = Environ("Temp") if sPfad "" Then Kill(sPfad + "*.tmp") Verwandte Befehle
................................................... Verwa ndte Befehle
Line Input #- Anweisung Line Input #iDateiNr, sVariable Beschreibung
................................................... Bes c hreibung
Die Anweisung Line Input# liest eine Textzeile aus einer sequenziellen Datei, die im Modus Input oder Binary geöffnet wurde, und weist diese der Zeichenfolgenvariablen sVariable als Wert zu. Als Trennzeichen zwischen zwei aufeinander folgenden Textzeilen wertet die Anweisung das Wagenrücklaufzeichen Chr(13) bzw. vbCr sowie die Kombination Chr(13)+Chr(10) bzw. vbCrLf. Anwendung
................................................... Anwendung
Der traditionelle Zweck der Anweisung Line Input# ist, Zeichenfolgen für die Textverarbeitung aus sequenziellen Dateien zu lesen. Im Unterschied zu Input# behandelt Line Input# weder Kommas als Trennzeichen, noch schneidet die Anweisung Leerzeichen und doppelte Anführungszeichen ab. Zum Schreiben der Daten, die mit Line Input# gelesen werden sollen, verwenden Sie am besten Print#. Beispiel
................................................... Beis piel
Der folgende Code liest eine Textdatei zeilenweise in ein dynamisches Zeichenfolgenarray. Dim sZeilen() As String Dim lZeilen As Long Open "Textdatei.txt" For Input As 1 While Not EOF(1) ReDim Preserve sZeilen(lZeilen + 1) As String Line Input #1, sZeilen(UBound(sZeilen)) lZeilen = UBound(sZeilen) Wend Verwandte Befehle
................................................... Verwa ndte Befehle
EOF, Get, Input, Input#, Print#, Put, Write#
1 45
Dateiorientierte Funktionen und Anweisungen
RmDir
Dateiorientierte Funktionen und Anweisungen
Loc- Funktion Function Loc(iDateiNr As Integer) As Long Beschreibung
................................................... Bes c hreibung
Die Funktion Loc liefert abhängig vom Modus, in dem die Datei mit der DateiNr geöffnet wurde, die Nummer des zuletzt bearbeiteten Datensatzes oder die Position des zuletzt gelesenen oder geschriebenen Bytes. Anwendung
Dateiorientierte Funktionen und Anweisungen
................................................... Anwendung
Visual Basic verwaltet für jede Datei einen Dateizeiger, der die aktuelle Schreib-/Leseposition angibt. Den »nackten« Wert dieses Zeigers liefert die Funktion Seek als Byte-Nummer, gleich in welchem Modus eine Datei geöffnet wurde. Loc liefert dagegen den logischen Dateizeiger. Im Modus Binary unterscheidet sich der Wert des logischen Dateizeigers von dem des gewöhnlichen Dateizeigers dahingehend, dass er um 1 kleiner ist als dieser. Im Modus Random hat der logische Dateizeiger dagegen den Wert des zuletzt gelesenen oder geschriebenen Datensatzes. Es gilt die Formel: ( Dateizeiger – 1 ) Datensatznummer = ---------------------------------------------Datensatzlänge Mithin liefert Loc vor der ersten Dateioperation den Wert 0. Warnung
................................................... Wa rnung
Loc liefert für sequenzielle Dateien zwar einen Wert, dieser ist aber unbrauchbar, da er auf eine Datensatzlänge von 128 gemünzt ist. Sie arbeiten in diesem Fall besser mit Seek. Beispiel
................................................... Beis piel
Open "test.idx" For Random As 1 Len = Datensatzlänge For i = 1 To iDatensätze Put 1, , bdt(i) Next Print Loc(1) ' Wert von iDatensätze Close1 Verwandte Befehle
................................................... Verwa ndte Befehle
EOF, LOF, Seek
Lock- Anweisung Sub Lock([#]iDateiNr As Integer[, lDatensatz As Long]) Sub Lock([#]iDateiNr As Integer, [lStartNr As Long] To lEndNr As Long) Beschreibung
................................................... Bes c hreibung
Die Anweisung Lock sperrt einen einzelnen Datensatz lDatensatz oder einen Bereich von Datensätzen lStartNr bis lEndNr in der Datei mit der Dateinummer iDateiNr vor dem Zugriff durch andere Prozesse. Fehlt bei Gebrauch der ersten Syntax der optionale Parameter lDatensatz, verhängt die Anweisung die Sperre über die gesamte Datei. Fehlt bei Gebrauch der zweiten Syntax der optionale Parameter lStartNr, sperrt die Anweisung alle Datensätze von der Nummer 1 bis zur Nummer lEndNr. Bei Dateien, die im Modus Binary geöffnet wurden, beziehen sich die Bereichsangaben auf Positionen des Dateizeigers.
1 46
LOF- Funktion
Anwendung
................................................... Anwendung
Wenn in einem System oder in einem Netzwerk mehrere Programme gleichzeitig Schreibzugriffe auf dieselbe Datei durchführen, kann das recht unangenehme Inkonsistenzen zur Folge haben. Das Anweisungspaar Lock/Unlock ermöglicht es einem Programm, sich temporär die Exklusivrechte für das Beschreiben eines gewissen Teils der Datei zu sichern. Lock löst den Laufzeitfehler 70, »Zugriff verweigert«, aus, wenn ein anderes Programm bereits eine Sperre auf einen Bereich hält, der mit dem angegebenen Bereich überlappt. Warnung
................................................... Wa rnung
Beispiel
................................................... Beis piel
Der folgende Code schreibt eine Reihe von Datensätzen in die gemeinsame genutzte Datei Kunden.idx: Open "Kunden.idx" For Random As 1 Len = Datensatzlänge On Error GoTo Fehler70 Lock 1, lStartBereich To lEndBereich ' Sperre errichten On Error GoTo 0 For i = lStartBereich To lEndBereich Put 1, i, bdt(i) Next Unlock 1, lStartBereich To lEndBereich ' Sperre aufheben Close 1 Verwandte Befehle
................................................... Verwa ndte Befehle
Open, Unlock Verwandte Themen
................................................... Verwandte Them en
Fehlerbehandlung (S. 43)
LOF- Funktion Function LOF(iDateiNummer As Integer) As Long Beschreibung
................................................... Bes c hreibung
Die Funktion LOF liefert die Länge der unter der Nummer iDateiNummer geöffneten Datei in Bytes. Anwendung
................................................... Anwendung
Wo immer die Länge einer geöffneten Datei eine Rolle spielt, beispielsweise wenn es darum geht, eine Datei en bloc mittels Input einzulesen oder die Anzahl der bereits geschriebenen Bytes (nicht jedoch Datensätze) zu ermitteln, ist LOF das Mittel zum Zweck.
1 47
Dateiorientierte Funktionen und Anweisungen
Bei Lock/Unlock-Anweisungen für sequenzielle Dateien (Input, Output, Append) ignoriert Visual Basic Bereichsangaben und sperrt immer die gesamte Datei. Entgegen anders lautenden Informationen in der Online-Hilfe zu Visual Basic 6.0 entfernt Close (respektive das Programmende) jedoch alle Sperren, die mit Lock gesetzt und nicht explizit mit Unlock freigegeben wurden. Sie sollten aber dennoch darauf achten, jede Lock-Anweisung mit einer Unlock-Anweisung zu paaren, um errichtete Sperren zum frühestmöglichen Zeitpunkt wieder aufzuheben.
Dateiorientierte Funktionen und Anweisungen
Tipp
................................................... Tipp
Die Länge einer noch nicht geöffneten Datei ermittelt die Funktion FileLen. Beispiel
................................................... Beis piel
Der folgende Code liest die unter der Dateinummer 1 geöffnete Datei in einem Stück: sDatei = Input(LOF(1), 1) Verwandte Befehle
Dateiorientierte Funktionen und Anweisungen
................................................... Verwa ndte Befehle
Loc, FileLen, Get, Input, Line Input, Open, Seek
LSet- Anweisung LSet sString1 = sString2 LSet bdtVar = bdtWert Siehe »LSet-Anweisung« (S. 80).
MkDir- Anweisung Sub MkDir(sVerzeichnisname As String) Beschreibung
................................................... Bes c hreibung
Die Anweisung MkDir legt unter dem Namen sVerzeichnisname ein neues Verzeichnis an. Anwendung
................................................... Anwendung
Der Wert des Parameters sVerzeichnisname kann ein (absoluter oder relativer) UNC-Pfad oder Laufwerkspfad sein. Enthält sVerzeichnisname keinen Pfadanteil, legt die Anweisung das Verzeichnis als Unterverzeichnis des standardmäßigen Verzeichnisses an (vgl. »CurDir-Funktion«, S. 134). Falls das Verzeichnis bereits existiert oder die Rechte für das Anlegen des Verzeichnisses nicht ausreichen, löst die Anweisung den Laufzeitfehler 75, »Fehler beim Zugriff auf Pfad/ Datei«, aus. Beispiel
................................................... Beis piel
MkDir "C:\Visual-Basic-Daten\MeineDaten" ' Laufwerkspfad MkDir "\\Tiger\c\Visual-Basic-Daten\MeineDaten" ' UNC-Pfad Verwandte Befehle
................................................... Verwa ndte Befehle
ChDir, CurDir, RmDir
Name- Anweisung Name sAlterDateiname As sNeuerDateiname Beschreibung
................................................... Bes c hreibung
Die Anweisung Name ändert den Namen der Datei oder des Verzeichnisses sAlterDateiname in sNeuerDateiname. Falls sich die Pfadanteile von sAlterDateiname und sNeuerDateiname unterscheiden, wird die Datei bzw. das Verzeichnis verschoben.
1 48
Open- Anweisung
Anwendung
................................................... Anwendung
Die Werte der Parameter sAlterDateiname und sNeuerDateiname können (absolute oder relative) UNC-Pfade oder Laufwerkspfade sein. Fehlt ein Pfadanteil, bezieht sich die Anweisung auf das standardmäßige Verzeichnis (»CurDir-Funktion«, S. 134). Name lässt sich nur auf einzelne Dateien und Verzeichnisse anwenden, Platzhalterzeichen wie »*« oder »?« kann die Anweisung nicht interpretieren – sie lösen den Laufzeitfehler 52, »Dateiname oder -Nummer falsch«, aus. Falls die Datei oder das Verzeichnis sAlterDateiname nicht existiert, löst die Anwendung den Laufzeitfehler 53, »Datei nicht gefunden«, aus. Existiert dagegen sNeuerDateiname bereits als Datei oder Verzeichnis, kommt es zum Laufzeitfehler 58, »Datei existiert bereits«.
................................................... Beis piel
Kill sPfad + "Daten.dat" Name sPfad + "Daten.tmp" As sPfad + "Daten.dat Verwandte Befehle
................................................... Verwa ndte Befehle
Kill
Open- Anweisung Open sName For Modus [Access Zugriffsart] [Sperre] As [#] iNr [Len = lDatensatzlänge] Beschreibung
................................................... Bes c hreibung
Die Anweisung Open öffnet die Datei sName und ordnet ihr für den weiteren Zugriff die Dateinummer iNr zu. Zugleich legt die Anweisung einen Bearbeitungsmodus Modus fest, der als Input, Output, Random oder Binary anzugeben ist. Mittels des optionalen Schlüsselwortes Access gefolgt von Read, Write oder Read Write für Zugriff lässt sich zudem die Art des Zugriffs genauer festlegen. Darüber hinaus besteht die Möglichkeit, für den indexsequenziellen Zugriff im Modus Random eine Datensatzlänge lDatensatzlänge zwischen 1 und 32767 als Len-Zusatz anzugeben. Anwendung
................................................... Anwendung
Für den schreibenden oder lesenden Zugriff auf eine Datei ist es erforderlich, diese zuvor mit Open unter Angabe des entsprechenden UNC- oder Laufwerkspfades zu öffnen. Dabei kann es sich um einen absoluten oder relativen Pfad handeln. Ist sName nur als Dateiname ohne Pfadanteil spezifiziert, geht die Anweisung davon aus, dass die Datei im standardmäßigen Verzeichnis zu finden ist. Als Dateinummer iNr lässt sich ein Wert zwischen 1 und 511 wählen, der fortan als Alias der Datei für jegliche Zugriffe fungiert, bis diese mittels Close wieder geschlossen wird. Bei der Vergabe der Dateinummer ist zu beachten, dass diese nicht bereits einer anderen Datei zugeordnet wurde (vgl. »FreeFile-Funktion«, S. 139). Open ordnet der Datei je nach Bearbeitungsmodus und Zugriffsart auch einen Schreib- und/oder Lesepuffer sowie einen Dateizeiger zu, wobei der Dateizeiger die jeweils aktuelle Position für die nächste Dateioperation wiedergibt, falls diese nicht explizit die Angabe einer Startposition enthält. Für Modus kennt Visual Basic als reine Textmodi Input, Output und Append, wobei mit Input nur ein lesender Zugriff möglich ist und mit Output und Append nur ein schreibender. Ein AccessZusatz für diese Modi ergibt keinen Sinn, da die Zugriffsart ja bereits feststeht. Daneben gibt es noch den indexsequenziellen Zugriffsmodus Random für den rein datensatzorientierten Zugriff sowie den binären Zugriffsmodus Binary, der als flexibelster Modus sowohl für den textorien-
1 49
Dateiorientierte Funktionen und Anweisungen
Beispiel
Dateiorientierte Funktionen und Anweisungen
Dateiorientierte Funktionen und Anweisungen
tierten als auch für den datensatzorientierten Zugriff geeignet ist. Dateioperationen finden im Allgemeinen mit Bezug auf eine Byteposition statt, einzig Operationen im Modus Random liegt eine Datensatznummer zugrunde, bei der die Datensatzlänge lDatensatzlänge eine Rolle spielt. Der Dateizeiger gibt in diesem Fall die Datensatznummer an und nicht die Byteposition. In allen anderen Modi hat die Angabe einer Datensatzlänge keinen Effekt. Für den Modus Append setzt Open den Dateizeiger an das Ende der Datei, ansonsten an den Anfang. Wird eine Datei im Modus Binary oder Random mit dem Zusatz Access Read geöffnet, führt jeder Versuch, eine Schreiboperation darauf auszuführen, zu dem Laufzeitfehler 75, »Fehler bei Zugriff auf Datei«. Analoges gilt für den Zusatz Access Write und Lesezugriffe. Lautet der Zusatz Access Read Write oder fehlt der Access-Zusatz, öffnet Open die Datei in diesen beiden Modi für den Schreib- und Lesezugriff. Ein- und Ausgabeoperationen beziehen sich in diesem Fall auf den gleichen Puffer und den gleichen Dateizeiger. Eine Datei lässt sich auch mehrfach öffnen, sofern sie nicht in einem der Modi Input, Output oder Append geöffnet wird. In diesem Fall verwendet Visual Basic für die zugehörigen Dateinummern den gleichen Puffer, so dass zu jeder Zeit über jede der Dateinummern ein und derselbe Dateiinhalt verfügbar ist. Dateizeiger gibt es aber je Dateinummer einen eigenen (vgl. Beispiel). Gleich, in welchem Modus Sie eine Datei öffnen, Visual Basic verwendet standardmäßig die Zugriffsart Shared, denn diese Zugriffsart erlegt Programmen die geringsten Einschränkungen für den gemeinsamen Zugriff auf dieselbe Datei auf. Vom Prinzip her ist das zwar erwünscht, im Einzelfall kann es aber dazu führen, dass sich Programme gegenseitig ins Handwerk pfuschen, weil ihre Puffer unter ungünstigen Bedingungen unterschiedliche Versionen des gleichen Datensatzes oder des gleichen Dateibereichs enthalten können. Es gibt drei Möglichkeiten, dem entgegenzuwirken: Die erste ist das härteste Geschütz und besteht darin, die Datei gleich beim Öffnen durch Angabe einer der Zugriffsarten Lock Read, Lock Write oder Lock Read Write für den exklusiven Lesezugriff, Schreibzugriff oder Schreib-/Lesezugriff zu öffnen. Die zweite besteht darin, sich die gesamte Datei unmittelbar vor einem Schreib- bzw. Lesezugriff mittels Lock für den exklusiven Zugriff zu reservieren. Diese beiden Techniken können natürlich scheitern, wenn ein anderes Programm seinerseits eine Sperre auf die Datei errichtet hat – sei es auch nur eine Sperre für einen einzelnen Datensatz respektive für einen kleinen Bereich der Datei. Die dritte und moderateste Möglichkeit, auf einen bestimmten Datensatz oder Dateibereich ungestört zugreifen zu können, ist das Sperren genau dieses Datensatzes oder Bereichs mittels Lock und das sofortige Entsperren mittels Unlock nach dem Zugriff. Die Wahrscheinlichkeit, dass diese Technik scheitert, ist am geringsten, da es nur dann zu dem Laufzeitfehler 70, »Zugriff verweigert«, kommt, wenn ein anderes Programm eine Sperre auf die gesamte Datei oder auf genau denselben Datensatz bzw. Dateibereich errichtet hat. Insbesondere, wenn auch die anderen Programme mit der gleichen Technik arbeiten, sind kaum Kollisionen zu befürchten – was natürlich eine Fehlerbehandlung nicht entbehrlich macht. Auch wenn Visual Basic bei Programmende offene Dateien automatisch schließt, sollten Sie generell darauf achten, eine Datei unmittelbar nach der letzten Dateioperation mittels Close zu schließen. Das gibt die Dateinummer und den Puffer frei und ermöglicht anderen Programmen wieder den uneingeschränkten Zugriff auf die Datei. Insbesondere entfernt Close auch alle Sperren, die mit Lock gesetzt und nicht explizit mit Unlock freigegeben wurden. Beispiel
................................................... Beis piel
Der folgende Codeauszug demonstriert zum einen die Fehlerbehandlung im Zusammenhang mit der Open-Anweisung und verschiedenen Dateioperationen. Die Variable sDateipfad enthält die leere Zeichenfolge als Wert. Daher scheitern alle dateibezogenen Operationen. Der Benutzer kann den Vorgang abbrechen, wiederholen oder überspringen (ignorieren). Letzteres ist zu empfehlen, um die verschiedenen Fehlermeldungen zu erhalten. Löscht man das erste Kommen-
1 50
Print #- Anweisung tarzeichen in der zweiten Zeile, läuft der Code fehlerlos und demonstriert, wie es sich mit den Dateizeigern verhält, wenn eine Datei im Modus Binary zweimal geöffnet wird. sDateipfad = "" ' Als Dateiname nicht erlaubt! ' sDateipfad = "Test1" ' Dateiname ist OK On Error GoTo OpenFehler ' Fehlerbehandlung einrichten Open sDateipfad For Binary As 1 Open sDateipfad For Binary As 2
1 5 5 1
OpenFehler: ' Routine für Fehlerbehandlung sFehler = "Fehler" + Str(Err.Number) + ": " + Err.Description Select Case MsgBox(sFehler, vbAbortRetryIgnore, "Fehler") Case vbAbort: Error 1001 Case vbRetry: Resume Case vbIgnore: Resume Next End Select
Vgl. auch die Beispiele in »Close-Anweisung« (S. 133), »EOF-Funktion« (S. 137), »FileAttrFunktion« (S. 138), »FreeFile-Funktion« (S. 139), »Get-Anweisung« (S. 140), »Input- und InputB-Funktion« (S. 142), »Input #-Anweisung« (S. 143) und »Loc-Funktion« (S. 146) sowie das Beispiel im Abschnitt »Fehlerbehandlung« (S. 43). Verwandte Befehle
................................................... Verwa ndte Befehle
Close, FreeFile
Print #- Anweisung Print #iDateiNr[, Ausdr1[Trennz [Ausdr2] ... ]] Beschreibung
................................................... Bes c hreibung
Die Anweisung Print # führt Ausgaben im gebietsspezifischen Format in die unter der Dateinummer iDateiNr geöffnete sequenzielle Datei durch. Die auf die Dateinummer folgende Parameterliste Ausdr1, Ausdr2 usw. darf Werte beliebiger Standardtypen enthalten. Print # gibt diese Werte unter Beachtung des jeweils zwischen den Parametern stehenden Trennzeichens Trennz aus. Anwendung
................................................... Anwendung
Während Print nur noch als Methode eines Form-, UserControl- und Debug-Objekts verfügbar und somit sozusagen zur objektorientierten Seite von Visual Basic übergelaufen ist, ist Print#
1 51
Dateiorientierte Funktionen und Anweisungen
Put 1, 1, "abcd" Print Seek(1), Seek(2) ' Dateizeiger #1 = 5, #2 = Put 2, 1, StrReverse(Input(LOF(2), 2)) Print Seek(1), Seek(2) ' Dateizeiger #1 = 5, #2 = Seek 1, 1 ' Dateizeiger #1 = 1, #2 = Seek 2, 1 ' Dateizeiger #1 = 1, #2 = Print LOF(1), Input(LOF(1), 1) ' Ausgabe: 4, "dcba" Print LOF(2), Input(LOF(2), 2) ' Ausgabe: 4, "dcba" On Error GoTo 0 ' Fehlerbehandlung beenden Close 1, 2 Exit Sub
Dateiorientierte Funktionen und Anweisungen
Dateiorientierte Funktionen und Anweisungen
nach wie vor auf der traditionellen Seite der Sprache verblieben. Charakteristikum für die Ausgabe von Print# im Gegensatz zu Write# ist, dass die literale Darstellung der Werte im Allgemeinen im gebietsspezifischen Format erfolgt. »Im Allgemeinen« deshalb, weil es auch Werte gibt, die ungeachtet des Gebietsschemas nicht übersetzt werden. So die Werte True und False des Datentyps Boolean und das Wort »Error« in der Ausgabe eines Error-Werts. Und obwohl die Anweisung Null als »Null« in eine Datei schreibt, gibt sie den Wert Empty als leere Zeichenfolge und somit gar nicht aus. Als Trennzeichen Trennz sind das Semikolon und das Komma erlaubt. Bei Angabe eines Semikolons setzt die Anweisung den folgenden Wert unmittelbar hinter den vorigen, wie bei der Verkettung von Zeichenfolgen. Das Komma hingegen bewirkt, dass Print# den folgenden Wert an die nächste Tabulatorposition setzt und den Zwischenraum gegebenenfalls mit Leerzeichen auffüllt. Der Abstand zwischen je zwei Tabulatorpositionen beträgt 14 Zeichen. Ist im Anschluss an den letzten Parameter der Liste kein Trennzeichen spezifiziert, ergänzt die Anweisung einen Wagenrücklauf Chr(13) und einen Zeilenvorschub Chr(10) bzw. vbCrLf. Als Werte in der Parameterliste sind auch die Ausdrücke Spc(n) und Tab(n) zulässig, die jedoch keine eigenständigen Zeichenfolgenfunktionen darstellen, sondern als Argument von Print, Print# und Write# zulässig sind. Spc(n) fügt n Leerzeichen ein, und Tab(n) füllt die aktuelle Zeile bis zur Tabulatorposition n mit Leerzeichen. Warnung
................................................... Wa rnung
Die Anweisung gibt Zeichenfolgen im ANSI-Code und nicht im Unicode aus. Es ist im Allgemeinen nicht möglich, Fließkommawerte und Datumswerte, die mit Print# geschrieben wurden, mittels Input # wieder in Variablen des gleichen Typs einzulesen, da Print # seinen Ausgaben das gebietsspezifische Format verpasst, Input# aber Literale im standardisierten Format erwartet. Damit das klappt, müssen Sie die Daten mit Write# und nicht mit Print# schreiben. Tipp
................................................... Tipp
Im Gegensatz zu Write# versieht Print# Zeichenfolgen nicht automatisch mit Anführungszeichen. Wenn Sie ausschließlich Zeichenfolgen ausgeben, also reine Textverarbeitung betreiben, ist Print# in jedem Fall die bessere Lösung. Zum zeilenweisen Lesen der Daten verwenden Sie dann die Anweisung Line Input#. Beispiel
................................................... Beis piel
Die Prozedur Ersetze sucht in einer Textdatei alle Vorkommen der Zeichenfolge sSuch und ersetzt diese gegen die Zeichenfolge sErsetz. Function Ersetze(sDatei As String, sSuch As String, sErsetz As String) Dim sZeile As String Open sDatei For Input As 1 Open "Ersetz.tmp" For Output As 2 ' Temporäre Ausgabedatei anlegen While Not EOF(1) Line Input #1, sZeile ' Zeile lesen Print #2, Replace(sZeile, sSuch, sErsetz) ' Ersetzen und schreiben Wend Close 1, 2 ' beide Dateien schließen Kill sDatei ' Ausgangsdatei löschen Name "Ersetz.tmp" As sDatei ' Temporäre Datei umbenennen End Function
1 52
Put- Anweisung
Verwandte Befehle
................................................... Verwa ndte Befehle
Input, Input#, Line Input#, Print, Write# Verwandte Themen
................................................... Verwandte Them en
Literale und Konstanten (S. 27)
Put- Anweisung Put [#]iDateiNr, [lSatzNr], Wert
................................................... Bes c hreibung
Die Anweisung Put ist das Gegenstück zur Anweisung Get. Sie schreibt die über den Parameter Wert spezifizierten Daten in der gegebenen Repräsentation (typerhaltend) in die Datei mit der Dateinummer iDateiNr. Ist eine Satznummer lSatzNr angegeben, schreibt die Anweisung im Modus Random den Wert Wert als Datensatz unter Berücksichtigung der bei der Open-Anweisung vereinbarten Datensatzlänge und im Modus Binary als schlichte Bytefolge ab der Byteposition lSatzNr. Fehlt lSatzNr, schreibt die Anweisung den Wert als nächsten Datensatz (Random) bzw. an der jeweils aktuellen Schreibposition (Binary) und aktualisiert danach den Datensatzzeiger bzw. die aktuelle Schreibposition. Der Parameter Wert kann einen beliebigen Typ tragen, nicht jedoch einen Objekttyp. Anwendung
................................................... Anwendung
Wenn es um das Schreiben und Lesen von Dateiformaten ging, waren Get und Put schon immer die Arbeitspferde der Sprache Basic. Die Arbeitsweise dieser Anweisungen ist traditionell auf indexsequenzielle Dateien zugeschnitten, deren Bearbeitung im Modus Random erfolgt. Get und Put werden aber auch – jedoch mit leicht modifizierter Arbeitsweise – im Modus Binary eingesetzt.
Der Modus Random Beim Öffnen von Dateien im Modus Random wird normalerweise eine Datensatzlänge in Bytes festgelegt, die fortan bestimmt, wie viele Bytes mit jeder Get- bzw. Put-Operation je Datensatz gelesen bzw. geschrieben werden. Die Zählung der Datensätze beginnt bei 1. Den Bytebedarf der elementaren Datentypen entnehmen Sie der Tabelle im Abschnitt »Elementare Datentypen« (S. 49); den von Datentypen mit fester Länge sowie von benutzerdefinierten Datentypen ermittelt man am besten mittels LenB, da die Speicherausrichtung der Datenfelder noch eine zusätzliche Rolle spielt. Liegt Wert ein Typ variabler Länge zugrunde (bzw. ein Typ, der Felder variabler Länge enthält), erweitert das den Datensatz um einen Deskriptor (lies: Längenangabe). Dabei gilt, dass ein Deskriptor dem Wert unmittelbar vorausgeht. Mithin muss also der Längenbedarf eines oder mehrerer Deskriptoren bei der Berechnung der Datensatzlänge berücksichtigt werden. Für Zeichenfolgen variabler Länge schlagen dabei 2 Längenbytes (!) zu Buche (Zeichenfolgen dürfen demnach nicht länger als 65.535 Zeichen sein), für Variant-Variablen gleichfalls zunächst 2 Bytes für den VarType-Typ plus gegebenenfalls weitere Längenbytes für Wertanteile mit variablen Längen. Dynamische Arrays schlagen mit 2 Bytes für den Array-Deskriptor zu Buche plus 8 Bytes je Dimension. Die maximale Datensatzlänge beträgt 32.767. Put schreibt Wert linksbündig in den Datensatz, ohne Füllbytes anzuhängen, wenn die Repräsentation von Wert kürzer als die Datensatzlänge ist. Sollte die Repräsentation von Wert länger sein als die bei Open angegebene Datensatzlänge, kommt es zum Laufzeitfehler 59, »Falsche Datensatzlänge«.
1 53
Dateiorientierte Funktionen und Anweisungen
Beschreibung
Dateiorientierte Funktionen und Anweisungen
Der Modus Binary Für den Modus Binary gilt im Wesentlichen dasselbe, mit folgenden Abweichungen: Eine Datensatzlänge wird nicht berücksichtigt, und die Anweisung schreibt ab der aktuellen Position bzw. der Position lSatzNr so viele Bytes, wie die Darstellung von Wert benötigt. Zeichenfolgen variabler Länge behandelt Put wie Zeichenfolgen fester Länge, schreibt also nur so viele Bytes wie der Wert an Zeichen enthält – ein Deskriptoranteil entfällt somit. Analoges gilt auch für Arrays. Im Zusammenhang mit benutzerdefinierten Datentypen finden Deskriptoranteile einzelner Datenfelder jedoch sehr wohl Berücksichtigung.
Dateiorientierte Funktionen und Anweisungen
Warnung
................................................... Wa rnung
Put schreibt Unicode-Zeichenfolgen als ANSI-Code und Get liest ANSI-Zeichenfolgen als Unicode. Beispiel
................................................... Beis piel
Die folgende Prozedur Crypt32 nimmt eine einfache 32 Bit-Verschlüsselung einer Datei sDatei mit dem Wert lKennzahl vor. Der gleiche Wert entschlüsselt die Datei auch wieder; probieren Sie es aus. Sub Crypt32(lKennzahl As Long, sDatei As String) Dim lData As Long Open sDatei For Binary As 1 For i = 1 To LOF(1) – Len(lData) + 1 Get 1, i, lData Put 1, i, lData Xor lData Next i Close 1 End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
Get, Input, Input#, LenB, Line Input#, LSet, Open, Print# Verwandte Themen
................................................... Verwandte Them en
Elementare Datentypen (S. 49); Benutzerdefinierte Datentypen (S. 60)
Reset- Anweisung Reset Beschreibung
................................................... Bes c hreibung
Die Anweisung Reset schließt alle offenen Dateien, die mittels Open-Anweisungen geöffnet wurden. Anwendung
................................................... Anwendung
Sinn und Zweck dieser Anweisung ist es, im Fehlerfall oder bei einem überraschenden Programmabbruch schnell aufräumen zu können. Reset erzwingt insbesondere die Ausgabe von Pufferinhalten in Dateien, die zum Schreiben geöffnet wurden. Es besteht kein Unterschied zwischen dem parameterlosen Aufruf von Close und Reset.
1 54
RmDir- Anweisung
Verwandte Befehle
................................................... Verwa ndte Befehle
Close, End
RmDir- Anweisung Sub RmDir(sVerzeichnisname As String) Beschreibung
................................................... Bes c hreibung
Die Anweisung RmDir löscht das Verzeichnis sVerzeichnisName.
................................................... Anwendung
Der Wert des Parameters sVerzeichnisName kann ein (absoluter oder relativer) UNC-Pfad oder Laufwerkspfad sein. Enthält sVerzeichnisName keinen Pfadanteil, geht die Anweisung davon aus, dass das Verzeichnis ein Unterverzeichnis des standardmäßigen Verzeichnisses (vgl. »CurDir-Funktion«, S. 134) ist. Falls das Verzeichnis noch Dateien enthält, löst die Anweisung den Laufzeitfehler 75, »Fehler beim Zugriff auf Pfad/Datei«, aus. Existiert das Verzeichnis überhaupt nicht, kommt es zum Laufzeitfehler 76, »Pfad nicht gefunden«. Beispiel
................................................... Beis piel
Die rekursive Prozedur DelTree löscht ein Verzeichnis mit allen Dateien und Unterverzeichnissen. Sub DelTree(sPfad As String) Dim sUVz As String If Right(sPfad, 1) = "\" Then sPfad = Left(sPfad, Len(sPfad) – 1) End On Error GoTo Fehlerbehandlung Kill sPfad + "\*.*" sUVz = Dir(sPfad + "\", vbDirectory) While sUVz "" If sUVz "." And sUVz ".." Then DelTree (sPfad + "\" + sUVz) sUVz = Dir(sPfad + "\", vbDirectory) Else sUVz = Dir End If Wend RmDir sPfad On Error GoTo 0 Exit Sub Fehlerbehandlung: Resume Next End Sub
' "\" am Ende? ' Abschneiden ' Falls Kill scheitert ' oder Schreibschutz
' Unterverz. abklappern ' Rekursion ' da Dir nicht rekursiv ' arbeitet ' Nächstes Verzeichnis löschen
Verwandte Befehle
................................................... Verwa ndte Befehle
ChrDir, CurDir, Kill, MkDir
1 55
Dateiorientierte Funktionen und Anweisungen
Anwendung
Dateiorientierte Funktionen und Anweisungen
Seek- Anweisung und Seek- Funktion Function Seek(iDateiNr As Integer) As Long Seek [#]iDateiNr, lPosition Beschreibung
Dateiorientierte Funktionen und Anweisungen
................................................... Bes c hreibung
Als Funktion liefert Seek die aktuelle Position des Dateizeigers der unter der Dateinummer iDateiNr geöffneten Datei. Für den Modus Random gibt diese Angabe die Nummer des nächsten zu lesenden oder zu schreibenden Datensatzes ab Dateianfang wieder, für alle anderen Modi die Nummer des nächsten zu lesenden oder zu schreibenden Bytes ab Dateianfang. Das erste Byte bzw. der erste Datensatz trägt die Nummer 1. Als Anweisung setzt Seek den Wert lPosition als neue Position des Dateizeigers. Im Modus Random ist diese Position eine Datensatznummer, in allen anderen Modi eine Bytenummer. Anwendung
................................................... Anwendung
Lese- und Schreiboperationen verschieben den Dateizeiger jeweils immer nur um die gelesene Anzahl von Bytes bzw. Datensätzen, was dem Muster für den sequenziellen Dateizugriff entspricht. Seek ermöglicht die Orientierung und Positionierung innerhalb von Dateien, wenn indexsequenzielle Dateizugriffe erforderlich sind. Warnung
................................................... Wa rnung
Als Anweisung setzt Seek nichts weiter als den Dateizeiger. Falls der Wert von lPosition größer als die von LOF gelieferte Dateilänge ist, bewirkt die nächste Schreiboperation einer zum Schreiben geöffneten Datei eine entsprechende Verlängerung. Dagegen führt die nächste Leseoperation, gleich im welchem Modus die Datei geöffnet wurde, zum Laufzeitfehler 62, »Einlesen hinter Dateiende«. Tipp
................................................... Tipp
Die Syntax für die Dateioperationen Get und Put sieht die Angabe expliziter Positionsangaben vor, so dass auf Seek verzichtet werden kann. Beispiel
................................................... Beis piel
Open sDatei For Output As 1 Seek 1, lOffs ' Dateizeiger auf bestimmte Zeile Line Input #1, sZeile ' Zeile lesen Print Seek(1) ' Dateizeiger abfragen
Die folgende Zeile zeigt, was passiert, wenn Seek über das Dateiende hinausschießt: Open "Test" For Input As 1 ' Die Datei enthält 4 Bytes! Seek 1, 10000 ' Dateizeiger auf 10000 setzen Print Loc(1) ' Ausgabe: 9999 Print Seek(1) ' Ausgabe: 10000 Input #1, a ' Laufzeitfehler 62 Close
Vgl. auch das Beispiel zu »Open-Anweisung« (S. 149). Verwandte Befehle
................................................... Verwa ndte Befehle
Get, Loc, Open, Put
1 56
SetAttr- Anweisung
SetAttr- Anweisung Sub SetAttr(sPfad As String, iAttributvektor As Integer) Beschreibung
................................................... Bes c hreibung
Die Anweisung SetAttr setzt die Attribute der Datei oder des Verzeichnisses sPfad entsprechend dem Attributvektor iAttributvektor. Anwendung
................................................... Anwendung
Konstante
Beschreibung
vbNormal (0)
Keines der Bits im Attributvektor ist gesetzt, es handelt sich um eine gewöhnliche Datei
vbReadOnly (1)
Datei/Verzeichnis ist schreibgeschützt
vbHidden (2)
Datei/Verzeichnis ist verborgen
vbSystem (4)
Datei ist Systemdatei bzw. Verzeichnis ist Systemverzeichnis
vbVolume (8)
Logischer Datenträger (wird von SetAttr nicht gesetzt)
vbDirectory (16)
Verzeichnis (wird von SetAttr nicht gesetzt)
vbArchive (32)
Datei wurde seit der letzten Datensicherung geändert
Konstanten für Dateiattribute Beispiel
................................................... Beis piel
Die folgenden Zeilen zeigen, wie man temporär einen Schreibschutz auf eine Datei entfernt und dann wieder errichtet: SetAttr sDateName, GetAttr(sDateiname) And Not vbReadOnly ... SetAttr sDateName, GetAttr(sDateiname) Or vbReadOnly
Falls nicht klar ist, ob eine Datei schreibgeschützt ist oder nicht, schreiben Sie vorsichtiger: AttrVekt = GetAttr(sDateiname) SetAttr sDateName, AttrVekt And Not vbReadOnly ... SetAttr sDateName, AttrVekt Verwandte Befehle
................................................... Verwa ndte Befehle
Dir, FileAttr, GetAttr
1 57
Dateiorientierte Funktionen und Anweisungen
Das Dateisystem pflegt für jeden Namenseintrag einen Attributvektor (Bytewert), dessen Elemente (Bits des Bytewerts) eine genauere Aussage darüber machen, welcher Art die zugeordnete Datei (bzw. das Verzeichnis) ist. Die folgende Tabelle gibt einen Überblick über die möglichen Attribute sowie über die Konstanten, die in Visual Basic als Elemente des Aufzählungstyps VbFileAttribute für diese Attribute definiert sind. SetAttr ignoriert Attribute, die es nicht setzen kann – so ist es beispielsweise nicht möglich, mittels SetAttr aus einer Datei ein Verzeichnis zu machen.
Dateiorientierte Funktionen und Anweisungen
Shell- Anweisung Function Shell( _ sAnwendName As String, _ [FensterStil As VbAppWinStyle = vbMinimizedFocus]) _ As Double Beschreibung
Dateiorientierte Funktionen und Anweisungen
................................................... Bes c hreibung
Die Funktion Shell ermöglicht den Start einer anderen Anwendung sAnwendName als eigenständige Anwendung und liefert als Funktionswert die Task-ID des zugehörigen Prozesses respektive 0, wenn der Start nicht erfolgreich verlaufen ist. Die Bedeutung der Werte für den optionalen Parameter FensterStil listet die folgende Tabelle auf. Konstante
Beschreibung
vbHide (0)
Das Fenster der Anwendung ist nicht sichtbar, erhält aber den Fokus.
vbNormalFocus (1)
Das Fenster der Anwendung ist sichtbar, hat Normalgröße und erhält den Fokus.
vbMinimizedFocus (2)
Die Anwendung startet als Symbol, erhält aber den Fokus (Standardwert).
vbMaximizedFocus (3)
Die Anwendung startet mit maximiertem Fenster und erhält den Fokus.
vbNormalNoFocus (4)
Das Fenster der Anwendung ist sichtbar, hat Normalgröße, erhält aber nicht den Fokus.
vbMinimizedNoFocus (6)
Die Anwendung startet als Symbol, ohne den Fokus zu erhalten.
Fensterstile für den Start einer Anwendung aus Visual Basic heraus Anwendung
................................................... Anwendung
Das gestartete Programm erbt das standardmäßige Verzeichnis des aufrufenden Programms (vgl. »CurDir-Funktion«, S. 134). Mit der von Shell gelieferten Task-ID lässt sich mit den inhärenten Mitteln von Visual Basic nicht anderes anfangen, außer sie der Anweisung AppActivate zu übergeben, um der gestarteten Anwendung den Fokus zuzuschanzen. Das könnte etwa geschehen, um diese Anwendung mittels der Anweisung SendKeys fernzusteuern. Auf diese Weise lassen sich »die Geister, die man rief« beispielsweise auch wieder loswerden. Tipp
................................................... Tipp
Um eine Anwendung unter Vorgabe eines bestimmten Arbeitsverzeichnisses zu starten, stellen Sie dieses Verzeichnis vor dem Shell-Aufruf mittels ChDrive und ChDir als standardmäßiges Arbeitsverzeichnis ein. Beispiel
................................................... Beis piel
Vgl. das Beispiel zur »Date-Funktion und Date-Anweisung« (S. 116).
1 58
Unlock- Anweisung
Unlock- Anweisung Sub Unlock([#]iDateiNr As Integer[, lDatensatz As Long]) Sub Lock([#]iDateiNr As Integer, [lStartNr As Long] To lEndNr As Long) Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Wenn in einem System oder in einem Netzwerk mehrere Programme gleichzeitig Schreibzugriffe auf dieselbe Datei durchführen, kann das recht unangenehme Inkonsistenzen zur Folge haben. Das Anweisungspaar Lock/Unlock ermöglicht es einem Programm, sich temporär die Exklusivrechte für das Beschreiben eines gewissen Teils der Datei zu sichern. Jeder Unlock-Anweisung muss eine gleichlautende Lock-Anweisung vorangegangen sein, sonst löst diese den Laufzeitfehler 70, »Zugriff verweigert« aus. Warnung
................................................... Wa rnung
Bei Lock/Unlock-Anweisungen für sequenzielle Dateien (Input, Output, Append) ignoriert Visual Basic Bereichsangaben und sperrt immer die gesamte Datei. Entgegen anders lautenden Informationen in der Online-Hilfe zu Visual Basic 6.0 entfernt Close (respektive das Programmende) jedoch alle Sperren, die mit Lock gesetzt und nicht explizit mit Unlock wieder freigegeben wurden. Beispiel
................................................... Beis piel
Der folgende Code schreibt eine Reihe von Datensätzen in die gemeinsame genutzte Datei Kunden.idx: Open "Kunden.idx" For Random As 1 Len = Datensatzlänge On Error GoTo Fehler70 Lock 1, lStartBereich To lEndBereich ' Sperre errichten On Error GoTo 0 For i = lStartBereich To lEndBereich Put 1, i, bdt(i) Next Unlock 1, lStartBereich To lEndBereich ' Sperre aufheben Close 1 Verwandte Befehle
................................................... Verwa ndte Befehle
Lock, Open
Write #- Anweisung Write #iDateiNr[, Ausdr1[Trennz [Ausdr2] ... ]]
1 59
Dateiorientierte Funktionen und Anweisungen
Die Anweisung Unlock hebt bestehende (programmeigene) Sperren für einen einzelnen Datensatz lDatensatz oder einen Bereich von Datensätzen lStartNr bis lEndNr auf, die für die Datei mit der Dateinummer iDateiNr mittels eines vorangegangenen Lock-Aufrufs errichtet wurden. Fehlt bei Gebrauch der ersten Syntax der optionale Parameter lDatensatz, hebt Unlock eine Sperre auf, die für die gesamte Datei errichtet wurde. Fehlt bei Gebrauch der zweiten Syntax der optionale Parameter lStartNr, entsperrt die Anweisung alle Datensätze von der Nummer 1 bis zur Nummer lEndNr. Bei Dateien, die im Modus Binary geöffnet wurden, beziehen sich die Bereichsangaben auf Positionen des Dateizeigers.
Dateiorientierte Funktionen und Anweisungen
Beschreibung
................................................... Bes c hreibung
Die Anweisung Write # schreibt Daten im Standardformat für literale Werte in die unter der Dateinummer iDateiNr geöffnete sequenzielle Datei. Die auf die Dateinummer folgende Parameterliste Ausdr1, Ausdr2 usw. darf Werte beliebiger Standardtypen enthalten. Write # gibt diese Werte unter Beachtung des jeweils zwischen den Parametern stehenden Trennzeichens Trennz aus. Anwendung
Dateiorientierte Funktionen und Anweisungen
................................................... Anwendung
Da Print# Daten im gebietsspezifischen Format schreibt, wird Write# immer dann anstelle von Print# eingesetzt, wenn die geschriebenen Daten später mittels Input# wieder eingelesen werden sollen. Das Standardformat für literale Werte sieht insbesondere vor, dass Zeichenfolgen in Anführungszeichen und Datumswerte im Format #mm/tt/jjjj# notiert werden. Als Trennzeichen Trennz sind das Semikolon und das Komma erlaubt. Im Gegensatz zu Print # unterscheidet Write# nicht zwischen den beiden Trennzeichen und trennt aufeinanderfolgende Werte der Parameterliste durch ein Komma. Ist im Anschluss an den letzten Parameter der Liste kein Trennzeichen spezifiziert, ergänzt die Anweisung einen Wagenrücklauf Chr(13) und einen Zeilenvorschub Chr(10) bzw. vbCrLf. Warnung
................................................... Wa rnung
Write# gibt Zeichenfolgen im ANSI-Code und nicht im Unicode aus. Tipp
................................................... Tipp
Im Gegensatz zu Write# versieht Print# Zeichenfolgen nicht automatisch mit Anführungszeichen. Wenn Sie ausschließlich Zeichenfolgen ausgeben, also reine Textverarbeitung betreiben, ist Print# in jedem Fall die bessere Lösung. Zum zeilenweisen Lesen der Daten verwenden Sie dann die Anweisung Line Input#. Beispiel
................................................... Beis piel
Vgl. das Beispiel zu »Input #-Anweisung« (S. 143). Verwandte Befehle
................................................... Verwa ndte Befehle
Input#, Open, Print# Verwandte Themen
................................................... Verwandte Them en
Literale und Konstanten (S. 27)
1 60
Variablen Eine Variable ist ein auf einen bestimmten Datentyp (Datenformat) zugeschnittener »Behälter«, der einen Bezeichner (lies: einen Namen) trägt und einen (in dem Datenformat gehaltenen) Wert enthält. Beschreibung
................................................... Bes c hreibung
Charakteristikum der Variable ist, dass ihr Wert veränderlich ist, das heißt, er kann nach Belieben zur Laufzeit im Rahmen von Zuweisungsoperationen sowie von Funktions- und Prozeduraufrufen geändert werden. Mit dieser Eigenschaft ist die Variable unverzichtbarer Bestandteil einer jeden Programmiersprache und Medium für den formalen Umgang mit Daten jeglicher Art. Anwendung
................................................... Anwendung
Für die Wahl des Variablenbezeichners gelten die üblichen Vorschriften für die Bezeichnerwahl (vgl. »Bezeichner und Namensraum«, S. 34). Variablen erhalten ihren Wert durch Zuweisung eines Literals, einer Konstante, einer anderen gleichartigen Variablen, eines Funktionswerts oder eines Ausdrucks, wobei die jeweiligen Datenformate miteinander verträglich sein müssen. Dim MyVar1 As Integer, MyVar2 As Integer, MyVar3 As Integer Dim MyVar4 As Integer MyVar1 = 17 ' Variable MyVar1 erhält Literal als Wert MyVar2 = MyVar1 ' Variable MyVar2 erhält Wert von MyVar1 MyVar3 = MyVar1 + 17 ' Variable MyVar3 erhält Ergebnis von Berechnung MyVar4 = Max(MyVar1, MyVar3) ' Variable MyVar4 erhält Funktionswert
Somit können Variablen für alles stehen, was einen in einen Datentyp gefassten Wert darstellt. Auch wenn es die Sprache Visual Basic im Vergleich zu anderen Programmiersprachen nicht gerade offensichtlich macht: Es besteht ein gewisser Unterschied zwischen Variablen, die einen einfachen Datentyp, und solchen, die einen komplexen Datentyp tragen. Zu den einfachen Datentypen zählen: alle elementaren Datentypen (vgl. »Elementare Datentypen«, S. 49), ausgenommen String und Variant; weiterhin: Aufzählungsdatentypen (vgl. »Enum-Aufzählungen«, S. 62), alle benutzerdefinierten Datentypen, die ihrerseits nur einfache Datentypen als Felder enthalten; der Typ String* für Zeichenfolgen fester Länge und Datenfelder fester Größe, deren Elemente einen einfachen Datentyp tragen. Diese Datentypen zeichnen sich dadurch aus, dass sich ihre Repräsentation während des Programmablaufs von der Länge her nicht verändert und sie deshalb als kompakte Bytefolge gespeichert werden können. Die einfachen Datentypen noch abgerechnet, die als spezielle öffentliche Datentypen im Objektkatalog des Systems registriert sind und ihrerseits aus einfachen Datentypen ausgebaut sind, rechnet man alle anderen Datentypen zu den komplexen Datentypen. Insbesondere zählen dynamische Zeichenfolgen des Typs String, der flexible Datentyp Variant, dynamische Arrays sowie alle zu Objekten gehörigen Datentypen (Klassen) zu den komplexen Datentypen. Komplexe Datentypen lassen sich nicht kompakt speichern, sondern bestehen aus Deskriptoranteilen (Verweisen, Längen etc.) und Wertanteilen. Während die komplexen Datentypen String und Variant mit einem elementaren Datentyp als Untertyp noch relativ einfach und größtenteils intuitiv zu handhaben sind, ist der Umgang mit dynamischen Arrays und Objekten nicht ohne ein gewisses Verständnis für die Natur der »dahinter liegenden« Größen zu bewerkstelligen. Obwohl andere Programmiersprachen hier eine recht klare Linie zwischen Variablen ziehen, die für eine konkrete Größe stehen und solchen, die nur einen Verweis auf eine andere Größe darstellen, gibt es in Visual Basic das Konzept des Verweises offiziell nur in Bezug auf die Parameterübergabe bei Funktionsaufrufen.
1 61
Variablendeklaration
Variablendeklaration
»Hinter den Kulissen« arbeitet aber auch Visual Basic massiv mit Verweisen. Deutlich wird das beispielsweise, wenn man eine Objektvariable einer abstrakten Klasse (etwa der Klasse Form) vereinbart, der man zwar konkrete via Set ins Leben gerufene und von Form abstammende Objekte als Werte zuweisen kann, nicht jedoch via Set einen Wert der Klasse Form selbst – einen solchen gibt es nämlich nicht als konkreten Wert, weil eine Objektvariable des Typs Form ein reiner Verweis ist. »Verständnis für die Natur eines Werts zu haben«, bedeutet für den Visual-Basic-Programmierer natürlich nicht, dass er bis auf das Genaueste wissen muss, wie Visual Basic Objekte repräsentiert (das ist auch C++-Programmierern im Allgemeinen nicht bis auf das Letzte klar, weil es letztlich vom Compiler abhängt, wie er ein Objekt repräsentiert). Das genau ist ja die Stärke der abstrakten Datentypen, deren Implementationen hinter Objekten verborgen bleiben. Es bedeutet aber sehr wohl, dass man bei der Verwendung von Variablen nicht alle Werte in einen Topf schmeißen darf und insbesondere wissen muss, ob man es mit einer Variablen für einen einfachen Datentyp, einen dynamischen Datentyp, ein konkretes Objekt oder ein abstraktes Objekt zu tun hat.
Variablendeklaration Dim [WithEvents] VarName[([Indizes])] [As Typ] Dim VarName[([Indizes])] [As [New] Typ] Dim [WithEvents] VarName[...], [WithEvents] VarName[...][, ...] Private VarName[([Indizes])] [As [New] Typ] Private [WithEvents] VarName[([Indizes])] [As Typ] Private [WithEvents] VarName[...], VarName[...][, ...] Public VarName[([Indizes])] [As [New] Typ] Public [WithEvents] VarName[([Indizes])] [As Typ] Public [WithEvents] VarName[...], VarName[...][, ...] Static VarName[([Indizes])] [As [New] Typ] Static VarName[...], VarName [...][, ...] Option Explicit Beschreibung
................................................... Bes c hreibung
Visual Basic ist eine typisierende Programmiersprache. Zwar nimmt der Compiler von sich aus eine – für den Programmierer weitgehend transparente – implizite Typzuordnung und Typumwandlung von Werten je nach Erfordernis vor, doch dieses Standardverhalten überdeckt nur einen kleinen Teil der mit Visual Basic verfügbaren Typenvielfalt. Der volle Umfang der von Visual Basic unterstützten Datentypen mit allen ihren Repräsentationsformen und Geltungsbereichen lässt sich nur bei Verwendung der expliziten Variablendeklaration nutzen. Jede Deklaration impliziert eine Initialisierung mit dem Standardwert des – implizit oder explizit – vereinbarten Datentyps. Anwendung
................................................... Anwendung
Bei der expliziten Deklaration von Variablen unterscheiden Programmiersprachen traditionell zwischen der statischen und der automatischen Vereinbarung. Statische Variablen, für deren Deklaration das Schlüsselwort Static erforderlich ist, finden ihre Repräsentation im Datensegment des Prozesses, während automatische Variablen ihr (meist kurzes) Dasein auf dem Stack fristen. Visual Basic erlaubt die Vereinbarung statischer Variablen nur auf Prozedurebene
1 62
Variablendeklaration
Dim myForm As Form1 Set MyForm = New Form1 MyForm.Show und Dim myForm As New Form1 MyForm.Show In diesem Fall kann also eine implizite Initialisierung durch Nennung erfolgen. Visual Basic unterscheidet bei der expliziten, automatischen Variablendeklaration weiterhin zwischen einer Vereinbarung auf Prozedurebene und einer Vereinbarung auf Modulebene (im Bereich ALLGEMEIN). Vereinbarungen auf Prozedurebene und auf Modulebene lassen sich mit dem traditionellen Basic-Schlüsselwort Dim treffen. Vereinbarungen auf Modulebene lassen sich alternativ auch mittels der neuen Visual-Basic-Schlüsselwörter Private und Public treffen. Private entspricht dabei dem Schlüsselwort Dim und begrenzt den Geltungsbereich der Variablen auf das aktuelle Modul. Public dehnt dagegen den Geltungsbereich der Variablen auf alle Module aus. Bei der Deklaration einer Objektvariablen auf Modulebene ist der Zusatz WithEvents möglich. Er spezifiziert, dass die Objektvariable auf ein Objekt verweisen wird, das von sich aus (mittels RaiseEvent) Ereignisse generiert und die der »Besitzer« (das ist die Ebene, auf der die Objektvariable bekannt ist) behandeln oder weiterreichen sollte. Zur Behandlung solcher Ereignisse lassen sich dann in dem jeweiligen Modul unter dem Namen der Objektvariablen Behandlungsroutinen bereitstellen – so wie man das von Steuerelementen, die auf einem Formular platziert wurden, oder von Menüeinträgen her gewöhnt ist. ' Bereich Allgemein Private WithEvents myObject As MyClass ... Private Sub myObject_EventOfMyClass() ...
In der Tat nimmt Visual Basic für jedes Steuerelement, das auf einem Formular platziert wird, implizit nichts anderes als eine WithEvents-Deklaration vor und vereinbart dabei den unter der Eigenschaft Name des Steuerelements genannten Bezeichner als Objektvariable. WithEvents lässt sich nur bei der Vereinbarung von Instanzen konkreter Klassen verwenden und schließt eine gleichzeitige Verwendung des Spezifizierers New aus.
1 63
Variablendeklaration
(innerhalb von Prozedur- bzw. Funktionskörpern) und ermöglicht damit Prozeduren »mit Gedächtnis«: Im Gegensatz zur automatischen Variablen, die bei jedem Aufruf neu auf dem Stack angelegt wird, bleibt eine statische Variable und damit auch ihr Wert von einem Aufruf zum nächsten erhalten. Bei der Darstellung komplexer Datentypen, so beispielsweise von dynamischen Arrays und Objekten, kommt – bei beiden Vereinbarungsarten – ein dritter Speicherbereich ins Spiel, der Heap. In diesem Fall stellt die statisch oder automatisch vereinbarte Variable eine Referenz auf den eigentlichen Wert dar, der seinerseits auf dem Heap liegt. Der Variablendeklaration muss dann eine explizite oder implizite Initialisierung mit New folgen, damit die Variable einen von Empty, Nothing bzw. Null abweichenden Wert erhält. Implizit erfolgt die Initialisierung, wenn bei der Deklaration der Variablen das Schlüsselwort New auftaucht. Äquivalent sind daher:
Variablendeklaration
Abkürzungen
Variablendeklaration
Visual Basic vereinbart Variablen bei schlichter Nennung implizit als automatische Variablen und ordnet ihnen den Datentyp Variant zu: Private Sub Form_Click() Set f = Me For i = 1 to 10 s = s + CStr(i) Next i f.Caption = s End Sub
' f ist Variant mit Objektreferenz ' i ist Variant mit numerischem Wert ' a ist Variant mit Stringwert ' Fenstertitel ändert sich zu 12345678910
Ein weitere, recht praktische Möglichkeit für die Abkürzung von Variablendeklarationen liefern die traditionellen Typkennzeichen $, %, &, !, # der Sprache Basic. Mehr dazu unter »Typkennzeichen und Bezeichnerbereiche für Typen« (S. 167). Beispiele
................................................... Beis piele
Das Projekt DMzuEuroRechner benutzt die explizite Variablendeklaration mit dem Datentyp Long für die Rundung auf zwei Stellen hinter dem Komma. Das Formular enthält die Textfelder TextDM und TextEuro, die bei Verlust des Eingabefokus den Wert des jeweils anderen Feldes an ihren eigenen Wert anpassen. ' Projekt: DMzuEuroRechner Private Const iKurs As Single = 1.95583 Private Sub TextDM_LostFocus() Dim l As Long l = TextDM.Text * 100 / iKurs TextEuro.Text = l / 100 End Sub
' implizite Typumwandlung ' Typumwandlung und Rundung
Private Sub TextEuro_LostFocus() Dim l As Long l = TextEuro.Text * iKurs * 100 ' implizite Typumwandlung TextDM.Text = l / 100 ' Typumwandlung und Rundung End Sub
Im folgenden Beispielprojekt NewForm erzeugt das von Visual Basic automatisch gestartete Formular bei jedem Mausklick eine weitere Instanz seiner selbst. Die zuständige Variable frmVar wird implizit durch Nennung initialisiert. Jede Formularinstanz zählt die Mausklicks, auf die es bereits reagiert hat, und gibt sie aus. Für das Zählen der Klicks ist iKlicks als statische Variable vereinbart. ' Projekt: NewForm Private frmVar As New Form1 Private Sub Form_Click() Static iKlicks As Integer ' mit 0 initialisiert iKlicks = iKlicks + 1 Print iKlicks; ". Klick in dieses Formular" frmVar.Show ' implizite Initialisierung End Sub
1 64
Variablendeklaration
Das kleine Programm zeigt sehr schön, dass jedes Formularobjekt auch von dieser statischen Variablen seine eigene Kopie erhält. Von jedem Formular aus lässt sich immer nur ein weiteres Formular starten, da fVar global deklariert ist. Schließt der Benutzer ein Fenster, bleibt das Formularobjekt erhalten und sein Fenster kommt durch den nächsten Klick in das jeweils vorgeordnete Formular erneut zur Anzeige. Man erkennt das an dem erhaltenen Wert von iKlicks, den ein Mausklick in das wieder sichtbare Formular zu Tage fördert.
................................................... Warnung
Warnung
Dim s1, s2, s3, s4 As String Dim i1, i2 As Integer
vier String-Variablen und zwei Integer-Variablen zu vereinbaren, ist bereits auf dem Holzweg, wie der folgende Code zeigt: i1 = 1234 i2 = 5678 s1 = i1 ' s2 = i2 ' s3 = s1 + s2 ' s4 = CStr(i1) + CStr(i2) ' Print s3, s4 '
erwartet: s1 = "1234" erwartet: s2 = "5678" erwartet: Stringaddition Stringaddition nach expliziter Typumwandlung unerwartete Ausgabe: 6912 12345678
Tatsächlich betrachtet der Compiler in diesem Codefragment i1, s1, s2 und s3 als Variablen vom Typ Variant, wie der Debugger schnell anhand des Initialisierungswerts Leer enthüllt. Die korrekte Formulierung lautet: Dim s1 As String, s2 As String, s3 As String, s4 As String Dim i1 As Integer, i2 As Integer i1 = 1234 i2 = 5678 s1 = i1 ' s1 = "1234" s2 = i2 s3 = s1 + s2 ' Stringaddition s4 = CStr(i1) + CStr(i2) ' CStr ist nun eigentlich unnötig Print s3, s4 ' erwartete Ausgabe: 12345678 12345678
Würde man den impliziten Typumwandlungsmechanismus nutzen, ließe sich die gesamte Variablendeklaration auf die Zeile Dim s1 As String, s2 As String
beschränken. Wenn nämlich s1 und s2 Zeichenfolgen sind, nimmt Visual Basic bei den Zuweisungen s1 = i1 s2 = i2
' Typumwandlung: von Variant mit numerischen ' Daten in String
eine implizite Typumwandlung in den Datentyp String vor.
1 65
Variablendeklaration
Die Syntax von Visual Basic für die akkumulierende Variablenvereinbarung ist leider in fehlerträchtiger Abweichung zu anderen Programmiersprachen (etwa zu C/C++, Pascal, Delphi) gestaltet, was gerade geübten Programmierern, die in vielen Sprachen zu Hause sind, gerne zum Stolperstein wird. Die resultierenden Bugs sind nicht nur extrem schwer zu finden, sie sind noch dazu ziemlich lästig, weil die implizite Typumwandlung des Compilers zuweilen die seltsamsten Kapriolen auf Lager hat. Wer glaubt, mit der Formulierung
Variablendeklaration
Generell merke man sich die einfache Regel: Visual Basic ordnet jeder Variablen, die nicht explizit und mit unmittelbar anschließender Nennung eines Datentyps deklariert wurde, den Datentyp Variant zu. Auf diese Weise werden auch schlichte Schreibfehler schnell zur Falle. Visual Basic vereinbart für den vertippten Bezeichner eine eigene Variable des Typs Variant. Tipp
Variablendeklaration
................................................... Tipp
Gewöhnen Sie sich an, Variablen explizit zu vereinbaren und auch explizite Typumwandlungen hinzuschreiben. Das hilft, unliebsame Überraschungen durch falsche Typisierung und durch ungewollte Doppelverwendung weitgehend zu vermeiden. Sie erhalten eine bessere Kontrolle über die Datentypen und gleichzeitig auch einen schnelleren Code. Wenn Sie wollen, dass Sie der Compiler zur expliziten Typdeklaration zwingt, fügen Sie die Anweisung Option Explicit
in den Bereich ALLGEMEIN des jeweiligen Moduls ein. Auf diese Weise schützen Sie sich (und ihre Kunden) vor unbemerkten Tippfehlern in Bezeichnern, die Visual Basic sonst ungefragt als eigenständige Variablen des Typs Variant vereinbart und mit dem jeweiligen Standardwert initialisiert. Wenn Sie in der Entwicklungsumgebung von Visual Basic über das Menü EXTRAS/ OPTIONEN auf der Eigenschaftsseite EDITOR die Einstellung VARIABLENDEKLARATION ERFORDERLICH treffen, setzt der Editor diese Anweisung automatisch in jedes neue Modul, das Sie anlegen. Wenn Sie es lieber auf die »sanfte Art« beigebracht haben wollen: Streuen Sie bei der Deklaration (explizit oder implizit) Großbuchstaben in die Variablenbezeichner ein und tippen Sie die Bezeichner später in Kleinbuchstaben. Der Editor von Visual Basic wandelt den Bezeichner bei Verlassen der Zeile automatisch in die bei der Deklaration gewählte Schreibweise um. Bleibt die Kleinschreibung erhalten, weist dies auf einen Tippfehler hin. Const cMinLänge = 1 Const cMaxLänge = 1000 Private lFileLength As Long ... ' Bei Schreibfehlern korrigiert Visual Basic die Schreibweise nicht! If lFileLength < cMaxLänge And lfilelenght > cminläng Then
Nachdem Dim-Anweisungen an beliebiger Stelle im Programm stehen dürfen, ist es darüber hinaus eine Frage des Programmierstils, wo Sie Ihre Variablen explizit deklarieren: ● ●
direkt »vor Ort«, unmittelbar vor der Initialisierung (populär) gleich zu Anfang der Prozedur (klassisch)
Die Deklaration »vor Ort« wird zwar immer populärer, weil sie angeblich die Lesbarkeit von Programmen verbessern soll, meines Erachtens bewirkt sie aber eher das Gegenteil: Deklarationen, die irgendwo mitten im Programmtext versteckt sind, lassen sich schwer auffinden, wenn der Typ der Variablen an späterer Stelle einmal unklar ist. Dagegen ist die Deklaration »zu Beginn« ein klare Sache – man weiß immer, wo die Deklaration einer Variablen zu finden ist. Welchen Stil auch immer Sie bevorzugen, bleiben Sie ihm treu. Es hat wenig Sinn, beide zu mischen, dann ist die Verwirrung nämlich komplett. Eine Variable mit eingestreuter Deklaration liest sich schnell als Variant, wenn einige zu Beginn deklarierte Variablen auf den klassischen Deklarationsstil hindeuten Verwandte Befehle
................................................... Verwa ndte Befehle
ReDim
1 66
Typkennzeichen und Bezeichnerbereiche für Typen
Verwandte Themen
................................................... Verwandte Them en
ActiveX-Steuerelemente (OCX) – Windows-Standardsteuerelemente (S. 433); Arrays (S. 55); Datentypen und ihre Operationen (S. 49); Funktionen selbst definieren (S. 181); Geltungsbereiche von Variablen (S. 173); Klassen als Datentypen für Objektvariablen (S. 196); Objekte und Klassen (S. 195); Prozeduren selbst definieren (S. 183); Typkennzeichen und Bezeichnerbereiche für Typen (S. 167); Variableninitialisierung (S. 168)
Typkennzeichen und Bezeichnerbereiche für Typen $, %, &, !, #
Beschreibung
................................................... Bes c hreibung
Neben der expliziten Typdeklaration unterstützt Visual Basic natürlich auch die traditionellen impliziten Möglichkeiten der Typdeklaration durch frei definierbare Präfixe (Bezeichnerbereiche) und durch vordefinierte Suffixe (Typkennzeichen). Anwendung
................................................... Anwendung
Syntaktisch gesehen findet die Deklaration hier durch Erweiterung des Bezeichners um ein Zeichen statt. Die Suffixlösung – einst die populärere – muss mit einem festen Vorrat an Typkennzeichen auskommen: $ für String, % für Integer, & für Long, ! für Single, # für Double. Selbst angesichts der reicheren Typenvielfalt von Visual Basic ist dieser Vorrat nicht mehr aufgestockt worden (nicht zuletzt mangels weiterer Sonderzeichen). Verwendung findet am ehesten noch das Zeichenfolgenzeichen $ For i% = 1 to 100 ' Implizite Deklaration durch Typkennzeichen a$ = a$ + Val(i%) Next i%
Die Präfixlösung erfordert eine Deklaration, die festlegt, welches Präfix welchen Datentyp kennzeichnen soll. Präfixe sind aus der Menge der für Bezeichner zulässigen Zeichen zu wählen. Dabei können auch mehrere Präfixe, ja sogar Buchstabenbereiche, ein und denselben Datentyp kennzeichnen. Der Compiler bemängelt allerdings, wenn Sie versuchen, einen Buchstaben mehreren Datentypen zuzuordnen. ' Bereich Allgemein DefLng L,X-Z DefStr S DefBool B DefCur C DefObj O
Damit erhalten alle Variablen, deren Bezeichner mit einem der Zeichen L, X, Y oder Z beginnt, bei schlichter Nennung (implizite Deklaration) automatisch den Typ Long. Zeichenfolgenvariablen werden dagegen durch einen mit S beginnenden Bezeichner implizit vereinbart usw. Bei expliziter Typdeklaration oder Verwendung eines vordefinierten Suffix ist diese Namenskonvention außer Kraft. DefCur C ...
1 67
Variablendeklaration
DefTyp AbisZ [, AbisZ[, ...]] DefBool, DefByte, DefInt, DefLng, DefCur, DefSng, DefDbl, DefDec, DefDate, DefStr, DefObj, DefVar
Variableninitialisierung
cWertInEuro c$ = "DM" Dim cents As Integer
' Typ ist Currency ' Typ ist String ' Typ ist Integer
Visual Basic verwendet implizit die Vereinbarung DefVar A-Z
das heißt, alle Variablen erhalten bei impliziter Deklaration den Standardtyp Variant. Um Long als neuen Standardtypen zu vereinbaren, schreiben Sie:
Variableninitialisierung
DefLong A-Z
Eine solche Vereinbarung kann durchaus sinnvoll sein, weil sie nicht nur den Code schneller macht, sondern auch eine explizite Deklaration des komplizierten Typs Variant erzwingt. Tipp
................................................... Tipp
Um den Typ einer Variablen mittels Suffix festzulegen, genügt es, das Suffix bei erstmaliger Nennung des Variablenbezeichners zu gebrauchen. Für weitere Nennungen ist ein Suffix nicht mehr erforderlich – aber auch nicht schädlich. Wenn Sie nicht wissen, welchen Typ eine Variable hat, können Sie den Typ mittels TypeName in Erfahrung bringen. a$ = 10 Print a, TypeName(a)
' implizite Deklaration als String, 10 ist "10" ' Ausgabe: 10 String
Verwandte Befehle
................................................... Verwa ndte Befehle
Option Base, Option Explicit Verwandte Themen
................................................... Verwandte Them en
Elementare Datentypen (S. 49); Variableninitialisierung (S. 168); Geltungsbereiche von Variablen (S. 173); Arrays (S. 55); Funktionen selbst definieren (S. 181); Prozeduren selbst definieren (S. 183)
Variableninitialisierung [Let] SimpleVar = Ausdruck Set ObjektVar = [New] ObjektAusdr Set ObjektVar = Nothing Beschreibung
................................................... Bes c hreibung
Im klassischen Programmiermodell für typisierende Sprachen muss eine Variable vor ihrem ersten Einsatz als »Rechtswert« (lies: auf der rechten Seite des Gleichheitszeichens oder als Parameter bei einem Funktions-/Prozeduraufruf) geeignet deklariert und initialisiert werden. Basic war in dieser Hinsicht schon immer etwas legerer, weil es weder die Deklaration noch die Initialisierung zwingend vorschreibt, sondern bei Nennung eines Bezeichners eine implizite Deklaration und im selben Aufwasch auch eine Initialisierung mit dem Standardwert des jeweiligen Datentyps vornimmt. Somit kann der Basic-Programmierer im Allgemeinen davon ausgehen, dass jede Variable zu jedem Zeitpunkt einen definierten Zustand besitzt (das ist nicht in allen Sprachen so). Dennoch wird in den meisten Fällen eine explizite Variableninitialisierung nicht nur die Lesbarkeit verbessern, sondern auch vonnöten sein.
1 68
Variableninitialisierung
Anwendung
................................................... Anwendung
Dim myObject As Object ... Set myObject = New Form1
' Deklaration ' an späterer Stelle ...
Warnung
................................................... Wa rnung
Wie schon angedeutet, spielt Visual Basic dem Programmierer gerne mal den einen oder anderen Streich, indem es von sich aus implizite Typzuordnungen und -umwandlungen vornimmt. Eine notorische Ursache für Ungereimtheiten im Programmverhalten ist die auf die gebietsspezifische Zahlendarstellung (Ländereinstellungen des Systems) zurückzuführende Punkt-/KommaProblematik bei der Initialisierung mit numerischen Literalen und literalen Zeichenfolgen. Wer mit der Gebietseinstellung »Deutsch (Standard)« auf seinem System einen Zahlenwert als literale Zeichenfolge spezifiziert, muss darauf achten, das Dezimalsymbol als echtes Komma zu schreiben. Punkte in literalen Zeichenfolgen ignoriert Visual Basic geflissentlich. Diese Problematik ist inzwischen fast schon älter als des Kaisers Bart, und man muss sich wahrlich die Frage stellen, warum Microsoft die Sprache inzwischen nicht um einen entsprechenden Schalter erweitert hat (etwa Option Locale), der es erlaubt, das Problem mit globaler Wirkung schlicht abzuschalten. Ein weiteres Problem wirft zuweilen die Initialisierung mit literalen Werten in hexadezimaler Darstellung auf. Visual Basic betrachtet ein vierstelliges Hex-Literal grundsätzlich als Wert vom Typ Integer, auch wenn der Linkswert vom Typ Long ist. Somit konvertiert Visual Basic beispielsweise den Wert &HFFFF in -1 und nicht in 65.535. Als Lösung bietet es sich an, dem Literal entweder eine (oder mehrere) führende Null(en) zu verpassen oder das Typkennzeichen & anzuhängen (vgl. unter Beispiele). Tipp
................................................... Tipp
Mit Visual Basic 6 hat sich zumindest etwas getan, was die Beilegung der Punkt-/Komma-Problematik betrifft, wenn auch nicht gerade viel. Die neue Funktion StrConv ermöglicht unter anderem die Angabe einer Gebietsschema-ID für die Umwandlung einer Zeichenfolge in den Typ Variant mit Untertyp String. Damit lässt sich ein bestimmtes Gebietsschema als Referenzschema verwenden, was eine gewisse Unabhängigkeit von den Systemeinstellungen bedeutet. Sollte eine Variable trotz sorgfältig geprüfter Deklaration und Initialisierung ihren Wert aus unerklärlichen Gründen plötzlich ändern, sind Sie aller Wahrscheinlichkeit nach einer Verletzung der Regeln für den Geltungsbereich aufgesessen. In den meisten Fällen wurde ein Prozedurparameter genauso benannt wie eine globale Variable.
1 69
Variableninitialisierung
Die Initialisierung von Variablen, die keine Objektvariablen sind, erfolgt grundsätzlich durch eine einfache Let-Zuweisung, wobei das optionale Schlüsselwort Let so gut wie immer der Einfachheit halber weggelassen wird. Visual Basic nimmt bei einer solchen Zuweisung gegebenenfalls erforderliche Typumwandlungen von sich aus vor – was nicht gerade immer zum gewünschten Ergebnis führt. Anders sieht die Sache bei Objektvariablen aus. Erfolgt die Deklaration einer Objektvariablen unter Angabe von New, erzeugt Visual Basic das entsprechende Objekt umgehend, das heißt, die Variable wird im Rahmen der Deklaration vollständig initialisiert (lies: an ein vollständig initialisiertes Objekt gebunden). Fehlt der Spezifizierer New, initialisiert Visual Basic die Objektvariable zunächst mit dem Standardwert Empty für den Datentyp Object (welcher für Objekte aller Klassen benutzt werden kann). Dem muss an späterer Stelle eine explizite Initialisierung der Objektvariablen im Rahmen einer Set-Anweisung unter Angabe des Schlüsselwortes New sowie einer konkreten Klasse folgen, die das Objekt schließlich ins Leben ruft:
Variableninitialisierung
Beispiele
................................................... Beis piele
Variableninitialisierung
' String Dim A As String Dim B As String A = "Literal" B = A + A A = 100 A = Hex$(65)
' ' ' ' ' '
' String * Dim A As String * 6 ' A = "String" ' A = "Integer" ' A = "DM" ' ' Byte Dim A As Byte A = i% A = AscB(s$) A = Asc(s$) ' Integer Dim A As Integer Dim B As Integer A = 10 A = &HFFFF A = 10.5 A = -10.5 B = A B = "10.5"
' Long Dim A As Long A = 123456789& A = &HFFFF
"" (Standardwert) "" (Standardwert) "Literal" "LiteralLiteral" "100" implizite Str-Umwandlung "41"
' "||||||" (Standardwert mit | als Nullzeichen) "String" "Intege" Wert ist abgeschnitten "DM " mit Leerzeichen aufgefüllt
' ' ' ' '
0 (Standardwert) 0 (implizite Typumwandlung geht gut, solange i% < 256) geht immer gut geht nicht immer gut, wenn s$ Unicode
' ' ' ' ' ' ' ' '
0 (Standardwert) 0 (Standardwert) 10 -1 (Zweierkomplement) 10 (Nachkommastellen abgeschnitten) -10 (Nachkommastellen abgeschnitten) 10 105 (implizite Val-Umwandlung, Punkt nicht als Komma erkannt, wegen Ländereinstellungen!)
' ' ' ' A = &HFFFF& ' A = &HFFFFFFFF ' b% = 10: A = b% ' A = "123,456789" ' ' A = "123.456789" ' '
0 (Standardwert) 123456789 (Long-Literal wegen &) -1 (Zweierkomplement und Interpretation als Integer-Literal) 65535 (Long-Literal) -1 (Zweierkomplement) 10 (implizite Typumwandlung) 123 (implizite Val-Umwandlung Nachkommastellen abgeschnitten) 123456789 (implizite Val-Umwandlung und Punkt nicht als Komma erkannt, wegen Ländereinstellungen!)
' Single Dim A As Single ' 0.0 (Standardwert) A = 1023.1234567 ' 1023.123 (nicht mehr als 7 Stellen)
1 70
Variableninitialisierung
A = 1E-23 ' A = "123,123456" ' A = "123.456789" ' '
' Boolean Dim A As Boolean Dim B As Boolean A = True A = (A True) A = 1234 A = 0
' ' ' ' ' '
0.0 (Standardwert) 1023.1234567 (maximal 14 Stellen) -1 (Hexzahl zuerst als Long, Zweierkomplement) 123.1234 (implizite Val-Umwandlung) 1.234568E+8 (Rundung! Punkt wird wegen Ländereinstellungen nicht als Komma erkannt!)
' ' ' ' ' '
False (Standardwert) False (Standardwert) True False True False
Variableninitialisierung
' Double Dim A As Double A = 1023.1234567 A = &HFFFFFFFF A = "123,123456" A = "123.456789"
1E-23 123.1234 (implizite Val-Umwandlung) 1.234568E+8 (Rundung und Punkt wird wegen Ländereinstellungen nicht als Komma erkannt!)
' Currency Dim A As Currency ' 0 (Standardwert) A = 12345.1234 ' 12345.1234 (Literal) A = "12345.1234" ' 123451234 (implizite Val-Umwandlung, Punkt wird ' wegen Ländereinstellungen nicht als Komma erkannt!) A = 12.123456 ' 12.1235 (Rundung auf vier Stellen hinter dem Komma) A = &HFFFFFFFF ' -1 (Longliteral und Zweierkomplement) ' Decimal Dim A As Variant ' Datentyp kann nicht direkt vereinbart werden! A = CDec("123456789012345678901234567890") ' 29 Stellen erlaubt A = CDec("12.12") ' 1212 (implizite Val-Umwandlung, Punkt wird
' wegen Ländereinstellungen nicht als Komma erkannt!) A = CDec("12,12") ' 12.12 A = CDec(12.12) ' 12.12 (Wandlung über Single) A = CDec(&HFFFF) ' -1 (Zweierkomplement und Interpretation als ' Integer -Literal) ' Date Dim A As Date ' 00:00:00 A = "01.01.2000" ' 01.01.00 A = "1.1.00" ' 01.01.00 A = 12.12 ' 11.01.1900 02:52:48 (Wandlung über Single) A = "1.1" ' 01.01.00 (aktuelles Jahr wird ergänzt) A = &HFFFF ' 29.12.1899 (Hausnummer, Wandlung über Integer) A = "11.11.11 11:11" ' Faschingsbeginn im Jahre 2011 A = "12:23:01" ' 12:23:01 (Uhrzeit!) ' Object Dim A As Object
' Nothing (Standardwert)
1 71
Variableninitialisierung
Variableninitialisierung
Dim B As New Form1 ' B ist Objekt der Klasse Form1 Set A = New Form1 ' A ist Objektvariable und verweist auf neues Objekt ' der Klasse Form1. New ist erforderlich! B.Hide ' Set oder New ist nicht erforderlich! Set A = B ' Altes Objekt von A stirbt, und A wird Objektvariable ' für B. Set ist erforderlich! A.Show ' B-Formular wird angezeigt B.Caption = "B" ' Titelleiste von B-Formular ändert sich in "B", denn ' Objektvariable A ist Synonym für Objekt B ' Variant Dim A As Variant Dim B Dim C As Object B = Null A = C A = "1234" A = 1234 A = TypeName(A)
' ' ' ' ' ' ' '
Empty (Standardwert) Empty (Standardwert) Nothing (Standardwert) Null Nothing "1234" 1234 "Integer"
' Arrays Dim A(20) As Integer
' ' ' ' Dim B(3 To 30) As Date ' ' ' ' Dim C(10,2) As Integer ' Dim D() ' ' ' ReDim D(2) ' ' '
A ist Arrayvariable für Array mit 21 Feldern bei standardmäßiger Indexzählung ab 0, sonst mit 20 Feldern. Alle Feldwerte sind mit 0 (Standardwert für Integer) initialisiert. B ist Arrayvariable für Array mit 28 Feldern. Die Indexzählung beginnt ab 3 und geht bis 30. Alle Feldwerte sind mit 00:00:00, dem Standardwert für Date, initialisiert. C ist Arrayvariable für zweidimensionales Array D wird als dynamisches Datenfeld des Typs Variant vereinbart (Visual Basic nimmt keine Initialisierung vor) D wird dimensioniert, dabei erhalten alle Felder den Wert Empty (Standardwert für Variant).
Verwandte Befehle
................................................... Verwa ndte Befehle
Property Let, Property Set Verwandte Themen
................................................... Verwandte Them en
Datentypen und ihre Operationen (S. 49); Geltungsbereiche von Variablen (S. 173); Variablendeklaration (S. 162)
1 72
Geltungsbereiche von Variablen
Geltungsbereiche von Variablen Private, Public, Dim Beschreibung
................................................... Bes c hreibung
' Modul Form1 Public iWert As Integer Sub MeineSub() Dim iWert As Integer ... iWert = Form1.iWert ...
' auf Programmebene vereinbart ' auf Prozedurebene vereinbart ' Mit Modulnamen qualifiziert
Anwendung
................................................... Anwendung
In der geschilderten Weise klingt das zunächst einmal recht abstrakt. Die Geltungsbereiche haben aber große Vorteile. Zunächst einmal unterliegt man bei der Programmierung von Prozeduren und Funktionen so gut wie keinen Einschränkungen, was die Wahl der Bezeichner betrifft. Zu beachten ist lediglich, dass man keinen Bezeichner erwischt, der auf Modulebene als Private vereinbart wurde und dessen aktueller Wert innerhalb der Prozedur benötigt wird. Die auf Modulebene gelegene Variable, Funktion oder Prozedur wäre dann nämlich nicht ansprechbar. Für öffentliche Bezeichner lässt sich die Herkunft dagegen jederzeit durch Qualifizierung ausdrücken, so dass hier keine Schwierigkeiten zu befürchten sind. Das ermöglicht es insbesondere Objekten, ihre öffentlichen Elementvariablen und Methoden gegenseitig anzusprechen: Sub Form1_Load() Dim frm2 As New Form2 frm2.ShowInTaskBar = False
' Qualifizierung
Tipp
................................................... Tipp
Die Bezeichner der öffentlichen Elemente von öffentlichen Datentypen lassen sich über den Objektkatalog (Taste (F2)) herausfinden. Verwandte Themen
................................................... Verwandte Them en
Bezeichner und Namensraum (S. 34)
1 73
Geltungsbereiche von Variablen
Der Geltungsbereich oder Gültigkeitsbereich einer Variablen ist der Teil des Codes, in dem eine Variable und ihr Wert bekannt sind. Der engste Geltungsbereich ist die Prozedurebene. Er gilt für Variablen, die innerhalb einer Prozedur bzw. Funktion als automatische oder statische Variablen vereinbart werden, sowie für alle Argumentvariablen. Der nächstgrößere Geltungsbereich ist die Modulebene. Er gilt für automatische Variablen, die mittels Private oder Dim außerhalb eines Prozedurkörpers vereinbart werden. Den größten Geltungsbereich, die Programmebene, haben Variablen, wenn sie auf Modulebene mittels Public als öffentliche Variablen vereinbart werden. Wird ein Variablenbezeichner in zwei unterschiedlichen Geltungsbereichen eingeführt, wovon der eine den anderen überlappt, bezeichnet er zwei unterschiedliche Variablen, von denen die eine nur im kleineren Geltungsbereich sichtbar ist und die andere im gesamten größeren Geltungsbereich, abzüglich des kleineren. Es besteht aber die Möglichkeit, von der Prozedurebene aus gleichnamige Variablen anzusprechen, die der Programmebene angehören, indem man den Bezeichner mit dem Modulnamen qualifiziert:
Funktionen und Prozeduren ProzedurBez [ParamListe] Call ProzedurBez [(WerteListe)] [Let] Var = FunktionsBez[(WerteListe)] := (Operator für benannte Parameter) Man kann sagen, was mal will, einem Basic-Programmierer der sechziger Jahre würde ein heutiges Visual-Basic-Programm nicht nur ausgesprochen »spanisch« vorkommen, er würde es wahrscheinlich gar nicht als solches erkennen. In der Tat hat die Einführung von Funktionen und Prozeduren den Charakter der Sprache von Grund auf und nachhaltig verändert – SpagettiCode ade, es lebe die strukturierte Programmierung. Das mit Visual Basic vorliegende Funktions- und Prozedurkonzept ist inzwischen soweit mit dem der Sprache C/C++ kompatibel, dass Visual Basic vollen Zugriff auf Bibliotheken bietet, die dem Standard für DLLs genügen. Dazu zählen natürlich in erster Linie die Systembibliotheken von Windows (Windows-APIs), aber auch die gesamte Palette an DLLs, die zur Unterstützung der einen oder anderen Anwendung geschrieben wurden. Ein eingefleischter C/C++-Programmierer wird aber immer noch das Konzept des Funktionszeigers vermissen, das Visual Basic wohl deshalb nicht explizit unterstützt, weil noch nicht einmal das Konzept des Zeigers an sich seinen Weg in die Sprache gefunden hat. Erfreulicherweise kann Visual Basic aber dennoch Systemdienste nutzen, für deren Aufruf die Angabe einer Rückruffunktion erforderlich ist – es gibt ein Hintertürchen, wenn auch nur ein recht schmales. Beschreibung
................................................... Bes c hreibung
Funktionen/Prozeduren stellen ein eigenständiges Stück Code dar, das eine definierte Schnittstelle zum restlichen Teil des Programms hat. Auf diese Weise erreichen Funktionen und Prozeduren eine weitgehende semantische Geschlossenheit, die für die strukturierte Programmierung eine wichtige Voraussetzung ist. Die Definition der Schnittstelle findet sich im so genannten Funktionskopf bzw. Prozedurkopf. Ein solcher Kopf enthält einen Bezeichner mit optionalem Spezifizierer für den Geltungsbereich, eine formale Auflistung mit Deklaration aller Argumentvariablen, in der für jede Variable festgelegt wird, ob der entsprechende Parameter als Wert oder als Verweis übergeben wird, sowie – im Falle einer Funktion – den Typ des Rückgabewerts. Die Definition dessen, was eine Prozedur/Funktion macht (ihr Code), findet sich schließlich als Anweisungsfolge im Prozedurkörper bzw. Funktionskörper. Das dem Bezeichnerwesen von Visual Basic zugrunde liegende Qualifizierungsmodell ordnet eine Funktion/Prozedur immer dem Modul als privates oder öffentliches Element zu, das seinen Körper enthält. Im Zusammenhang mit Objekten und Klassen spricht man statt von Funktionen und Prozeduren von Methoden. Um auf eine Funktion/Prozedur von DLLs zugreifen zu können, die nicht standardmäßig von Visual Basic unterstützt werden, sind in dem jeweiligen Modul explizite Importdeklarationen nötig (vgl. »Routinen aus DLLs und der Windows-API einsetzen«, S. 185) Anwendung
................................................... Anwendung
In Visual Basic ist die Unterscheidung zwischen Prozeduren und Funktionen sehr streng. Eine Prozedur verkörpert eine Anweisung und wird wie eine solche notiert. Eine Funktion ist dagegen eine Operation, die einen Wert mit einem zugrunde liegenden Datentyp verkörpert. Mithin lässt sich eine Funktion also überall da notieren, wo ein Wert erwartet wird: als Rechtswert bei Zuweisungen und in Ausdrücken. Rein formal gesehen besteht der Unterschied zwischen Prozeduren und Funktionen somit darin, dass Prozeduren keinen Wert zurückgeben, während Funk-
1 75
Geltungsbereiche von Variablen
tionen einen Funktionswert liefern. In allen anderen Aspekten sind sich die beiden mehr ähnlich als dass sie sich unterscheiden. So lässt sich eine Anweisung ohne Schwierigkeiten als Funktion formulieren und eine Funktion ebenso einfach als Prozedur – die Wertübergabe lässt sich ja über Parameter lösen.
Geltungsbereiche von Variablen
Aufruf Der Aufruf einer Funktion kann überall dort erfolgen, wo ein Wert mit dem Ergebnistyp der Funktion stehen kann. Man notiert dazu einfach den Funktionsbezeichner gefolgt von einer geklammerten Werteliste mit Komma als Trennzeichen, welche der Reihenfolge nach die einzelnen Parameter mit Werten versorgt. sDateiname = Left(sDateiname,10)
Für den Aufruf von Prozeduren kennt Visual Basic dagegen zwei unterschiedliche Notationen: das Anweisungsformat oder das Call-Format. Das Anweisungsformat sieht die Nennung des Prozedurbezeichners mit nachfolgender nicht geklammerter Werteliste als eigenständige Anweisung vor. Rnd 1.1234
Das Call-Format überlässt der Anweisung Call den Aufruf der Prozedur, wobei diese im Anschluss an das Schlüsselwort Call wie eine Funktion – also mit geklammerter Werteliste – notiert wird. Call Rnd (1.1234)
Die Werteliste kann auch fehlen, wenn die Funktions-/Prozedurdefinition dies zulässt. Ein leeres Klammerpaar ist dann nicht zu notieren: datZeit = Now Rnd
' Now ist parameterlose Funktion (Eigenschaft) ' Prozedur ist für parameterlosen Aufruf definiert
Benannte Argumente Seit noch nicht langer Zeit unterstützt Visual Basic auch das Konzept der benannten Argumente für Funktionen und Prozeduren (genauer: Visual Basic 6.0 (SP3) unterstützt das Konzept in zunehmendem Maße, da die Objektbibliothek VB dem Konzept bisher noch nicht angepasst wurde). Es sieht vor, dass für den Aufruf einer Funktion/Prozedur anstelle einer Werteliste auch eine Wertzuordnungsliste übergeben werden kann, deren Einträge eine explizite Wertzuordnung zwischen dem Bezeichner eines Parameters und seinem Wert vorschreiben. Das hat den Vorteil, dass die Reihenfolge der Elemente in der Liste nicht mehr an die Vereinbarungsreihenfolge angepasst sein muss, erspart aber nicht die Versorgung obligatorischer Parameter mit Werten. Während in einfachen Wertelisten weggelassene optionale Parameter zumindest durch ein Komma zu notieren sind, es sei denn, sie stehen am Schluss der Liste, müssen in Wertzuordnungslisten tatsächlich nur so viele Einträge enthalten sein, wie es obligatorische Parameter gibt. Die ganze Sache sieht dann so aus: Sub MeineProzedur(a, Optional b = 0, Optional c = 0, Optional d = 2) ... End Sub Sub Demo() MeineProzedur 2, , , 1 ' Aufruf mit Werteliste MeineProzedur d:= 1, a:= 2 ' Aufruf mit Wertzuordnungsliste End Sub
1 76
Geltungsbereiche von Variablen
Gegenseitiger und rekursiver Aufruf Funktionen und Prozeduren können jederzeit andere Funktionen und Prozeduren aufrufen, deren Bezeichner im jeweiligen Geltungsbereich bekannt sind. Erlaubt ist auch der Selbstaufruf – man spricht dann von einer rekursiven Funktion oder einer rekursiven Prozedur. Bei rekursivem Aufruf ist allerdings auf einen sicheren Abbruch der Rekursion zu achten, damit kein Laufzeitfehler wegen Überlaufs des Stapelspeichers auftritt. Die Festlegung des Funktionswerts einer Funktion erfolgt durch Zuweisung eines Werts an den Funktionsbezeichner innerhalb des Funktionskörpers. Als Linkswert verkörpert der Funktionsbezeichner nichts weiter als eine Variable mit dem Rückgabetyp der Funktion – als Rechtswert dagegen einen rekursiven Aufruf!
In allen Fällen ist anstelle der rekursiven aber auch eine iterative Formulierung möglich, die zwar weniger elegant aussieht, dafür aber sicherer und meist auch schneller ist: Function Fakultät(zahl) Dim Erg Erg = 1 while zahl > 1 Erg = Erg * zahl zahl = zahl -1 Wend Fakultät = Erg End Function Tipp
................................................... Tipp
Es lohnt sich, beim Programmentwurf auf eine gute Strukturierung durch Funktionen und Prozeduren zu achten. Wer zu viel in eine Funktion/Prozedur packt, verschenkt Universalität. Fassen Sie Ihren Code daher am besten in viele kleine möglichst allgemein und übersichtlich gehaltene Funktionen/Prozeduren und dokumentieren Sie die Aufrufschnittstellen gut in Form von Kommentaren. Warnungen
................................................... Wa rnungen Da in Visual Basic sowohl Sprungmarken als auch mehrere Befehle in einer Zeile durch einen Doppelpunkt notiert werden, ist folgender Aufruf zweideutig: Save: Print " Me"
Der Compiler betrachtet Save hier als Sprungmarke, wie folgendes Programm zeigt: Private Sub Form_Load() Save: Print " Me" Call Save: Print "Me", End Sub
' Ausgabe: Me ' Ausgabe: Save Me
Sub Save()
1 77
Geltungsbereiche von Variablen
Function Fakultät(a) If a < 2 Then Fakultät = 1 Else Fakultät = a * Fakultät(a-1) End If End Function
Parameterübergabe an Funktionen und Prozeduren
Parameterübergabe an Funktionen und Prozeduren
Print "Save "; End Sub
Ein kleiner Tipp: Der Editor der Entwicklungsumgebung zieht Sprungmarken automatisch an den Zeilenanfang. Daran müssten Sie bereits merken, dass etwas nicht stimmt. Am besten aber, Sie gewöhnen sich an, keine Anweisungen hinter Sprungmarken zu setzen, das erhöht auch die Lesbarkeit des Programms. Der Compiler von Visual Basic kann arithmetische Ausdrücke aus Optimierungsgründen intern umstellen. Vermeiden Sie daher Function-Aufrufe innerhalb eines arithmetischen Ausdrucks, wenn die Funktion als Seiteneffekt den Wert von Variablen ändert, die in diesem Ausdruck auftreten. Verwandte Themen
................................................... Verwa ndte Them en
Methoden (S. 199); Eigenschaften (S. 201); Ereignisroutinen (S. 204)
Parameterübergabe an Funktionen und Prozeduren [Geltungsbereich] [Static] Function FuncName ([ParamListe]) [As Typ] ... End Function [Geltungsbereich] [Static] Sub ProcName ([ParamListe]) ... End Sub Function IsMissing(ArgumentName) As Boolean Funktionen/Prozeduren lassen sich als parametergesteuerte Unterprogramme auffassen, die aus den Werten ihrer Parameter weitere Werte generieren und zudem gewisse Seiteneffekte haben. Die Sichtbarkeit des Bezeichners FuncName bzw. ProcName beschränkt sich auf den vereinbarten Geltungsbereich Geltungsbereich. Geltungsbereich = Public | Private | Friend Fehlt die Angabe eines Geltungsbereichs oder lautet der Spezifizierer Public, ist der Bezeichner auf Programmebene bekannt. Lautet der Spezifizierer dagegen Private, ist der Bezeichner nur auf Modulebene bekannt. In Klassenmodulen ist weiterhin die Angabe des Spezifizierers Friend möglich, der die Sichtbarkeit der Methode auf das aktuelle Projekt beschränkt und einen expliziten Aufruf durch Besitzer von Objekten dieser Klasse vereitelt. Die zusätzliche Angabe des Spezifizierers Static bewirkt, dass alle innerhalb der Funktion/Prozedur implizit oder explizit deklarierten Variablen generell als statische Variablen vereinbart werden, so dass diese von einem Aufruf zum nächsten ihren Wert behalten und nur beim ersten Aufruf automatisch initialisiert werden. Jeder Funktion/Prozedur ist eine Parameterliste ParamListe zugeordnet, die bis zu 59 Parametervereinbarungen umfassen, aber auch leer sein kann. ParamListe = [Param[, Param ...]] Die Vereinbarung eines einzelnen Parameters Param hat die Gestalt Param = [Optional][ByVal | ByRef][ParamArray] Var[()] As Typ [= Vorgabe] Ein Parameter kann als Platzhalter für einen Eingabewert, einen Ausgabewert oder einen Ein-/ Ausgabewert fungieren, der innerhalb der Funktion/Prozedur über die Argumentvariable Var verfügbar wird. Die Deklaration von Argumentvariablen für reine Eingabeparameter erfordert
1 78
Parameterübergabe an Funktionen und Prozeduren
Sub TestProc(Optional OptParam) If IsMissing(OptParam) Then ... End Sub
Für den letzten Parameter in einer Parameterliste ist darüber hinaus der Spezifizierer ParamArray erlaubt – unter der Voraussetzung jedoch, dass die Argumentvariable als dynamisches Array des Typs Variant ohne weitere Spezifizierer vereinbart wird. Eine Funktion/Prozedur, für die ein ParamArray-Parameter vereinbart ist, kann beliebig lange Parameterlisten verarbeiten (vgl. Print). Anwendung
................................................... Anwendung
Für die Reihenfolge der Parameter gibt es keine Vorschriften. Es ist aber üblich, Eingabeparameter an den Beginn der Parameterliste zu setzen, Ein-/Ausgabeparameter in der Mitte und die Ausgabeparameter an den Schluss. Allerdings hat die exakt umgekehrte Reihenfolge den Vorteil, dass sich optionale Parameter an den Schluss setzen lassen, damit sie nicht notiert werden müssen. Wenn Sie jedoch die Aufrufsyntax der »benannten Argumente« benutzen, spielt die Reihenfolge ohnehin keine Rolle. Der Unterschied zwischen reinen Eingabeparametern und Parametern mit Ein- und Ausgabefunktion bzw. reiner Ausgabefunktion ist konzeptueller Natur und erfordert aufseiten des Programmierers eine gewisse Disziplin. Da ByVal-Variablen beim Aufruf Kopien der übergebenen Werte erhalten, kann die Funktion/Prozedur damit anstellen, was sie will: Eventuelle Wertänderungen verbleiben auf der Prozedurebene und sind für den Aufrufer generell unsichtbar. Anders verhält es sich, wenn die Deklaration einer Argumentvariablen mit dem standardmäßigen Spezifizierer ByRef erfolgt. In diesem Fall wird aus der Argumentvariablen eine Zeigervariable, deren Wert die Adresse des in dem entsprechenden Parameter übergebenen Werts ist – ein Konzept, das als solches in Visual Basic nirgendwo sonst so offen zu Tage tritt. Am Gebrauch der Argumentvariablen ändert sich äußerlich dadurch nichts, außer dass sie als Platzhalter für einen Ausgabewert bzw. Ein-/Ausgabewert fungieren kann. Nach außen hin wirksame Wertänderungen sind sinnvollerweise nur möglich, wenn als Parameter eine Variable (also ein Linkswert) übergeben wurde, da diese das indirekte Ziel jeglicher Wertänderungen seitens der Argumentvariablen ist. Wird einem ByRef-Parameter ein literaler Wert, eine Konstante, ein Funktionswert oder der Wert eines berechneten Ausdrucks übergeben, steht dieser nur als Eingabewert zur Verfügung; der Versuch einer Änderung führt zwar zu keinem Laufzeitfehler, bleibt aber wirkungslos.
1 79
Parameterübergabe an Funktionen und Prozeduren
den Spezifizierer ByVal, die von Argumentvariablen für Ausgabe- bzw. Ein-/Ausgabeparameter den Spezifizierer ByRef. Letzterer ist optional, da Visual Basic Argumentvariablen auch implizit mit dem Zusatz ByRef vereinbart. Arrays und Objekte lassen sich ausschließlich als ByRef-Parameter übergeben. Parameter sind im Allgemeinen obligatorisch, es sei denn, die zugehörige Argumentvariable wird mit dem Zusatz Optional vereinbart. Ein obligatorischer Parameter muss beim Aufruf der Funktion/Prozedur mit einem Wert versorgt werden, ein optionaler kann auch weggelassen werden. Als Vorgabewert für optionale Parameter nimmt Visual Basic den standardmäßigen Initialisierungswert des Datentyps Typ, sofern keine explizite Zuweisung eines Vorgabewerts Vorgabe deklariert ist. Um innerhalb der Funktion/Prozedur festzustellen, ob für einen optionalen Variant-Parameter beim Aufruf ein Wert spezifiziert wurde, lässt sich die Funktion IsMissing einsetzen. Sie ist vom Typ Boolean und liefert den Wert True, wenn der im Argument genannte optionale Parameter beim Aufruf weggelassen wurde.
Parameterübergabe an Funktionen und Prozeduren
Warnung
................................................... Wa rnung
Nachdem Visual Basic alle Parameter, die nicht explizit mit ByVal spezifiziert werden, als ByRefParameter vereinbart, sind bei sorglosem Umgang mit Argumentvariablen für Eingabewerte unerwünschte Rückwirkungen auf die Ebene des Aufrufers möglich – ein Eingabewert kann so unbemerkt zum Ein-/Ausgabewert mutieren. Fehler dieser Art sind meist schwer zu finden. Um sie auszuschließen, besteht auch die Möglichkeit, Variablen, die nur Eingabewerte bereitstellen, in der Werteliste zu klammern. Visual Basic sieht einen geklammerten Wert als Ausdruck an und verhindert so Rückwirkungen auf die Variable.
Parameterübergabe an Funktionen und Prozeduren
Beispiele
................................................... Beis piele
Die Funktion Standardabweichung berechnet die Standardabweichung einer Messreihe mit der Menge der Messwerte als Grundgesamtheit. Die Anzahl der Parameter für den Aufruf der Funktion ist nicht festgelegt, wie die Aufrufe zeigen. ... Print Standardabweichung(15.2, 11.1, 13.4,12.2, 18.3) ' 2,517... Print Standardabweichung(15.2, 11.1, 13.4,12.2, 18.3, 12.1) ' 2,417... ... Function Standardabweichung(ParamArray MessWerte()) Dim iAnz As Integer iAnz = UBound(MessWerte) + 1 For Each i In MessWerte Sum = Sum + i Qsum = Qsum + i * i Next i Standardabweichung = Sqr((iAnz * Qsum – Sum * Sum) / (iAnz * iAnz)) End Function
Die folgende Prozedur demonstriert den Unterschied zwischen einem ByRef- und einem ByValParameter sowie die Wirkung eines Ausdrucks auf einen ByRef-Parameter: ... Dim iWert1, iWert2 As Integer iWert1 = 10 iWert2 = 10 ByValByRef iWert1, iWert2 Print iWert1, iWert2 iWert2 = 10 ByValByRef iWert1, (iWert2) Print iWert1, iWert2 ... Sub ByValByRef(ByVal a As Integer, b a = a * a b = b * b End Sub Verwandte Themen
................................................... Verwandte Them en
Ereignisroutinen (S. 204)
1 80
' Ausgabe: 10
100
' (iWert2) ist Ausdruck! ' Ausgabe: 10 10 As Integer)
Funktionen selbst definieren
Funktionen selbst definieren [Public| Private | Friend][Static] Function Name [(ParamListe)][ As Typ] [Anweisungsfolge] [Name = Ausdruck] [Exit Function] [Anweisungsfolge] [Name = Ausdruck] End Function Beschreibung
Die Definition einer eigenen Funktion (Methode) gliedert sich in drei Schritte: 1. Deklaration der prozeduralen Schnittstelle 2. Deklaration eines Rückgabetyps 3. Definition des Funktionskörpers mit Zuweisung des Funktionswerts Die prozedurale Schnittstelle einer Funktion umfasst die Spezifikation des Funktionsbezeichners sowie die Deklaration der Parameterliste. Dieser Schritt ist im Abschnitt »Parameterübergabe an Funktionen und Prozeduren« (S. 178) ausführlich beschrieben. Da eine Funktion im Gegensatz zu einer Prozedur einen Wert verkörpert, den sie als Funktionswert zurückliefert, definiert der Rückgabetyp Typ den Datentyp des Werts, den die Funktion zurückgibt. Fehlt die Angabe eines Rückgabetyps, lautet die Voreinstellung Variant. Zu den möglichen Rückgabetypen zählen die elementaren Datentypen Boolean, Byte, Integer, Long, Currency, Single, Double, Date, String (Decimal wird derzeit nur als Untertyp von Variant unterstützt), benutzerdefinierte Datentypen, Variant sowie Objektverweise des Typs Object. Darüber hinaus kann eine Funktion auch ein dynamisches Array mit einem der genannten Datentypen als Elementtyp zurückgeben. Der Funktionskörper kann eine beliebige Anweisungsfolge enthalten, die für die Berechnung des Funktionswerts sowie der gegebenenfalls über Argumentvariablen zurückzugebenden Ausgabewerte erforderlich ist. Der Funktionswert Ausdruck wird dem Funktionsbezeichner Name zugewiesen und die anderen Ausgabewerte den entsprechenden Argumentvariablen. Die an beliebiger Stelle erlaubte Anweisung Exit Function gibt die Kontrolle unmittelbar an den Aufrufer zurück. Falls dem Funktionsbezeichner bis dahin noch kein Rückgabewert zugewiesen wurde, liefert die Funktion den standardmäßigen Initialisierungswert des Rückgabetyps. Anwendung
................................................... Anwendung
Der Unterschied zwischen einem Ausdruck und einer Funktion ist gar nicht so groß. Beide liefern einen Wert, den sie auf Basis anderer Werte berechnen. Im Gegensatz zu einem Ausdruck legt eine Funktion im Allgemeinen aber ihre Schnittstelle mit der Außenwelt en bloc in Form der prozeduralen Schnittstelle offen – so zumindest der hehre Anspruch. In der Praxis sieht es oft anders aus: Um Aufrufparameter zu sparen, wird viel mit globalen Variablen hantiert, was zwar das Laufzeitverhalten der Funktion verbessern kann, jedoch gegen die goldenen Regeln für die strukturierte Programmierung verstößt und nicht selten zu schwer auffindbaren Bugs im Code führt. Gewöhnen Sie sich an, nach Möglichkeit alle Werte, die eine Funktion vom Aufrufer benötigt, über die prozedurale Schnittstelle zugänglich zu machen und gegebenenfalls als optionalen Parameter mit sinnvollem Vorgabewert zu deklarieren. Der Gebrauch von globalen Variablen sollte weitgehend auf das Wesentliche beschränkt bleiben. ByVal-Parameter schützen zwar vor ungewollten Seiteneffekten, kosten aber aufgrund der zu erstellenden Kopien bei Werten mit umfangreichen Repräsentationen – etwa bei Zeichenfolgen oder benutzerdefinierten Datentypen – wertvolle Laufzeit. ByRef-Parameter sind dann oft die bessere Wahl.
1 81
Funktionen selbst definieren
................................................... Bes c hreibung
Funktionen selbst definieren
Funktionen selbst definieren
Die größte Kunst bei der Programmierung besteht darin, es einer potenziellen Anweisungsfolge anzusehen, dass sie eine gute Funktion abgibt, und dann die Schnittstelle dieser Funktion geeignet festzulegen. Das Motto dafür lautet, wie schon einst bei Cäsar: Teile und herrsche. Je allgemeiner und je kürzer eine Funktion, desto besser. Das erleichtert die Fehlersuche ebenso wie die spätere Codepflege. Zu guter Letzt noch ein Wort zum Gebrauch der Anweisung Exit Function. Eine weitere goldene Regel der strukturierten Programmierung besagt, dass Routinen möglichst nur einen Ausgang haben sollten. Gegen den überlegten Gebrauch von Exit Function ist natürlich nichts einzuwenden. Je komplizierter die Logik jedoch wird, desto unübersichtlicher und schwerer lesbar wird eine Funktion, wenn sie zu viele Ausgänge hat. Am besten, Sie spalten den Code dann in mehrere kleine Funktionen auf. Tipp
................................................... Tipp
Bei Problemstellungen, in denen die Laufzeit eine Rolle spielt, können Funktionsaufrufe zum Hemmschuh werden, insbesondere wenn noch ByVal-Parameter im Spiel sind. In einigen Fällen verbessert sich das Laufzeitverhalten, wenn man zu Inline-Formulierungen übergeht, also anstelle eines Funktionsaufrufs den eigentlichen Code der Funktion setzt. Allerdings ist auch der Visual-Basic-Compiler in der Lage, von sich aus Funktionen in Inline-Code zu verwandeln, sofern der Compilerschalter CODE-AUSFÜHRUNGSGESCHWINDIGKEIT OPTIMIEREN gesetzt ist, so dass sich Vergleichsmessungen lohnen. Beispiel
................................................... Beis piel
Die rekursive Funktion NextPrim ermittelt die nächste Primzahl, die kleiner oder gleich dem Eingabeparameter lZahl ist. Für negative Werte und 0 liefert die Funktion den Wert 0. Function NextPrim(ByVal lZahl As Long) Dim i As Long If lZahl 0 And Shift = vbShiftMask Then Effect = vbDropEffectMove End If End Sub Verwandte Ereignisse
................................................... Verwandte Ereignis s e OLECompleteDrag, OLEDragDrop, OLEGiveFeedback, OLESetData, OLEStartDrag
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
OLEGiveFeedback- Ereignis Private Sub Objekt_OLEGiveFeedback(Effect As Long, _ DefaultCursors As Boolean) Betroffene Objekte
................................................... Betro ffene Objekte Animation, CoolBar, DataList, DateTimePicker, DBCombo, DBList, DirListBox, FileListBox, FlatScrollBar, Grid, Image, ImageCombo, ListBox, ListView, MaskEdBox, MSChart, MSFlexGrid, MSHFlexGrid, OLE, PictureBox, PropertyPage, RichTextBox, SSTab, TabStrip, TextBox, TreeView, ToolBar, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Das OLEGiveFeedback-Ereignis tritt nach jedem OLEDragOver-Ereignis aufseiten der Quellkomponente auf, wenn diese im manuellen Modus (OLEDragMode = vbDragManual) betrieben wird. Der Parameter Effect ist ein von der Zielkomponente nach Auswertung des Maus- und Funktionstastenstatus sowie gegebenenfalls des Inhaltsformats gesetzter Bitvektor, der die anvisierte Operation ausdrückt. Der Aufzählungstyp OLEDropEffectConstants definiert eine Reihe von Konstanten für die einzelnen Operationen: vbDropEffectNone (0) steht für »keine Operation«, vbDropEffectCopy (1) für »Kopieroperation« und vbDropEffectMove (2) für »Verschiebeoperation«. DefaultCursors ist ein Ausgabeparameter, den die Quellkomponente auf True setzen kann, um die über die Eigenschaften MouseIcon und MousePointer des Screen-Objekts spezifizierte Mauszeigerform einzustellen. Anwendung
................................................... Anwendung
Mit diesem Ereignis erhält die Quellkomponente Gelegenheit, dem Benutzer eine geeignete Rückmeldung für die von ihm anvisierte Operation zukommen zu lassen. Da Komponenten mit OLE-Unterstützung standardmäßig für jede der möglichen Operationen eine andere, vom System her bereitgestellte Mauszeigerform anzeigen, lohnt sich der Austausch der Mauszeigerform meist nur in speziellen Fällen. Eine Behandlung des Ereignisses kann aber auch die Ausgabe einer kurzen Befehlsbeschreibung in der Statusleiste zum Ziel haben oder gar, bei Verwendung einer One-Shot-Logik, eine akustische Rückmeldung. Wenn Sie mit eigenen Mauszeigerformen arbeiten, sollten Sie die alte Mauszeigerform auf jeden Fall speichern und im Zuge der Behandlung von OLEDragComplete wieder herstellen.
247
Standardereignisse
Verwandte Themen
Standardereignisse
Beispiel
................................................... Beis piel
Standardereignisse
Der folgende Code zeigt, wie man für die unterschiedlichen Operationen eigene Cursorformen zur Anzeige bringt. Er geht davon aus, dass die Formen in den EffectOperationIcon-Variablen bereitstehen. Private Sub File1_OLEGiveFeedback(Effect As Long, _ DefaultCursors As Boolean) Select Case Effect Case vbDropEffectCopy ' Kopieren Set Screen.MouseIcon = EffectCopyIcon ' Eigene Form setzen Case vbDropEffectMove ' Verschieben Set Screen.MouseIcon = EffectMoveIcon ' Eigene Form setzen Case vbDropEffectNone ' Operation nicht möglich Set Screen.MouseIcon = EffectNoneIcon ' Eigene Form setzen Case Else DefaultCursors = True End Select DefaultCursors = False ' Eigene Form verwenden End Sub Verwandte Ereignisse
................................................... Verwandte Ereignis s e OLECompleteDrag, OLEDragDrop, OLEDragOver, OLESetData, OLEStartDrag Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
OLESetData- Ereignis Private Sub Objekt_OLESetData(Data As DataObject, DataFormat As Integer) Betroffene Objekte
................................................... Betro ffene Objekte Animation, CoolBar, DataList, DateTimePicker, DBCombo, DBList, DirListBox, FileListBox, FlatScrollBar, Grid, Image, ImageCombo, ListBox, ListView, MaskEdBox, MSChart, MSFlexGrid, MSHFlexGrid, OLE, PictureBox, PropertyPage, RichTextBox, SSTab, TabStrip, TextBox, TreeView, ToolBar, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Das OLESetData-Ereignis fordert die Quellkomponente einer OLE-Drag&Drop-Operation auf, den Inhalt in dem Format DataFormat bereitzustellen. Voraussetzung für das Auftreten des Ereignisses ist allerdings, dass die Quellkomponente das Format zuvor durch einen SetDataAufruf ohne Angabe eines Inhalts (Value) gesetzt hat. Anwendung
................................................... Anwendung
Vater dieses Ereignisses ist die Strategie der »späten Bereitstellung« von OLE-Inhalten. Diese Strategie verfolgt das Ziel, den Ressourcenbedarf für eine OLE-Operation so gering wie möglich zu halten. Würde man umfangreiche Inhalte sozusagen »in vorauseilendem Gehorsam« bereits zu Beginn einer OLE-Drag&Drop-Operation, also auf das OLEDragStart-Ereignis hin, in allen unterstützten Formaten bereitstellen, wäre das mitunter mit einem erheblichen Speicherbedarf verbunden. Da ist es natürlich weitaus sinnvoller, den Inhalt erst dann in einem spezifischen Format bereitzustellen, wenn er in diesem Format tatsächlich benötigt wird.
248
OLESetData- Ereignis
Eine Aufstellung der von Visual Basic für die verschiedenen ActiveX-Steuerelemente direkt unterstützten Standardformate finden Sie im Abschnitt »OLEDragDrop-Ereignis«. Sie haben aber auch die Möglichkeit, eigene Formate in OLE-Operationen zu verwenden. Einzelheiten zur Vorgehensweise entnehmen Sie dem Abschnitt »OLE-Drag&Drop«, S. 501, des Praxisteils. Warnung
................................................... Wa rnung
Ein GetData-Aufruf löst bei der Zielkomponente regulär den Laufzeitfehler 461 aus, wenn die Quellkomponente das spezifizierte Format zwar angeblich unterstützt, aber letztlich keinen Inhalt dafür bereitstellt.
................................................... Beis piel
Das folgende kleine Programm demonstriert die »späte Bereitstellung« sowie die Abfolge der Ereignisse. Das verwendete Formular enthält ein Textfeld, dessen Inhalt sich in das Formular ziehen lässt, dort jedoch in umgekehrter Zeichenfolge ankommt.
Das Textfeld arbeitet mit später Bereitstellung und dreht die Zeichenfolge um Private Sub Form_Load() Text1.OLEDragMode = vbOLEDragAutomatic OLEDropMode = vbOLEDropManual AutoRedraw = True End Sub Private Sub Form_OLEDragDrop(Data As DataObject, Effect As Long, _ Button As Integer, Shift As Integer, X As Single, Y As Single) Print "Form_OLEDragDrop" Print Data.GetData(vbCFText) End Sub Private Sub Text1_OLESetData(Data As DataObject, DataFormat As Integer) Print "Text1_OLESetData" Data.SetData StrReverse(Text1), vbCFText End Sub Private Sub Text1_OLEStartDrag(Data As DataObject, _ AllowedEffects As Long) Print "Text1_OLEStartDrag" Data.SetData , vbCFText ' Inhalt wird später bereitgestellt End Sub
249
Standardereignisse
Beispiel
Standardereignisse
Verwandte Ereignisse
................................................... Verwandte Ereignis s e OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLEStartDrag Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
OLEStartDrag- Ereignis
Standardereignisse
Sub Objekt_OLEStartDrag(Data As DataObject, AllowedEffects As Long) Betroffene Objekte
................................................... Betro ffene Objekte Animation, CoolBar, DataList, DateTimePicker, DBCombo, DBList, DirListBox, FileListBox, FlatScrollBar, Grid, Image, ImageCombo, ListBox, ListView, MaskEdBox, MSChart, MSFlexGrid, MSHFlexGrid, OLE, PictureBox, PropertyPage, RichTextBox, SSTab, TabStrip, TextBox, TreeView, ToolBar, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Das OLEStartDrag-Ereignis tritt als erstes Ereignis gleich zu Anfang einer OLE-Drag&DropOperation auf. Es informiert die Quellkomponente über den Beginn der Operation und gibt ihr Gelegenheit, die unterstützten Operationen sowie Inhalte und Formate zu setzen. Der Parameter Data verweist auf ein Objekt vom Typ DataObject, das als Container für die zu übermittelnden Inhalte und die dazugehörigen Formatinformationen fungiert. Der Ausgabeparameter AllowedEffects kommt bei der Zielkomponente als Effect-Parameter an und wird dort als Bitvektor interpretiert, dessen gesetzte Bits die möglichen Operationen anzeigen. Der Aufzählungstyp OLEDropEffectConstants definiert eine Reihe von Konstanten dafür: vbDropEffectNone (0) steht für »keine Operation«, vbDropEffectCopy (1) für »Kopieroperation« und vbDropEffectMove (2) für »Verschiebeoperation«. Anwendung
................................................... Anwendung
Die auf OLE basierende Drag&Drop-Operation ermöglicht den dokumentenorientierten Austausch von Daten zwischen einer Quellkomponente und einer Zielkomponente. Medium des Austauschs ist aus der Sicht von Visual Basic das DataObject-Objekt, ein im System verankertes Containerobjekt, dessen Dienste allen OLE-tauglichen Anwendungen für den anwendungsübergreifenden, aber auch -internen Transport von Daten zur Verfügung stehen. Grundlegender Gedanke bei dieser Art von Kommunikation ist, dass die Daten in einem anwendungsunabhängigen Format gehalten sind. Damit kann eine Komponente jederzeit Inhalte von einer anderen Komponente entgegennehmen, sofern sich beide auf ein gemeinsames Format »einigen« können. Für die wichtigsten Standardformate definiert der Aufzählungstyp ClipBoardConstants Formatkonstanten: Formatkonstante
Beschreibung des Formats
vbCFText (1)
Data enthält Zeichenfolge im Format TXT
vbCFBitmap (2)
Data enthält Bitmap im Format BMP
vbCFMetafile (3)
Data enthält Grafik im Zwischendateiformat WMF
vbCFEMetafile (14)
Data enthält Grafik im erweiterten Zwischendateiformat EMF
Standardmäßige Datenformate eines DataObject-Objekts
250
OLEStartDrag- Ereignis
Formatkonstante
Beschreibung des Formats
vbCFDIB (8)
Data enthält geräteunabhängige Bitmap im DIB-Format
vbCFPalette (9)
Data enthält Palette im Format PAL
vbCFFiles (15)
Data enthält Files-Auflistung
vbCFRTF (-16639)
Data enthält Zeichenfolge im RTF-Format
Standardmäßige Datenformate eines DataObject-Objekts
Data.SetData , vbCFBitmap
Im automatischen Modus (OLEDragMode = vbOLEDragAutomatic) überträgt eine Steuerelementkomponente ihren Standardwert noch vor dem OLEStartDrag-Ereignis in das Containerobjekt – im manuellen Modus passiert das nicht, und das ist oft auch erwünscht. Um ein DataObjectObjekt in einen definierten Zustand zu versetzen, rufen Sie die Clear-Methode auf. Sie löscht alle Formatinformationen und Inhalte. Unterbleibt der SetData-Aufruf, kann Visual Basic von sich aus zwischen den Formaten BMP, WMF, EMF und TXT unterscheiden, mehr jedoch nicht. Alle anderen Formate müssen explizit gesetzt werden, damit kein Laufzeitfehler aufseiten der Zielkomponente auftritt. Bei Verwendung eines Formats, das nicht zu den von Visual Basic anerkannten Standardformaten zählt, müssen Sie Inhalte in Form von Byte-Arrays bereitstellen. Außerdem sollte jedes Array Längeninformationen beinhalten, da der OLE-Mechanismus die Daten ohne Längenangabe in einem »hinreichend großen« Puffer übermittelt, der auch größer sein kann als das Array – und es in der Regel auch ist. Beispiel
................................................... Beis piel
Das folgende Beispielprojekt OLEDragStart ist eine etwas kompliziertere Version des Beispiels zu OLESetData, wenngleich das Szenario (ohne dass dies eine Rolle spielt) recht einfach gewählt ist: Der Benutzer kann den Inhalt eines Textfelds mittels OLE-Drag&Drop auf das Formular verschieben. Quell- und Zielkomponente arbeiten jedoch mit zwei unterschiedlichen Formaten: zum einen mit dem standardmäßigen Format vbCFText, zum anderen mit dem eigenen Format »Mein Textformat«.
251
Standardereignisse
Das Containerobjekt ist speziell darauf eingerichtet, Inhalte in verschiedenen Formaten entgegennehmen zu können. Da die Einhaltung der Formate für die sichere Kommunikation eine wichtige Rolle spielt, sind die Formate mit einer eindeutigen Nummer (Handle) assoziiert und in der Systemregistrierung niedergelegt. Damit ist es einer Anwendung prinzipiell möglich, die Nummer für ein registriertes Format in Erfahrung zu bringen und auch eigene Formate zu registrieren. Allerdings bietet Visual Basic dafür keine Funktionen an, so dass man in diesem Fall die entsprechenden Routinen der Win32-API direkt aufrufen muss (RegisterClipBoardFormat und GetClipFormatName). Vom Prinzip her lassen sich Inhalte auch in nicht registrierten Formaten übermitteln, sofern deren Nummern auf beiden Seiten bekannt sind. Das birgt allerdings gewisse Gefahren, wenn unter einer verwendeten Nummer ein anderes Format registriert ist. Eine Quellkomponente reagiert auf das OLEStartDrag-Ereignis, indem sie den AllowedEffectsParameter mit einem Bitvektor versorgt und für jedes unterstützte Format die SetData-Methode des DataObject-Objekts aufruft. Falls der Speicherbedarf für die zugehörigen Inhalte erträglich ist, spricht nichts dagegen, diese bereits in dieser Phase der SetData-Methode über den ValueParameter mitzugeben. Ab einer bestimmten Datenmenge empfiehlt es sich jedoch, mit der Bekanntgabe des Inhalts auf das OLESetData-Ereignis zu warten und die SetData-Methode vorerst nur mit einer Formatkonstanten zu versorgen (späte Bereitstellung).
Standardereignisse
Standardereignisse
Nachdem das Textfeld als Quellkomponente seinen Wert bereits von sich aus im vbCFText-Format in das Containerobjekt einfügt, kann sich die OLEDragStart-Behandlungsroutine darauf beschränken, das eigene Format zu registrieren und zu setzen. Für die Registrierung ist der Aufruf der Win32-API-Funktion RegisterClipboardFormat notwendig, die das Format mit einer Nummer identifiziert, wie sie der SetData-Aufruf erwartet. Unglücklicherweise besteht SetData auf einen Wert vom Typ Integer, während das Add-In API-Viewer für die Funktion den Rückgabetyp Long deklariert. Die einfachste Lösung besteht darin, den Rückgabetyp manuell auf Integer zu ändern, was keinerlei weitere Probleme aufwerfen sollte, da das System Formatkonstanten als 16-Bit-Werte behandelt. Das war die Sicht der Quellkomponente. Die Zielkomponente muss nun ihrerseits bei der Behandlung von OLEDragDrop die Funktion RegisterClipboardFormat aufrufen (im Allgemeinen werden Quelle und Ziel ja nicht demselben Prozess angehören), um die Nummer des Formats in Erfahrung zu bringen. Der Rest ist zwar nicht elegant, aber doch geradlinig: Da das DataObjectObjekt bei eigenen Formaten auf Byte-Arrays besteht, liefert die Methode GetData auch ein solches, was nicht nur aufseiten der Zielkomponente ein gewisses Geschick bei der Konvertierung erfordert (das Beispiel verzichtet der Einfachheit halber auf die Einarbeitung einer Längeninformation und bedient sich für die Konvertierung einer Variant-Variablen). ' Formularmodul: OLEDragStart-Demo Option Explicit Private Declare Function RegisterClipboardFormat Lib "user32" Alias _ "RegisterClipboardFormatA" (ByVal lpString As String) As Integer Private MeinFormat As Integer Private Sub Form_Load() OLEDropMode = vbOLEDropManual Text1.OLEDropMode = vbOLEDragAutomatic AutoRedraw = True End Sub Private Sub Form_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) ' Zuerst im gewöhnlichen Textformat If Data.GetFormat(vbCFText) Then Print Data.GetData(vbCFText) ' Nun im eigenen Format If Data.GetFormat(RegisterClipboardFormat("Mein Textformat")) Then Print Data.GetData(MeinFormat) End If End Sub Private Sub Text1_OLESetData(Data As DataObject, DataFormat As Integer) Dim Daten As Variant ' Zur einfachen Typ-Konversion Dim ByteArray() As Byte ' Für eigenes Format bei SetData If DataFormat = MeinFormat Then ' MeinFormat? Daten = " " + StrReverse(Text1) ' Daten zuerst in Variant ByteArray = Daten ' Typkonversion Data.SetData ByteArray, MeinFormat ' Byte-Array als Inhalt setzen End If End Sub
252
Paint- Ereignis
Private Sub Text1_OLEStartDrag(Data As DataObject, AllowedEffects _ As Long) AllowedEffects = vbDropEffectMove ' Eigenes Format registrieren und setzen MeinFormat = RegisterClipboardFormat("Mein Textformat") If MeinFormat Then Data.SetData , MeinFormat End Sub Verwandte Ereignisse
................................................... Verwandte Ereignis s e
Standardereignisse
OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
Paint- Ereignis Sub Form_Paint() Sub Objekt_Paint([Index As Integer]) Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, PropertyPage, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Das Paint-Ereignis tritt auf, wenn der Fensterbereich des Objekts teilweise oder vollständig neu gezeichnet werden muss, weil er (teilweise) verdeckt, unsichtbar oder minimiert war respektive vergrößert oder explizit durch einen Aufruf der Refresh-Methode für ungültig erklärt wurde. Voraussetzung für das Ereignis ist aber, dass die AutoRedraw-Eigenschaft den Wert False hat. Durch Behandlung dieses Ereignisses erhält das Objekt Gelegenheit, seinen Fensterbereich aufzufrischen oder – gegebenenfalls mit anderem Inhalt – komplett neu zu zeichnen. Beim Start eines Formulars herrscht die Ereignisreihenfolge: Load, Resize, Paint, GotFocus usw. Anwendung
................................................... Anwendung
Ein Objekt, das auf das Paint-Ereignis reagieren kann, verfügt über die beiden Eigenschaften AutoRedraw und ClipControls. AutoRedraw hat als Voreinstellung den Wert False und ClipControls den Wert True. Wird AutoRedraw auf True gesetzt, speichert Visual Basic den Fensterinhalt des Objekts als Bitmap und restauriert ungültig gewordene Bereiche in eigener Regie, wann immer dies erforderlich ist. Für die meisten Anwendungsfälle dürfte dies die praktischste Einstellung sein, da man sich als Programmierer eigentlich um nichts kümmern muss und an jeder beliebigen Stelle Ausgaben vornehmen kann. Wie alle Automatismen hat er aber auch Nachteile: Er verzehrt Ressourcen, kostet Zeit und lässt einiges an Flexibilität vermissen. Die Eigenschaft ClipControls wirkt sich nur aus, wenn AutoRedraw auf False gesetzt ist. Sie regelt, ob Visual Basic für Steuerelemente Bildausschnitte bei der Restaurierung des Objektbereichs berechnet oder nicht. Ohne diese Berechnung ist die Grafikausgabe schneller, es kann jedoch zu Ungereimtheiten bei der Anzeige sich überlappender Steuerelemente kommen. Visual Basic unterscheidet beim Zeichnen eines Objekts drei Ebenen: 1. Die hintere Ebene – in dieser Ebene landet die Bitmap, die über die Picture-Eigenschaft des Objekts festgelegt ist, über die Print-Methode ausgegebener Text sowie alle Ausgaben der Grafikmethoden Line, Circle und PSet.
253
Standardereignisse
2. Die mittlere Ebene – in dieser Ebene erscheinen fensterlose Steuerelemente, wie das Bezeichnungsfeld (Label), die grafischen Steuerelemente (Shape, Line) sowie alle UserControl-Steuerelemente, deren Windowless-Eigenschaft auf True gesetzt wurde. 3. Die obere Ebene – in dieser Ebene erscheinen alle Steuerelemente, denen ein eigenes Fenster zugeordnet ist. Das sind alle Steuerelemente bis auf die unter 2. genannten.
Standardereignisse
Die folgende Tabelle gibt einen Überblick über die Wirkung der Eigenschaften AutoRedraw und ClipControls, wenn die Grafikausgabe innerhalb oder außerhalb der Paint-Behandlung stattfindet. AutoRedraw
ClipControls
Effekt
True
True
Paint-Ereignis bleibt aus und die Grafikausgabe unterscheidet drei Ebenen.
True
False
Beschleunigte Grafikausgabe in drei Ebenen, da keine Bildausschnitte für Steuerelemente berechnet werden. Platzierte Steuerelemente sollten sich nicht überlappen.
False (Voreinstellung)
True (Voreinstellung)
Grafikausgabe findet in drei Ebenen statt, sofern Grafikmethoden ausschließlich innerhalb der Paint-Routine aufgerufen werden. Beim Aufruf von Grafikmethoden außerhalb von Paint kann das Ergebnis fehlerhaft sein, da die Abfolge beim Zeichnen der mittleren Ebene nicht mehr garantiert ist.
False
False
Die Grafikausgabe findet in drei Ebenen statt. Neu gezeichnet werden nur Rechteckbereiche, die bis zum Auftreten des nächsten Paint-Ereignisses für ungültig erklärt wurden, etwa weil sie verdeckt waren. Beim Aufruf von Grafikmethoden außerhalb von Paint kann das Ergebnis fehlerhaft sein, da die Abfolge der Ebenen nicht mehr garantiert ist.
Warnung
................................................... Wa rnung
Wenn Sie mit einer Paint-Routine arbeiten, sollten alle expliziten Grafikausgaben innerhalb dieser Routine erfolgen. Tipp
................................................... Tipp
Innerhalb einer Ebene legt die Tabulatorordnung fest, in welcher Reihenfolge überlappende Steuerelemente einander verdecken. Um eine eigene Reihenfolge festzulegen, können Sie die ZOrder-Methode der beteiligten Steuerelemente aufrufen, um diese nacheinander an die oberste Position zu bringen. Der folgende Code aus dem Beispielprojekt Schach1 arbeitet mit einem Array fensterloser Steuerelemente. Nach jeder Verschiebung einer Figur wird die Reihenfolge wieder hergestellt: For i = 31 To 0 Step -1 figur(i).ZOrder (0) Next i
' Steuerelement ganz nach oben
Wenn Sie den Fensterbereich eines Objekts explizit restaurieren wollen, zum Beispiel nach einem Resize-Ereignis, sollten Sie die Refresh-Methode aufrufen.
254
Paint- Ereignis
Beispiel
................................................... Beis piel
Der folgende in zwei Varianten vorgestellte Code zeichnet eine Ellipse, die immer exakt den Client-Bereich des Formulars ausfüllt. Die erste Variante verlässt sich darauf, dass Visual Basic den Formularbereich automatisch neu zeichnet, die zweite verwendet eine Paint-Routine. Ändert man die Größe des Formulars, flackert die Anzeige im ersten Fall ein wenig, im zweiten Fall jedoch nicht.
Standardereignisse
' Erste Variante Private Sub Form_Load() AutoRedraw = True End Sub Private Sub Form_Resize() Dim Radius If ScaleWidth > ScaleHeight Then Radius = ScaleWidth / 2 Else Radius = ScaleHeight / 2 End If Cls Circle (ScaleWidth / 2, ScaleHeight / 2), Radius, , , , ScaleHeight / ScaleWidth End Sub
Die Ellipse füllt das Formular in jeder Größe ganz aus ' Zweite Variante Private Sub Form_Load() AutoRedraw = False End Sub Private Sub Form_Paint() Dim Radius If ScaleWidth > ScaleHeight Then Radius = ScaleWidth / 2 Else Radius = ScaleHeight / 2 End If Cls Circle (ScaleWidth / 2, ScaleHeight / 2), Radius, , , , ScaleHeight / ScaleWidth End Sub
255
Standardereignisse
Private Sub Form_Resize() Refresh End Sub
QueryUnload- Ereignis Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) MIDForm_QueryUnload(Cancel As Integer, UnloadMode As Integer) Betroffene Objekte
Standardereignisse
................................................... Betro ffene Objekte Form, MDIForm Beschreibung
................................................... Bes c hreibung
Dieses dem Unload-Ereignis vorangehende Ereignis teilt einem Formular mit, dass es geschlossen werden soll. Falls die gesamte Anwendung beendet werden soll, schickt Windows dieses Ereignis der Reihe nach an alle geöffneten Formulare. QueryUnload stellt eine Anfrage dar, die ein einzelnes Formular (im Namen aller Formulare) auch ablehnen kann, indem es den Ausgabeparameter Cancel auf einen Wert ungleich 0 setzt. MDI-Formulare sehen das Ereignis vor ihren untergeordneten Formularen (beim Unload-Ereignis ist die Reihenfolge dagegen genau andersherum). Der Parameter UnloadMode liefert den Grund für das Ereignis. Die folgende Tabelle gibt einen Überblick über die verschiedenen Gründe und die über den Aufzählungstyp QueryUnloadConstants dafür definierten Konstanten. Konstante
Grund
vbFormControlMenu (0)
Der Benutzer beendet die Anwendung über das Systemmenü.
vbFormCode (1)
Eine Unload-Anweisung wurde für das Formular ausgeführt.
vbAppWindows (2)
Windows soll heruntergefahren werden.
vbAppTaskManager (3)
Der Task-Manager fordert die Anwendung zum Abbrechen auf.
vbFormMDIForm (4)
Das übergeordnete MDI-Formular soll geschlossen werden.
vbFormOwner (5)
Das übergeordnete Formular soll geschlossen werden.
Anwendung
................................................... Anwendung
Eine Anwendung kann dieses Ereignis behandeln, um sicherzustellen, dass alle Operationen in allen Formularen abgeschlossen sind und alle Daten gespeichert wurden. Andernfalls sollte der Benutzer die Möglichkeit erhalten, dies nachzuholen. Beispiel
................................................... Beis piel
Der folgende Code zeigt die typische Reaktion auf QueryUnload. Private Textgeändert As Boolean ... Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) If Textgeändert Then Select Case MsgBox("Datei speichern?", vbExclamation + vbYesNoCancel) Case vbCancel ' Programmabbruch vereiteln Cancel = True
256
Resize- Ereignis
Case vbYes mnuDateiSpeichern_Click Cancel = False Case vbNo Cancel = False End Select End If End Sub
' Datei speichern, dann Unload
' Datei nicht speichern, sofort Unload
Verwandte Ereignisse
................................................... Verwandte Ereignis s e
Standardereignisse
Unload
Resize- Ereignis Sub Form_Resize() Sub Objekt_Resize([HeightNew As Single, WidthNew As Single]) Betroffene Objekte
................................................... Betro ffene Objekte CoolBar, Data, DataReport, Form, MDIForm, OLE, PictureBox, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Das Resize-Ereignis zeigt einem Objekt an, dass sich seine Größe geändert hat. Die Ursache dafür kann entweder eine entsprechende Benutzeraktion wie »Vergrößern«, »Verkleinern«, »Maximieren« oder »Wiederherstellen« sein, aber auch die Ausführung einer Anweisung, die Einfluss auf die Größe oder Sichtbarkeit des Objekts hat. Für ein Formular tritt das Ereignis erstmals nach dem Load-Ereignis auf, wenn es automatisch gestartet wurde, oder im Zuge eines Show-Aufrufs, der es sichtbar macht. Ansonsten ist es Seiteneffekt, wenn eine der Eigenschaften WindowState, Height, Width einen neuen Wert erhält oder die Visible-Eigenschaft auf True gesetzt wird. Die Parameter HeightNew und WidthNew geben die neuen Abmessungen im aktuellen Koordinatensystem an. Anwendung
................................................... Anwendung
Ein Objekt behandelt dieses Ereignis, um auf Größenänderungen reagieren zu können und seinen Bereich gegebenenfalls neu zu zeichnen oder zu organisieren. Häufig wird in einer ResizeRoutine auch das Koordinatensystem via ScaleHeight, ScaleWidth, ScaleLeft, ScaleTop geändert, um die Grafikausgaben von der Bereichsgröße unabhängig zu machen. Falls die AutoRedraw-Eigenschaft eines Formulars auf False gesetzt wurde, sollte die ResizeRoutine einen Refresh-Aufruf enthalten, wenn sich das Koordinatensystem geändert hat. Beispiel
................................................... Beis piel
Die folgende Resize-Routine reagiert auf Änderungen der Formularabmessungen, indem sie eine Periode der Sinuskurve ausgibt, die immer genau in den Client-Bereich des Formulars eingepasst ist. Der Einfachheit halber ändert der Code das Koordinatensystem, nicht die Parameter der Kurve. Private Sub Form_Resize() Dim Winkel As Single Dim Pi As Single Pi = 4 * Atn(1)
257
Standardereignisse
ScaleHeight = -2 ' Positive Koordinaten oben! Me.ScaleTop = 1 ' Ursprung in die Mitte ScaleWidth = 2 * Pi ' reicht für eine volle Sinusperiode Cls ' Bereich löschen ' Sinuskurve zeichnen For Winkel = 0 To 2.1 * Pi Step Pi / 30 Line -(Winkel, Sin(Winkel)) Next Winkel End Sub
Standardereignisse
Verwandte Themen
................................................... Verwandte Them en
Bildlauf – ein kleiner Betrachter für große Bilder (S. 545); HexView – eine schnelle Textansicht für große Dateien (S. 551)
Terminate- Ereignis Sub Objekt_Terminate() Betroffene Objekte
................................................... Betro ffene Objekte ClassModule, DataReport, DHTMLPageDesigner, Form, MDIForm, PropertyPage, UserControl, UserDocument, WebClass Beschreibung
................................................... Bes c hreibung
Terminate ist das letzte Ereignis, das ein Objekt ereilt. Es tritt ein, sobald keine Verweise auf das Objekt mehr existieren, das heißt, wenn das Fenster des Objekts entladen wurde und der Geltungsbereich der letzten Objektvariable, die noch auf das Objekt verwiesen hat, erloschen ist oder auf den Wert Nothing gesetzt wurde. Für Objekte mit eigenem Fenster folgt das TerminateEreignis unmittelbar auf das Unload-Ereignis, nicht jedoch für Objekte, die von einer auf ClassModule aufsetzenden Klasse abstammen. Für diese Objekte fungiert Terminate als alleiniger Destruktor. Anwendung
................................................... Anwendung
Die Ereignisse Terminate und Initialize treten beide nur ein einziges Mal auf. Aus diesem Grund sollte eine Terminate-Routine dazu verwendet werden, genau die Ressourcen wieder freizugeben, die während Initialize angefordert wurden. Warnungen
................................................... Wa rnungen Formularvariablen sollten nicht ohne vorherigen Unload-Aufruf auf Nothing gesetzt werden, da sie sonst geladen bleiben (und ebenso alle Objekte, die dem Formular untergeordnet sind, das heißt: alle Steuerelemente sowie gegebenenfalls weitere Formulare). Terminate tritt nicht auf, wenn ein Formular oder die Instanz einer Klasse aus dem Hauptspeicher entfernt, weil die Anwendung nicht ordnungsgemäß beendet wurde, oder wenn die Anwendung durch eine End-Anweisung beendet wird, ohne dass zuvor alle bestehenden Instanzen der Klasse oder des Formulars aus dem Hauptspeicher entfernt wurden. Beispiel
................................................... Beis piel
Private Sub Form_Terminate Redim MeinArray(0) ' Arrayelemente freigeben End Sub
258
Unload- Ereignis
Verwandte Ereignisse
................................................... Verwandte Ereignis s e Initialize, Load, Unload
Unload- Ereignis Sub Objekt_UnLoad(Cancel As Integer) Betroffene Objekte
................................................... Betro ffene Objekte Form, MDIForm, PropertyPage
................................................... Bes c hreibung
Das Unload-Ereignis tritt auf, wenn ein Formularobjekt sein Fenster sowie alle darin enthaltenen Steuerelemente freigibt bzw. entlädt – das Objekt selbst bleibt bestehen. Ursache des Ereignisses kann eine Unload-Anweisung sein, aber auch eine Benutzeraktion, die das Schließen des Fensters oder die Beendigung des gesamten Programms zum Ziel hat – beispielsweise ein Klick auf die Schaltfläche SCHLIEßEN in der Titelleiste des Fensters oder der Aufruf eines entsprechenden Menübefehls. Der Ausgabeparameter Cancel lässt sich auf einen Wert ungleich 0 oder auf True setzen, um das Entladen zu verhindern. Ein Herunterfahren von Windows wird dadurch aber nicht abgebrochen, das kann nur bei der Behandlung von QueryUnload geschehen. Anwendung
................................................... Anwendung
Erhält ein Objekt das Unload-Ereignis, heißt das noch lange nicht, dass es selbst auch abgebaut wird. Das ist erst der Fall, wenn ein Terminate-Ereignis folgt. Es zeugt sogar von gutem Programmierstil, Formulare zwischendurch mit der Unload-Anweisung zu entladen, wenn sie gerade nicht benötigt werden. Das Objekt selbst bleibt dabei erhalten, und das Fenster lässt sich jederzeit über einen Load- oder besser Show-Aufruf erneut laden und zur Anzeige bringen, ja, es reicht auch ein Zugriff auf die Visible-Eigenschaft. Das spart Ressourcen, kann aber zu Verzögerungen bei der erneuten Anzeige des Formulars führen, weil das Fenster sowie alle darauf befindlichen Steuerelemente neu initialisiert werden müssen. Warnungen
................................................... Wa rnungen Visual Basic entlädt das Fenster eines Formularobjekts nicht automatisch, wenn die letzte Referenz auf das Objekt auf Nothing gesetzt wird. Das Entladen muss explizit durch den Benutzer oder durch den Programmcode geschehen. Erfolgt für ein entladenes Formularfenster ein Hide-Aufruf, bringt dieser – entgegen aller Logik – das Fenster zur Anzeige. Tipp
................................................... Tipp
Um ein Fenster verschwinden zu lassen, können Sie auch die Hide-Methode des Formularobjekts ausführen. In diesem Fall wird das Fenster zwar unsichtbar, bleibt aber geladen. Das Fenster selbst ist dann inaktiv und kann insbesondere den Fokus nicht erhalten. Um das Fenster wieder sichtbar zu machen, kann die Visible-Eigenschaft auf True gesetzt werden oder ein ShowAufruf erfolgen. Beispiel
................................................... Beis piel
Private Sub Form_Unload(Cancel As Integer) If vbYes = MsgBox("Sind Sie sicher?", vbYesNo, "Fenster schließen") _
259
Standardereignisse
Beschreibung
Standardereignisse
Then Cancel = 0 Else Cancel = 1 End If End Sub Verwandte Ereignisse
................................................... Verwandte Ereignis s e
Standardereignisse
Initialize, Load, Terminate
Validate- Ereignis Sub Objekt_Validate(Cancel As Boolean) Betroffene Objekte
................................................... Betro ffene Objekte Adodc, Animation, CheckBox, ComboBox, CommandButton, Data, DataGrid, DataList, DataRepeater, DateTimePicker, DBCombo, DBGrid, DBList, DirListBox, DriveListBox, FileListBox, HScrollBar, ListBox, ListView, MaskEdBox, MMControl, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, MSTab, OptionButton, PictureBox, PropertyPage, RemoteData, RichTextBox, Slider, TabStrip, TextBox, TreeView, VScrollBar Beschreibung
................................................... Bes c hreibung
Das unmittelbar vor LostFocus eintreffende Validate-Ereignis kündigt einem Steuerelement an, dass es den Fokus abgeben soll. Setzt das Steuerelement den Ausgabeparameter Cancel auf True, kann es die Weitergabe des Fokus unterbinden – etwa, wenn sein aktueller Wert gegen eine Gültigkeitsregel verstößt. Voraussetzung für das Auftreten dieses Ereignisses ist allerdings, dass die CausesValidation-Eigenschaft sowohl des betroffenen Steuerelements als auch des Steuerelements, auf das der Fokus übergehen soll, den Wert True hat. Anwendung
................................................... Anwendung
Die normale Reaktion auf das Validate-Ereignis ist eine Gültigkeitsprüfung des Werts bzw. des aktuellen Zustands des Steuerelements. Stellt sich der Wert als »ungültig« heraus, ist kein besonderes Verhalten vorgeschrieben: Die Behandlungsroutine kann eine belehrende Fehlermeldung ausgeben und die Fokusabgabe verweigern, sie kann aber auch den Wert schlichtweg korrigieren und der Weitergabe des Fokus nichts in den Weg legen. Falls auch nur ein Steuerelement auf einem Formular eine Gültigkeitsprüfung durchführt, wird die CausesValidation-Eigenschaft der anderen als Empfänger des Fokus in Frage kommenden Steuerelemente im Allgemeinen auf True gesetzt sein. In besonderen Fällen kann es jedoch Vorteile bringen, die CausesValidation-Eigenschaft bestimmter Steuerelemente – etwa einer ABBRECHEN- oder HILFE-Schaltfläche – auf False zu setzen. Der Benutzer kann dann den Fokus auf diese Steuerelemente verschieben, ohne das Validate-Ereignis des verlassenen Steuerelements auszulösen. Sobald der Fokus jedoch auf ein Steuerelement weitergehen soll, dessen CausesValidation-Eigenschaft auf True gesetzt wurde, tritt zunächst einmal das Validate-Ereignis des ursprünglichen Steuerelements auf. Beachten Sie aber, dass dem Benutzer auf diese Weise gegebenenfalls das Schließen des Formulars möglich werden kann, ohne dass die Gültigkeitsprüfung des zuletzt verlassenen Steuerelements zum Zuge kommt. Die Unload-Behandlung für das Formular sollte daher einen ValidateControls-Aufruf enthalten. Die Behandlung des Validate-Ereignisses ist angezeigt, wenn der Benutzer ein Datenfeld ausfüllen muss oder wenn er nur bestimmte Daten in ein Datenfeld eintragen darf.
260
Global- Objekt
Warnung
................................................... Wa rnung
Vom Prinzip her könnte man auch versuchen, eine Gültigkeitsprüfung im Zuge von LostFocus zu implementieren. Das kann aber Probleme verursachen, da das Steuerelement zu dem Zeitpunkt, an dem das Ereignis auftritt, den Fokus bereits abgegeben hat. Es wäre also ein SetFocus-Aufruf erforderlich, der aber wiederum dem neuen Inhaber des Fokus diesen sofort wieder entreißt und ihm das LostFocus-Ereignis beschert. Falls dieses Steuerelement gleichfalls nicht bereit ist, den Fokus herzugeben und seinerseits einen SetFocus-Aufruf durchführt, kommt es zu einer Ereignisflut, die das System destabilisieren kann. Beispiel
Global- Objekt
................................................... Beis piel
Private Sub Text1_Validate(Cancel As Boolean) Cancel = Not IsDate(Text1) End Sub Verwandte Ereignisse
................................................... Verwandte Ereignis s e LostFocus, GotFocus
Global- Objekt Die Einbettung der traditionellen Standardfunktionen von Basic in das inzwischen vollkommen objektorientierte Programmiermodell von Visual Basic geschieht formal gesehen über ein Global-Objekt, das den übergeordneten Kontext für alle Module einer Anwendung bereitstellt. Damit sind die in der Klasse Global definierten Methoden größtenteils »alte Bekannte«, die (nach wie vor) den operativen Kern der Sprache selbst ausmachen. Mit den Eigenschaften des Global-Objekts verhält es sich anders; sie sind ihrerseits Objekte und verkapseln die Standardumgebung, in die jedes Visual-Basic-Programm sozusagen beim Start »hineingeboren« wird. Diese Objekte müssen (und können) nicht eigens instanziiert werden, da sie von Visual Basic automatisch im Verlauf des Programmstarts angelegt werden und ihre Bezeichner global bekannt sind. Eine Qualifikation mit dem Bezeichner »Global« ist weder nötig noch möglich.
................................................... Eigens c ha ften App, Calendar, ClipBoard, Date, Forms, Now, Printer, Printers, Screen, Time, Timer Die folgende Tabelle gibt einen Überblick über die nicht an anderer Stelle vorgestellten globalen Eigenschaften: Eigenschaft
Beschreibung
App
App-Objekt, das die aktuelle Laufzeitinstanz repräsentiert
Calendar
Integerwert, der den Kalender für alle Datumsfunktionen festlegt. Voreinstellung ist vbCalGreg (0) für den Gregorianischen Kalender. Alternative ist der Hijri-Kalender: vbCalHijri (1)
ClipBoard
ClipBoard-Objekt, das die OLE-Zwischenablage und ihre Operationen repräsentiert
Err
ErrObject-Objekt, das den Fehlerkontext der Anwendung repräsentiert
261
Global- Objekt
Eigenschaft
Beschreibung
Forms
Object-Auflistung aller von der aktuellen Laufzeitinstanz geladenen Formularinstanzen
Printer
Printer-Objekt, das den aktuellen Standarddrucker repräsentiert
Printers
Object-Auflistung aller auf dem System installierten Drucker
Screen
Screen-Objekt, das die Grafikanzeige auf dem Bildschirm repräsentiert
................................................... Methoden
Global- Objekt
Methoden
Abs, AppActivate, Asc, AscB, AscW, Atn, Beep, CallByName, CBool, CByte, CCur, CDate, CDbl, CDec, ChDir, ChDrive, Choose, Chr, ChrB, ChrW, CInt, CLng, Command, Cos, CreateObject, CSng, CStr, CurDir, CVar, CVDate, CVErr, DateAdd, DateDiff, DatePart, DateSerial, DateValue, Day, DDB, DeleteSetting, Dir, DoEvents, Environ, EOF, Err, Error, Exp, FileAttr, FileCopy, FileDateTime, FileLen, Filter, Fix, Format, FormatCurrency, FormatDateTime, FormatNumber, FormatPercent, FreeFile, FV, GetAllSettings, GetAttr, GetObject, GetSetting, Hex, Hour, IIF, InputBox, InStr, InStrB, InStrRev, Int, IPmt, IRR, IsArray, IsDate, IsEmpty, IsError, IsMissing, IsNull, IsNumeric, IsObject, Join, Kill, LCase, Left, LeftB, Len, Load, LoadPicture, LoadResData, LoadResPicture, LoadResString, Loc, LOF, Log, LTrim, Mid, MidB, Minute, MIRR, MkDir, Month, MonthName, MsgBox, NPer, NPV, Oct, Partition, Pmt, PPmt, PV, QBColor, Randomize, Rate, Replace, Reset, RGB, Right, RightB, RmDir, Rnd, Round, RTrim, SavePicture, SaveSetting, Second, Seek, SendKeys, SetAttr, Sgn, Shell, Sin, SLN, Space, Split, Sqr, Str, StrComp, StrConv, String, StrReverse, Switch, SYD, Tan, TimeSerial, TimeValue, Trim, TypeName, UCase, Unload, Val, VarType, Weekday, WeekdayName, Year Die folgende Tabelle gibt einen Überblick über die nicht an anderer Stelle vorgestellten Methoden. Die Prototypen lauten: Function CallByName(Object As Object, ProcName As String, _ CallType As VbCallType, Args()) As Variant Sub CallByName(Object As Object, ProcName As String, _ CallType As VbCallType, Args()) Function Command() As String Function CreateObject(Class As String, [ServerName As String]) As Object Sub DeleteSetting(AppName As String, [Section As String], _ [Key As String]) Sub DoEvents() Function GetAllSettings(AppName As String, Section As String) _ As String()() Function GetObject([PathName As String], _ [AnwName.ObjektTyp As String]) As Object Function GetSetting(AppName As String, Section As String, _ Key As String, [Default]) As String Function InputBox(Prompt, Title, Default, XPos, YPos, HelpFile, _ Context) As String
262
Global- Objekt
Function Load(Object As Object) Function LoadPicture([FileName], [Size], [ColorDepth], [X], [Y]) _ As Picture Function LoadResData(Id, ResType As Integer) As Byte() Function LoadResPicture(Id, ResType As Integer) As Picture
Function LoadResString(Id As Long) As String Function QBColor(Color As Integer) As Long
Global- Objekt
Function RGB(Red As Integer, Green As Integer, Blue As Integer) As Long Sub SavePicture(Picture As Picture, FileName As String) Sub SaveSetting(AppName As String, Section As String, _ Key As String, Setting As String)
Sub SendKeys(String As String, [Wait As Boolean]) Sub Unload(Object) Methode
Beschreibung
CallByName
Ermöglicht den Aufruf einer Methode oder Eigenschaft ProcName eines zur Laufzeit gebundenen Automatisierungsobjekts Object unter Angabe des Bezeichners ElementName als Zeichenfolge, gefolgt von der Art des Elements (vbGet, vbLet, vbMethod, vbSet) und der Parameterliste Params, die auch als Variant-Array übergeben werden kann. Der Aufruf kann in Funktions- oder Prozedurform erfolgen.
Command
Liefert die Kommandozeilenargumente, die beim Aufruf der Anwendung angegeben wurden
CreateObject
Erzeugt eine neue Instanz eines ActiveX-Objekts optional unter Spezifikation eines Servers und liefert einen Verweis darauf zurück
DeleteSetting
Löscht persistente Einstellungen eines Programms aus der Systemregistrierung. Die Methode wird unter Angabe des Anwendungsnamens als Schlüssel, eines Abschnittsbezeichners als Unterschlüssel (optional) und eines Bezeichners (optional) aufgerufen und löscht den entsprechenden Eintrag, Unterschlüssel oder Schlüssel.
DoEvents
Unterbricht die Ausführung der aktuellen Routine, um die Behandlung gegebenenfalls anstehender Ereignisse zu ermöglichen, und setzt die Routine danach fort
GetAllSettings
Ermittelt persistente Einstellungen eines Programms aus der Systemregistrierung. Die Funktion wird unter Angabe des Anwendungsnamens als Schlüssel sowie eines Abschnittsbezeichners als Unterschlüssel aufgerufen und liefert ein zweidimensionales String-Array, das in der ersten Dimension alle in dem Abschnitt gespeicherten Bezeichner und in der zweiten die dazugehörigen Werte wiedergibt.
GetObject
Liefert eine Object-Referenz auf ein ActiveX-Objekt
263
Global- Objekt
Global- Objekt
Methode
Beschreibung
GetSetting
Ermittelt eine persistente Einstellung eines Programms aus der Systemregistrierung. Die Funktion wird unter Angabe des Anwendungsnamens als Schlüssel, eines Abschnittsbezeichners als Unterschlüssel sowie eines Bezeichners aufgerufen und liefert einen String-Wert, der den unter dem Bezeichner abgelegten Wert wiedergibt.
InputBox
Ruft ein Dialogfeld auf, das den Benutzer zur Eingabe eines String-Werts auffordert und diesen als Ergebnis liefert
Load
Lädt ein Formular oder Steuerelement für die spätere Anzeige in den Hauptspeicher. Die Methode lässt sich insbesondere für die dynamische Erweiterung von Steuerelemente-Arrays verwenden.
LoadPicture
Lädt eine Bitmap aus einer Datei und liefert sie als Objekt vom Typ Picture. Die Methode unterstützt die gängigen Grafikformate BMP, JPG, JPEG, GIF, WMF, EMF, ICO und CUR.
LoadResData
Lädt eine Ressource aus einer Ressourcendatei (RES) und liefert deren Daten in Form eines Byte-Arrays
LoadResPicture
Lädt eine Bildressource (Bitmap, Cursor, Symbol) aus einer Ressourcendatei (RES) und liefert sie als Picture-Objekt
LoadResString
Lädt eine Zeichenfolgenressource aus einer Ressourcendatei (RES) und liefert sie als String-Wert
QBColor
Liefert den zu einer QBasic-Farbe gehörigen Farbwert als Long
RGB
Komponiert einen Farbwert aus den Farbanteilen Rot, Grün und Blau und liefert diesen als Long
SavePicture
Speichert ein als Picture-Objekt vorliegendes Bild in einer Datei
SaveSetting
Speichert persistente Einstellungen des Programms in der Systemregistrierung. Die Anweisung wird unter Angabe des Anwendungsnamens, eines Abschnittsbezeichners, eines Schlüssels sowie eines Schlüsselwerts aufgerufen.
SendKeys
Sendet eine Folge von Tastaturereignissen an das aktive Fenster (Formular, Steuerelement im Formular) der im Vordergrund ausgeführten Anwendung und ermöglicht so deren Fernsteuerung
Shell
Ermöglicht den Aufruf einer anderen Anwendung und gibt optional einen Fensterstil dafür vor
Unload
Entfernt ein Formular oder Steuerelement Object aus dem Hauptspeicher
App- Objekt Public App As App Beschreibung
................................................... Bes c hreibung
Dem App-Objekt liegt als Datentyp die in der Bibliothek VB definierte gleichnamige Klasse App zugrunde. Visual Basic vereinbart dieses Objekt automatisch in jeder Anwendung mit globalem Geltungsbereich. Es repräsentiert die Laufzeitinstanz bei Ausführung der Anwendung und speichert eine Reihe von Informationen über die Anwendung, darunter die Versions- und Herstel-
264
App- Objekt
lerinformationen und den Pfad der ausführbaren Datei sowie diverse Informationen über die konkrete Laufzeitinstanz (so beispielsweise die Tatsache, ob bereits eine weitere Instanz der gleichen Anwendung in Ausführung ist) sowie über das Verhalten der Anwendung im Zusammenspiel mit OLE-Servern. Eigenschaften
................................................... Eigens c ha ften Ein guter Teil der Eigenschaften (insbesondere die zur Laufzeit schreibgeschützten) des AppObjekts lassen sich interaktiv im Eigenschaftsfenster PROJEKTEIGENSCHAFTEN des zugehörigen Projekts setzen. Die folgende Tabelle gibt einen Überblick: Beschreibung
Comments
Zur Laufzeit schreibgeschützte Zeichenfolge für Kommentare zur aktuellen Version
CompanyName
Zur Laufzeit schreibgeschützte Zeichenfolge für Firmenname. Vorbesetzt mit Firmenname aus der Visual-Basic-Lizenz.
EXEName
Zur Laufzeit schreibgeschützte Zeichenfolge mit dem Anwendungsnamen ohne Erweiterung
FileDescription
Zur Laufzeit schreibgeschützte Zeichenfolge mit Dateibeschreibung
HelpFile
Zur Laufzeit schreibgeschützte Zeichenfolge; enthält Pfad für die zur Anwendung gehörige kontextbezogene Hilfedatei.
hInstance
Zur Laufzeit schreibgeschützter Handle der Laufzeitinstanz (für Aufrufe der Win32-API)
LegalCopyright
Zur Laufzeit schreibgeschützte Zeichenfolge mit Copyrightinformationen
LegalTrademarks
Zur Laufzeit schreibgeschützte Zeichenfolge mit Warenzeicheninformationen
LogMode
Zur Laufzeit schreibgeschützter Protokollmodus; wird von StartLogging-Methode gesetzt. Der Wert dieser Eigenschaft ist ein Vektor und kann eine Kombination aus Werten des Aufzählungstyps LogEventTypeConstants sein: vbLogAuto (0) – Protokoll wird unter Windows 9x in durch LogPath spezifizierte Datei ausgegeben, unter Windows NT in Ereignisprotokoll (Quelle ist »VBRunTime«, Title wird als genauere Beschreibung der Instanz ausgegeben). vbLogOff (1) – keine Protokollierung mehr, LogEvent-Aufrufe bleiben ohne Effekt vbLogToFile (2) – Ausgabe in durch LogPath spezifizierte Datei; ein ungültiger Dateiname erzwingt vbLogOff; falls LogPath leere Zeichenfolge, ist vbevents.log die Vorgabe vbLogToNT (3) – Ausgabe in NT-Ereignisprotokoll; erzwingt vbLogOff unter Windows 9x vbLogOverwrite (16) – legt Protokolldatei bei jedem Start neu an vbLogThreadID (32) – Meldungen werden um Thread-ID ergänzt (bei Multithreaded-Anwendung); erzwingt vbLogOff bei Singlethreaded-Anwendung
265
Global- Objekt
Eigenschaft
Global- Objekt
Global- Objekt
Eigenschaft
Beschreibung
LogPath
Zur Laufzeit schreibgeschützte Zeichenfolge mit Namen der Protokolldatei, wird von StartLogging-Methode gesetzt
Major
Zur Laufzeit schreibgeschützter Wert für primäre Versionsnummer
Minor
Zur Laufzeit schreibgeschützter Wert für sekundäre Versionsnummer
NonModalAllowed
Laufzeiteigenschaft vom Typ Boolean – ungebundene Anzeige
OLERequestPendingMsgText
Laufzeiteigenschaft vom Typ String für die Spezifikation einer eigenen Meldung im Zusammenhang mit einer Zeitüberschreitung bei der Bearbeitung einer Anforderung durch einen ActiveX-Server (weiteres unter OLEServerBusyRaiseError)
OLERequestPendingMsgTimeOut
Laufzeiteigenschaft für die Anzahl der Millisekunden (Vorgabewert: 5 Sekunden), welche die Instanz auf die Anwort eines ActiveX-Servers wartet; gilt auch für ActiveX-Dokumente, die via OLE-Container-Steuerelement eingebettet bzw. verknüpft sind
OLERequestPendingMsgTitle
Laufzeiteigenschaft vom Typ String; Vorgabewert ist die TitleEigenschaft des Objekts
OLEServerBusyMsgText
Laufzeiteigenschaft vom Typ String für die Spezifikation einer eigenen Meldung im Zusammenhang mit einer Zeitüberschreitung bei einer Anforderung an einen ActiveX-Server (Weiteres unter OLEServerBusyRaiseError)
OLEServerBusyMsgTitle
Laufzeiteigenschaft vom Typ String; Vorgabewert ist die TitleEigenschaft des Objekts
OLEServerBusyRaiseError
Laufzeiteigenschaft vom Typ Boolean – bei Auftreten eines Timeouts im Verlauf einer Anforderung an einen ActiveX-Server bestimmt der Vorgabewert True dieser Eigenschaft, dass umgehend der Automatisierungsfehler -2147418111 (&H80010001) ausgelöst werden soll. Bei False erscheint entweder der standardmäßige Dialog KOMPONENTE BESCHÄFTIGT (bzw. KOMPONENTENANFORDERUNG WIRD BEARBEITET) oder ein mit den Werten der Eigenschaften OLEServerBusyMsgText und OLEServerBusyMsgTitle (bzw. OLERequestPendingMsgText und OLERequestPendingMsgTitle) zusammengestellter Dialog – je nachdem, ob der Wert der Eigenschaft OLEServerBusyMsgText (bzw. OLERequestPendingMsgText) die leere Zeichenfolge ist oder nicht. Jeden der Dialoge kann der Benutzer mit OK oder mit ABBRECHEN beenden. Ein Abbruch löst den genannten Automatisierungsfehler aus.
OLEServerBusyRaiseTimeOut
Laufzeiteigenschaft für die Anzahl der Millisekunden (Vorgabewert: 10 Sekunden), welche die Instanz auf die Anwort eines ActiveX-Servers wartet; gilt auch für ActiveX-Dokumente, die via OLE-Container-Steuerelement eingebettet bzw. verknüpft sind
Path
Zur Laufzeit schreibgeschützte Zeichenfolge, die den vollständigen Pfad der VBP-Projektdatei bzw. der EXE-Datei wiedergibt.
266
App- Objekt
Beschreibung
PrevInstance
Zur Laufzeit schreibgeschützter Boolean-Wert – True besagt, dass eine andere Instanz der gleichen Anwendung in Ausführung ist, False das Gegenteil
ProductName
Zur Laufzeit schreibgeschützte Zeichenfolge für Produktnamen
RetainedProject
Zur Laufzeit schreibgeschützter Boolean-Wert – True besagt, Laufzeitinstanz bleibt im Speicher geladen, False (Vorgabe), das Gegenteil
Revision
Zur Laufzeit schreibgeschützter Wert für Revisionsanteil der Versionsnummer
StartMode
Zur Laufzeit schreibgeschützter Wert, der besagt, ob eine Laufzeitinstanz im Stand-alone-Modus (vbSModeStandalone = 0) oder als ActiveX-Komponente (vbSModeAutomation = 1) gestartet wurde
TaskVisible
Boolean-Wert, der bestimmt, ob die Laufzeitinstanz in der Taskliste von Windows als Eintrag erscheint (True) oder nicht (False)
ThreadID
Long-Wert mit der Thread-ID der Laufzeitinstanz (für Aufrufe der Win32-API)
Title
String-Wert, der den Namen der Laufzeitinstanz für die Ausgabe in der Taskliste bestimmt
UnAttendedApp
Zur Laufzeit schreibgeschützter Boolean-Wert; wenn False (Vorgabe), erhält die Anwendung eine Benutzeroberfläche, sonst nicht
................................................... Methoden Methoden
Sub App.StartLogging( _ LogTarget As String = "vbevents.log", LogModes As Long) Sub App.LogEvent( _ LogBuffer As String, EventType As LogEventTypeConstants) Die zwei Methoden des App-Objekts dienen der Protokollierung von Ereignissen. Sie verrichten Ihren Dienst allerdings nur, wenn das Programm als eigenständige Exe-Datei ausgeführt wird – bei Ausführung der Projektdatei innerhalb der Entwicklungsumgebung sollte die LogEvent-Ausgabe laut Spezifikation in das Direktfenster stattfinden, was jedoch in der Version 6.0 (SP3) nicht passiert. Methode
Beschreibung
StartLogging
Legt LogTarget als Protokolldatei und LogModes als Protokollmodus für die Ereignisaufzeichnung mittels LogEvent fest (vgl. LogModus-Eigenschaft)
LogEvent
Protokolliert den in LogBuffer enthaltenen Text als Meldung in der Protokolldatei LogTarget der Anwendung. (Unter Windows NT schreibt die Methode in das NT-Ereignisprotokoll.) Der Parameter EventType kategorisiert die Meldung in »Fehler« (vbLogEventTypeError oder 1), »Warnung« (vbLogEventTypeWarning oder 2) bzw. »Information« (vbLogEventTypeInformation oder 4).
267
Global- Objekt
Eigenschaft
Global- Objekt
Anwendung
Global- Objekt
................................................... Anwendung
Als Laufzeitinstanz eines Programms ist das App-Objekt zwar das »Objekt der Objekte«, doch bei der Programmierung spielt es eher eine untergeordnete Rolle. Am häufigsten dürften die Eigenschaften PrevInstance und Path von Interesse sein. PrevInstance gibt Aufschluss darüber, ob bereits eine andere Instanz der Anwendung in Ausführung ist, und Path gibt Aufschluss über den Pfad der Exe-Datei. (Der Name der Exe-Datei ergibt sich aus der Eigenschaft Title.) Ab und an sind aber auch die Möglichkeiten der Ereignisprotokollierung des App-Objekts von Nutzen, zum Beispiel wenn es darum geht, die Aktivitäten eines Servers zu protokollieren. Seltener dagegen wird das App-Objekt für die Gestaltung von Time-outs und Abbrüchen bei Anforderungen an ActiveX-Server herangezogen. (Das Vorgabeverhalten ist hier in den meisten Fällen ausreichend. In speziellen Fällen, etwa wenn ActiveX-Server im Netzwerk verteilt sind, kann eine explizite Definition der entsprechenden Eigenschaften nötig sein.) Warnung
................................................... Wa rnung
Die Time-out-Intervalle des App-Objekts lassen sich zwar beliebig ausdehnen, da die entsprechenden Eigenschaften den Typ Long tragen, doch ein zu langes Zeitintervall kann die Anwendung lahmlegen, wenn der kontaktierte Server nicht reagiert. Sollten Sie für eine bestimmte Aufgabe die Time-outs des App-Objekts ändern müssen, empfiehlt es sich, die Werte nach Erledigung der Aufgabe umgehend wieder zu restaurieren, wenn die Anwendung mit mehr als einem ActiveX-Objekt arbeitet. Beispiel
................................................... Beis piel
Der folgende Code verhindert den mehrfachen Start der Anwendung. Die Beschränkung auf eine Laufzeitinstanz ist im Zusammenhang mit MDI-Anwendungen zwar nicht zwingend, aber doch weit verbreitet. Private Sub Form_Load() If App.PrevInstance Then MsgBox ("Es gibt eine ältere Instanz der Anwendung") End End If End Sub
Der folgende Codeauszug demonstriert die Ereignisprotokollierung in eine Datei namens C:\Test.log. (Achtung: Kompilierung erforderlich). Option Explicit Dim Nr As Long Private Sub Form_Load() App.StartLogging "C:\Test.log", 0 End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) Nr = Nr + 1 App.LogEvent "Mousedown " + Str(Nr), vbLogEventTypeError End Sub
Die Ausgabe in die Datei c:\test.log hat folgende Gestalt: Error Application C:\Test.log: Thread ID: -513437 ,Logged: Mousedown 1 Error Application C:\Test.log: Thread ID: -513437 ,Logged: Mousedown 2
268
CallByName- Methode
CallByName- Methode Function CallByName(Object As Object, ProcName As String, _ CallType As VbCallType, Args()) As Variant Sub CallByName(Object As Object, ProcName As String, _ CallType As VbCallType, Args()) Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Der Visual-Basic-Compiler versucht, Objekte nach Möglichkeit bereits zur Übersetzungszeit zu binden und Verweise auf ihre Eigenschaften und Methoden möglichst umgehend aufzulösen. Man spricht in diesem Zusammenhang von früher Bindung. Diese Art der Bindung ist aber bei COM-Objekten nicht immer möglich, etwa wenn das Objekt keine duale Schnittstelle besitzt (oder die Typbibliothek dafür nicht bekannt ist), sondern nur eine Automatisierungsschnittstelle (IDispatch) anbietet. Für den Zugriff auf das Objekt bleibt dann nur noch die späte Bindung, das heißt, die Bindung zur Laufzeit. Das ist beispielsweise der Fall, wenn der Programmierer mit Object-Verweisen hantiert und Automatisierungsobjekte zur Laufzeit via CreateObject instanziiert. Hinter der CallByName-Methode steckt übrigens nichts weiter als ein Aufruf der Invoke-Funktion der IDispatch-Schnittstelle des Automatisierungsobjekts. Die CallByName-Methode ermöglicht es nun, gewissermaßen in letzter Sekunde auf Eigenschaften eines Objekts zuzugreifen, ohne dass diese bei der Kompilierung des Visual-Basic-Programms bekannt waren oder gar existiert haben. Auf diese Weise kann ein Programm mit maximaler Flexibilität vom jeweils aktuellen Dienstangebot des Automatisierungsobjekts profitieren. Beispiel
................................................... Beis piel
Da für das Scripting-Objekt FileSystemObject eine Typbibliothek sowie eine duale Schnittstelle zur Verfügung stehen, kann der Compiler die Methoden des Objekts selbst auflösen. Wer will, kann aber die Methoden auch über die Automatisierungsschnittstelle mit CallByName ansprechen. Die folgenden drei Print-Anweisungen leisten genau dasselbe, sie geben den gesamten Inhalt der Textdatei DateiName aus. (Da ReadAll die gesamte Datei ausliest, müssen immer zwei Print-Anweisungen auskommentiert sein.) Set fs = CreateObject("Scripting.FileSystemObject") ' Print fs.OpenTextfile(Dateiname).ReadAll ' Datei en bloc ausgeben ' Print CallByName(fs, "OpenTextFile", VbMethod, Dateiname).ReadAll Print CallByName(CallByName(fs, "OpenTextFile", VbMethod, Dateiname), _ "ReadAll", VbMethod) Verwandte Methoden
................................................... Verwa ndte Metho den CreateObject, GetObject
269
Global- Objekt
Die globale CallByName-Methode ermöglicht den Zugriff auf eine Funktion (Eigenschaft oder Methode) eines zur Laufzeit gebundenen Automatisierungsobjekts Object. Zur Spezifikation der Funktion ist ihr Bezeichner als Zeichenfolge ProcName anzugeben. Der Parameter CallType legt fest, ob die Funktion als Get, Set oder Let Property deklariert ist oder als gewöhnliche Methode. Der Aufzählungstyp VbCallType definiert dafür die Konstanten: vbMethod (1), vbGet (2), vbLet (4), vbSet (8). Etwaige Argumente für den Aufruf lassen sich über den Args-Parameter in Form eines Variant-Arrays oder als schlichte Parameterliste übergeben.
Global- Objekt
Clipboard- Objekt Public Clipboard As Clipboard Beschreibung
Global- Objekt
................................................... Bes c hreibung
Das Clipboard-Objekt vermittelt den Zugriff auf die von allen Anwendungen gemeinsam für den Datenaustausch genutzte Zwischenablage des Systems. Es gehört der in der Bibliothek VB definierten gleichnamigen Klasse an und wird von Visual Basic in jeder Anwendung automatisch als globales Objekt vereinbart. Das Objekt besitzt zwei voneinander unabhängige Puffer, von denen der eine für den Transport von Zeichenfolgen als Text, Text im RTF-Format oder DDE-Nachrichten für OLE-Objekte gedacht ist, während der andere die Übermittlung von Daten unterschiedlichen Formats (Grafiken oder Dateien) ermöglicht. Eine zusätzliche Formatinformation gibt Aufschluss über die Art der in den Puffern enthaltenen Daten. Methoden
................................................... Metho den Function Clipboard.Clear() Function Clipboard.GetData( _ Format As ClipBoardConstants) As IPictureDisp Function Clipboard.GetFormat( _ Format As ClipBoardConstants) As Boolean Function Clipboard.GetText( _ [Format As ClipBoardConstants = vbCFText]) As String Sub Clipboard.SetData(Picture As IPictureDisp, _ [Format As ClipBoardConstants]) Sub Clipboard.SetText(Str As String, _ [Format As ClipBoardConstants = vbCFText]) Die sechs Methoden des Clipboard-Objekts ermöglichen Zugriffe und Manipulationen der Zwischenablage (das heißt: der Pufferinhalte sowie der Formatinformationen). Die folgende Tabelle gibt einen Überblick über die Aufgaben der einzelnen Methoden: Methode
Beschreibung
Clear
Löscht alle Inhalte der Zwischenablage
GetData
Liefert Grafikdaten aus der Zwischenablage
GetFormat
Testet, ob die Zwischenablage Daten eines bestimmten Formats enthält, und liefert True, wenn die Daten in der Zwischenablage das im Parameter bezeichnete Format tragen, ansonsten False
GetText
Liefert Text (als Zeichenfolge) aus der Zwischenablage
SetData
Überträgt Grafikdaten und Formatbeschreibung in die Zwischenablage
SetText
Überträgt Text (als Zeichenfolge) in die Zwischenablage
Die folgende Tabelle gibt einen Überblick über die in Visual Basic für das Clipboard-Objekt definierten Formatkonstanten:
27 0
Clipboard- Objekt
Wert
Beschreibung
vbCFLink
&HFFFFBF00
Zwischenablage enthält Informationen für DDE-Verbindung
vbCFRTF
&HFFFFBF01
Zwischenablage enthält eine RTF-Datei (Rich Text Format)
vbCFText
1
Zwischenablage enthält TXT-Datei (ASCII-Text)
vbCFBitmap
2
Zwischenablage enthält eine Grafik vom Typ BMP (Bitmap)
vbCFMetafile
3
Zwischenablage enthält eine Grafik vom Typ WMF (Windows Metafile = Windows-Zwischendatei)
vbCFDIB
8
Zwischenablage enthält eine Grafik vom Typ DIB (geräteunabhängige Bitmap)
vbCFPalette
9
Zwischenablage enthält eine Farbpalette
vbCFEMetafile
14
Zwischenablage enthält eine Grafik vom Typ EMF (Enhanced Windows Metafile = erweiterte WindowsZwischendatei)
vbCFFiles
15
Zwischenablage enthält eine Dateiliste des Windows Explorers (wird vom Clipboard-Objekt zwar als Format angezeigt, jedoch nicht weiter unterstützt)
Anwendung
................................................... Anwendung
Über den Einsatz der Methode Clear muss man nicht viele Worte verlieren: Sie sollte immer dann zum Aufruf kommen, wenn der Inhalt der Zwischenablage nicht mehr vonnöten ist. Sie sorgt für die Freigabe der von dem Objekt belegten Ressourcen (die im Falle von Grafiken beträchtlich sein können). Die mit dem Ergebnistyp Boolean sicherlich etwas ungeschickt implementierte Methode GetFormat testet, ob die Daten in der Zwischenablage ein bestimmtes Format tragen. Nachdem die Zwischenablage allen Anwendungen gleichermaßen zur Verfügung steht, ist eine solche Prüfung in der Praxis unerlässlich, um Laufzeitfehlern aufgrund falscher Datenformate vorzubeugen. Die Methoden GetText und SetText dienen dem Transport von Daten im einfachen Textformat (TXT; Voreinstellung bei fehlendem Parameter Format), im Rich Text Format (RTF) sowie von Informationen, die im Zusammenhang mit DDE-Verbindungen übertragen werden. Der Imund Export von Text ist auf den Datentyp String ausgerichtet. Die Methoden GetData und SetData dienen dem Transport von Grafiken und binären Daten, die in verschiedenen Formaten vorliegen können. Der Im- und Export von Bitmaps ist auf den Datentyp Picture ausgerichtet und die Anzeige erfordert ein Steuerelement mit Picture-Eigenschaft. Bei dem im Prototyp der beiden Methoden genannten Datentyp IPictureDisp handelt es sich um die Automatisierungsschnittstelle des Picture-Objekts. Er stimmt in Visual Basic mit dem Datentyp Picture überein (diesen Typ liefert die TypeName-Funktion auch als Ergebnistyp der Methode GetData). Tipp
................................................... Tipp
Das Clipboard-Objekt lässt sich auch für die Übermittlung anderer auf dem System registrierter Datenformate heranziehen. Analoges dazu finden Sie im Abschnitt »OLEStartDrag-Ereignis« (S. 250). Allerdings unterstützt das Clipboard-Objekt von Visual Basic nicht alle Operationen
27 1
Global- Objekt
Formatkonstante
Global- Objekt
der OLE-Zwischenablage. So zeigt es zwar an, wenn in der Zwischenablage Dateien enthalten sind (vbCFFiles), es besitzt aber keine Methoden für den Austausch, da es (im Gegensatz zu einem DataObject-Objekt) keine Files-Eigenschaft verfügbar macht. Eine in der Zwischenablage befindliche Datei lässt sich aber in ein RTF-Steuerelement sowie in ein OLE-ContainerSteuerelement als Inhalt einfügen. Beispiel
Global- Objekt
................................................... Beis piel
Das folgende für seinen Funktionsumfang wirklich kurz geratene Projekt ZwischenAblage demonstriert recht eindrucksvoll den unkomplizierten Einsatz der Zwischenablage. Das Formular enthält ein RTF-Steuerelement (RICHTX32.OCX) namens RichTextBox, ein BildausschnittSteuerelement (PICCLP32.OCX) namens PicClip1, ein Bildfeld-Steuerelement (PictureBox) namens Picture1 sowie ein Menü mit den beiden Befehlen EINFÜGEN und KOPIEREN. Importiert man Text oder Text mit RTF-Format über die Zwischenablage in das Programm, macht der Befehl EINFÜGEN diesen im RTF-Steuerelement sichtbar. (Da RTF-Steuerelemente aber auch von sich aus mit der Zwischenablage des Systems interagieren, wenn sie den Fokus haben, ist eine explizite Implementation der Zwischenablagenfunktionen eher unnötig – zumal der Funktionsumfang des Clipboard-Objekts in Visual Basic Einschränkungen aufweist.) Importiert man in das Programm dagegen eine Grafik (beispielsweise einen mittels der Taste (Druck) erstellten Bildschirmabschuss), macht der Befehl EINFÜGEN diese im Bildfeld sichtbar. Der Befehl KOPIEREN ist dagegen so implementiert, dass er nur einen Ausschnitt des im Bildausschnitt-Steuerelement gespeicherten Bildes, nämlich 100×100 Bildpunkte von links oben gesehen, in die Zwischenablage überträgt. (Falls das Bild keine 100×100 Bildpunkte hat, wird auf ein Viertel verkleinert.) EINFÜGEN bringt das Ergebnis dieser Operation zutage. Private Sub mnuEinfügen_Click() If Clipboard.GetFormat(vbCFText) Then ' Text? RichTextBox1.Text = Clipboard.GetText End If If Clipboard.GetFormat(vbCFRTF) Then ' RTF-Text? RichTextBox1.TextRTF = Clipboard.GetText(vbCFRTF) End If If Clipboard.GetFormat(vbCFDIB) Then ' Grafik? PicClip1.Picture = Clipboard.GetData(vbCFDIB) Picture1 = PicClip1.Picture End If End Sub Private Sub mnuKopieren_Click() If PicClip1.Picture Then ' Bild zugewiesen? PicClip1.ClipHeight = 100 ' Bildausschnitt definieren PicClip1.ClipWidth = 100 Clipboard.SetData PicClip1.Clip, vbCFDIB ' In Zwischenablage End If End Sub Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
27 2
Command- Methode
Command- Methode Public Command As String Beschreibung
................................................... Bes c hreibung
Die globale Command-Methode liefert die beim Aufruf der Anwendung angegebenen Kommandozeilenparameter als Zeichenfolge. Anwendung
................................................... Anwendung
MeinProgramm.exe Param1 Param2 Param3
Falls das Programm nicht kompiliert ist, lautet der Aufruf für Visual Basic 6.0, der den sofortigen Start der Anwendung bewirkt und Kommandozeilenparameter bereitstellt, so: Vb6 projekt1 /run /cmd Param1 Param2 Param3
Wenn Verzeichnisse für Vb6.Exe und Projekt1.vbp nicht zum Suchpfad von Windows gehören (vgl. Umgebungsvariable PATH), müssen Sie natürlich die entsprechenden Pfade angeben: "C:\Programme\Microsoft Visual Studio\VB98\Vb6" (fortgesetzt) "Vb60 Programme\Projekt1" /run /cmd Param1 Param2 Param3
In jedem der genannten Fälle liefert die Command-Methode als Wert die Zeichenfolge: "Param1 Param2 Param3"
CreateObject- Methode Function CreateObject(Class As String, [ServerName As String]) As Object Beschreibung
................................................... Bes c hreibung
Die CreateObject-Methode generiert eine neue Instanz des ActiveX-Objekts Class für die Automatisierung und liefert einen Verweis vom Typ Object darauf zurück. Läuft die für das Objekt zuständige Serveranwendung zum Zeitpunkt des Aufrufs noch nicht, startet die Methode den Server. Um das Objekt (via DCOM) auf einem bestimmten Server im Netzwerk auszuführen, ist dessen Name optional über den Parameter ServerName zu spezifizieren. Anwendung
................................................... Anwendung
Visual Basic kann mittels CreateObject eine Bindung zur Laufzeit mit allen COM-Objekten herstellen, die über eine Automatisierungsschnittstelle verfügen – und daher Automatisierungsobjekte genannt werden. Diese Schnittstelle stellt einen standardisierten Mechanismus dar, der es einer Host-Anwendung (lies: einem Visual-Basic-Programm) ermöglicht, auf eigens für die Automatisierung exponierte Methoden und Eigenschaften des Objekts zuzugreifen, wobei die Bindung erst zur Laufzeit erfolgt. Man spricht dann von später Bindung. Späte Bindung hat den Vorteil, dass zur Übersetzungszeit außer den Bezeichnern für das Objekt, seine Methoden und Eigenschaften nichts weiter über das Objekt bekannt sein muss – alle Informationen lassen sich zur Laufzeit ermitteln. Der Nachteil ist allerdings, dass sie einiges an Laufzeit verschlingt. Dim fs As Object Set fs = CreateObject("Scripting.FileSystemObject")
27 3
Global- Objekt
Seit Windows sind die Kommandozeile sowie die darin übergebenen Aufrufparameter zunehmend in den Hintergrund geraten. Von einer MS-DOS-Kommandozeile aus oder über den Befehl AUSFÜHREN im START-Menü von Windows können Sie eine als EXE-Datei vorliegende Anwendung aber jederzeit unter Angabe zusätzlicher Kommandozeilenparameter, Schalter etc. aufrufen. Die Kommandozeile lautet:
Global- Objekt
Global- Objekt
Die meisten Automatisierungsobjekte besitzen aber eine duale Schnittstelle und ermöglichen so auch eine Anbindung über die für die Klasse definierte Standardschnittstelle. Für diese Art der Bindung, die bereits zur Übersetzungszeit (bis auf einen einzigen Verweis auf eine zentrale Zeigertabelle) vollständig vorbereitet werden kann und somit als frühe Bindung bezeichnet wird, muss dem Compiler allerdings die gesamte Objektdeklaration in Form einer Objektbibliothek (OLB) vorliegen. Um dem Compiler eine bestimmte Objektbibliothek zugänglich zu machen, rufen Sie das Dialogfeld VERWEISE über das Menü PROJEKT/VERWEISE auf und setzen ein Häkchen vor den gewünschten Objekttyp. Für das Objekt Scripting.FileSystemObject wäre das die Bibliothek Microsoft Scripting Runtime. Über den Aufbau des Scripting-Moduls, also die darin definierten Konstanten, Eigenschaften und Methoden, sowie die Objektstruktur der Eigenschaften, also wiederum deren Konstanten, Eigenschaften und Methoden etc., können Sie sich dann im Objektkatalog (aufzurufen über ANSICHT/OBJEKTKATALOG) bis in alle Einzelheiten informieren.
Zum Scripting-Modul gehörige Objektbibliothek Bei Verwendung der frühen Bindung deklarieren Sie die Objektvariable wie gewohnt unter Angabe eines konkreten Datentyps: Dim fs As New Scripting.FileSystemObject
Vielfach spielt die Ausführungsgeschwindigkeit aber keine so große Rolle, so dass der geringere Overhead sowie die große Flexibilität, die CreateObject ermöglicht, nicht zu übersehende Vorteile bietet. Visual Basic ermöglicht es auch, eigene ActiveX-Server zu implementieren, um anderen Anwendungen Automatisierungsobjekte zur Verfügung zu stellen. Hierfür gibt es die speziellen Projekttypen »ActiveX-DLL« und »ActiveX-EXE«. Beispiel
................................................... Beis piel
Der folgende Code gibt den Inhalt einer Textdatei unter Verwendung des FileSystemObjectObjekts en bloc aus.
27 4
DeleteSetting- Methode
Dim fs As Object Set fs = CreateObject("Scripting.FileSystemObject") Print fs.OpenTextfile(DateiName).ReadAll ' Datei en bloc ausgeben Verwandte Methoden
................................................... Verwa ndte Metho den CallByName, GetObject
DeleteSetting- Methode Beschreibung
................................................... Bes c hreibung
Die Methode DeleteSetting ermöglicht es, persistente Einstellungen eines Programms aus der Systemregistrierung wieder zu entfernen, die mittels der SaveSetting-Methode als Unterschlüssel des Schlüssels HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ gespeichert wurden. Es gilt: AppName ist Unterschlüssel von "VB and VBA Program Settings" und steht für den Programmnamen, Section ist Unterschlüssel von AppName und steht für den Abschnitt und Key ist Bezeichner eines Werts in Section. Falls der zu löschende Schlüssel, Unterschlüssel oder Wert nicht existiert, löst die Methode den Laufzeitfehler 5 »Ungültiger Prozeduraufruf oder ungültiges Argument« aus. Anwendung
................................................... Anwendung
Früher mussten Windows-Anwendungen ihre persistenten Einstellungen noch in je eigenen INIDateien ablegen. Spätestens seit Windows 95 (aber auch schon zuvor) gibt es eine Systemregistrierung, in der sich solche Daten an zentraler Stelle speichern lassen. Für den Zugriff auf die Systemregistrierung von Visual Basic aus stehen im Wesentlichen vier Methoden zur Verfügung: GetSetting, GetAllSettings, SaveSetting und DeleteSetting, deren Funktion bereits durch die Bezeichner deutlich wird. Um auf andere Schlüssel zuzugreifen, müssen Sie die entsprechenden Funktionen der Win32-API (RegDeleteKey, RegDeleteValue etc.) benutzen. Beispiel
................................................... Beis piel
On Error Resume Next ' Fehler ignorieren DeleteSetting "MeineAnwendung" ' Alle Einträge des Programms entfernen DeleteSetting "MeineAnwendung1", "Metrik" ' Abschnitt entfernen On Error Goto 0' Verwandte Methoden
................................................... Verwa ndte Metho den GetSetting, GetAllSettings, SaveSetting Verwandte Themen
................................................... Verwandte Them en
Registrierung (S. 561)
27 5
Global- Objekt
Sub DeleteSetting(AppName As String, [Section As String], _ [Key As String])
Global- Objekt
DoEvents- Methode Sub DoEvents() Beschreibung
................................................... Bes c hreibung
Die DoEvents-Methode unterbricht die Ausführung der aktuellen Routine temporär, um die Behandlung gegebenenfalls anstehender Ereignisse zu ermöglichen, und setzt die Routine danach wieder fort. Die Methode lässt sich als Prozedur und als Funktion verwenden. Als Funktion aufgerufen, liefert sie die Anzahl der geöffneten Formulare.
Global- Objekt
Anwendung
................................................... Anwendung
Die DoEvents-Methode ist in Programmen mit nur einem einzigen Ausführungspfad (Thread) ein wichtiges Mittel, um die Reaktivität der Benutzerschnittstelle auch im Verlauf länger andauernder Operationen aufrechtzuerhalten. Da die in der Ereigniswarteschlange bereitstehenden Ereignisse immer nacheinander abgearbeitet werden, kann eine zeitintensive Routine die Behandlung anderer wartender Ereignisse spürbar (wenn nicht gar ewig) verzögern, was der Benutzer als »zähe Reaktion« auf seine Aktivitäten zu spüren bekommt. Damit zeitaufwändige Routinen quasi im Hintergrund ablaufen, fügen Sie an passender Stelle (nicht zu häufig, nicht zu selten; eine Faustregel ist: ca. jede Zehntelsekunde auf einem durchschnittlichen System) einen DoEvents-Aufruf ein. Tipp
................................................... Tipp
In manchen Fällen lassen sich längere Wartezeiten für den Benutzer nicht vermeiden. Um ihm aber dennoch das Gefühl zu geben, dass etwas passiert, können Sie eine Fortschrittsleiste anzeigen oder zumindest die Mauszeigerform auf »Sanduhr« umschalten. Warnung
................................................... Wa rnung
Wenn eine durch DoEvents unterbrochene Routine erneut aufgerufen wird, kommt es zur Rekursion. Rekursion an sich bereitet keine Probleme, solange Sie bei der Programmierung darauf achten, dass keine statischen oder globalen Variablen im Spiel sind. Wird die Rekursion jedoch zu tief, kommt es zum Laufzeitfehler »Stapelüberlauf«. Ein weiteres Problem im Zusammenhang mit DoEvents sind die so genannten »Stehaufmännchen«, die auftreten können, wenn Unload innerhalb einer DoEvents-Unterbrechung zur Ausführung kommt. In diesem Fall wird Visual Basic das Formularobjekt beim nächsten Zugriff auf eine Eigenschaft oder Methode automatisch erneut laden, und das ganze Spiel beginnt von vorne. Schlimmer noch: wenn das einmal passiert ist, lässt sich das Formular nicht mehr beenden, weil jeder Versuch es zu beenden eine neue Instanz hervorzaubert, selbst wenn keine DoEvents-Unterbrechung mehr vorliegt. (Wenn Sie es ausprobieren, müssen Sie das Programm über das Entwicklungssystem beenden.) Sie umgehen das Problem, indem Sie den von DoEvents gelieferten Funktionswert auswerten. Dieser ist nämlich 0, wenn der Benutzer inzwischen das Formular geschlossen hat, ansonsten ungleich 0 (detailliertere Informationen dazu entnehmen Sie dem Abschnitt »ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge«, S. 478 im Praxisteil). Beispiel
................................................... Beis piel
Die folgende Routine ist eine Variante des »Apfelmännchens«, die mit regelmäßigen DoEventsAufrufen während der Bildberechnung die Benutzerschnittstelle am »Leben« erhält. Private Sub Apfel(m_x1, m_x2, m_y1, m_y2, step_x, step_y) Dim r1 As Double, re As Double, im As Double Dim zr As Double, zi As Double, it As Integer
27 6
Err- Objekt
Global- Objekt
For zr = m_x1 To m_x2 Step step_x ' alle Spalten in x-Richtung For zi = m_y1 To m_y2 Step step_y ' alle Punkte in Spalte zr re = 0 ' Realteil initialisieren im = 0 ' Imaginärteil initialisieren For it = 0 To cMaxIterat ' Iteration für Punkt r1 = re * re – im * im + zr im = 2 * re * im + zi re = r1 If re < -cGrenze Or re > cGrenze Or _ im < -cGrenze Or im > cGrenze Then PSet (zr, zi), it * 16 ' Punkt ausgeben Exit For End If Next it Next zi if DoEvents = 0 Then Exit Sub Next zr End Sub
Err- Objekt Public Err As ErrObject Beschreibung
................................................... Bes c hreibung
Für den Umgang mit Laufzeitfehlern besitzt Visual Basic ein altes und eine neues Informationskonzept. Für das alte steht die Error-Anweisung, für das neue das Err-Objekt. Das von Visual Basic in jeder Anwendung automatisch als globales Objekt vereinbarte Err-Objekt gehört der Klasse ErrObject aus der Bibliothek VBA an. Seine Aufgabe besteht darin, Laufzeitfehler zu signalisieren und spezifische Fehlerinformationen für deren Behandlung bereitzustellen. Eigenschaften
................................................... Eigens c ha ften Das Err-Objekt verfügt über eine Reihe von Eigenschaften für die nähere Spezifikation eines Fehlers und dessen Behebung. Die folgende Tabelle gibt einen Überblick über alle Eigenschaften des Objekts: Eigenschaft
Beschreibung
Description
Zeichenfolge mit dem aktuellen Fehlertext
HelpContext
Zeichenfolge mit der Kontextkennung für das aktuelle Hilfethema in Hilfedatei. Wenn leer, wird die Kontextkennung über den Wert von Number ermittelt.
HelpFile
Zeichenfolge mit dem Zugriffspfad für die Hilfedatei. Wenn leer, wird die Visual-Basic-Hilfedatei benutzt.
LastDllError
zur Laufzeit schreibgeschützter Long-Wert, der den Rückgabewert der zuletzt aufgerufenen DLL-Routine übermittelt. Die Bedeutung des Rückgabewerts ist der Dokumentation der entsprechenden Funktion zu entnehmen (vgl. »Routinen aus DLLs und der Windows-API einsetzen«, S. 185).
Number
Wert vom Typ Long mit der aktuellen Fehlernummer
27 7
Global- Objekt
Eigenschaft
Beschreibung
Source
Zeichenfolge mit dem Klassennamen des den Fehler signalisierenden Objekts (gegebenenfalls Objekt-ID) oder dem Namen des Programmmoduls; hilfreich, wenn keine modulinterne Behandlung des Fehlers erfolgt
Ein explizites Setzen der Eigenschaften erübrigt sich, da alle Eigenschaften im Zuge des RaiseAufrufs mit einem Wert versorgt werden können.
Global- Objekt
Methoden
................................................... Metho den Sub Err.Clear () Sub Err.Raise(Number, _ [Source], [Description], [HelpFile], [HelpContext]) Die Methode Clear ermöglicht es, das Err-Objekt in den Grundzustand zurück zu versetzen. Das ist beispielsweise im Zusammenhang mit der Anweisung On Error Resume Next erforderlich, wenn eine Inline-Fehlerbehandlung unmittelbar im Anschluss an eine Anweisung erfolgt. Die Methode Raise löst einen Laufzeitfehler mit der Nummer Number aus. Die benannten Parameter der Methode setzen die gleichnamigen Eigenschaften des Objekts. Der Wertebereich für Visual-Basic-Fehler liegt zwischen 0 und 65.535, wobei der Bereich zwischen 0 und 512 für Systemfehler reserviert ist, so dass für benutzerdefinierte Fehler der Bereich zwischen 513 und 65.535 übrig bleibt. In Klassenmodulen arbeitet man mit Fehlernummern, die den Offset vbObjectError haben. Anwendung
................................................... Anwendung
Das Err-Objekt stellt gegenüber dem traditionellen Fehlermechanismus von Visual Basic eine Verfeinerung dar, weil es eine bessere Kontrolle über den Kontext eines Fehlers bietet. Am Fehlerbehandlungsmechanismus von Visual Basic ändert das Err-Objekt jedoch nichts (Einzelheiten dazu im Abschnitt »Fehlerbehandlung«, S. 43). Mit Ausnahme der Eigenschaft LastDllError, die nur im Zusammenhang mit Aufrufen der Win32-API eine Bedeutung hat, lassen sich die Eigenschaften des Fehlerobjekts an beliebiger Stelle in einer Funktion/Prozedur setzen. Im Allgemeinen wird man die Werte für die diese Eigenschaften bei einem Raise-Aufruf bereitstellen. Beachten Sie aber, dass die Anweisungen Exit Function, Exit Sub, Exit Property sowie Resume Next implizit einen Clear-Aufruf des Err-Objekts veranlassen, so dass die Eigenschaften jedes Mal neu gesetzt werden müssen. Tipp
................................................... Tipp
Die Fehlerbehandlung sollte bei der Entwicklung eines Programms von Anfang an einen sehr hohen Stellenwert haben. Testen Sie Ihre Fehlerroutinen ausgiebig auf alle Spezialfälle und schließen Sie aus, dass eine Fehlerbehandlungsroutine in die Verlegenheit kommt, Fehler zu behandeln, für die sie nicht ausgelegt ist. Beispiel
................................................... Beis piel
Vgl. das Beispiel zu dem Thema »Fehlerbehandlung« (S. 43) Verwandte Themen
................................................... Verwandte Them en
Fehlerbehandlung (S. 43)
27 8
Forms- Auflistung
Forms- Auflistung Forms As Object Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Sie können die Auflistung Forms mit einem For Each-Konstrukt durchlaufen, um festzustellen, welche Formulare es gibt, oder um beispielsweise den Anwendungsfokus an ein bestimmtes Formular weiterzureichen. Als Datentyp für die Laufvariable vereinbaren Sie Object oder besser Form. Beispiel
................................................... Beis piel
Dim Formular As Form For Each Formular In Forms Print Formular.Caption Next Verwandte Themen
................................................... Verwandte Them en
Auflistungen und Collection-Objekte (S. 304)
GetAllSettings- Methode Function GetAllSettings(AppName As String, Section As String) _ As String()() Beschreibung
................................................... Bes c hreibung
Die Methode GetAllSettings ermöglicht die Abfrage aller zum Abschnitt (Unterschlüssel) Section gehörigen persistenten Einstellungen eines Programms AppName, die mittels der SaveSetting-Methode als Unterschlüssel des Schlüssels HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ gespeichert wurden. Die Methode liefert ihr Ergebnis in einem zweidimensionalen Zeichenfolgenarray mit nullbasiertem Index, wobei in der ersten Dimension die Bezeichner der Werte und in der zweiten Dimension die Daten zu den Werten enthalten sind. Falls ein Schüssel nicht existiert oder keine Werte enthält, liefert die Methode den Wert Empty. Anwendung
................................................... Anwendung
Früher mussten Windows-Anwendungen ihre persistenten Einstellungen noch in je eigenen INIDateien ablegen. Spätestens seit Windows 95 (aber auch schon zuvor) gibt es eine zentrale Systemregistrierung, in der sich solche Daten an zentraler Stelle speichern lassen. Für den Zugriff auf die Systemregistrierung von Visual Basic aus stehen im Wesentlichen vier Methoden zur
27 9
Global- Objekt
Die nicht mit dem Datentyp Collection kompatible Forms-Auflistung enthält eine Liste der aktuell von der Anwendung instanziierten Formularobjekte – gewöhnliche Formulare, MDIFormulare, MDI-Formularen untergeordnete Formulare. Elementtyp ist der Klassenname (Formularname) der jeweiligen Instanz. Einzige Eigenschaft der Auflistung ist Count, über die sich die Anzahl Listenelemente in Erfahrung bringen lässt. Um die Pflege der Auflistung kümmert sich das Laufzeitsystem (im Rahmen von Load), so dass sie jederzeit auf dem neuesten Stand ist.
Global- Objekt
Verfügung: GetSetting, GetAllSettings, SaveSetting und DeleteSetting, deren Funktion bereits durch die Bezeichner deutlich wird. Um auf andere Schlüssel zuzugreifen, müssen Sie die entsprechenden Funktionen der Win32-API (RegOpenKeyEx etc.) benutzen. Beispiel
................................................... Beis piel
Global- Objekt
Der folgende Code fügt vier Werte unter dem Schlüssel »Abschnitt« in die Registrierung ein. Danach liest er sie wieder mittels GetAllSettings, gibt sie aus und löscht sie schließlich en bloc. Dim a, i SaveSetting "MeineAnwendung", "Abschnitt", "Wert", 10 SaveSetting "MeineAnwendung", "Abschnitt", "Wert1", 20 SaveSetting "MeineAnwendung", "Abschnitt", "Höhe", 100 SaveSetting "MeineAnwendung", "Abschnitt", "Breite", 100 a = GetAllSettings("MeineAnwendung", "Abschnitt") If not IsEmpty(a) Then For i = 0 To UBound(a) Print a(i, 0) & " = " & a(i, 1) Next i End If DeleteSetting "MeineAnwendung" Verwandte Methoden
................................................... Verwa ndte Metho den DeleteSetting, GetSetting, SaveSetting Verwandte Themen
................................................... Verwandte Them en
Registrierung (S. 561)
GetObject- Methode Function GetObject([PathName As String], _ [AnwName.ObjektTyp As String]) As Object Beschreibung
................................................... Bes c hreibung
Die GetObject-Methode liefert die Referenz auf ein ActiveX-Objekt (Automatisierungsobjekt) mit registrierter Klasse. Existiert das Objekt bereits als Datei, lässt es sich unter Angabe des entsprechenden Dateinamens (PathName) öffnen, was dazu führt, dass die für das Objekt zuständige (lies: für den Objekttyp registrierte) Serveranwendung automatisch gestartet wird. Optional lässt sich über den zweiten String-Parameter die Klasse des zu aktivierenden Objekts noch genauer spezifizieren, falls in der Datei mehrere Objekte enthalten sind. Ist Pathname die leere Zeichenfolge, muss der zweite Parameter in jedem Fall angegeben sein, da die Methode dann eine Referenz auf ein neues Objekt dieser Klasse liefert. Beispiel
................................................... Beis piel
Der folgende Code organisiert eine Referenz auf ein Word-Dokument sowie auf eine CorelDRAW-Zeichnung: Dim Wdoc As Object, CorelDoc As Object Set Wdoc = GetObject("\Eigene Dateien\Basic.doc") Set Wdoc = GetObject("Zeichnung.cdr", "CorelDRAW.Graphic.7")
280
GetSetting- Methode
Einige Anwendungen ermöglichen es auch, einzelne Eigenschaften eines gegebenen Objekts zu aktivieren. Der Name der Eigenschaft wird dann durch ein Ausrufezeichen abgetrennt hinten angefügt.
GetSetting- Methode Function GetSetting(AppName As String, Section As String, _ Key As String, [Default]) As String Beschreibung
................................................... Bes c hreibung
Beispiel
................................................... Beis piel
Print GetSetting ("MeineAnwendung", "Abmessungen", "Breite", 100) Verwandte Methoden
................................................... Verwa ndte Metho den DeleteSetting, GetAllSettings, SaveSetting Verwandte Themen
................................................... Verwandte Them en
Registrierung (S. 561)
InputBox- Methode Function InputBox(Prompt, [Title], [Default], [XPos, YPos], _ [HelpFile], [Context]) As String Beschreibung
................................................... Bes c hreibung
Die Methode InputBox ruft ein Dialogfeld mit den Schaltflächen OK und ABBRECHEN auf, in dessen Client-Bereich die Eingabeaufforderung Prompt sowie ein einzeiliges Textfeld für die Werteingabe erscheinen. Als Ergebnis liefert Sie den Wert des Textfeldes als Zeichenfolge. Standardmäßige Beschriftung des Dialogfelds ist der Name der Anwendung, sie lässt sich aber über den optionalen Parameter Title frei gestalten. Ist ein Wert für Default angegeben, erscheint dieser markiert als Vorgabewert im Textfeld des Dialogs. Bricht der Benutzer den Dialog ab, resultiert die leere Zeichenfolge, unabhängig von der Existenz eines Vorgabewerts. Über XPos und YPos kann die Position des Dialogfelds relativ zum linken oberen Punkt der Bildschirmanzeige (Screen) gesetzt werden. Fehlen diese Parameter, setzt Windows das Dialogfeld leicht nach oben verschoben in die Mitte des Bildschirms. Darüber hinaus lassen sich optional ein Hilfethema HelpFile sowie eine zuständige Hilfedatei Context angeben. Anwendung
................................................... Anwendung
Obwohl der Anwendungsbereich der Methode vom Prinzip her den gesamten Bereich der zeilenorientierten Benutzereingabe abdeckt, wird sie eigentlich nur in Situationen eingesetzt, wo sich der Entwurf eines eigenen Dialogfelds nicht lohnt – so in provisorischen Programmentwürfen oder wenn bei der Reaktion auf einen Fehler interaktive Eingaben erforderlich sind.
281
Global- Objekt
Die GetSetting-Methode entspricht von der Funktionalität her der GetAllSettings-Methode, mit dem Unterschied, dass sie nur die Daten zu einem bestimmten Wert Key des Abschnitts (Unterschlüssels) Section liefert. Als Vorgabe für den Fall, dass der Eintrag Key nicht existiert, kann der optionale Parameter Default angegeben werden.
Global- Objekt
Beispiel
................................................... Beis piel
Do a = InputBox("Bitte eine Zahl zwischen 10 und 100 eingeben", _ "Bereich einstellen") Loop Until IsNumeric(a) And Val(a) = 10 Verwandte Methoden
................................................... Verwa ndte Metho den
Global- Objekt
MsgBox
Load- Methode Function Load(Object As Object) Beschreibung
................................................... Bes c hreibung
Die Load-Methode lädt das Objekt Object in den Hautspeicher und initialisiert es, ohne es anzuzeigen. Das Objekt kann ein Formular, ein MDI-Formular oder ein Steuerelement sein. Anwendung
................................................... Anwendung
Normalerweise ist es unnötig, ein Formular oder ein zur Entwurfszeit eingefügtes Steuerelement explizit zu laden, denn jeder Verweis auf das Formular (mit Ausnahme von TypeOf- und SetKonstrukten) veranlasst Visual Basic dazu, dieses samt aller ihm untergeordneten Steuerelemente implizit zu laden. Für ein Formular, das nicht Startobjekt des Projekts ist und somit zum Programmstart auch nicht automatisch geladen wird, genügt ein Show-Aufruf, um es zu laden und anzeigen. Die explizite Verwendung von Load vor Show kann aber den Vorteil haben, dass das Objekt dann, wenn es benötigt wird, bereits geladen ist und nur noch die Visible-Eigenschaft mittels Show oder explizit zu setzen ist, um es ohne weitere Wartezeiten anzuzeigen. Explizit ist der Load-Aufruf eigentlich nur erforderlich, wenn Sie mit einem SteuerelementeArray arbeiten und in dieses zur Laufzeit eine neue Instanz des Steuerelements einfügen wollen. Visual Basic erweitert das Array dann automatisch, initialisiert die Visible-Eigenschaft jedoch mit False, so dass Sie diese Eigenschaft extra auf True setzen müssen, damit das neue Steuerelement sichtbar wird. Tipp
................................................... Tipp
Um Ressourcen zu sparen, können Sie selten benötigte Formulare oder monströse Steuerelemente mittels Unload umgehend nach Gebrauch wieder entladen. Das erneute Laden erfolgt dann implizit mit dem nächsten Show-Aufruf. Diese Technik führt dazu, dass auch alle Steuerelemente auf dem Formular neu initialisiert werden – ein Vorgang, der natürlich auf Kosten der Laufzeit geht. Beispiel
................................................... Beis piel
Load Form1 Verwandte Befehle
................................................... Verwa ndte Befehle
Unload, Show Verwandte Themen
................................................... Verwandte Them en
Schach – klare Sicht auf Hintergründliches (S. 607)
282
LoadPicture- Methode
LoadPicture- Methode Function LoadPicture([FileName As String], _ [Size As LoadPictureSizeConstants], _ [ColorDepth As LoadPictureColorConstants], _ [X], [Y]) _ As Picture Beschreibung
................................................... Bes c hreibung
Konstante
Beschreibung
vbLPSmall (0)
Kleines Systemsymbol (Voreinstellung)
vbLPLarge (1)
Großes Systemsymbol
vbLPSmallShell (2)
Größe von »Titelleistensymbol«, wie im Systemdialog EIGENANZEIGE auf der Registerkarte DARSTELLUNG festgelegt SCHAFTEN VON
vbLPLargeShell (3)
Größe von Symbol, wie im Systemdialog EIGENSCHAFTEN ANZEIGE auf der Registerkarte DARSTELLUNG festgelegt
vbLPCustom (4)
Benutzerdefinierte Größe
VON
Für den optionalen Parameter ColorDepth gibt es drei Werte, für die der Aufzählungstyp LoadPictureColorConstants Konstanten definiert. Konstante
Beschreibung
vbLPDefault (0)
System wählt beste Übereinstimmung mit Anzeige
vbLPMonochrom (1)
Schwarz/Weiß
vbLPVGAColor (2)
16 Grundfarben
vbLPColor (3)
256 Farben
Wird die Methode ohne Parameter aufgerufen, liefert Sie den Wert Empty und kann dafür benutzt werden, die Picture-Eigenschaft eines Steuerelements oder Formulars auf »Kein Bild« zu setzen. Beispiel
................................................... Beis piel
Set Picture = LoadPicture(Dateiname) Set Picture1.Picture = LoadPicture(Dateiname1)
283
Global- Objekt
Die LoadPicture-Methode lädt eine Grafikdatei FileName, die in einem der Formate DIB, BMP, RLE, ICO, CUR, GIF, JPG, WMF oder EMF vorliegt, und liefert eine Referenz vom Typ Picture dafür. Falls die Datei eines der Formate ICO oder CUR trägt, können Sie für den optionalen Parameter Size zwischen verschiedenen Symbolgrößen auswählen (sofern in der Datei verfügbar). Der Aufzählungstyp LoadPictureSizeConstants definiert dafür die folgenden Konstanten:
Global- Objekt
LoadResData- Methode, LoadResPicture- Methode, LoadResString- Methode Function LoadResData(Id, ResType As Integer) As Byte() Function LoadResPicture(Id, ResType As Integer) As Picture Function LoadResString(Id As Long) As String Beschreibung
Global- Objekt
................................................... Bes c hreibung
Die Methoden LoadResData, LoadResPicture und LoadResString ermöglichen das Laden von binären Ressourcen, Bildressourcen oder Zeichenfolgenressourcen aus einer Ressourcendatei (RES). Für den Parameter Id ist die Ressourcenkennung anzugeben, wie im Ressourcen-Editor festgelegt. Die Methoden LoadResData und LoadResPicture erwarten noch einen weiteren Parameter, ResType, der den Typ der zu ladenden Ressource genauer spezifiziert. LoadResPicture akzeptiert für diesen Parameter die drei Werte vbResBitmap (0), vbResIcon (1) vbResCursor (2), während LoadResData den Zugriff auf alle Arten von Ressourcen (also auch auf Zeichenfolgen und Bitmaps) ermöglicht, diese aber in Form eines Byte-Arrays zurückliefert. Der Parameter ResType kann für diese Methode folgende Werte tragen: Wert für ResType
Art der Ressource
1
Cursor
2
Bitmap
3
Symbol
4
Menü
5
Dialogfeld
6
Zeichenfolge
7
Schriftartverzeichnis
8
Schriftart
9
Zugriffstasten (Accelerator)
10
benutzerdefiniert
12
Gruppen-Cursor
14
Gruppensymbol
Printer- Objekt Public Printer As Printer Beschreibung
................................................... Bes c hreibung
Das in jeder Anwendung als globales Objekt bekannte Printer-Objekt entstammt der gleichnamigen in der Bibliothek VB beheimateten Klasse und ermöglicht Druckerausgaben aus einer Anwendung heraus. Bei Start einer Anwendung ist das Printer-Objekt auf den aktuellen Standarddrucker des Systems gesetzt, und seine Eigenschaften spiegeln die dafür in der Systemsteuerung getroffenen Standardeinstellungen wider. Die Eigenschaften des Printer-Objekts lassen sich ohne Auswirkungen für andere Anwendungen individuell ändern. Um die Druckerausgabe gezielt auf einen bestimmten Drucker zu leiten (bzw. über einen bestimmten Druckertreiber auszugeben), kann dem Printer-Objekt jederzeit ein anderes Element aus der Printers-Auflistung zugewiesen werden. In dieser Auflistung sind alle auf dem jeweiligen System installierten Drucker enthalten.
284
Printer- Objekt
Eigenschaften
................................................... Eigens c ha ften Das Printer-Objekt verfügt über eine stattliche Anzahl von Eigenschaften, auf deren Basis der für den jeweiligen Drucker installierte Druckertreiber die Druckausgabe durchführt. Da nicht alle Drucker alle Eigenschaften unterstützen, können einzelne Eigenschaften auch ohne Wirkung bleiben oder verschiedene Einstellungen die gleiche Wirkung haben (insbesondere »Transparenz« kann ein Problem sein). Einstellungen außerhalb der zulässigen Wertebereiche können einen Laufzeitfehler verursachen – müssen aber nicht. Genaue Informationen über die Wirkung der einzelnen Werte bezogen auf eine spezielle Konstellation aus Drucker und Treiber finden Sie in den jeweiligen Herstellerdokumentationen. Beschreibung
ColorMode
Wert vom Typ Integer, der den Farbmodus des Druckers wiedergibt bzw. festlegt. Der Aufzählungstyp PrinterObjectConstants definiert dafür zwei Konstanten: vbPRCMColor (1) – Ausdruck nach Möglichkeit in Farbe; vbPRCMMonochrom (2) – Ausdruck in Graustufen.
Copies
Wert vom Typ Integer, der die Anzahl der Kopien eines Ausdrucks festlegt
CurrentX CurrentY
Werte vom Typ Single, die die aktuelle Position auf der Ausgabefläche für die nächste Zeichenoperation wiedergeben bzw. festlegen. Standardmäßig gilt die Einheit Twips, es sei denn, über die Eigenschaft ScaleMode wurde eine andere Einheit festgelegt.
DeviceName
Schreibgeschützter Wert vom Typ String, der den Gerätenamen des dem Printer-Objekt aktuell zugewiesenen Druckers wiedergibt
DrawMode
Wert vom Typ Integer, der den Zeichenmodus für Zeichenoperationen sowie für das Zeichnen von Figur- und Liniensteuerelementen festlegt. Der Aufzählungstyp DrawModeConstants definiert dafür eine Reihe von Konstanten: Schwarzintensität vbBlackness (1) vbNotMergePen (2)
Stift mischen invers (invers zu 15)
vbMaskNotPen (3)
inversen Stift maskieren; Kombination der Farben, die der Hintergrund mit der invertierten Stiftfarbe gemeinsam hat
vbNotCopyPen (4)
Stift kopieren invers (invers zu 13)
vbMaskPenNot (5)
Stift und inverse Anzeige maskieren; Kombination der Farben, die der Stift mit der invertierten Anzeigefarbe gemeinsam hat
vbInvert (6)
Anzeigefarbe invers
vbXorPen (7)
Stift Xor; Kombination der Farben, die im Stift und in der Anzeigefarbe, aber nicht in beiden vorhanden sind
vbNotMaskPen (8)
Stift maskieren invers (invers zu 9)
vbMaskPen (9)
Stift maskieren; Kombination der Farben, die Stift und Anzeigefarbe gemeinsam haben (invers zu 10)
vbNotMaskPen (10)
Stift maskieren invers (invers zu 9)
285
Global- Objekt
Eigenschaft
Global- Objekt
Global- Objekt
Eigenschaft
Beschreibung
DrawMode (Forts.)
vbNop (11)
Keine Operation, Stift zeichnet nicht
vbMergeNotPen (12)
inversen Stift mischen – Kombination der Anzeigefarbe und der invertierten Stiftfarbe
vbCopyPen (13)
Stift kopieren (Voreinstellung); Stiftfarbe ist durch Eigenschaft ForeColor gegeben (invers zu 4)
vbMergePenNot (14)
Stift und inverse Anzeige mischen; Kombination der Stiftfarbe und der invertierten Anzeigefarbe
vbMergePen (15)
Stift mischen; Kombination aus Stift- und Anzeigefarbe (invers zu 2)
vbWhiteNess (16)
Weißintensität
DrawStyle
Wert vom Typ Integer, der den Linienstil für Zeichenoperationen festlegt. Der Aufzählungstyp DrawStyleConstants definiert dafür eine Reihe von Konstanten: vbSolid (0) Durchgezogen (Voreinstellung) vbDash (1)
Gestrichelt
vbDot (2)
Gepunktet
vbDashDot (3)
Folge aus Strichen und Punkten
vbDashDotDot (4)
Folge aus Strichen und zwei Punkten
vbInvisible (5)
Transparent
vbInsideSolid (6)
Innen ausgefüllt
DrawWidth
Wert vom Typ Integer, der die Linienbreite in Bildpunkten für Zeichenoperationen festlegt. Der Wert kann zwischen 1 (Haarlinie; Voreinstellung) und 32767 liegen. Ist der Wert ungleich 1, erzeugen die Werte 0 bis 4 für die DrawStyle-Eigenschaft eine durchgezogene Linie.
DriverName
Zur Laufzeit schreibgeschützter Wert vom Typ String mit dem Gerätenamen des Druckers
Duplex
Wert vom Typ Integer für einseitiges oder beidseitiges Drucken. Der Aufzählungstyp DrawStyleConstants definiert dafür drei Konstanten: vbPRDPSimplex (1) Einseitiges Drucken
FillColor
286
vbPRDPHorizontal (2)
Beidseitiges Drucken mit horizontalem Seitenwechsel
vbPRDPVertical (3)
Beidseitiges Drucken mit vertikalem Seitenwechsel
Farbwert vom Typ Long, der die Füllfarbe für das Ausmalen von Figuren angibt. Standardwert ist 0 (vbBlack). Beliebige Farben lassen sich aus ihren Komponentenanteilen über die Funktion RGB komponieren. Die Funktion QBColor liefert den Farbwert einer der 16 Grundfarben. Zudem stehen die Elemente des Aufzählungstyps ColorConstants als vordefinierte Konstanten zur Verfügung.
Printer- Objekt
Eigenschaft
Beschreibung
FillStyle
Wert vom Typ Integer, der das Füllmuster für das Ausmalen von Figuren angibt. Der Aufzählungstyp FillStyleConstants definiert dafür acht Konstanten: vbFSSolid (0) Ausgefüllt Transparent (Voreinstellung)
VbHorizontalLine (2)
Horizontales Linienmuster
vbVerticalLine (3)
Vertikales Linienmuster
vbUpwardDiagonal (4)
Aufwärtsdiagonales Linienmuster
vbDownwardDiagonal (5)
Abwärtsdiagonales Linienmuster
vbCross (6)
Kreuzmuster
vbDiagonalCross (7)
Diagonalkreuzmuster
Font
Objekt vom Typ Font, das die Schrift für Ausgaben auf das Gerät repräsentiert
FontBold FontItalic FontStrikethru FontUnderline
Werte vom Typ Boolean, die als Attribute für die Schriftstile Fett, Kursiv, Durchgestrichen und Unterstrichen fungieren
FontCount
Schreibgeschützter Wert von Typ Integer, der die Anzahl der dem Printer-Objekt bekannten Schriften wiedergibt
FontName
Wert vom Typ String, der den Namen der aktuell eingestellten Schriftart wiedergibt bzw. festlegt
FontTransparent
Wert vom Typ Boolean, der festlegt, ob die Textausgabe mit durchscheinendem Hintergrund oder in einem Kasten mit Hintergrundfarbe erfolgt. Ein Ändern der Eigenschaft während der Druckerausgabe wirkt sich nur auf nachfolgende Textausgaben aus.
Fonts
Schreibgeschützte Auflistung der dem Printer-Objekt bekannten Schriften
FontSize
Wert vom Typ Single, der die Schriftgröße wiedergibt bzw. festlegt
ForeColor
Farbwert vom Typ Long, der die Vordergrundfarbe für Zeichenoperationen im Modus 13 (vbCopyPen) wiedergibt bzw. festlegt. Beliebige Farben lassen sich aus ihren Komponentenanteilen über die Funktion RGB komponieren. Die Funktion QBColor liefert den Farbwert einer der 16 Grundfarben. Zudem stehen die Elemente des Aufzählungstyps ColorConstants als vordefinierte Konstanten zur Verfügung.
hDC
Zur Laufzeit schreibgeschützter Wert vom Typ Long, der auf den Gerätekontext des Ausgabegerätes verweist und nur im Zusammenhang mit Funktionen der Win32-API benötigt wird
Height Width
Werte vom Typ Long, die die Höhe bzw. Breite der Ausgabefläche in Twips beschreiben. Sie richten sich im Allgemeinen nach der Eigenschaft PaperSize. Setzt man einen dieser Werte, ändert sich gleichzeitig der Wert von PaperSize auf 256. (Bei A4 ist die Ausgabefläche 16.834 × 11.909 Twips, was bei 600 dpi 7.014 × 4.962 Bildpunkten entspricht.)
287
Global- Objekt
vbFSTransparent (1)
Global- Objekt
Eigenschaft
Beschreibung
Orientation
Wert vom Typ Integer, der die Orientierung des Papiers beim Ausdruck festlegt. Der Aufzählungstyp PrinterObjectConstants definiert dafür zwei Konstanten: vbPRORPortrait (1) Hochformat (Standard)
Global- Objekt
vbPRORLandscape (2)
Querformat
Page
Zur Laufzeit schreibgeschützter Wert vom Typ Integer, der die aktuelle Seitennummer seit dem letzten Aufruf von EndDoc bzw. dem Programmstart wiedergibt. Der mit 1 initialisierte Wert erhöht sich mit jedem Aufruf von NewPage um 1, aber auch, wenn die Print-Methode den unteren Papierrand erreicht hat.
PaperBin
Wert vom Typ Integer, der die Papierzufuhr für die Druckerausgabe festlegt. Der Aufzählungstyp PrinterObjectConstants definiert dafür folgende Konstanten: vbPRBNUpper (1) Oberer Behälter
PaperSize
288
vbPRBNLower (2)
Unterer Behälter
vbPRBNMiddle (3)
Mittlerer Behälter
vbPRBNManual (4)
Manueller Einzug
vbPRBNEnvelope (5)
Umschlagspapiereinzug automat.
vbPRBNEnvManual (6)
Umschlagspapiereinzug manuell
vbPRBNAuto (7)
Standardbehälter (Voreinstellung)
vbPRBNTractor (8)
Traktor-Einzug
vbPRBNSmallFmt (9)
Kleiner Papierbehälter
vbPRBNLargeFmt (10)
Großer Papierbehälter
vbPRBNLargeCapacity (11)
Einzug mit großem Papiervorrat
vbPRBNCassette (14)
Kassetten-Cartridge
Wert vom Typ Integer, der die Papiergröße und damit die Größe der Ausgabefläche festlegt. Ein Setzen dieses Werts ändert gleichzeitig die Werte der Eigenschaften Height und Width. Der Aufzählungstyp PrinterObjektConstants definiert dafür folgende Konstanten: vbPRPSLetter (1) US Letter: 8½×11 Zoll vbPRPSLetterSmall (2)
US Letter Small: 8½×11 Zoll
vbPRPSTabloid (3)
US Tabloid: 11×17 Zoll
vbPRPSLedger (4)
US Ledger: 17×11 Zoll
vbPRPSLegal (5)
US Legal: 8½×14 Zoll
vbPRPSStatement (6)
US Statement: 5½×8½ Zoll
vbPRPSExecutive (7)
Executive: 7½×10½ Zoll
vbPRPSA3 (8)
DIN A3: 297×420 mm
vbPRPSA4 (9)
DIN A4: 210×297 mm
vbPRPSA4Small (10)
DIN A4: 210×297 mm
vbPRPSA5 (11)
DIN A5: 148×210 mm
Printer- Objekt
Eigenschaft
Beschreibung
PaperSize (Forts.)
vbPRPSB4 (12)
DIN B4: 250×354 mm
vbPRPSB5 (13)
DIN B5: 182×257 mm
vbPRPSFolio (14)
Folio: 8½×13 Zoll
vbPRPSQuarto (15)
Quarto: 215×275 mm
vbPRPS10x14 (16)
10×14 Zoll
vbPRPS11x17 (17)
11×17 Zoll US Note: 8½×11 Zoll Umschlag 9: 37/8×87/8 Zoll
vbPRPSEnv10 (20)
Umschlag 10: 41/8×9½ Zoll
vbPRPSEnv11 (21)
Umschlag 11: 4½×103/8 Zoll
vbPRPSEnv12 (22)
Umschlag 12: 4½×11 Zoll
vbPRPSEnv14 (23)
Umschlag 14: 5×11½ Zoll
vbPRPSCSheet (24)
Blatt in C-Größe
vbPRPSDSheet (25)
Blatt in D-Größe
vbPRPSESheet (26)
Blatt in E-Größe
vbPRPSEnvDL (27)
Umschlag DL: 110×220 mm
vbPRPSEnvC5 (28)
Umschlag C5: 162×229 mm
vbPRPSEnvC3 (29)
Umschlag C3: 324×458 mm
vbPRPSEnvC4 (30)
Umschlag C4: 229×324 mm
vbPRPSEnvC6 (31)
Umschlag C6: 114×162 mm
vbPRPSEnvC65 (32)
Umschlag C65:114×229 mm
vbPRPSEnvB4 (33)
Umschlag B4: 250×353 mm
vbPRPSEnvB5 (34)
Umschlag B5: 176×250 mm
vbPRPSEnvB6 (35)
Umschlag B: 176×125 mm
vbPRPSEnvItaly (36)
Umschlag: 110×230 mm
vbPRPSEnvMonarch (37)
Umschlag Monarch: 37/8×7½ Zoll
vbPRPSEnvPersonal (38)
Umschlag, 35/8×6½ Zoll
vbPRPSFanfoldUS (39)
U.S. Stand. Fanfold: 147/8×11 Zoll
vbPRPSFanfoldStdGerman (40)
Standard-Durchschlag: 8½×12 Zoll
vbPRPSFanfoldLglGerman (41)
Legal-Durchschlag: 8½×13 Zoll
vbPRPSUser (256)
benutzerdefiniert
Global- Objekt
Port
vbPRPSNote (18) vbPRPSEnv9 (19)
Schreibgeschützter Wert vom Typ String, der den Namen der Schnittstelle (zum Beispiel: »LPT1«) oder Netzwerkfreigabe wiedergibt, über die die Druckausgabe an den Drucker geleitet wird
289
Global- Objekt
Eigenschaft
Beschreibung
PrintQuality
Wert vom Typ Integer, der die Auflösung als Qualitätsstufe (negativer Wert) oder in dpi (positiver Wert, z.B.: 600) wiedergibt bzw. festlegt. Der Aufzählungstyp PrinterObjectConstants definiert vier Konstanten für die Wahl der Qualitätsstufe: vbPRPQDraft (-1) Entwurfsqualität
Global- Objekt
vbPRPQLow (-2)
Geringe Qualität
vbPRPQMedium (-3)
Mittlere Qualität
vbPRPQHigh (-4)
Hohe Qualität
RightToLeft
Schreibgeschützter Wert vom Typ Boolean, der angibt, ob das Gerät Ausgaben in umgekehrter Leserichtung ermöglicht (nur im Zusammenhang mit bidirektionalen Systemen von Interesse)
ScaleHeight ScaleWidth
Werte vom Typ Single, die die Höhe bzw. Breite der für die Druckausgabe zur Verfügung stehenden Fläche in der jeweils geltenden Maßeinheit (vgl. ScaleMode) und Vergrößerungsstufe (vgl. Zoom) wiedergeben. Jede Änderung dieser Werte wirkt sich als Skalierung des logischen Koordinatensystems aus, die physikalischen Abmessungen der für die Druckausgabe zur Verfügung stehenden Fläche bleiben dabei unverändert (vgl. PaperSize). Setzt man beispielsweise ScaleHeight auf den Wert 100, ordnet das der physikalischen Höhe der Druckausgabefläche (die im metrischen System beispielsweise 30 cm beträgt) im logischen Koordinatensystem das Maß 100 zu. Jede Wertänderung zieht implizit eine Änderung der Eigenschaft ScaleMode auf den Wert 0 (benutzerdefiniert) nach sich.
ScaleLeft ScaleTop
Werte vom Typ Single, die die Koordinaten der linken bzw. oberen Ecke der Druckausgabefläche wiedergeben (vgl. auch ScaleMode und Zoom). Jede Änderung dieser Werte wirkt sich als Translation des logischen Koordinatensystems aus. Die physikalischen Abmessungen der für die Druckausgabe zur Verfügung stehenden Fläche bleiben dabei unverändert (vgl. PaperSize). Setzt man beispielsweise ScaleLeft sowie ScaleTop auf den Wert -100 und ScaleWidth sowie ScaleHeight auf 200, wird die Druckausgabefläche durch das von den Punkten (-100, -100) und (100, 100) aufgespannte Rechteck beschrieben.
ScaleMode
Wert vom Typ Integer, der das für die Druckausgabe geltende Koordinaten- und Maßsystem beschreibt. Ist der Wert ungleich 0, liegt der Ursprung des Koordinatensystems links oben. Der Aufzählungstyp ScaleModeConstants definiert mehrere Konstanten für die Wahl des Maßsystems: vbUser (0) Benutzerdefiniertes Koordinaten- und Maßsystem (wird implizit gesetzt, wenn mindestens eine der Eigenschaften ScaleHeight, ScaleWidth, ScaleLeft und ScaleTop einen benutzerdefinierten Wert erhält)
290
vbTwips (1)
Maßeinheit ist Twips (567 Twips entsprechen einem Zentimeter und 1440 Twips einem Zoll)
vbPoints (2)
Maßeinheit ist Punkt (72 Punkt entsprechen einem Zoll)
Printer- Objekt
Beschreibung
ScaleMode (Forts.)
vbPixels (3)
Maßeinheit ist Bildpunkt (kleinste Einheit, die in der geltenden Auflösung auf dem Drucker dargestellt werden kann)
vbCharacters (4)
Maßeinheit ist Zeichen (horizontal: 120 Twips je Einheit; vertikal: 240 Twips je Einheit)
vbInches (5)
Maßeinheit ist Zoll
vbMillimeters (6)
Maßeinheit ist Millimeter
vbCentimeters (7)
Maßeinheit ist Zentimeter
vbHimetric (8)
Maßeinheit ist HiMetric (0,01 mm)
TrackDefault
Wert von Typ Boolean, der festlegt, ob das Printer-Objekt vonseiten des Betriebssystems veranlasste Änderungen des Standarddruckers zur Laufzeit des Programms mitmacht (True; Voreinstellung) oder nicht (False). Eine Änderung dieser Eigenschaft während der Druckausgabe erzwingt implizit den Aufruf der Methode EndPage.
TwipsPerPixelX TwipsPerPixelY
Zur Laufzeit schreibgeschützte Werte vom Typ Single, die ausdrücken, wie viele Twips bei der aktuell eingestellten Auflösung einem Bildpunkt in horizontaler (X) und vertikaler Richtung (Y) entsprechen (bei 600 dpi entsprechen 2,4 Twips einem Bildpunkt)
Width
Siehe Height
Zoom
Wert vom Typ Long, der den Vergrößerungsfaktor für die Druckausgabe in Prozent enthält. (Um von A4 auf A5 zu verkleinern, ist beispielsweise der Vergrößerungsfaktor 71 einzustellen.) Bei Druckern, die keine Vergrößerung unterstützen, ist dieser Wert 0, Standardvorgabe ist 100.
................................................... Methoden Methoden
Sub Printer.Circle (x As Single, y As Single, Radius As Single, _ [Color As Long, Start As Single, End As Single, Aspect As Single] Sub Printer.EndDoc() Sub Printer.KillDoc() Sub Printer.Line (Flags As Integer, X1 As Single, Y1 As Single, _ X2 As Single, Y2 As Single, Color As Long) Sub Printer.NewPage() Sub Printer.PaintPicture(pic As Picture, X1 As Single, _ Y1 As Single, [Width1 As Single], [Height1 As Single], [X2 As Single], [Y2 As Single], [Width2 As Single], _ [Height2 As Single], [Opcode]) Sub Printer.Print (Ausdr1[Trennz [Ausdr2] ... ]]) Sub Printer.PSet( X As Single, Y As Single, Color As Long) Function Printer.ScaleX(Width As Single, [FromScale], [ToScale]) _ As Single
291
Global- Objekt
Eigenschaft
Global- Objekt
Function Printer.ScaleY(Width As Single, [FromScale], [ToScale]) _ As Single Function Printer.TextHeight(Str As String) As Single
Global- Objekt
Function Printer.TextWidth(Str As String) As Single Das Printer-Objekt hat zwölf Methoden mit benannten Argumenten. Drei davon (EndDoc, NewPage und KillDoc) sind originäre Methoden des Printer-Objekts und dienen der Drucksteuerung. Die anderen Methoden finden sich auch bei anderen Objekten, die über einer Ausgabefläche operieren (Form, PictureBox, PropertyPage, UserControl, UserDocument), und ermöglichen Berechnungen sowie Operationen, die mittelbar oder unmittelbar mit dem Zeichnen im Zusammenhang stehen. Die Textausgabe erfolgt mit der Print-Anweisung, die Grafikausgabe mit PaintPicture, und gezeichnet wird mit Line, Circle und PSet. Die Syntax für den Aufruf der Methoden Circle, Line und PSet ist traditionell spezifisch: Circle [Step] (x, y), Radius, [Color], [Start], [End], [Aspect] Line [Step] (x1, y1) – [Step] (x2, y2), [Color], [B[F]] PSet [Step] (x, y), [Color] Ist das optionale Schlüsselwort Step angegeben, wird das unmittelbar folgende Koordinatenpaar als relativer Offset bzgl. der aktuellen Position (CurrentX, CurrentY) interpretiert, ansonsten als absolute Position – jeweils bezogen auf das geltende Koordinatensystem. Standardmäßig zeichnen die Methoden in der durch die Eigenschaft ForeColor spezifizierten Farbe (Standardwert ist Schwarz: vbBlack). Beliebige Farben lassen sich aus ihren Komponentenanteilen über die Funktion RGB zu einem Long-Wert für den optionalen Parameter Color komponieren. Definierte Farben liefert die Funktion QBColor (16 Grundfarben) sowie der Aufzählungstyp ColorConstants. Füllfarbe ist FillColor, sofern FillStyle ungleich 1 ist. Methode
Beschreibung
Circle
Zeichnet einen Kreis um den Mittelpunkt (x, y) mit Radius Radius und der optionalen Stiftfarbe Color. Sind die optionalen Parameter Start und End angegeben, zeichnet die Methode nur einen Teilkreis. Start und End bezeichnen den Start- und Endwinkel (im Bogenmaß). Ist der Parameter Aspect mit einem Wert ungleich 1 bzw. -1 angegeben, zeichnet die Methode eine Ellipse, die dem Kreis einbeschrieben (positive Werte) bzw. umbeschrieben (negative Werte) ist. Aspect drückt das Verhältnis zwischen Höhe und Breite des begrenzenden Rechtecks aus.
EndDoc
Schließt den aktuellen Druckjob ab und gibt gegebenenfalls zuvor noch die aktuelle Druckseite für den Ausdruck frei, wenn bereits Ausgabeoperationen darauf erfolgt sind
KillDoc
Bricht den aktuellen Druckjob ab
Line
Zeichnet eine Linie zwischen den Punkten (x1, y1) und (x2, y2). Ist der optionale Zusatz »B« gegeben, zeichnet die Methode das Rechteck, das die beiden Punkte definieren. Ist der optionale Zusatz »BF« gegeben, zeichnet die Methode das Rechteck und füllt es mit der Füllfarbe FillColor aus.
NewPage
Schließt die aktuelle Druckseite ab und gibt sie für den Ausdruck frei
292
Printer- Objekt
Beschreibung
PaintPicture
Zeichnet das im Datentyp Picture vorliegende Bild pic an der Position (X1, Y1), die den linken oberen Bildpunkt beschreibt. Alle Werte sind in der aktuellen Maßeinheit (ScaleMode) anzugeben. Sind die optionalen Parameter Height1 und Width1 angegeben, wird das Bild auf diese Maße skaliert, ansonsten errechnet sich die Methode diese Werte selbst und gibt das Bild in originaler Größe aus. Sind die optionalen Parameter X2 und Y2 sowie Width2 und Height2 vorhanden, beschreiben diese einen Bildausschnitt innerhalb des Bildes, der (nach impliziter Skalierung) in dem durch X1, Y1, Width1 und Height1 spezifizierten Rechteck ausgegeben wird. (Achtung: die Eigenschaften Height und Width eines PictureObjekts sind in der Maßeinheit »HiMetric« gehalten und müssen gegebenenfalls mittels ScaleX und ScaleY in die geltende Maßeinheit – Vorgabe ist Twips – umgewandelt werden.) Negative Werte für Height und/oder Width führen zu einer spiegelverkehrten und/oder um 180° gedrehten Ausgabe. Koordinaten für Ausschnitte sind auf den Ursprung des aktuellen Koordinatensystems zu beziehen!
Print
Gibt die in der Parameterliste genannten Werte unter Berücksichtigung etwaiger Trennzeichen (Semikolon, Komma, Tab(n)) in der gegebenen Schrift (Font-Eigenschaft) als Zeichenfolge an der aktuellen Position aus. Dabei beschreiben die Eigenschaften CurrentX und CurrentY den linken oberen Punkt des begrenzenden Rechtecks. Der Platzbedarf lässt sich mittels TextHeight und TextWidth ermitteln.
PSet
Zeichnet einen Punkt an der Position (x, y) in der Farbe Color
ScaleX ScaleY
Rechnet die Koordinate Width für die X-Achse (bzw. Y-Achse) vom Koordinatensystem FromScale in das Koordinatensystem ToScale um und liefert die neue Koordinate als Single. Fehlt der Parameter für ein Koordinatensystem, bezieht sich die Methode auf das aktuell geltende Koordinatensystem. Für die verschiedenen Koordinatensysteme sind Integer-Konstanten definiert (vgl. »ScaleMode-Eigenschaft«, S. 369)
TextHeight
Liefert die für die Ausgabe der Zeichenfolge Str benötigte Höhe in der aktuellen y-Maßeinheit des aktuellen Koordinatensystems
TextWidth
Liefert die für die Ausgabe der Zeichenfolge Str benötigte Breite in der aktuellen x-Maßeinheit des aktuellen Koordinatensystems
Anwendung
................................................... Anwendung
Das Druckmodell von Visual Basic ist relativ einfach, erlegt dem Programmierer leider aber auch gewisse Beschränkungen auf. Ein Visual-Basic-Programm muss damit auskommen, was auf dem jeweiligen System im Angebot ist, da es weder möglich ist, ein neues Printer-Objekt ins Leben zu rufen, noch die Printers-Auflistung zu erweitern. Das heißt auch, es kann zu einem Zeitpunkt immer nur einen Drucker ansprechen, nämlich den, auf den das PrinterObjekt gesetzt ist. (Die parallele Ausgabe auf mehreren Druckern ist zwar vom Prinzip her möglich, wenn man direkt auf Funktionen des GDI zurückgreift, die Angelegenheit wird dann jedoch recht aufwändig. (Vgl. auch den Tipp) Das Printer-Objekt verfügt über die nötige Ausstattung, die Druckausgabe durchzuführen. Die Ausgabe selbst ist seitenorientiert: Die Anwendung zeichnet (ohne weitere Vorbereitungen) jeweils den Inhalt einer Seite unter Verwendung der entsprechenden Methoden des Printer-
293
Global- Objekt
Methode
Global- Objekt
Global- Objekt
Objekts (darunter: Line, Circle, Print, PSet, Print TextHeight und TextWidth) und gibt diese Seite dann nach Fertigstellung explizit durch Aufruf der Methode NewPage für den Ausdruck frei. Die Freigabe der ersten Seite eröffnet einen Druckjob in der Warteschlange des dem Printer-Objekt zugeordneten Druckers. Nachfolgende Ausgaben erscheinen dann – bis zum nächsten NewPage-Aufruf – auf der nächsten Seite. NewPage pflegt darüber hinaus die Page-Eigenschaft des Objekts, die somit (beginnend mit 1) immer die aktuelle Seitennummer wiedergibt. Der Zeichenvorgang an sich unterscheidet sich nicht vom Zeichnen in ein Formular oder ein Steuerelement. Falls der eingestellte Drucker keine Farben unterstützt, setzt der Druckertreiber die Farbwerte je nach Voreinstellung im Eigenschaftsfenster in Grauwerte um. Zum Abschluss eines Druckjobs ist ein Aufruf der Methode EndDoc erforderlich. (Visual Basic führt diesen Aufruf bei Programmende zwar von sich aus durch, darauf zu bauen, wäre aber schlechter Programmierstil und würde insbesondere auch den Drucker bis zum Programmende blockieren.) Falls zwischen dem letzten Aufruf von NewPage und EndDoc Ausgaben stattgefunden haben, gibt EndDoc erst die angefangene Seite zum Ausdruck frei und beendet dann den Druckjob. Mit Beendigung eines Druckjobs erhält Page wieder den Wert 1. Die Methode KillDoc erlaubt es, einen noch nicht abgeschlossenen Druckjob unmittelbar abzubrechen (je nach Zustand der Warteschlange des eingestellten Druckers kann dies auch während des Ausdrucks sein, im Drucker gepufferte vollständige Seiten kommen aber noch zum Ausdruck). Zur Gestaltung der Ausgabe können die Eigenschaften des Printer-Objekts jederzeit geändert werden, etwa um eine andere Schriftart oder Schriftgröße einzustellen oder ein Attribut zu ändern. Eine Änderung wirkt sich erst für die nächste Ausgabeoperation aus, hat also keinen Rückbezug auf bereits geschehene Ausgabeoperationen für die jeweilige Seite. Tipps
................................................... Tipps In manchen Fällen ist der mit dem Betriebssystem verbundene und verallgemeinernde Overhead bei der Druckerausgabe eher eine Last als eine Erleichterung, so beispielsweise, wenn der installierte Treiber das Ausgabegerät nicht im gewünschten Umfang unterstützt oder wenn Lösungen für ganz spezifische Problemstellungen gefragt sind. Ein Programm kann einen Drucker (oder ein sonstiges Ausgabegerät) dann gegebenenfalls direkt über die jeweilige Geräteschnittstelle ansprechen – die klassische Methode der Druckerausgabe also. Dazu öffnet und schließt man die Schnittstelle wie eine Datei (Open "LPT1:" For Binary …) und versorgt das Gerät via Print# mit geeigneten Daten. Wenn Sie ein Formular ausdrucken wollen, wie es auf dem Bildschirm erscheint, führt an der Methode PrintForm des jeweiligen Formularobjekts kein Weg vorbei. Diese Methode gibt den Inhalt des dem Formular untergelegten Fensters als eigenständige Seite auf das Printer-Objekt (unter Beachtung des aktuellen Zustands) aus – die Ausgabe auf eine bereits angefangene Seite nötigt das Printer-Objekt, einen Laufzeitfehler auszulösen. Aber Achtung, alle Inhalte müssen in Steuerelementen untergebracht sein. Wie das Beispielprogramm zeigt, berücksichtigt PrintForm nämlich nur die auf dem Formular befindlichen Steuerelemente (samt Inhalten), nicht jedoch sonstige, direkt in das Formular gezeichnete Inhalte, seien es Texte, Grafiken oder Bilder. Zur Abhilfe sollte man solche Inhalte in ein PictureBox-Steuerelement zeichnen. Mit diesem Steuerelement lässt sich auch eine (allerdings nicht sehr befriedigende) Druckvorschau implementieren. Man legt ein Formular an, das nichts weiter als ein PictureBox-Steuerelement enthält, und zeichnet alle auszudruckenden Inhalte in dieses Steuerelement. Zu beachten gilt es lediglich, dass die AutoRedraw-Eigenschaft des Formularobjekts auf True gesetzt ist. Der Ausdruck selbst ist dann mit einem einfachen PrintForm-Aufruf erledigt. Leider werden nur die Inhalte eines Formulars gedruckt, die bei der gegebenen Auflösung auf dem Bildschirm Platz haben (wenn Teile des Formulars verdeckt sind, spielt das keine Rolle). Zudem lässt die Qualität von Grafiken wegen der kleineren Auflösung des Bildschirms (96 dpi) stark zu wünschen übrig.
294
Printer- Objekt
Beispiel
................................................... Beis piel
Formular des Projektes PrinterDemo Das Formular enthält zwei Schaltflächen: Die eine (cmdDemoAusdruck) demonstriert die Druckausgabe unter Verwendung der verschiedenen Methoden des Printer-Objekts, die andere (cmdFormularAusdruck) zeigt die Ausgabe des Formulars mittels der PrintForm-Methode des Form-Objekts. Option Explicit ' Mit etwas Unterstützung der WinApi ... Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
295
Global- Objekt
Das Projekt PrinterDemo zeigt die wichtigsten Aspekte im Umgang mit dem Printer-Objekt. Der Code initialisiert das Kombinationsfeld-Steuerelement Combo1 (dessen Style-Eigenschaft beim Entwurf auf 1 oder 2 gesetzt wurde) mit den Namen der auf dem System verfügbaren Drucker und zeigt den Standarddrucker als aktuelle Auswahl im Kombinationsfeld an. Verliert das Kombinationsfeld den Fokus, erhält das Printer-Objekt – entsprechend der im Kombinationsfeld getroffenen Auswahl – gegebenenfalls einen neuen Wert. Um den Zustand des Kombinationsfelds mit dem aktuellen Wert des Printer-Objekts zu synchronisieren, bedient sich der Code der SendMessage-Funktion aus der Win32-API mangels einer geeigneten Methode seitens des Steuerelements. Diese Funktion ermöglicht es, dem Steuerelement eine Nachricht zu senden, die es anweist, nach einem bestimmten Eintrag zu suchen und dessen Index zu liefern. Die folgende Abbildung zeigt das Fenster der Anwendung:
Global- Objekt
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ lParam As Any) As Long Private Const CB_FINDSTRING = &H14C
Global- Objekt
Private Sub cmdDemoAusdruck_Click() Demo Printer Printer.EndDoc End Sub
' Druckjob abschließen
Private Sub cmdFormularAusdruck_Click() PrintForm End Sub Private Sub Combo1_Lostfocus() If Printer.DeviceName Combo1.Text Then ' Hat sich was geändert? Set Printer = Printers(Combo1.ListIndex) End If End Sub Private Sub Form_Load() Dim p As Printer, lIndex As Long For Each p In Printers ' Kombifeld initialisieren Combo1.AddItem p.DeviceName Next ' Standarddrucker auswählen. Suchen lassen lIndex = SendMessage(Combo1.hwnd, CB_FINDSTRING, -1, _ ByVal Printer.DeviceName) Combo1.ListIndex = lIndex ' Eintrag auswählen End Sub Sub Demo(obj As Object) Dim x As Single obj.ScaleMode = vbMillimeters obj.ScaleLeft = -obj.ScaleWidth / 2 obj.ScaleTop = -obj.ScaleHeight / 2
' Millimeter als Maßeinheit ' Ursprung in die Mitte
obj.Line (-70, 0)-(70, 0), vbBlack ' Koordinatenkreuz obj.Line (0, -70)-(0, 70), vbBlack obj.Line (-70, -70)-(70, 70), vbBlack, B ' Quadrat drum herum For x = 10 To 70 Step 10 obj.Circle (0, 0), x, vbBlack ' Kreise drum herum Next x ' Überschrift obj.FontName = "Times New Roman" obj.FontSize = 30 obj.FontBold = True
' Schrift für Beschriftung
obj.CurrentX = -obj.TextWidth("Demo-Ausdruck") / 2 obj.CurrentY = -70 – obj.TextHeight("Demo-Ausdruck") obj.Print "Demo-Ausdruck"
296
Printers- Auflistung
' Beschriftung obj.FontName = "Courier New" obj.FontSize = 8.5
' Schrift für Beschriftung
Global- Objekt
For x = -70 To 70 Step 10 ' Skala horizontal obj.CurrentX = x – obj.TextWidth(CStr(x)) / 2 obj.CurrentY = 0 obj.Print CStr(x) ' Skala vertikal obj.CurrentX = -obj.TextWidth(CStr(x)) obj.CurrentY = x – obj.TextHeight(CStr(x)) / 2 obj.Print CStr(x) Next x End Sub Private Sub Form_Paint() Demo Me End Sub Private Sub Form_Resize() Refresh End Sub Verwandte Objekte
................................................... Verwandte Objekte Form, PictureBox Verwandte Themen
................................................... Verwandte Them en
Standarddialoge-Steuerelement (CommonDialog) (S. 444)
Printers- Auflistung Printers As Object Beschreibung
................................................... Bes c hreibung
Die nicht mit dem Auflistungstyp Collection kompatible Printers-Auflistung stellt eine Liste mit allen auf dem System installierten Druckern bereit. Elementdatentyp ist Printer. Einzige Eigenschaft der Auflistung ist Count, über die sich die Anzahl der Listenelemente in Erfahrung bringen lässt. Anwendung
................................................... Anwendung
Sie können die Auflistung mit einem For Each-Konstrukt und einer Zählvariablen des Typs Printer durchlaufen. Für den direkten Zugriff auf ein Element verwenden Sie die übliche ArraySchreibweise unter Angabe eines Index (Zählung beginnt bei 0). Visual Basic initialisiert das Printer-Objekt grundsätzlich mit dem aktuellen Standarddrucker des Systems. Um auf einem anderen Drucker Ausgaben anzufertigen, weisen Sie dem PrinterObjekt das zugehörige Element der Auflistung über eine Set-Anweisung zu. Beispiel
................................................... Beis piel
Vgl. das Beispiel zu »Printer-Objekt« (S. 284).
297
Global- Objekt
Verwandte Themen
................................................... Verwandte Them en
Auflistungen und (CommonDialog) (S. 444)
Collection-Objekte
(S. 304);
Standarddialoge-Steuerelement
QBColor- Methode Function QBColor (Color As Integer) As Long Beschreibung
Global- Objekt
................................................... Bes c hreibung
Die QBColor-Funktion liefert die zur Farbnummer Color gehörige RGB-Farbe als Long-Farbwert zurück. Anwendung
................................................... Anwendung
Bei älteren noch auf DOS basierenden Basic-Versionen (etwa QBasic), musste sich der Programmierer (mittels der Screen-Anweisung) noch explizit um die Steuerung der Grafikanzeige (CGA, EGA, VGA, PVGA etc.) kümmern und konnte je nach vorhandener Hardware zwischen verschiedenen Bildschirmauflösungen und Farbtiefen wählen. Mit Windows und der Philosophie der geräteunabhängigen Ausgabe ist die Angelegenheit einfacher geworden: Da die Ausgabe unter Windows fensterbasiert ist, ist sie gewissermaßen auflösungsunabhängig geworden, und für die Farbausgabe wird inzwischen einheitlich der TrueColor-Farbraum des 24-Bit-Farbmodells zugrunde gelegt. Die Farben des 16-farbigen EGA/VGA-Modus spielen aber bei der Programmierung als Grundfarben nach wie vor eine wichtige Rolle, da sie eine klar zu unterscheidende Farbauswahl darstellen. Da die QBColor-Funktion den indizierten Farbraum des 16-farbigen EGA/VGA-Modus in den TrueColor-Farbraum des 24-Bit-Farbmodells abbildet, ist sie ein unverzichtbares Werkzeug für die Umsetzung älterer Basic-Programme nach Visual Basic. Die folgende Tabelle gibt einen Überblick über die Zuordnung zwischen den Farbnummern und den Farben: Farbnummer
Farbe
Farbnummer
Farbe
0
Schwarz
8
Grau
1
Blau
9
Hellblau
2
Grün
10
Hellgrün
3
Zyan
11
Hellzyan
4
Rot
12
Hellrot
5
Magenta
13
Hellmagenta
6
Gelb
14
Hellgelb
7
Weiß
15
Leuchtend Weiß
Beispiel
................................................... Beis piel
Line (0, 0)-(1000, 1000), QBColor(6) Verwandte Befehle
................................................... Verwa ndte Befehle
RGB
298
RGB- Methode
RGB- Methode Function RGB(Red As Integer, Green As Integer, Blue As Integer) As Long Beschreibung
................................................... Bes c hreibung
Die RGB-Methode komponiert eine RGB-Farbe für den TrueColor-Farbraum aus den Werten für die einzelnen Farbkomponenten Rot, Grün und Blau und gibt diese als Long-Farbwert zurück. Die Funktion unterscheidet die Werte 0 bis 255 für die drei Parameter Red, Green und Blue. (Größere Werte verursachen keinen Laufzeitfehler, sondern werden auf 255 abgerundet.) Anwendung
Der Einsatz der RGB-Methode ist immer dann angesagt, wenn eine Farbe aus dem TrueColorFarbraum komponentenweise zusammengestellt werden muss. Die Parameter der Methode drücken die zwischen 0 und 255 abgestuften Helligkeitsanteile der einzelnen Farbkomponenten aus, so dass der Aufruf RGB(0, 0, 0) den Farbwert für Schwarz und RGB(255, 255, 255) den Farbwert für Weiß liefert. Die Methode macht eigentlich nichts weiter, als die Komponentenwerte in die unteren drei Bytes des Farbwerts umzumünzen nach der Formel RGBWert = (Rot Mod 256) + (Green Mod 256) * 256 + (Blue Mod 256) * 65536 Beispiel
................................................... Beis piel
Der folgende Code gibt einen so genannten Graukeil aus: ScaleMode = vbPixels For i = 0 To 255 Line (i, 0)-(i, 1000), RGB(i, i, i) Next i
SavePicture- Methode Sub SavePicture(Picture As Picture, FileName As String) Beschreibung
................................................... Bes c hreibung
Die SavePicture-Methode speichert ein Bild Picture in der Datei FileName. Bilder der Formate BMP, JPG, und GIF werden dabei unabhängig von ihrem ursprünglichen Format im BMP-Format abgespeichert, während Bilder der Formate ICO, WMF, EMF und CUR ihr ursprüngliches Format beibehalten. Anwendung
................................................... Anwendung
Ein interessanter Einsatzbereich dieser Methode ist das Abspeichern des aktuellen Zustands der Zeichenfläche eines Formulars, die über die Image-Eigenschaft verfügbar ist. Beispiel
................................................... Beis piel
Der folgende Code speichert den von Grafikmethoden (PSet, Circle, Line, Print) gezeichneten Inhalt eines Formulars im BMP-Format. (Beachten Sie, dass dazu die AutoRedraw-Eigenschaft des Formulars auf True gesetzt sein muss!) SavePicture Image, "Forminhalt.bmp"
299
Global- Objekt
................................................... Anwendung
Global- Objekt
SaveSetting- Methode Sub SaveSetting(AppName As String, Section As String, _ Key As String, Setting As String) Beschreibung
................................................... Bes c hreibung
Die Methode SaveSetting ermöglicht es, persistente Einstellungen eines Programms in Systemregistrierung persistent als Unterschlüssel des Schlüssels
Global- Objekt
HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ zu speichern. Für den Aufruf gilt: AppName steht für den Anwendungsnamen und ist Unterschlüssel von »VB and VBA Program Settings«; Section steht für den Abschnitt und ist Unterschlüssel von AppName; Key ist Eintrag unter Section und steht für den Namen des zu speichernden Werts; Setting ist der Key zugeordnete Datenwert. Anwendung
................................................... Anwendung
Früher mussten Windows-Anwendungen ihre persistenten Einstellungen noch in je eigenen INIDateien ablegen. Spätestens seit Windows 95 (aber auch schon zuvor) gibt es eine zentrale Systemregistrierung, in der sich solche Daten an zentraler Stelle speichern lassen. Für den Zugriff auf die Systemregistrierung von Visual Basic aus stehen im Wesentlichen vier Methoden zur Verfügung: GetSetting, GetAllSettings, SaveSetting und DeleteSetting, deren Funktion bereits durch die Bezeichner deutlich wird. Um auf andere Schlüssel zuzugreifen, müssen Sie die entsprechenden Funktionen der Win32-API (RegSaveKey etc.) benutzen. Beispiel
................................................... Beis piel
Vgl. »GetAllSettings-Methode« (S. 279).
Screen- Objekt Public Screen As Screen Beschreibung
................................................... Bes c hreibung
Das aus der Bibliothek VB stammende Screen-Objekt ist in jeder Anwendung als globales Objekt bekannt. Es repräsentiert den gesamten Bildschirm als Ausgabegerät, ohne jedoch selbst Methoden für die Ausgabe zu besitzen. Seine Eigenschaften geben Aufschluss über die physikalische Auflösung sowie die Abmessungen des eingestellten Bildschirmmodus, die auf dem System installierten Schriften und darüber, welches Formular und Steuerelement der Anwendung gerade aktiv ist (lies: im Besitz des Fokus ist). Weiterhin erlauben sie die Kontrolle über den für alle Formulare und Steuerelemente der Anwendung geltenden Mauszeiger. Die folgende Tabelle gibt einen Überblick über die Eigenschaften des Screen-Objekts. Eigenschaft
Beschreibung
ActiveControl
Zur Laufzeit schreibgeschützter Wert, der vom System gepflegt wird und eine Objektreferenz auf das Steuerelement des aktiven Formulars darstellt, das augenblicklich den Fokus besitzt; der Datentyp der Objektreferenz richtet sich nach dem Steuerelement (als Datentyp für die Parameterübergabe ist daher Control zu wählen)
3 00
Screen- Objekt
Beschreibung
ActiveForm
Zur Laufzeit schreibgeschützter Wert, der vom System gepflegt wird und eine Objektreferenz auf das aktive Formular darstellt. Ist ein MDI-Formular aktiv, bezeichnet diese Eigenschaft das aktive, dem MDI-Formular untergeordnete Unterformular.
FontCount
Zur Laufzeit schreibgeschützter Wert vom Typ Integer, der die Anzahl der auf dem System installierten Schriftarten wiedergibt
Fonts
Auflistung mit dem Elementtyp Font und Indexbereich: 0 bis FontCount – 1 für die auf dem System installierten Schriftarten
Height Width
Zur Laufzeit schreibgeschützte Werte vom Typ Single, die die Höhe bzw. Breite des Bildschirms in Twips ausdrücken (1 Zentimeter entspricht ca. 567 Twips, 1 Zoll entspricht 1440 Twips)
MouseIcon
Wert von Typ Picture. Lässt sich zur Laufzeit auf ein CUR- oder ICO-Bild (nicht jedoch ANI) setzen. Ermöglicht die Anzeige eines benutzerdefinierten Mauszeigers im Bereich des aktiven Formulars, wenn MousePointer den Wert 99 hat.
MousePointer
Wert vom Typ MousePointerConstants, der festlegt, welcher Mauszeiger im Bereich des aktiven Formulars angezeigt wird. vbDefault (0) objektspezifisch (Voreinstellung)
TwipsPerPixelX TwipsPerPixelY
vbArrow (1)
Pfeilsymbol
vbCrosshair (2)
Kreuz
vbIbeam (3)
I-Symbol
vbIconPointer (4)
Symbol (Quadrat in Quadrat)
vbSizePointer (5)
Pfeilkreuz Nord/Süd/West/Ost
vbSizeNESW (6)
Doppelpfeil Nord-Ost/Süd-West
vbSizeNS (7)
Doppelpfeil Nord/Süd
vbSizeNWSE (8)
Doppelpfeil Nord-West/Süd-Ost
vbSizeWE (9)
Doppelpfeil West/ Ost
vbUpArrow (10)
Pfeil aufwärts zeigend
vbHourglass (11)
Sanduhr
vbNoDrop (12)
nicht ablegen
vbArrowHourglass (13)
Sanduhr mit Pfeil
vbArrowQuestion (14)
Pfeil mit Fragezeichen
vbSizeAll (15)
Größenänderung alle
vbCustom (99)
benutzerdefiniertes Symbol, wie in MouseIcon definiert
Zur Laufzeit schreibgeschützte Werte vom Typ Single, die ausdrücken, wie viele Twips bei der aktuell eingestellten Bildschirmauflösung einem Bildpunkt in horizontaler (X) und vertikaler Richtung (Y) entsprechen
3 01
Global- Objekt
Eigenschaft
Global- Objekt
Anwendung
Global- Objekt
................................................... Anwendung
Eine wichtige Aufgabe des Screen-Objekts ist die Kontrolle des Mauszeigers für die gesamte Anwendung. Solange Screen.MousePointer den Wert vbDefault hat, kann jedes Formular und Steuerelement den Mauszeiger für seinen Fensterbereich individuell über seine eigene MousePointer-Eigenschaft kontrollieren. Jeder andere Wert für Screen.MousePointer erklärt den entsprechenden Mauszeiger als allgemeingültig und setzt die objektspezifischen Einstellungen für die Fenster der Anwendung (temporär) außer Kraft. Auf diese Weise kann eine Anwendung beispielsweise auf die Sanduhr umschalten, wenn eine zeitaufwändige Operation die Reaktivität der Benutzerschnittstelle beeinträchtigt. Eine wichtige Informationsquelle für die Bildschirmausgabe ist auch die Fonts-Auflistung des Screen-Objekts. Sie gibt einen Überblick über die auf dem System installierten Schriften. Beispiel
................................................... Beis piel
Das folgende Codefragment überträgt die Namen der auf dem System installierten Schriftarten in die Liste eines Kombinationsfeld-Steuerelements namens Combo1. Dim f As Integer For f = 0 To Screen.FontCount -1 Combo1.AddItem Screen.Fonts(f) Next
Sendkeys- Methode Sub SendKeys(String As String, [Wait As Boolean]) Beschreibung
................................................... Bes c hreibung
Die SendKeys-Methode interpretiert den Wert des Parameters String als Tastenfolge und sendet entsprechende Tastaturereignisse an das aktive Fenster (lies: an das Element, das den Fokus besitzt), so als ob der Benutzer dort die Tastenfolge per Tastatur eingegeben hätte. Wird der Parameter Wait mit dem Wert True versorgt, wartet die Anwendung, bis die Tastenfolge von der Zielanwendung tatsächlich verarbeitet wurde (Synchronbetrieb), ansonsten findet die Verarbeitung asynchron statt. Anwendung
................................................... Anwendung
Die SendKeys-Methode macht es möglich, das Fenster einer beliebigen Anwendung, das den Fokus besitzt, durch die Simulation von Tastaturereignissen gewissermaßen »fernzusteuern«. In der Tat ist dieser einfache Mechanismus seit jeher ein probates Mittel, die Prozessgrenze zu fremden Anwendungen zu überwinden und deren Steuerung zu übernehmen – eine primitive Form der Automatisierung also. Eine einfache Syntax mit einer Reihe von Schlüsselwörtern für die Bildung des Parameterwerts stellt sicher, dass sich alle Tasten und Tastenkombinationen ausdrücken lassen. Die Sonderzeichen »+«, »^« und »%« stehen für die Funktionstasten (Umschalt), (Strg) und (Alt) und wirken sich auf das folgende Zeichen bzw. die folgende durch einfache Klammern ausgezeichnete Gruppierung aus: SendKeys "+abs" SendKeys "+(abs)"
' sendet "Abs" ' sendet "ABS"
Um mehrere Funktionstasten auf ein Zeichen oder eine Zeichengruppe anzuwenden, ist keine Klammerung erforderlich. Für Zeichen, die sich in Großschreibung notieren lassen, ist die Angabe von »+« nicht erforderlich – aber auch nicht schädlich: SendKeys "ABS"
3 02
' sendet "ABS"
Unload- Methode
Zu den weiteren Sonderzeichen zählen »~« für die Eingabetaste sowie die geschweiften Klammern »{Schlüsselwort}« zur Notation der Sonderzeichen »+^%~(){}« in literaler Bedeutung sowie von Schlüsselwörtern für Tasten, die selbst kein Zeichen hervorbringen. SendKeys "{{ }" SendKeys "erste Zeile+~zweite Zeile"
' sendet "{" ' Zeilenwechsel in Multiline' Textfeld SendKeys "nähmlich{Left 5}{Backspace}{Right 4}" ' Eingabe der Zeichen' folge "nämlich"
Symbol
Bedeutung
Symbol
Bedeutung
+
(Umschalt)
^
(Strg)
%
(Alt)
~
(Eingabe)
(
Zeichengruppierung
)
Zeichengruppierung
{
Schlüsselwort folgt
}
Schlüsselwort zu Ende
{Backspace} {BS}, {Bksp}
(Rücktaste)
{Delete} {Del}
(Entf)
{Capslock}
(Feststelltaste)
{Break}
(Pause)
{Down}
(Unten)
{End}
(Ende)
{Enter}
(Eingabe)
{Esc}
(Esc)
{Help}
(Hilfe)
{Home}
(Pos1)
{Insert}, {Ins}
(Einf)
{Left}
(Links)
{Numlock}
(Num)
{PgDn}
(BildAb)
{PgUp}
(BildAuf)
{PrtSc}
(Druck)
{Scrolllock}
(Rollen)
{Tab}
(Tab)
{Up}
(Oben)
{F1} bis {F16}
(F1) bis (F16)
Beispiel
................................................... Beis piel
SendKeys "%{F4}"
' beendet aktives Fenster
Unload- Methode Sub Unload(Object) Beschreibung
................................................... Bes c hreibung
Die Unload-Methode entlädt ein Formular oder ein zuvor mittels Load in ein SteuerelementeArray geladenes Steuerelement Object. Der Entladevorgang zerstört zwar das Fenster der Instanz, nicht jedoch das in der Visual-Basic-Umgebung dafür existierende Objekt. (Dieses wird erst abgebaut, wenn sein Geltungsbereich erloschen ist und das Terminate-Ereignis eintritt!) Für ein Formular bewirkt der Unload-Aufruf der Reihe nach die Ereignisse QueryUnload und Unload. Das Formular kann im Zuge der Behandlung dieser Ereignisse den Entladevorgang unterbinden, indem es den Cancel-Parameter auf True setzt. In diesem Fall bleibt der UnloadAufruf ohne weitere Wirkung.
3 03
Global- Objekt
Die folgende Tabelle gibt einen Überblick über alle von der Methode erkannten Schlüsselwörter und Symbole sowie deren Bedeutung:
Auflistungen und Collection- Objekte
Anwendung
................................................... Anwendung
Ein einmal entladenes Steuerelement oder Formular kann jederzeit mit Load erneut geladen und durch Setzen der Visible-Eigenschaft auf True (bzw. einen Show-Aufruf) erneut angezeigt werden. Das Fenster des Objekts wird dann neu initialisiert. Beachten Sie jedoch, dass sich Steuerelemente, die bereits zur Entwurfzeit auf einem Formular platziert wurden, nicht entladen lassen. Beispiel
Auflistungen und Collection- Objekte
................................................... Beis piel
Ein Formular enthalte zum Beenden seiner selbst eine Befehlsschaltfläche namens cmdBeenden. Der Code dafür ist denkbar einfach: Private Sub cmdBeenden_Click() Unload Me End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
Load
Auflistungen und Collection- Objekte Dim cols As Collection Objekt.Controls, Printers, Objekt.ListImages
Forms,
Screen.Fonts,
Printer.Fonts,
DataObject.Files,
Beschreibung
................................................... Bes c hreibung
Bei Auflistungen handelt es sich um spezielle Datentypen, die ähnlich einem dynamischen Array beliebige Elemente eines Datentyps speichern können und den indexsequenziellen Zugriff darauf ermöglichen. Trotz der rein – funktional gesehen – engen Verwandtschaft mit dynamischen Arrays sind Auflistungen Objekte mit Eigenschaften und Methoden, und der zugehörige allgemeine Objektdatentyp Collection ist so etwas wie eine »objektorientierte Implementation dynamischer Arrays«. Wie für jeden Objektdatentyp lassen sich auch für den Typ Collection Objektvariablen vereinbaren, die auf bestehende Auflistungen verweisen können. Neue Auflistungsobjekte werden wie üblich mit dem New-Operator generiert. Anders als bei dynamischen Arrays ist der Elementdatentyp einer Auflistung grundsätzlich Variant, so dass Auflistungen als Elementwerte alles »schlucken«, was sich auch einer Variablen des Typs Variant zuweisen lässt – Werte mit benutzerdefinierten Datentypen, für die eine Type-Deklaration vorliegt, gehören somit nicht dazu. Ein Collection-Objekt besitzt die vier Methoden Add, Remove, Count und Item. Die Methode Add fügt ein neues Element in die Auflistung ein. Ihr Prototyp lautet: Sub Liste.Add (Item, [Key As String], [Before As Long], [After As Long])
Der Parameter Item stellt den Wert den neuen Elements. Über den Zeichenfolgenparameter Key lässt sich optional ein Schlüssel für den assoziativen Zugriff auf das Element festlegen. Er muss eindeutig sein. Die optionalen Parameter Before bzw. After erlauben die Angabe eines Positionswerts größer 0, vor bzw. nach dem das Element für den indexsequenziellen Zugriff eingefügt wird. Ohne Positionsangabe fügt das Objekt neue Elemente grundsätzlich hinten an.
3 04
Auflistungen und Collection- Objekte
Umgekehrt ermöglicht die Methode Remove das Entfernen eines Elements aus der Auflistung. Sie wird unter Angabe der Position Index oder des für das Element vereinbarten Schlüssels Key aufgerufen: Sub Liste.Remove (Index As Long | Key As String)
Function Liste[.Item](Index As Long | Key As String)
Äquivalent sind folgende Schreibweisen: Element = MeineListe.Item(i) Element = MeineListe(i)
Falls das Element i seinerseits eine Auflistung ist, mutet die reduzierte Schreibweise für den Zugriff auf deren j-tes Element ein wenig seltsam an, sie ist aber korrekt: Element = MeineListe(i)(j) Anwendung
................................................... Anwendung
Die Bezeichner von Eigenschaften und Variablen, die als Auflistung definiert sind, tragen in Visual Basic traditionell das Plural-«s« der englischen Sprache. Allerdings ist nicht überall, »wo Auflistung draufsteht, auch Collection drin«. Das liegt im Wesentlichen daran, dass Windows selbst eine Reihe verschiedener Objektdatentypen für spezifische Auflistungen verwendet, für die andere Eigenschaften und Methoden als für Collection definiert sind. Mithin ist es also nicht möglich, einer Collection-Variablen jede in Visual Basic anzutreffende Auflistung zuzuordnen, so dass in vielen Fällen ein spezieller Typ für die Variable vereinbart oder auf den allgemeinen Datentypen Object zurückgegriffen werden muss. Als Programmierer bekommt man hier allerdings schnell den Eindruck des Wildwuchses, denn was hier eindeutig fehlt, ist eine klare Linie. So ist es beispielsweise nicht gerade sehr instruktiv, dass manche Auflistungen mit dem Index 0 beginnen, andere dagegen mit dem Index 1, und dass Auflistungen wie Fonts der Objekte Screen und Printer oder die List-Eigenschaft von Listenfeldern weder einer Objektvariablen noch einer Array-Variablen als Wert zugeordnet werden können – mit dem dummen Effekt, dass sie sich auch nicht als Parameter bei Funktionsaufrufen übergeben lassen. Immerhin ist die Schreibweise für den Zugriff auf einzelne Elemente einheitlich: Es kann durchgehend die Array-Notation unter Angabe eines Positionsindex verwendet werden – was übrigens nur deshalb geht, weil Item als Standardmethode für Auflistungen vereinbart ist und nicht notiert werden muss. Darüber hinaus erweist sich die Möglichkeit, neben dem Positionsindex auch Bezeichner für die Elemente einer Auflistung zu vereinbaren, als höchst praktisch, wenn es eine Sortierordnung gibt oder mit einer Fluktuation der Elemente zu rechnen ist. Nachdem die Remove-Methode dafür sorgt, dass keine Lücken in der fortlaufenden Zählung der Elemente entstehen, verkleinern sich die Positionsindizes aller Elemente nach einem gelöschten Element um 1. Umgekehrt erhöht die Add-Methode die Positionsindizes nachfolgender Elemente um 1, wenn sie ein Element an einer bestimmten Position einfügt. Während sich gewöhnliche Arrays elementweise ausschließlich in For-Zählschleifen mit Zählindex durchlaufen lassen, gibt es für Auflistungen als Alternative die For Each-Kontrollstruktur,
3 05
Auflistungen und Collection- Objekte
Die parameterlose Methode Count liefert die Anzahl der Elemente in der Auflistung und zugleich – da Auflistungen 1-basiert sind – die Position des letzten Elements. Solange eine Auflistung leer ist, lautet das Ergebnis 0. Die Methode Item wird unter Angabe eines Positionswerts Index oder Schlüssels Key aufgerufen und liefert das entsprechende Element. Da es sich bei dieser Methode um die Standardmethode des Objekts handelt, muss ihr Bezeichner nicht unbedingt notiert werden, der Parameter aber sehr wohl. Der Prototyp lautet:
Formulare
die kein Problem damit hat, wenn sich die Anzahl der Elemente während der Aufzählung ändert, und die auch die Ergebnisse von Add und Remove berücksichtigt, sofern sich diese auf noch nicht aufgezählte Positionen beziehen. Dim Drucker As Printer For Each Drucker In Printers List1.AddItem Drucker.DeviceName Next Beispiel
Formulare
................................................... Beis piel
Der folgende Code arbeitet mit drei verschiedenen Auflistungstypen. Er instanziiert ein neues Auflistungsobjekt und fügt die Schriftnamen des zweiten (!) auf dem System installierten Druckers als Einträge ein. Dim l As Collection Set l = New Collection For i = 0 To Printers(1).FontCount – 1 ' Printers beginnt bei Index 0 l.Add Printers(1).Fonts(i) ' Fonts beginnt bei Index 0 Next Print TypeName(l(1)) ' Ausgabe: "String"
Formulare Wenn es so etwas wie einen Standardzugang für die Programmierung mit Visual Basic gibt, dann ist dies das Formular. Es vereinigt zunächst einmal alles unter sich, was für die Umsetzung traditioneller Basic-Programme benötigt wird: die zeichenorientierte Ein- und Ausgabe sowie eine grafische Ausgabefläche in Form eines Fensters. Damit aber nicht genug. Hinzu kommt die mühelose Integration nicht nur aller klassischen Elemente der Windows-Benutzerschnittstelle: Menü, Symbolleiste, Statusleiste und der üblichen Steuerelemente (Kontrollkästchen, Optionsfeld, Listenfeld, Textfeld, Schaltfläche etc.), sondern auch beliebiger im COM-Standard gehaltener ActiveX-Steuerelemente und -Komponenten. Wer unter Visual Basic ein neues Projekt anlegt und »Standard EXE« als Projekttyp auswählt, erhält den Rahmen für ein einfaches im Stand-alone-Betrieb ausführbares Programm, in dem sich als Vorgabe ein einzelnes Formularmodul mit dem Namen Form1 befindet. Aus Sicht der objektorientierten Programmierung stellt ein Formularmodul einen eigenständigen Objektdatentyp (bzw. Klasse) dar, der auf die Klasse Form aufsetzt und für den sich nach Belieben Instanzen ins Leben rufen sowie Objektvariablen vereinbaren lassen. Ist ein Formular (wie für den Projekttyp »Standard-EXE« bereits voreingestellt) im Dialogfeld PROJEKTEIGENSCHAFTEN auf der Seite ALLGEMEIN als Startobjekt für das Projekt angegeben, sorgt der Compiler dafür, dass beim Programmstart implizit eine Instanz dieses Formulars generiert wird, zur Anzeige kommt und die Kontrolle erhält (lies: initialisiert wird und den Fokus erhält). Ein neues Projekt des Typs »Standard EXE« lässt sich somit bereits ohne weiteres Zutun des Programmierers sofort kompilieren und stellt das Gerüst für ein vollständiges Programm im Sinne der Windows-Programmierung dar: ein Fenster (als visuelle Komponente des Formulars) mit Systemmenü, das sich vergrößern, verkleinern, verschieben und wieder schließen lässt. Im Programmiermodell von Windows ist ein Fenster mehr als nur eine Ausgabefläche. Ausgestattet mit einer Schnittstelle für den Empfang von Nachrichten, die das Fenster über die Aktivitäten des Benutzers (Mausereignisse, Tastatureingaben) sowie über sonstige Ereignisse (Initialisierungsphasen, Mitteilungen anderer Fenster) informieren, wird es zu einer Art Kom-
306
Form- Objekt (Basisobjekt für Formulare)
Form- Objekt (Basisobjekt für Formulare) Dim Formular As Form Beschreibung
................................................... Bes c hreibung
Der Datentyp Form ist Grundlage aller Formulare und stattet diese mit einer reichhaltigen Sammlung an Eigenschaften, Methoden und Ereignissen aus. Es lassen sich zwar Variablen dieses Datentyps vereinbaren, die Referenzen auf beliebige Formularobjekte (konkrete Instanzen von Formulardatentypen) enthalten können, das hinter dem Objektdatentyp selbst steckende Objekt lässt sich jedoch weder instanziieren noch ansprechen. Das liegt daran, dass es sich bei Form (ebenso wie bei MDIForm, UserControl, UserDocument, PropertyPage und ClassModul) um einen Schnittstellendatentyp (abstrakte Klasse) handelt, der als Vorlage für konkrete Klassen fungiert, jedoch nicht dafür gedacht ist, eigenständige Objekte hervorzubringen. Vielmehr tritt das Form-Objekt als Basisobjekt und somit als invarianter Kern konkreter Formulare auf, die nicht nur Objekte (nämlich Dialogfelder) hervorbringen können, weil sie eigenständige Datentypen bzw. Klassen darstellen, sondern auch in je eigenen Modulen organisiert sind. Da sich die Eigenschaften, Methoden des Form-Objekts auf die konkreten Formulardatentypen übertragen und das Form-Objekt dem jeweils umhüllenden konkreten Objekt Ereignisse signalisiert, die dieses behandeln kann, aber nicht muss, erhält man ein Aggregat, das landläufig als Formularobjekt bezeichnet wird – ohne dass sprachlich ein Unterschied zwischen dem Formulardatentyp und der konkreten Instanz des Formulardatentyps (dem »Formular«, das als Fens-
3 07
Formulare
mandozentrale für alle das Fenster als visuellen Bereich (gegebenenfalls mit Binnenstruktur) und als eigenständige operationale Einheit (Objekt mit untergeordneten Objekten) betreffenden Vorkommnisse. In der Dokumentation zu Visual Basic wird selten ein Unterschied zwischen einem Formularobjekt und dem dazugehörigen Fenster gemacht – eine Sicht, die in den meisten Fällen wohl ausreichend ist, doch vielfach auch Verständnisschwierigkeiten bereitet, was die wahre Natur des Formulars betrifft. Genau genommen ist ein Fenster nämlich ein vom Betriebssystem als Ressource zur Verfügung gestelltes Objekt mit visueller Repräsentation und der besagten Nachrichtenschnittstelle, während das Formularobjekt eine aufseiten von Visual Basic gelegene Instanz einer Klasse mit Eigenschaften, Methoden und Ereignissen ist, die das Fenster gewissermaßen umhüllt. Mithin sollte man also nicht sagen: »ein Formular ist ein Fenster«, sondern: »ein Formular hat ein Fenster«. (Deutlich wird der Unterschied, wenn man sich vor Augen hält, dass das Fenster eines Formularobjekts mittels Unload jederzeit abgebaut werden kann, während das Objekt weiter existiert und sich jederzeit über einen Load- bzw. Show-Aufruf ein neues Fenster organisieren kann.) Um das genannte Programmgerüst weiter auszugestalten, fügt man zum einen in den Entwurfsbereich des Formulars Steuerelemente ein, die eine geeignete Umsetzung der gewünschten spezifischen Ein-/Ausgabefunktionalität gestatten, und definiert zum anderen im Codefenster des Formulars geeignete Behandlungsroutinen für die verschiedenen von den Steuerelementen und dem Fenster signalisierten Ereignisse. Bei der Programmierung mit Formularen unterscheidet man zwischen SDI-Formularen (Single Document Interface) und MDI-Formularen (Multiple Document Interface). SDI-Formularen liegt der Datentyp Form zugrunde. Sie verfügen über eine reichhaltige Ausstattung an Eigenschaften und Methoden für die Grafik- und Textausgabe und können als Container für Steuerelemente und sonstige Komponenten fungieren, jedoch nicht für weitere Formulare. MDI-Formularen liegt hingegen der Datentyp MDIForm zugrunde. Sie kennen keine Grafikmethoden, erlauben nur die Platzierung von bestimmten Steuerelementen (nämlich solchen, die als Leisten definiert sind) und sind ansonsten speziell auf die Verwaltung und Darstellung untergeordneter SDI-Formulare im eigenen Client-Bereich eingerichtet.
Formulare
ter auf dem Bildschirm erscheint) gemacht wird. Dennoch sollte man sich immer darüber im Klaren sein, dass zu unterschiedlichen Formularen unterschiedliche Formulardatentypen gehören, die auf ein und dieselbe Standardschnittstelle Form aufbauen, und dass jeder Formulardatentyp beliebig viele Instanzen des gleichen Formulars hervorbringen kann, deren Bildschirmdarstellungen (Fenster) sich aber je nach Objektzustand erheblich voneinander unterscheiden können. Eigenschaften
Formulare
................................................... Eigens c ha ften ActiveControl, Appearance, AutoRedraw, BackColor, BorderStyle, Caption, ClipControls, ControlBox, Controls, Count, CurrentX, CurrentY, DrawMode, DrawStyle, DrawWidth, Enabled, FillColor, FillStyle, Font, FontBold, FontItalic, FontName, FontStrikethru, FontTransparent, FontUnderline, ForeColor, HasDC, hDC, Height, HelpContextID, hWnd, Icon, Image, KeyPreview, Left, LinkMode, LinkTopic, MaxButton, MDIChild, MinButton, MouseIcon, Mousepointer, Moveable, Name, OLEDropMode, Palette, PaletteMode, Picture,RightToLeft, ScaleHeight, ScaleLeft, ScaleMode, ScaleTop, ScaleWidth, ShowInTaskbar, StartupPosition, Tag, Top, Visible, WhatsThisButton, WhatsThisHelp, WhatsThisMode, Width, WindowState Die folgende Tabelle gibt einen Überblick über die nicht anderer Stelle vorgestellten Eigenschaften des Formulars: Eigenschaft
Beschreibung
ActiveControl
Zur Laufzeit schreibgeschützter Object-Verweis auf das Steuerelement des Formulars, das im Besitz des Fokus ist; der Wert ist Nothing, wenn kein Steuerelement, sondern das Formular den Fokus hat
AutoRedraw
Boolean-Wert, der bestimmt, ob das Formularobjekt den Client-Bereich automatisch neu zeichnet oder dazu eine Paint-Routine verwendet (vgl. »Paint-Ereignis«, S. 253)
ClipControls
Boolean-Wert, der bestimmt, ob Visual Basic für Steuerelemente Bildausschnitte bei der Restaurierung des Objektbereichs berechnet oder nicht
ControlBox
Zur Laufzeit schreibgeschützter Boolean-Wert, der bestimmt, ob das Formularfenster zur Laufzeit ein Systemmenü besitzt.
Controls
Schreibgeschützte Object-Auflistung, die alle Steuerelemente des Formulars als Elemente enthält. Beim Entwurf zuletzt eingefügte Steuerelemente kommen zuerst.
Count
Schreibgeschützter Integer-Wert, der die Anzahl der in der Controls-Auflistung des Formulars befindlichen Steuerelemente wiedergibt.
CurrentX CurrentY
Single-Werte, die die Startkoordinaten für die Zeichenoperationen Print, Circle, Pset, Line im aktuellen Koordinatensystem (vgl. ScaleMode) beschreiben und von diesen Methoden auch aktualisiert werden
KeyPreview
Boolean-Wert, der bestimmt, ob das Formular Tastaturereignisse, die seinen Steuerelementen gelten, gleichfalls behandeln kann (True) – und zwar vor diesen – oder nicht (False). Diese Eigenschaft ermöglicht beispielsweise die zentrale Tastatursteuerung auf Formularebene.
MaxButton MinButton
Boolean-Werte, die bestimmen, ob das Formularfenster die Schaltflächen MINIMIEREN, MAXIMIEREN und WIEDERHERSTELLEN anzeigt (True) oder nicht (False)
308
Form- Objekt (Basisobjekt für Formulare)
Beschreibung
MDIChild
Zur Laufzeit schreibgeschützter Boolean-Wert, der bestimmt, ob das Formular einem MDI-Formular untergeordnet ist (True) oder nicht (False)
Moveable
Boolean-Wert, der bestimmt, ob der Benutzer das Formular verschieben kann (True) oder nicht (False)
Palette
Picture-Wert, der auf ein Bild mit Palette verweist. Voreinstellung der Eigenschaft ist ein Verweis auf die Standardpalette des Systems, in der die unteren und oberen 20 Einträge mit den Systemfarben besetzt sind. Die Palette definiert einen indizierten Farbraum für die Darstellung von Bildern und Grafik in palettenorientierten Anzeigemodi (beispielsweise der Anzeigemodus »256-Farben«). Die Verwendung der Palette ist vom Wert der Eigenschaft PaletteMode abhängig
PaletteMode
Integer-Wert, der bestimmt, welche Palette das Formular (oder Benutzersteuerelement) für die Anzeige seiner Steuerelemente verwendet. Der Aufzählungsdatentyp PaletteModeConstants definiert Konstanten für die verschiedenen zur Auswahl stehenden Paletten: vbPaletteModeHalftone (0) Systempalette verwenden (Voreinstellung) vbPaletteModeUseZOrder (1) Palette des zuvorderst gezeichneten Steuerelements verwenden vbPaletteModeCustom (2)
Über Palette-Eigenschaft definierte Palette verwenden
vbPaletteModeContainer (3) Über Palette-Eigenschaft des Container-Objekts definierte Palette verwenden, sofern bekannt vbPaletteModeNone (4)
Keine Palette verwenden (betrifft nur Benutzersteuerelemente)
vbPaletteModeObject (5)
Palette des ActiveX-Designers verwenden. (Betrifft nur ActiveX-Designer, die eine Palette enthalten.)
ShowInTaskbar
Boolean-Wert, der bestimmt, ob das Formular in der Taskleiste erscheint (True) oder nicht (False)
StartupPosition
Integer-Wert, der die Position qualitativ beschreibt, an der das Formular unmittelbar nach dem Laden angezeigt wird. Der Aufzählungsdatentyp StartupPositionConstants definiert Konstanten für die verschiedenen zur Auswahl stehenden Positionen: vbStartupManual (0) Keine Vorgabe, Windows gibt die Position nach eigenen Kriterien vor vbStartupOwner (1)
Fenstermitte; das Formular erscheint zentriert im übergeordneten Fenster (MDIFormular)
vbStartUpScreen (2)
Bildschirmmitte; das Formular erscheint zentriert im Fenster des Screen-Objekts (Bildschirm)
vbStartUpWindowsDefault (3)
Das Formular erscheint in der linken oberen Ecke im Fenster des Screen-Objekts (Bildschirm)
3 09
Formulare
Eigenschaft
Formulare
Eigenschaft
Beschreibung
WhatsThisButton
Boolean-Wert, der bestimmt, ob das Formular die Schaltfläche HILFE in der Titelleiste erhält (True) oder nicht (False). Achtung: Damit die Anzeige erfolgen kann, müssen MinButton und MaxButton auf False gesetzt sein.
WindowState
Integer-Wert, der den Anzeigezustand des Formularfensters zur Laufzeit bestimmt – zur Auswahl stehen die Werte: vbNormal (0); vbMinimized (1); vbMaximized (2).
................................................... Methoden
Formulare
Methoden
Circle, Cls, Line, Hide, Move, OLEDrag, PaintPicture, Print, Point, PopupMenu, Pset, PrintForm, Refresh, Scale, ScaleX, ScaleY, SetFocus, Show, TextHeight, TextWidth, ValidateControls, WhatsThisMode, ZOrder Die folgende Tabelle gibt einen Überblick über die nicht an anderer Stelle vorgestellten Methoden des Formulars. Die Prototypen lauten: Sub Circle [Step] (x, y), r, [color As Long], [start, end], [ratio] Sub Cls() Sub Line [Step] (x1, y1) – [Step] (x2, y2), [color As Long], [B[F]] Sub Hide() Sub PaintPicture(Pic As Picture, x1, y1, Height1, Width1, x2, y2, _ Height2, Width2) Function Point(x, y) As Long Sub PopupMenu(Menu As Object, Flags, x, y, DefaultMenu) Sub Print Wert1 [,|;] Wert2 [,|;] ... Sub PrintForm() Sub PSet [Step] (x, y), [Color As Long] Sub Scale(x1, y1) – (x2, y2) Function ScaleX(Width, [FromScale], [ToScale]) As Single Function ScaleY(Height, [FromScale], [ToScale]) As Single Sub Show() Function TextHeight(Str As String) As Single Function TextWidth(Str As String) As Single Sub ValidateControls() Sub WhatsThisMode()
31 0
Form- Objekt (Basisobjekt für Formulare)
Kurzbeschreibung
Circle
Zeichnet einen Kreis um den Mittelpunkt (x, y) mit Radius Radius und der optionalen Stiftfarbe Color. Es gilt das aktuelle Koordinatensystem des Formulars. Sind die optionalen Parameter Start und End angegeben, zeichnet die Methode nur einen Teilkreis. Start und End bezeichnen den Startund Endwinkel (im Bogenmaß). Ist der Parameter Aspect mit einem Wert ungleich 1 bzw. -1 angegeben, zeichnet die Methode eine Ellipse, die dem Kreis einbeschrieben (positive Werte) bzw. umbeschrieben (negative Werte) ist. Aspect drückt das Verhältnis zwischen Höhe und Breite des begrenzenden Rechtecks aus.
Cls
Löscht den Client-Bereich, indem es diesen mit der Hintergrundfarbe BackColor füllt
Line
Zeichnet eine Linie zwischen den Punkten (x1, y1) und (x2, y2). Ist der optionale Zusatz »B« gegeben, zeichnet die Methode das Rechteck, das die beiden Punkte definieren. Ist der optionale Zusatz »BF« gegeben, zeichnet die Methode das Rechteck und füllt es mit der Füllfarbe FillColor aus.
Hide
Setzt die Visible-Eigenschaft auf False und macht das Formular unsichtbar
PaintPicture
Zeichnet das im Datentyp Picture vorliegende Bild Pic an der Position (x1, y1), die den linken oberen Bildpunkt beschreibt. Alle Werte sind in der aktuellen Maßeinheit des für das Formular geltenden Koordinatensystems (ScaleMode) anzugeben. Sind die optionalen Parameter Height1 und Width1 vorhanden, wird das Bild auf diese Maße skaliert, ansonsten errechnet sich die Methode diese Werte selbst und gibt das Bild in originaler Größe aus. Sind die optionalen Parameter x2 und y2 sowie Width2 und Height2 angegeben, beschreiben diese einen Bildausschnitt innerhalb des Bildes, der (nach impliziter Skalierung) in dem durch x1, y1, Width1 und Height1 spezifizierten Rechteck ausgegeben wird. (Achtung, die Eigenschaften Height und Width eines Picture-Objekts sind in der Maßeinheit »HiMetric« gehalten und müssen gegebenenfalls mittels ScaleX und ScaleY in die geltende Maßeinheit – Vorgabe ist Twips – umgewandelt werden.) Negative Werte für Height und/oder Width führen zu einer spiegelverkehrten und/oder um 180° gedrehten Ausgabe. Koordinaten für Ausschnitte sind auf den Ursprung des aktuellen Koordinatensystems zu beziehen!
Point
Liefert den Farbwert des Punkts mit den Koordinaten (x, y) als Long-Wert
PopupMenu
Zeigt das Popup-Menü Menu als Kontextmenü an der aktuellen Mausposition an. Der optionale Parameter Flags ermöglicht die Angabe eines Bitvektors, der die Position sowie das Verhalten des Menüs bestimmt. Für die einzelnen Bits sind folgende Konstanten definiert. vbPopupMenuLeftAlign (0) links an der Position (x, y) ausgerichtet (Voreinstellung) vbPopupMenuCenterAlign (4) mittig zur Position (x, y) ausgerichtet vbPopupMenuRightAlign (8)
rechts an der Position (x, y) ausgerichtet
vbPopupMenuLeftButton (0)
linke Maustaste aktiviert Menübefehl (Voreinstellung)
vbPopupMenuRightButton (2) rechte Maustaste aktiviert Menübefehl
31 1
Formulare
Methode
Formulare
Formulare
Methode
Kurzbeschreibung
PopupMenu (Forts.)
Die optionalen Parameter x und y ermöglichen die Angabe einer Position (x, y) im Koordinatensystem des Formulars, relativ zu der das Menü ausgerichtet wird. Fehlen beide Parameter, verwendet die Methode die aktuellen Mauskoordinaten. Über den optionalen Parameter DefaultMenu lässt sich schließlich der Bezeichner für den als Standard vorgeschlagenen Menübefehl spezifizieren. Der entsprechende Befehl erscheint dann im Menü fett.
Print
Gibt die in der Parameterliste befindlichen Werte in textueller Repräsentation an der Position (CurrentX, CurrentY) und mit den aktuellen Schrifteinstellungen (Font) aus. Als Trennzeichen für die Parameter sind das Semikolon und das Komma zulässig. Folgt ein Semikolon auf einen Parameter, wird der nächste Wert (ggf. auch im Rahmen der nächsten PrintAnweisung) ohne Zwischenraum dahinter gesetzt. Folgt ein Komma auf einen Parameter, wird der nächste Wert (ggf. auch im Rahmen der nächsten Print-Anweisung) an der nächsten Tabulatorposition ausgegeben. Print-Anweisungen, deren Parameterliste nicht mit einem Trennzeichen endet, bewirken einen Zeilenvorschub. Ein automatischer Zeilenumbruch findet ansonsten nicht statt.
PrintForm
Gibt die auf dem Formular befindlichen Steuerelemente samt Inhalte auf dem Standarddrucker aus. Direkt in den Client-Bereich des Formulars gezeichnete Ausgaben werden nicht ausgegeben, auch keine Hintergrundbilder (Picture).
PSet
Zeichnet einen Punkt an der Position (x, y) in der Farbe Color
Scale
Setzt ein Koordinatensystem für den Client-Bereich des Formulars, bei dem der linke obere Punkt die Koordinaten (x1, y1) und der rechte untere Punkt die Koordinaten (x2, y2) hat
ScaleX ScaleY
Rechnet die Koordinate Width für die X-Achse (bzw. Y-Achse) vom Koordinatensystem FromScale in das Koordinatensystem ToScale um und liefert die neue Koordinate als Single. Fehlt einer der optionalen Parameter für ein Koordinatensystem, bezieht sich die Methode auf das aktuell geltende Koordinatensystem. Für die verschiedenen Koordinatensysteme sind Integer-Konstanten definiert (vgl. »ScaleMode-Eigenschaft«, S. 369)
Show
Die Methode zeigt das Formular an, indem sie die Visible-Eigenschaft auf True setzt. Falls das Formular noch nicht geladen ist, die Formularvariable aber unter Angabe von New deklariert wurde, findet implizit ein Load-Aufruf statt.
TextHeight
Liefert die für die Ausgabe der Zeichenfolge Str benötigte Höhe in der aktuellen y-Maßeinheit des aktuellen Koordinatensystems
TextWidth
Liefert die für die Ausgabe der Zeichenfolge Str benötigte Breite in der aktuellen x-Maßeinheit des aktuellen Koordinatensystems
ValidateControls Sorgt dafür, dass die Inhalte aller Steuerelemente auf dem Formular gültig sind (Validate-Ereignis), bevor das Formular geschlossen wird WhatsThisMode
31 2
Aktiviert den Direkthilfemodus (Mauszeiger wird zu Pfeil mit Fragezeichen)
MDIForm- Objekt
Die Syntax für den Aufruf der Methoden Circle, Line und PSet ist traditionell spezifisch: Ist das optionale Schlüsselwort Step angegeben, wird das unmittelbar folgende Koordinatenpaar als relativer Offset bzgl. der aktuellen Position (CurrentX, CurrentY) interpretiert, sonst als absolute Position – jeweils bezogen auf das geltende Koordinatensystem. Standardmäßig zeichnen die Methoden in der durch die Eigenschaft ForeColor spezifizierten Farbe (Standardwert ist Schwarz: vbBlack). Beliebige Farben lassen sich aus ihren Komponentenanteilen über die Funktion RGB zu einem Long-Wert für den optionalen Parameter Color komponieren. Definierte Farben liefert die Funktion QBColor (16 Grundfarben) sowie der Aufzählungstyp ColorConstants. Füllfarbe ist FillColor, sofern FillStyle ungleich 1 ist. Anwendung
Die Möglichkeiten und Anlässe für die Anwendung von Formularobjekten sind so vielfältig und unerschöpflich, dass es wenig Sinn hat, sich darüber im Einzelnen auszulassen. Allein dieses Buch dürfte um die hundert unterschiedliche Konzeptionen für Formulare bzw. formularbasierte Programme vorstellen, und letztlich lässt sich fast der gesamte Text des Buches in dem Kontext »für den Einsatz auf/mit/in einem Formular« lesen. Mit dem Objektdatentyp Form verhält es sich anders. Dass es überhaupt möglich ist, Variablen dieses Typs zu vereinbaren und ihnen Formularinstanzen (wohlgemerkt: Instanzen, nicht Formulare) als Wert zuzuordnen, resultiert aus dem von Visual Basic verwendeten PolymorphieKonzept. Da die einzelnen Formulardatentypen eines Projekts nichts weiter als spezifische Implementationen ein und derselben der Form-Schnittstelle darstellen und somit dieselbe Grundstruktur besitzen, ist es zulässig, den gleichen Zeiger für Referenzen auf unterschiedliche Datentypen zu verwenden. Beispiel
................................................... Beis piel
Im folgenden Codeauszug vertritt eine Variable des Typs Form Instanzen zweier unterschiedlicher Formulare. Dim f As Form Dim erstesFormular As New Form1 ... Set f = erstesFormular ' Form1 wird implizit instanziiert! f.Show ' Instanz wird angezeigt ... Set f = New Form2 ' Form2 wird explizit instanziiert! f.Show ' Form2-Instanz wird angezeigt Verwandte Themen
................................................... Verwandte Them en
Vollbildanzeige (S. 536); DiaProjektor – SDI-Formulare synchronisieren (S. 511)
MDIForm- Objekt Dim mdiFormVar As MDIForm Dim mdiFormTypVar As MDIFormTyp Beschreibung
................................................... Bes c hreibung
Was die formale Natur des MDIForm-Objekts als Datentyp betrifft, so gilt das Gleiche wie für das Form-Objekt (vgl. dort, insbesondere die Klärung zur sprachlichen Verwendung des Wortes »MDI-Formularobjekt«).
31 3
Formulare
................................................... Anwendung
Formulare
Formulare
Im Gegensatz zu gewöhnlichen Formularobjekten sind MDI-Formularobjekte in der Lage, Formulare in ihrem Client-Bereich anzuzeigen. Zudem bieten sie einen gewissen Komfort für die Verwaltung untergeordneter Formulare. Methoden für eigene Grafikoperationen (die über ein Setzen der vorhandenen Picture-Eigenschaft hinausgehen) kennt das MDI-Formular jedoch nicht. MDI-Formulare werden daher meist als Grundlage für die Implementation von Anwendungen verwendet, die mit mehreren Dokumentenfenstern arbeiten. Damit ein gewöhnliches Formular einem MDI-Formular untergeordnet werden kann, muss seine MDIChild-Eigenschaft (bereits zur Entwurfszeit) auf True gesetzt werden. Neben Formularen lassen sich auf einem MDI-Formular nur solche Steuerelemente platzieren, die im engeren oder weiteren Sinne als Leiste definiert sind: StatusBar, ProgressBar, Data, RemoteData, Adodc, ToolBar und PictureBox (erscheint als Leiste in voller Breite des Client-Bereichs). Darüber hinaus kann ein MDI-Formular ein Menü besitzen und Kontextmenüs zur Anzeige bringen. Eigenschaften
................................................... Eigens c ha ften ActiveControl, ActiveForm, Appearance, AutoShowChildren, BackColor, Caption, Controls, Count, Enabled, Height, HelpContextID, hWnd, Icon, Left, LinkMode, LinkTopic, MouseIcon, Mousepointer, Moveable, Name, NegotiateToolsbars, OLEDropMode, Picture,RightToLeft, ScaleHeight, ScaleWidth, ScrollBars, StartupPosition, Tag, Top, Visible, Width, WindowState Die folgende Tabelle gibt einen Überblick über die nicht anderer Stelle vorgestellten Eigenschaften des MDI-Formulars (vgl. insbesondere: Form-Objekt): Eigenschaft
Beschreibung
ActiveForm
Verweis auf das untergeordnete Formular, das im Besitz des Fokus ist (Datentyp entspricht dem Objektdatentyp des jeweiligen Formulars)
AutoShowChildren
Boolean-Wert, der bestimmt, ob nach dem Load-Aufruf für ein untergeordnetes Formular implizit ein Show-Aufruf erfolgt (True; Voreinstellung) oder nicht (False)
Controls
Schreibgeschützte Object-Auflistung, die alle Steuerelemente (nicht Formulare!) des MDI-Formulars als Elemente enthält. Beim Entwurf zuletzt eingefügte Steuerelemente kommen zuerst. Beachten Sie, dass sich nicht alle Arten von Steuerelementen in ein MDI-Formular einfügen lassen.
Count
Schreibgeschützter Integer-Wert, der die Anzahl der in der ControlsAuflistung für das Formular geführten Steuerelemente (nicht Formulare!) wiedergibt.
NegotiateToolbars
Boolean-Wert, der bestimmt, ob die Symbolleisten eines untergeordneten Objekts im MDI-Formular angezeigt werden, solange das Objekt aktiv ist
ScrollBars
Boolean-Wert, der bestimmt, ob das MDI-Formular automatisch Bildlaufleisten anzeigt, wenn der Client-Bereich für die vollständige Anzeige eines untergeordneten Formulars nicht ausreicht
Methoden
................................................... Metho den Arrange, Hide, Move, OLEDrag, PopupMenu, SetFocus, Show, ValidateControls, WhatsThisMode, ZOrder
31 4
MDIForm- Objekt
Die einzige nicht an anderer Stelle vorgestellte Methode des MDI-Formulars ist Arrange. Ihr Prototyp lautet: Sub Arrange (Arrange As FormArrangeConstants) Für den Aufruf der Methode definiert der Aufzählungstyp FormArrangeConstants drei Konstanten: Beschreibung
vbCascade (0)
Die Methode ordnet alle dem MDI-Formular untergeordneten sichtbaren und nicht minimierten Formulare als Kaskade an – das heißt: überlappend, mit zunehmender Verschiebung von links oben nach rechts unten, so dass von hinteren Fenstern die Titelleisten lesbar bleiben.
vbTileHorizontal (1)
Die Methode ordnet alle dem MDI-Formular untergeordneten sichtbaren und nicht minimierten Formulare in einer Reihe untereinander an, so dass sie den Client-Bereich der Breite und der Höhe nach vollständig ausfüllen.
vbTileVertical (2)
Die Methode ordnet alle dem MDI-Formular untergeordneten sichtbaren und nicht minimierten Formulare in einer Reihe nebeneinander an, so dass sie den Client-Bereich der Breite und der Höhe nach vollständig ausfüllen.
Anwendung
................................................... Anwendung
Wer MDI von anderen Programmiersprachen her kennt, wird die von Visual Basic vorgestellte MDI-Konzeption als denkbar einfach empfinden: Man füge dem Projekt ein neues Modul des Typs »MDI-Formular« hinzu (wobei je Projekt maximal ein MDI-Formular zulässig ist), das die Implementation für das MDI-Formular enthalten wird, und füge dem Projekt weiterhin für jeden dem MDI-Formular untergeordneten Formulartyp ein gewöhnliches Formularmodul hinzu, in dem die Eigenschaft MDIChild auf True gesetzt ist. Das war bereits alles; den Rest erledigt Visual Basic für Sie. Ist ein untergeordnetes Formular im Dialog PROJEKTEIGENSCHAFTEN als Startobjekt festgelegt, lädt Visual Basic das übergeordnete MDI-Formular automatisch noch vor dem untergeordneten Formular und zeigt es dann im Client-Bereich des MDI-Formulars an. Ist dagegen das MDI-Formular als Startobjekt definiert, kommt dieses mit leerem ClientBereich zur Anzeige und kann sich (beispielsweise im Rahmen seiner Load-Behandlung) selbst um die Anzeige untergeordneter Formulare kümmern. Die Ereignisreihenfolge für ein als Startobjekt festgelegtes MDI-Formular sieht so aus: Initialize Load Resize Activate ... QueryLoad Unload Terminate
Beim Entladen eines MDI-Formulars trifft das QueryUnload-Ereignis zuerst beim MDI-Formular und dann der Reihe nach bei den untergeordneten Formularen ein. Falls nur ein einziges Formular die Cancel-Eigenschaft auf True setzt, unterbricht das den Entladevorgang für alle Formulare. Ansonsten folgt das Unload-Ereignis, das diesmal zuerst aber alle untergeordneten
31 5
Formulare
Konstante
Formulare
Formulare
Formulare erreicht und erst zum Schluss das MDI-Formular. Falls ein untergeordnetes Formular bei der Behandlung des Unload-Ereignisses die Cancel-Eigenschaft auf True setzt, unterbricht das den Entladevorgang für alle folgenden Formulare (und damit auch für das MDI-Formular). Die Ereignisreihenfolge für ein automatisch über ein untergeordnetes Formular geladenes (und später wieder geschlossenes) MDI-Formular sieht damit so aus: Form.Initialize MDIForm.Initialize MDIForm.Load Form.Load MDIForm.Resize Form.Resize MDIForm.Activate Form.Activate Form.GotFocus ... MDIForm.QueryLoad Form.QueryLoad Form.Unload MDIForm.Unload Form.Terminate MDIForm.Terminate
Untergeordnete Formulare sind im Client-Bereich des MDI-Formulars eingesperrt, lassen sich darin aber bequem mittels Arrange auf drei verschiedene Arten anordnen. Automatisch vom MDIForm-Objekt gepflegte Bildlaufleisten sorgen dafür (ScrollBars-Eigenschaft), dass der Benutzer auch mit Formularen vernünftig arbeiten kann, die nicht vollständig in den Client-Bereich passen. Ein wichtiges Mittel für die Arbeit mit untergeordneten Formularen ist die Eigenschaft ActiveControl. Sie ermöglicht es, Operationen immer auf das Formular zu beziehen, das im Besitz des Fokus ist, ohne eigens darüber Buch führen zu müssen, welches Formular dies gerade ist. Um beispielsweise den Namen des aktiven Steuerelements im aktiven Formular zu ermitteln, schreiben Sie: sName = ActiveForm.ActiveControl.Name
Wie das Beispiel zu diesem Abschnitt zeigt, kann es einem diese Eigenschaft sogar ersparen, Objektvariablen auf geladene untergeordnete Variablen zu halten. Es versteht sich, dass die Eigenschaft nur dann einen von Nothing unterschiedlichen Wert aufweist, wenn es ein aktives untergeordnetes Formular gibt. Da ein Formular weder über eine Container-Eigenschaft noch über eine Parent-Eigenschaft verfügt, haben untergeordnete Formulare umgekehrt jedoch keine Information über das MDI-Formular, dem sie angehören. Beispiel
................................................... Beis piel
Mit dem Projekt MDIForm liegt die einfache Implementation eines MDI-Formulars vor, das beliebig viele Bilder in untergeordneten Fenstern anzeigen kann. Das Formular verfügt über eine Menüleiste mit den beiden Menüs DATEI und ANORDNEN. Ersteres enthält die Kommandos ÖFFNEN, um ein weiteres Bild in ein neues Fenster zu laden, SCHLIEßEN, um das aktive untergeordnete Fenster zu schließen, und BEENDEN, um das MDI-Formular samt aller untergeordneter Fenster zu schließen und das Programm zu beenden. Die Routine mnuDateiÖffnen_Click für die Behandlung von ÖFFNEN speichert das neue Formularobjekt in einer lokalen Variablen und demonstriert so recht schön, dass das Formularobjekt erhalten
31 6
MDIForm- Objekt
bleibt, obwohl im Programm keine Referenz mehr darauf existiert – allerdings hält das MDIFormular implizit noch eine Referenz darauf, nicht zuletzt um im Zuge des Unload-Aufrufs im Rahmen der Behandlung von BEENDEN automatisch alle untergeordneten Formulare entladen zu können. Die ebenso elegante wie undurchsichtige Implementation des zweiten Menüs ANORDNEN profitiert davon, dass die Menüeinträge als Array vereinbart sind. Sie nutzt den Parameter Index der Behandlungsroutine schlicht als Argument für Arrange. Klickt der Benutzer in den Client-Bereich des MDI-Formulars, wird dieses Menü auch als Kontextmenü angezeigt.
Formulare
' Modul MDIForm1: Formular zeigt Bilder in untergeordneten Formularen an Private Sub MDIForm_Load() mnuDateiÖffnen_Click ' Erstes Fenster öffnen End Sub Private Sub MDIForm_Click() PopupMenu mnuAnordnen End Sub Private Sub mnuDateiBeenden_Click() Unload Me ' Programm beenden End Sub Private Sub mnuDateiÖffnen_Click() ' Nächstes Fenster öffnen Dim SDIForm As New Form1 CommonDialog1.Filter = "Bilder|*.jpg;*.gif;*.bmp;*.wmf;*.emf;*.ico;*.cur" CommonDialog1.ShowOpen If CommonDialog1.filename "" Then SDIForm.ShowPic (CommonDialog1.filename) End If End Sub Private Sub mnuDateiSchließen_Click() Unload ActiveForm ' Fenster schließen End Sub Private Sub mnuOrdnen_Click(Index As Integer) Arrange (Index) ' Fenster anordnen End Sub
Das Formularmodul, das den Objektdatentyp für die untergeordneten Formulare definiert, ist recht geradlinig implementiert. Die Routine ShowPic lädt das Bild und baut ansonsten auf die Resize-Routine, die das Bild in geeigneter Skalierung zentriert mit Hilfe von PaintPicture in den Client-Bereich des Formulars zeichnet. ' Modul Form1: Formular lädt Bild und zeigt es in passender Größe an Private Bild As Picture Private Sub Form_Resize() Dim w, h ' Bild geeignet zentrieren w = Bild.Width: h = Bild.Height If w < Width Or w > ScaleWidth Then
31 7
Selbst definierte Klassen
Selbst definierte Klassen
w = ScaleWidth h = h * w / Bild.Width End If If h > ScaleHeight Then h = ScaleHeight w = Bild.Width * h / Bild.Height End If Cls PaintPicture Bild, (ScaleWidth – w) / 2, (ScaleHeight – h) / 2, w, h End Sub Public Sub ShowPic(filename As String) On Error GoTo Fehler Set Bild = LoadPicture(filename) ' Bild Laden On Error GoTo 0 Form_Resize ' Bild zeichnen Caption = Mid(filename, InStrRev(filename, "\") + 1) Exit Sub Fehler: Print "Dateiformat nicht erkannt" End Sub
Selbst definierte Klassen Wer schon das eine oder andere Formular oder gar Benutzersteuerelement implementiert hat, steckt bereits tiefer in der objektorientierten Programmierung, als er vermutet – und hat vom Prinzip her eigentlich schon das Wesentliche begriffen, was man für die Implementierung eigener Klassen benötigt. Jedes Formular oder Benutzersteuerelement verkörpert in Visual Basic nämlich einen eigenständigen Datentyp bzw. eine eigene Klasse, so dass die Programmiertechnik für den Umgang mit Formularen und Steuerelementen fundamental die gleiche ist wie für den Umgang mit Objekten selbst definierter Klassen – und auch die Implementation unterliegt den gleichen Gesetzmäßigkeiten und Prinzipien. Ja, selbst definierte Klassen sind sogar um einiges »pflegeleichter« als Formulare und Benutzersteuerelemente, da sie zunächst einmal weder eine visuelle Repräsentation in Form eines Fensters besitzen noch auf eine vergleichbar komplexe Schnittstelle aufsetzen. Was die Form-Schnittstelle für das Formular und die UserControl-Schnittstelle für das Benutzersteuerelement, das ist die ClassModule-Schnittstelle für eine selbst definierte Klasse. Sie stattet eine Instanz der selbst definierten Klasse mit dem Nötigsten aus, was ein Objekt benötigt: Konstruktor und Destruktor. Beide lassen sich als Ereignisbehandlungsroutinen implementieren und fügen sich somit nahtlos in das ereignisorientierte Programmiermodell ein. Definition Für die Definition einer eigenen Klasse fügen Sie dem Projekt über das Menü PROJEKT ein Klassenmodul hinzu und legen im Eigenschaftsfenster den Namen der Klasse fest. Die Implementation nehmen Sie dann wie gewohnt im Codefenster vor. Der erste Schritt bei der Implementation einer neuen Klasse wird die Definition der Datenstruktur sein, die ein Objekt der Klasse verkörpern soll – mit anderen Worten: die Deklaration der Datenelemente der Klasse. (Wie im Abschnitt »Klassen als Datentypen für Objektvariablen«, S. 196, näher ausgeführt, gibt es hier eine Innensicht und eine Außensicht.) Der nächste Schritt ist die Initialisierung der Datenelemente. Sie erfolgt im Konstruktor der Klasse, also im Rahmen der Behandlungsroutine für das Initialize-Ereignis. Im dritten Schritt implementieren Sie die Eigenschaften der Klasse in Form
31 8
Selbst definierte Klassen
1. Aktivieren Sie das Codefenster der Klasse und öffnen Sie das Dialogfeld PROZEDURATTRIBUTE über das Menü EXTRAS/PROZEDURATTRIBUTE. 2. Wählen Sie im Kombinationsfeld NAME den Bezeichner des Elements, das Sie als Standardelement vereinbaren wollen, und zeigen Sie über die Schaltfläche WEITERE die detaillierte Form des Dialogfelds an. 3. Wählen Sie im Kombinationsfeld PROZEDUR-ID den Eintrag (Voreinstellung) oder tragen Sie den Wert 0 als ID ein.
Die Eigenschaft Betrag als Standardeigenschaft festlegen Von nun an können Sie auf das Standardelement (hier: Betrag) referieren, indem Sie schlicht den Objektbezeichner notieren – und zwar als Rechtswert oder Linkswert, vorausgesetzt, die entsprechenden Methoden (meist: Property Set/Let und/oder Property Get) sind vorhanden. Schnittstellen implementieren Für die fortgeschrittene Programmierung mit Klassen besteht weiterhin die Möglichkeit, eine Klasse durch Verwendung des Schlüsselworts Implements als Implementation einer bestimmten Schnittstelle zu deklarieren. Bei der Schnittstelle kann es sich um eine Standardschnittstelle handeln, aber auch um eine selbst definierte sog. abstrakte Klasse, die Methoden als Rümpfe deklariert, ohne eine Implementation dafür bereitzustellen. Letzteres ist dann Aufgabe der Klasse, die die Schnittstelle implementiert – sie muss für jede in der Schnittstelle deklarierte Methode eine Implementation bereitstellen.
31 9
Selbst definierte Klassen
von Property-Methoden (vgl. »Eigenschaften«; S. 201) und die sonstigen Methoden der Klasse. Im letzten Schritt müssen Sie gegebenenfalls noch für den Abbau aller durch ein Objekt dieser Klasse angeforderter Ressourcen sorgen, die Visual Basic nicht von sich aus mit dem Objekt zusammen abbaut – so beispielsweise: Formularinstanzen. Den Code dafür setzen Sie in die Behandlungsroutine für das Terminate-Ereignis. Standardeigenschaft Von der Programmierung mit Steuerelementen her sind Sie es sicher gewohnt: Ein Objekt kann ein so genanntes Standardelement (Standardeigenschaft) besitzen, das heißt eine Eigenschaft oder eine Methode, deren Wert bzw. Aufruf sich durch alleinige Notation des Objektbezeichners (also unter Weglassung des zugehörigen Elementbezeichners) ergibt. Um eine Methode (eine Eigenschaft ist ja nichts anderes als eine Property Get-Methode) als Standardelement zu vereinbaren, gehen Sie wie folgt vor:
Selbst definierte Klassen
Eine ausführlichere Diskussion dieses Konzepts führt jedoch sehr schnell in die komplexe Welt des COM und der Programmierung von und mit ActiveX-Komponenten. Beispiel
................................................... Beis piel
Ein Beispiel für die Implementation einer einfachen selbst definierten Klasse finden Sie im Abschnitt »Eigenschaften« (S. 201).
Selbst definierte Klassen
ClassModul- Schnittstelle Bei der ClassModule-Schnittstelle handelt es sich um eine rudimentäre Schnittstelle, die eine selbst definierte Klasse mit den beiden Ereignissen Initialize und Terminate sowie den Eigenschaften DatabindingBehavior und DataSourceBehavior ausstattet. Weitere »Erblasten« gibt es zunächst einmal nicht. Anwendung
................................................... Anwendung
Im Gegensatz zu Schnittstellen wie Form oder UserControl steht ClassModule nicht als Objektdatentyp für Objektvariablen zur Verfügung. Wer eine generische Objektvariable benötigt (und nichts anderes wäre eine Variable des Typs ClassModul) muss also mit dem Datentyp Object vorlieb nehmen. Das Initialize-Ereignis tritt für jedes Objekt einer gegebenen selbst definierten Klasse ein einziges Mal auf, nämlich bei der Instanziierung. Eine Behandlung dieses Ereignisses gibt dem Objekt Gelegenheit, seine Elemente zu initialisieren, Ressourcen anzufordern usw., kurz gesagt: sich zu konstruieren. Da die Datenstruktur eines Objekts seinerseits Elemente mit Objektdatentypen enthalten kann, stellt sich die Frage nach der Reihenfolge der Initialize-Ereignisse. Die Antwort lautet: Visual Basic instanziiert Objekte top-down, also zuerst das Objekt und dann seine Elemente. Das ist nicht verwunderlich, da Visual Basic Objekte generell erst dann konstruiert, wenn es (implizit oder explizit) eine New-Anweisung ausführt. Das Terminate-Ereignis ist das Gegenstück zu Initialize und tritt gleichfalls nur einziges Mal auf, nämlich beim Ableben des Objekts. Es gibt dem Objekt umgekehrt Gelegenheit, angeforderte Ressourcen wieder freizugeben. Ein expliziter Abbau von Elementen mit Objektdatentyp ist allerdings nicht erforderlich, da Visual Basic diese automatisch abbaut. Die Reihenfolge des Abbaus ist gleichfalls top-down, das heißt, die Elemente eines Objekts werden nach dem Objekt abgebaut (was natürlich sinnvoll ist, denn das Objekt sollte bei der Behandlung von Terminate noch über alle Elemente verfügen). Die nur zur Entwurfszeit verfügbaren Eigenschaften DatabindingBehavior und DataSourceBehavior legen fest, ob (und wenn ja wie) das Objekt an eine Datenquelle gebunden werden kann bzw. ob es selbst als Datenquelle für andere Objekte auftreten kann. Sie sind nur von Interesse, wenn Sie die Klasse für die Implementation von Datenbankverbindungen verwenden.
320
Steuerelemente Was das Lenkrad, der Tacho, die Instrumente, Schalter, Regler, Hebel und Pedale für ein Auto oder ein Flugzeug, das sind die Steuerelemente für ein Programm. Steuerelemente sind nach ergonomischen Gesichtspunkten gestaltete Ein- und Ausgabemedien für die Interaktion zwischen Benutzer und Programm. Dabei vereint jedes Steuerelement (genauer: die meisten Steuerelemente) in sich eine visuelle Repräsentation seiner Zustände sowie eine operationale Repräsentation der mit diesen Zuständen verbundenen Befehle und Aktionen. Gut 80 Prozent der Programmierung mit Visual Basic hat etwas mit Steuerelementen zu tun. Das ist kein Wunder, denn das Erfolgsrezept von Visual Basic war seit jeher der unkomplizierte Umgang mit Steuerelementen sowie die Möglichkeit, in kürzester Zeit selbst komplexeste Formulare nicht nur zusammenstellen, sondern auch ans Laufen bringen zu können. Während der visuell orientierte Entwurf von Benutzeroberflächen sehr schnell auch in die Entwicklungsumgebungen anderer Programmiersprachen Einzug gehalten hat, ist die mit Visual Basic vorliegende Integration der Codeentwicklung in die interaktive visuelle Gestaltung der Benutzeroberfläche nach wie vor außerordentlich. Das liegt daran, dass auch für den gesamten modularen Aufbau eines Programms bzw. einer Komponente das gleiche Baukastenprinzip zur Anwendung kommt: Der Entwickler zieht ein Steuerelement bzw. eine Komponente in den Entwurfsbereich eines Formulars (bzw. der zu entwickelnden Komponente) und eröffnet sich damit den gesamten Funktionsumfang des dahinter steckenden Bibliotheksmoduls. Eine zum Modul gehörige und von der Entwicklungsumgebung automatisch konsultierte Typbibliothek gibt zudem Auskunft über die Eigenschaften, Methoden und Ereignisse, die für das Steuerelement definiert sind. (Rufen Sie doch einmal mit (F2) den Objektkatalog auf.) Ein Steuerelement muss nicht unbedingt als sichtbares Element der Benutzeroberfläche mit eigenem Fensterbereich in Erscheinung treten. Visual Basic fasst den Begriff des Steuerelements wesentlich weiter. Hat man erst einmal verstanden, dass in Visual Basic (fast) alles, was von »außen« kommt, als Steuerelement auf den Entwurfsbereich eines Formulars oder einer Komponente platziert wird, lebt es sich leicht: »Sage mir, was Du machen willst, und ich besorge Dir ein Steuerelement dafür«. Die Sparte VB-Steuerelemente ist inzwischen zu einem Boombereich auf dem Softwaremarkt geworden, und frei nach dem Motto »es gibt nichts, was es nicht gibt«, reduziert sich so manches Problem durch Einsatz einer fertigen kommerziellen Komponente zu einer trivialen Angelegenheit. Umgekehrt steht einem Programmierer aber auch nichts im Wege, sich seine eigenen Bibliotheken als Benutzersteuerelemente (ActiveX-Steuerelemente oder ActiveX-Komponenten) zusammenzustellen und sich gegebenenfalls sogar seine Nische in dem breiten Markt zu erobern. In der Dokumentation wird selten zwischen einem Steuerelement als Fenster, das einem anderen Fenster (etwa dem eines Formulars) untergeordnet ist, und einem Steuerelement als Objekt, das die operationale Repräsentation dieses Fensters innerhalb eines Programms vornimmt, unterschieden. Gerade für Anfänger im Bereich der Windows-Programmierung ist diese Unterscheidung für ein besseres Verständnis aber sehr wichtig, weil sie die über eine Schnittstelle vermittelte Dualität sichtbares GDI-Objekt, als Fensterobjekt einer bei Windows registrierten Fensterklasse, und operatives Visual-Basic-Objekt, das auf Nachrichten des Fensterobjekts reagiert und bemüht ist, seinen Zustand mit dem des Fensterobjekts zu synchronisieren, unterstreicht. Mit diesem Wissen im Hinterkopf erklärt sich auch, warum ein Formular (und alle darauf befindlichen Steuerelemente) geladen und wieder entladen werden kann, obwohl das Formularobjekt (respektive die Steuerelementobjekte) erhalten bleibt. Einen kleinen Nachteil hatte der visuelle Ansatz, bevor die Version 6.0 eine Lösung anbot: Im Gegensatz zu anderen Programmiersprachen war es Visual Basic bisher nicht so ohne Weiteres möglich, ein Steuerelement zur Laufzeit zu generieren, das nicht bereits zur Entwurfszeit wenigstens in einer Instanz als »Samen« auf dem jeweiligen Formular platziert worden war. Darüber hinaus mussten dynamisch generierte Steuerelementinstanzen in Steuerelemente-
3 21
Selbst definierte Klassen
Selbst definierte Klassen
Arrays verwaltet werden, was die Bezeichnerwahl natürlich einschränkte. Die Version 6.0 behebt dieses Manko nun mit Mitteln der Automatisierung, indem sie die Möglichkeit bietet, der Controls-Auflistung eines Formulars über die Methode Add dynamisch neue, noch nicht als »Samen« existierenden Steuerelemente hinzuzufügen – um den Preis einer späten Bindung zur Laufzeit. Mit der Version 4.0 hat Visual Basic nicht nur den Sprung in den 32-Bit-Welt vorgenommen, sondern sich auch konzeptuell dem COM (Component Object Model) verschrieben. Steuerelemente sind seither Komponenten im Sinne des COM. Traditionell gibt es die Unterscheidung zwischen den Standardsteuerelementen, die den Kern der von Windows unterstützten Steuerelemente ausmachen, in der grundlegenden Werkzeugsammlung von Visual Basic zu finden sind und sich ohne weiteres Zutun sofort einsetzen lassen, und den ActiveX-Steuerelementen, die über den Menübefehl PROJEKT/KOMPONENTEN ((Strg)+(T)) bei Bedarf explizit in die Werkzeugsammlung übernommen werden müssen. Die ActiveX-Steuerelemente zerfallen wiederum in verschiedene Gruppen, die aber im Allgemeinen die Bibliothekszugehörigkeit widerspiegeln. Die wichtigsten darunter sind die Standarddialoge (COMDLG32.OCX) und die WindowsStandardsteuerelemente (MSCOMCTL.OCX, MSCOMCT2.OCX, MSCOM332.OCX). Die folgende Tabelle gibt einen Überblick, in welchem OCX-Modul welches Steuerelement zu finden ist: Steuerelement
Komponentenname
Dateiname
Adodc (ADO DatenSteuerelement)
Microsoft ADO Data Control 6.0
MSADODC.OCX
MSChart
Microsoft Chart Control 5.5
MSCHART.OCX
MSComm
Microsoft Comm Control 6.0
MSCOMM32.OCX
CommonDialog
Microsoft Common Dialog Control 6.0
COMDLG32.OCX
DBGrid
Microsoft Data Bound Grid Control 5.0
DBGRID32.OCX
DBCombo, DBList
Microsoft Data Bound List Controls 6.0
DBLIST32.OCX
DataRepeater
Microsoft Data Repeater Control 6.0
MSDATREP.OCX
DataGrid
Microsoft Data Grid Control 6.0
MSDATGRD.OCX
DataList, DataCombo
Microsoft Data List Controls 6.0
MSDATLST.OCX
MSFlexGrid
Microsoft FlexGrid Control 6.0
MSFLXGRD.OCX
Grid
Microsoft Grid Control
GRID32.OCX
MSHFlexGrid
Microsoft Hierarchical Flex Grid Control 6.0
MSHFLXGD.OCX
Inet (Internet Trans- Microsoft Internet Transfer Control 6.0 fer-Steuerelement)
MSINET.OCX
MAPIMessages, MAPISession
Microsoft MAPI Controls 6.0
MSMAPI32.OCX
MaskEdBox
Microsoft MaskedEdit Control 6.0
MSMASK32.OCX
MMControl
Microsoft Multimedia Control 6.0
MCI32.OCX
PictureClip
Microsoft PictureClip Control 6.0
PICCLP32.OCX
RemoteData
Microsoft RemoteData Control 6.0
MSRDC20.OCX
RichTextBox
Microsoft RichTextBox Control 6.0
RICHTX32.OCX
Komponentenzugehörigkeit der ActiveX- Steuerelemente
322
Gemeinsame Eigenschaften
Komponentenname
Dateiname
SysInfo
Microsoft SysInfo Control 6.0
SYSINFO.OCX
Tab (Microsoft TabSteuerelement)
Microsoft TabbedDialog Control 6.0
TABCTL32.OCX
ImageCombo, ImageList, ListView, ProgressBar, Slider, StatusBar, TabStrip, Toolbar, TreeView
Microsoft Windows Common Controls 6.0
MSCOMCTL.OCX (in der Version 5.0: COMCTL32.OCX)
Animation, DTPicker, FlatScrollbar, MonthView, UpDown,
Microsoft Windows Common Controls-2 6.0
MSCOMCT2.OCX (in der Version 5.0: COMCT232.OCX)
CoolBar
Microsoft Windows Common Controls-3 6.0
COMCT332.OCX
WinSock
Microsoft Winsock Control 6.0
MSWINSCK.OCX
Komponentenzugehörigkeit der ActiveX- Steuerelemente
Gemeinsame Eigenschaften Da die Standardsteuerelemente und ActiveX-Steuerelemente viele Eigenschaften mit mehr oder weniger gleicher Bedeutung – teilweise aber mit unterschiedlichen Wertebereichen – besitzen, folgt zunächst einmal eine Besprechung der wichtigsten Eigenschaften und Methoden, bevor es dann mit den einzelnen Steuerelementtypen weitergeht. Die folgende Tabelle gibt einen Überblick über die Eigenschaften, die bei der Besprechung der einzelnen Steuerelemente sowie des Formularobjekts nicht eigens diskutiert werden. Eigenschaft
Beschreibung
Alignment
Integer-Wert, der die Ausrichtung des Werts oder der Beschriftung des Steuerelements im Fensterbereich ausdrückt
Appearance
Integer-Wert, der die Darstellungsart des Steuerelements ausdrückt (2D oder 3D)
AutoSize
Boolean-Wert, der bestimmt, ob das Steuerelement seine Bereichsabmessungen automatisch anpasst, um den Standardwert vollständig darstellen zu können
BackColor
Long-Wert, der die Hintergrundfarbe des Steuerelements ausdrückt
BackStyle
Integer-Wert, der ausdrückt, ob der Hintergrund des Steuerelements durchscheint oder nicht
BorderStyle
Integer-Wert, der den Stil der Randlinie des Steuerelements ausdrückt
Caption
String-Wert für die Beschriftung des Steuerelements
Container
Objektverweis auf das Containerobjekt des Steuerelements
Die wichtigsten gemeinsamen Eigenschaften der Steuerelemente
323
Gemeinsame Eigenschaften
Steuerelement
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Eigenschaft
Beschreibung
CausesValidation
Boolean-Wert, der ausdrückt, ob ein Validate-Ereignis bei Fokusverlust an ein anderes Steuerelement (mit auf True gesetzter CausesValidation-Eigenschaft) auftritt
DataChanged
Boolean-Wert, der ausdrückt, ob sich der Wert des Steuerelements gegenüber dem Datensatz, an den es gebunden ist, geändert hat.
DataField
String-Wert für den Namen des Datenfelds, wenn das Steuerelement an ein bestimmtes Datenfeld im aktuellen Datensatz gebunden ist
DataFormat
DataFormat-Objekt, das die Schnittstelle IStdDataFormatDisp implementiert und für eine formatierte Darstellung des Steuerelementwerts sorgt
DataMember
String-Wert für den Namen des Datenelements in einer Datenquelle, wenn das Steuerelement an eine solche gebunden ist
DataSource
String-Wert für den Namen der Datenquelle, wenn das Steuerelement an eine solche gebunden ist
DisabledPicture
Picture-Objekt mit Verweis auf Bitmap für die benutzerdefinierte Darstellung des inaktiven Steuerelements
DownPicture
Picture-Objekt mit Verweis auf Bitmap für die benutzerdefinierte Darstellung des Steuerelements im angeklickten Zustand
DragIcon
Picture-Objekt mit Verweis auf benutzerdefinierten Mauszeiger für die Anzeige während Drag&Drop-Operationen
DragMode
Integer-Wert, der das Verhalten des Steuerelements bei Drag&DropOperationen bestimmt
DrawMode
Integer-Wert, der den Zeichenmodus für Zeichenoperationen sowie für das Zeichnen von Figur- und Liniensteuerelementen festlegt
DrawStyle
Integer-Wert, der den Linienstil für Grafikmethoden bestimmt
FillColor
Long-Wert, der die Füllfarbe für die Darstellung nichttransparenter Füllbereiche des Steuerelements ausdrückt
FillStyle
Integer-Wert, der den Füllstil für die Darstellung nichttransparenter Füllbereiche des Steuerelements ausdrückt
Font
Font-Objekt, das die Schrift für die Darstellung textorientierter Werte definiert
FontBold, FontIta- Boolean-Werte für zusätzliche Schriftattribute bei der Darstellung textorientierter Werte lic, FontStrikethru, FontUnderline FontName
String-Wert, der den Namen der aktuell eingestellten Schrift bestimmt
FontSize
Single-Wert, der die Schriftgröße der aktuell eingestellten Schrift bestimmt
ForeColor
Long-Wert, der die Farbe für das Zeichnen von Vordergrundanteilen des Steuerelements ausdrückt
Die wichtigsten gemeinsamen Eigenschaften der Steuerelemente
324
Gemeinsame Eigenschaften
Beschreibung
HasDC
Schreibgeschützter Boolean-Wert, der angibt, ob das Formular oder Steuerelement einen eigenen Gerätekontext für die Ausgabe besitzt
Height
Single-Wert, der die Höhe des Steuerelements bezogen auf das aktuelle Koordinatensystem des Containers bestimmt
HelpContextID
Long-Wert, der dem Steuerelement die Nummer eines Thema in der kontextbezogenen Hilfedatei (App.HelpFile) zuordnet
hDC
Zur Laufzeit schreibgeschützter Wert vom Typ Long der auf den Gerätekontext des Ausgabegerätes verweist und nur im Zusammenhang mit Funktionen der Win32-API benötigt wird.
hWnd
Long-Wert, der die Windows-Fensternummer (Handle) des dem Steuerelement zugeordneten Fensters wiedergibt
Image
Zur Laufzeit schreibgeschützter Picture-Wert, der einen Verweis auf die beständige Bitmap im Gerätekontext des Steuerelements oder Formulars darstellt
Index
Indexnummer des Steuerelements im Steuerelemente-Array (reine Entwurfseigenschaft)
Left
Single-Wert, der die horizontale Position (linker Rand) des Steuerelements im Container bezogen auf das aktuelle Koordinatensystem des Containers ausdrückt
MaskColor
Long-Wert, der die Transparenzfarbe für die Maskierung transparenter Bereiche des Steuerelements ausdrückt (Verwendung abhängig von UseMaskColor)
MouseIcon
Picture-Objekt mit Verweis auf benutzerdefinierten Mauszeiger (Verwendung abhängig von MousePointer)
MousePointer
Integer-Wert, der das für das Steuerelement angezeigte Mauszeigersymbol auswählt
MultiLine
Boolean-Wert, der bestimmt, ob der Wert des Steuerelements für eine mehrzeilige Darstellung umbrochen werden kann
Name
String-Wert, der den Bezeichner des Steuerelementobjekts wiedergibt
OLEDropAllowed
Boolean-Wert, der bestimmt, ob das Steuerelement das Ablegen von OLE-Objekten im Rahmen von OLE-Drag&Drop-Operationen zulässt
OLEDropMode
Integer-Wert, der das Verhalten des Steuerelements bei OLEDrag&Drop-Operationen bestimmt
OLETypeAllowed
Integer-Wert, der bestimmt, ob das Steuerelement das Einbetten und/ oder das Verknüpfen von OLE-Objekten unterstützt, die im Rahmen von OLE-Drag&Drop-Operationen abgelegt werden
Parent
Verweis auf das (Formular-)Objekt, dem das Steuerelement untergeordnet ist
Die wichtigsten gemeinsamen Eigenschaften der Steuerelemente
325
Gemeinsame Eigenschaften
Eigenschaft
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Eigenschaft
Beschreibung
Picture
Picture-Objekt mit Verweis auf das im Bereich des Steuerelements angezeigte (Hintergrund-)Bild (Aktivierung und grafischer Modus ggf. erforderlich)
RightToLeft
Boolean-Wert, der die Ausrichtung der textorientierten Darstellung auf bidirektionalen Systemen bestimmt
ScaleLeft
Single-Wert, der die Ursprungsverschiebung des Koordinatensystems in horizontaler Richtung ausdrückt
ScaleMode
Integer-Wert, der das Koordinatensystem und die darin geltenden Maßeinheiten bestimmt
ScaleTop
Single-Wert, der die Ursprungsverschiebung des Koordinatensystems in vertikaler Richtung ausdrückt
ShowTips
Boolean-Wert, der die QuickInfo ein- oder ausschaltet
Style
Integer-Wert, der Art und/oder Darstellungsform des Steuerelements ausdrückt
TabIndex
Integer-Wert, der dem Steuerelements eine Position in der Tabulatorreihenfolge für die Fokusweitergabe zuordnet
TabStop
Boolean-Wert, der festlegt, ob das Steuerelement den Fokus durch Betätigung der Tabulatortaste (entlang der Tabulatorordnung) erlangen kann
Tag
Variant-Wert für zusätzliche benutzerdefinierte Daten (Eigenschaft wird von Visual Basic nicht benutzt)
ToolTipText
String-Wert mit Hilfetext, der als QuickInfo für das Steuerelement angezeigt wird, wenn die Maus darüber eine Zeit lang verharrt
Top
Single-Wert, der die vertikale Position (oberer Rand) des Steuerelements im Container bezogen auf das aktuelle Koordinatensystem des Containers ausdrückt
UseMaskColor
Boolean-Wert, der bestimmt, ob die in MaskColor festgelegte Farbe für die transparente Darstellung des Steuerelements benutzt wird
Visible
Boolean-Wert, der die Sichtbarkeit des Steuerelements bestimmt
WhatsThisHelpID
Long-Wert, der den Index für das Hilfethema der Popup-Direkthilfe festlegt. Wenn 0, kommt die Windows-Standardhilfe unter Beachtung von HelpContextID zum Aufruf
WhatsThisHelp
Boolean-Wert, der festlegt, ob die Direkthilfe für ein Formular aktiv ist
Width
Single-Wert, der die Breite des Steuerelements bezogen auf das aktuelle Koordinatensystem des Containers bestimmt.
Die wichtigsten gemeinsamen Eigenschaften der Steuerelemente
326
Alignment- Eigenschaft
Alignment- Eigenschaft Objekt.Alignment As Integer Betroffene Objekte
................................................... Betro ffene Objekte DataGrid, Label, ColumnHeader, Function, CheckBox, OptionButton, Panel, RptFunction, RptLabel, RptText,TextBox, UpDown Beschreibung
................................................... Bes c hreibung
Konstante (Wert)
definiert für ...
Wirkung
vbLeftJustify (0)
TextBox, Label, OptionButton, CheckBox
Wert bzw. Beschriftung wird linksbündig im Bereich des Steuerelements ausgerichtet (Voreinstellung)
vbRightJustify (1)
TextBox, Label, OptionButton, CheckBox
Wert bzw. Beschriftung wird rechtsbündig in Steuerelementbereich ausgerichtet
vbCenterJustify (2)
TextBox, Label
Wert oder Beschriftung wird zentriert in Steuerelementbereich ausgerichtet
IvwColumnLeft (0)
ColumnHeader
Spaltenbeschriftung wird linksbündig ausgerichtet (Voreinstellung)
IvwColumnRight (1)
ColumnHeader
Spaltenbeschriftung wird rechtsbündig ausgerichtet
IvwColumnCenter (2)
ColumnHeader
Spaltenbeschriftung wird zentriert ausgerichtet
sbrLeft (0), hdrLeft (0)
Panel
Text erscheint linksbündig rechts neben der Bitmap (Voreinstellung)
sbrCenter (1), hdrCenter (1)
Panel
Text erscheint zentriert rechts neben der Bitmap
sbrLeft (2), hdrLeft (2)
Panel
Text erscheint rechtsbündig links neben der Bitmap
cc2AlignmentLeft (0)
UpDown
AufAb-Steuerelement erscheint links von Buddy
cc2AlignmentRight (1)
UpDown
AufAb-Steuerelement erscheint rechts von Buddy (Voreinstellung)
dbgLeft (0)
DataGrid
Wert wird linksbündig in Spalte ausgerichtet
dbgRight (1)
DataGrid
Wert wird rechtsbündig in Spalte ausgerichtet
dbgCenter (2)
DataGrid
Wert wird zentriert in Spalte ausgerichtet
3 27
Gemeinsame Eigenschaften
Die Alignment-Eigenschaft bestimmt die Ausrichtung eines Steuerelements in dem ihm zur Verfügung stehenden Bereich. Für Ausrichtung sind für die verschiedenen Steuerelemente in den jeweiligen Modulen diverse Integer-Konstanten definiert. Die folgende Tabelle gibt einen Überblick:
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Konstante (Wert)
definiert für ...
Wirkung
dbgGeneral (3)
DataGrid
Text wird links, Zahlen werden rechts in Spalte ausgerichtet (Voreinstellung)
rptJustifyLeft (0)
RptFunction, RptLabel, Wert wird linksbündig in Bereich ausgerichtet (Voreinstellung) RptText
rptJustifyRight (1)
RptFunction, RptLabel, Wert wird rechtsbündig in Bereich ausgerichtet RptText
rptJustifyCenter (2)
RptFunction, RptLabel, Wert wird zentriert in Bereich ausgerichtet RptText
Hinweis
................................................... Hinweis Entgegen anders lautenden Informationen in der Online-Hilfe zu Visual Basic lässt sich diese Eigenschaft für Kontrollkästchen, Optionsfelder und Textfelder zur Laufzeit manipulieren. Auch lassen sich die Inhalte von Textfeldern unabhängig vom Wert der Eigenschaft MultiLine ausrichten.
Appearance- Eigenschaft Objekt.Alignment As Integer Betroffene Objekte
................................................... Betro ffene Objekte Adodc, CheckBox, ComboBox, CommandButton, Data, DataCombo, DataList, DirListBox, DriveListBox, FileListBox, FlatScrollBar, Form, Frame, Image, Label, ListBox, MDIForm, OLE, OptionButton, PictureBox, PropertyPage, RemoteData, TextBox, ToolBar, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Appearance-Eigenschaft legt fest, ob das Steuerelement oder Formular im 3D-Stil von Windows 9x ausgegeben wird oder im flachen 2D-Stil von Windows 3.x. Die Eigenschaft wirkt sich nur auf das Objekt selbst und nicht auf untergeordnete Objekte aus – sie ist also für diese getrennt zu setzen. Konstante (Wert)
Definiert für ...
0
Die meisten Komponenten 3D-Darstellung
1
Die meisten Komponenten 2D-Darstellung
fsb3D (0)
FlatScrollBar
3D-Darstellung wie Windows-Bildlaufleiste
fsbFlat (1)
FlatScrollBar
Flache 2D-Darstellung (Voreinstellung)
fsbTrack3D (2)
FlatScrollBar
Bildlaufleiste ist 2D, Bildlaufmarke und Bildlaufpfeile werden 3D, wenn der Mauszeiger darüber steht
cc3D (0)
Toolbar, ListView, Tree- 3D-Darstellung View
ccFlat (1)
Toolbar, ListView, Tree- 2D-Darstellung View
328
Wirkung
AutoSize- Eigenschaft
Hinweis
................................................... Hinweis Entgegen anders lautenden Informationen in der Online-Hilfe zu Visual Basic lässt sich diese Eigenschaft zur Laufzeit ändern. Auch wirkt sich der Wert 3 für die Eigenschaft BorderStyle nicht auf die Darstellung eines Formulars aus.
AutoSize- Eigenschaft Objekt.AutoSize As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Beschreibung
................................................... Bes c hreibung
Die AutoSize-Eigenschaft bestimmt, ob ein Steuerelement seinen Bereich automatisch an die für die vollständige Darstellung seines Standardwerts benötigten Abmessungen anpasst (True) oder nicht (False; Voreinstellung). Anwendung
................................................... Anwendung
Trotz der augenscheinlichen Vorzüge, die der hinter der AutoSize-Eigenschaft steckende Automatismus verspricht, sollte sein Einsatz gut überlegt werden – insbesondere bei Bezeichnungsfeldern, die mit einem Feld in einer Datenbank oder mit einer DDE-Quelle verbunden sind und ihren Wert somit automatisch ändern können. (Wie das Beispiel zeigt, ist der Automatismus in Visual Basic 6.0 zudem nicht sauber implementiert). Wenn ein Steuerelement seine Größe automatisch anpasst, kann es nämlich dazu kommen, dass es nicht mehr auf das Formular passt und abgeschnitten wird, oder schlimmer noch, sich mit anderen Steuerelementen überlappt, diese verdeckt oder selbst verdeckt wird. Beim Bildfeld-Steuerelement lässt sich das Ergebnis der automatischen Bereichsanpassung immerhin durch Behandlung des Resize-Ereignisses noch kontrollieren und gegebenenfalls nachbessern, beim Bezeichnungsfeld-Steuerelement sind »Hopfen und Malz verloren«. Beispiel
................................................... Beis piel
Das Beispielprojekt FadeOut demonstriert die Tücken der AutoSize-Eigenschaft. Ein Timer animiert ein Bezeichnungsfeld mit automatischer Größenanpassung auf einem Formular mit einem Fade-out-Effekt. Damit die Bereichsgrenzen gut zu sehen sind, ist der Hintergrund des Bezeichnungsfelds weiß. Wenn Sie das Programm starten, werden Sie feststellen, dass die Bereichsanpassung durch die AutoSize-Eigenschaft nur unvollständig funktioniert und der Bereich immer breiter wird. Einen Work-around für das Problem bieten die beiden auskommentierten Zeilen. Dim Texte() Dim i Private Sub Form_Load() Texte = Array("Rauchen", "schadet", "Ihrer", "Gesundheit") Label1 = Texte(0) Label1.AutoSize = True Label1.BackColor = vbWhite ' Hintergrund Weiß Label1.FontName = "Arial" ' TrueType, wegen Size-Änderung Timer1.Interval = 40 End Sub
3 29
Gemeinsame Eigenschaften
Label, PictureBox
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Private Sub Timer1_Timer() Label1.Font.Size = Label1.Font.Size + 1.2 If Label1.FontSize > 60 Then Label1.FontSize = 8 ' Label1.Left = Label1.Left + Label1.Width / 2 ' Label1.Width = 1 i = (i + 1) Mod (UBound(Texte) + 1) Label1 = Texte(i) End If End Sub
BackColor- Eigenschaft und ForeColor- Eigenschaft Objekt.BackColor As Long Objekt.ForeColor As Long Betroffene Objekte
................................................... Betro ffene Objekte Adodc, AmbientProperties, Animation, Band, CheckBox, ComboBox, CommandButton, CoolBar, Data, DataCombo, DataList, DirListBox, DriveListBox, FileListBox, Form, Frame, Image, ImageCombo, ImageList, Label, ListBox, MDIForm, OLE, OptionButton, RptFunction, RptImage, RptLabel, RptText, RptShape, PictureBox, Printer, PropertyPage, RemoteData, RichTextBox, Shape, SSTab, TextBox, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Eigenschaften BackColor und ForeColor sind Farbwerte vom Typ Long, die die Hintergrundfarbe bzw. die Vordergrundfarbe (oder Stiftfarbe) für ein Objekt festlegen. Die Voreinstellungen dieser Eigenschaften sind je nach Komponententyp verschieden, entsprechen aber den standardmäßig dafür in der Systemsteuerung festgelegten Systemfarben. Zur Auswahl stehen neben den Systemfarben auch beliebige andere Farben, die sich entweder zur Entwurfszeit aus der Palette wählen oder zur Laufzeit über die Funktion RGB komponentenweise zu einem Farbwert komponieren lassen. Die Funktion QBColor liefert den Farbwert einer der 16 Grundfarben. Zudem definiert der Aufzählungstyp SystemColorConstants die folgenden Konstanten für die Systemfarben: Konstante
Wert
Systemfarbe für ...
vbScrollBars
0x80000000
Farbe der Bildlaufleiste
vbDesktop
0x80000001
Farbe des Desktop
vbActiveTitleBar
0x80000002
Farbe der Titelleiste des aktiven Fensters
vbInactiveTitleBar
0x80000003
Farbe der Titelleiste des inaktiven Fensters
vbMenuBar
0x80000004
Hintergrundfarbe für Menüs
vbWindowBackground
0x80000005
Hintergrundfarbe für Fenster
vbWindowFrame
0x80000006
Rahmenfarbe für Fenster
vbMenuText
0x80000007
Farbe für Menütext
vbWindowText
0x80000008
Textfarbe in Fenstern
vbTitleBarText
0x80000009
Farbe für Titeltext
330
BackStyle- Eigenschaft
Wert
Systemfarbe für ...
vbActiveBorder
0x8000000A
Rahmenfarbe für aktives Fenster
vbInactiveBorder
0x8000000B
Rahmenfarbe für inaktives Fenster
vbApplicationWorkspace
0x8000000C
Hintergrundfarbe von MDI-Anwendungen
vbHighlight
0x8000000D
Hintergrundfarbe für ausgewählte Elemente oder Bereiche des Steuerelements
vbHighlightText
0x8000000E
Textfarbe für ausgewählte Elemente oder Bereiche des Steuerelements
vbButtonFace
0x8000000F
Farbe für Oberfläche von Schaltflächen
vbButtonShadow
0x80000010
Farbe für Schattierung von Schaltflächen
vbGrayText
0x80000011
Textfarbe für deaktiviertes Steuerelement
vbButtonText
0x80000012
Farbe für Schaltflächenbeschriftung
vbInactiveCaptionText
0x80000013
Titeltextfarbe für inaktives Fenster
vb3DHighlight
0x80000014
Farbe für markierten Zustand von 3D-Elementen
vb3DDKShadow
0x80000015
Farbe für dunkelsten Schatten von 3D-Elementen
vb3DLight
0x80000016
Farbe für helle Bereiche in 3D-Elementen
vbInfoText
0x80000017
Textfarbe für QuickInfo
vbInfoBackground
0x80000018
Hintergrundfarbe für QuickInfo
Anwendung
................................................... Anwendung
Der Wertebereich für RGB-Farben liegt zwischen 0 und 16.777.215 (&H00FFFFFF), so dass das höchstwertige Byte des Long-Werts immer gleich 0 ist. Die drei niederwertigen Bytes bestimmen (in aufsteigender Reihenfolge) jeweils den Rot-, Grün- und Blauanteil, dargestellt durch einen Wert zwischen 0 und 255 (&HFF). Ist das höchstwertige Byte 128 (&H80), drückt das niederwertige Byte eine der 25 reservierten Systemfarben aus (vgl. Tabelle). Beispiel
................................................... Beis piel
Form1.BackColor = RGB(124, 12, 120) Form1.ForeColor = RGB(255, 255, 255)
' Lila Hintergrund ' Weiße Textfarbe
BackStyle- Eigenschaft Objekt.Alignment As Integer Betroffene Objekte
................................................... Betro ffene Objekte Animation, Label, RptFunction, RptImage, RptLabel, RptText, RptShape, OLE, Shape, UserControl Beschreibung
................................................... Bes c hreibung
Die BackStyle-Eigenschaft bestimmt, ob ein Steuerelement mit durchsichtigem Hintergrund angezeigt wird oder nicht.
331
Gemeinsame Eigenschaften
Konstante
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Konstante (Wert)
Definiert für ...
Wirkung
0
Label, OLE, Shape, UserControl
transparenter Hintergrund
1
Label, OLE, Shape, UserControl
Hintergrund in Hintergrundfarbe
cc2BackStyleTransparent (0)
Animation
transparenter Hintergrund
cc2BackStyleTransparent (1)
Animation
Hintergrund in Hintergrundfarbe
rptBkOpaque (0)
RptFunction, RptImage, RptLabel, RptText, RptShape
transparenter Hintergrund
rptBkTransparent (1)
RptFunction, RptImage, RptLabel, RptText, RptShape
Hintergrund in Hintergrundfarbe
Hinweis
................................................... Hinweis Diese Eigenschaft muss auf den Wert 0 gesetzt sein, damit die Eigenschaft MaskColor ihre Wirkung entfalten kann. Verwandte Themen
................................................... Verwandte Them en
Transparenz und Drag&Drop (S. 606)
BorderStyle- Eigenschaft Objekt.BorderStyle As Integer Betroffene Objekte
................................................... Betro ffene Objekte Form, Frame, Image, Label, Line, ListView, MonthView, MSChart, OLE, ProgessBar, RptFunction, RptImage, RptLabel, RptLine, RptShape, PictureBox, ProgressBar, Shape, Slider, TextBox, ToolBar, TreeView, UserControl Beschreibung
................................................... Bes c hreibung
Für ein Steuerelement bestimmt die BorderStyle-Eigenschaft, mit welchem Linientyp es selbst oder seine Umrandung gezeichnet wird, und für ein Formular, welchen Fenstertyp dieses erhält. Konstante (Wert)
Definiert für ...
Wirkung
vbBSNone (0)
Frame, Form, Image, Label, OLE, Text, UserControl
«Keine« – Darstellung ohne Randlinie oder Umrandung; bei Formularen fehlt zudem eine Titelleiste
vbFixedSingle (1)
Frame, Form, Image, Label, OLE, Text, UserControl
«Fest Einfach« – Steuerelemente erhalten eine Umrandung; für UserControl-Steuerelemente ist dieser Wert nur definiert, wenn die Windowless-Eigenschaft auf False gesetzt ist; bei Formular kann der Benutzer die Größe nur mittels der Schaltflächen MINIMIEREN, MAXIMIEREN und WIEDERHERSTELLEN ändern
332
BorderStyle- Eigenschaft
Definiert für ...
Wirkung
vbSizable (2)
Form
«Änderbar« (Voreinstellung) – der Benutzer kann die Größe ändern
vbFixedDouble (3)
Form
«Fester Dialog« – Formular kann Systemmenü, nicht jedoch die Schaltflächen MINIMIEREN, MAXIMIEREN und WIEDERHERSTELLEN enthalten. Die Größe ist nicht änderbar.
vbFixedToolWindow (4)
Form
«Festes Werkzeugfenster« – Fenster mit schmaler Titelleiste, ohne Systemmenü jedoch mit Schaltfläche SCHLIEßEN. Das Formular wird nicht in der Taskleiste von Windows 95 angezeigt und seine Größe ist nicht änderbar.
vbSizableToolWindow (5) Form
«Änderbares Werkzeugfenster« – größenveränderliches Fenster mit schmaler Titelleiste, ohne Systemmenü, jedoch mit der Schaltfläche SCHLIEßEN. Das Formular wird nicht in der Taskleiste von Windows 9x angezeigt.
vbTransparent (0)
Line, Shape
«Transparent« – keine Linie
vbBSSolid (1)
Line, Shape
«Ausgefüllt« – durchgezogene Linie
vbBSDash (2)
Line, Shape
«Strich« – gestrichelte Linie
vbBSDot (3)
Line, Shape
«Punkt« – gepunktete Linie
vbBSDashDot (4)
Line, Shape
«Strich-Punkt»
vbBSDashDotDot (5)
Line, Shape
«Strich-Punkt-Punkt»
vbBSInsideSolid (6)
Line, Shape
«Innen ausgefüllt« – Randlinie innerhalb der Bereichsgrenzen
rptBSTransparent (0)
RptLine, RptShape
Keine Linie
rptBSSolid (1)
RptLine, RptShape
Durchgezogene Linie
rptBSDashes (2)
RptLine, RptShape
Gestrichelte Linie
rptBSDots (3)
RptLine, RptShape
Gepunktete Linie
rptBSDashDot (4)
RptLine, RptShape
Strich-Punkt-Linie
rptBSDashDotDot (5)
RptLine, RptShape
Strich-Punkt-Punkt-Linie
cc2None (0)
MonthView, ListView, Randlos ProgressBar, Slider, ToolBar, TreeView
cc2FixedSingle (1)
MonthView, ListView, Umrandet ProgressBar, Slider, ToolBar, TreeView
vtStyleNone (0)
MSChart
Randlos
vbStyleFixedSingle (1)
MSChart
Umrandet
333
Gemeinsame Eigenschaften
Konstante (Wert)
Gemeinsame Eigenschaften
Anwendung
Gemeinsame Eigenschaften
................................................... Anwendung
Für ein Formular legt die BorderStyle-Eigenschaft einen Teil der Ausstattung des Fensters fest. Der Wert 0 steht für ein rahmenloses Fenster ohne Titelleiste, wie es beispielsweise für eine Vollbildansicht benötigt wird. Die Werte 1 und 2 stehen für ein Mehrzweckfenster wahlweise mit Systemmenü (ControlBox) und den Schaltflächen MAXIMIEREN MINIMIEREN und WIEDERHERSTELLEN (MaxButton, MinButton). Der Wert 3 (Fester Dialog) steht für das klassische Dialogfeld, dessen Größe der Benutzer nicht ändern kann. Die Einstellungen 4 (Festes Werkzeugfenster) und 5 (Änderbares Werkzeugfenster) erzeugen Fenster mit der Schaltfläche SCHLIEßEN und ohne Systemmenü, wie sie gewöhnlich für Werkzeugsammlungen verwendet werden. Einem MDI-Formular untergeordnete Formulare (MDIChild-Eigenschaft hat den Wert True) mit der Einstellung 2 (Änderbar) erscheinen innerhalb des MDI-Formulars in einer voreingestellten Größe, die durch Windows zur Laufzeit festgelegt wird. Bei allen anderen Einstellungen erscheint das Formular in der zur Entwurfszeit angegebenen Größe. Hinweise
................................................... Hinweis e Entgegen anders lautender Informationen in der Online-Hilfe zu Visual Basic ist diese Eigenschaft auch für Textfelder und Formulare zur Laufzeit nicht schreibgeschützt. Eine Änderung der Eigenschaft zur Laufzeit zeigt für Formulare jedoch keine Wirkung. Wenn Sie diese Eigenschaft für ein Formular auf eine der Einstellungen 0, 1, 3, 4, 5 setzen, ändert die Entwicklungsumgebung von Visual Basic zugleich die Eigenschaften MinButton, MaxButton und ShowInTaskbar ungefragt auf False. Allerdings spielen diese Eigenschaften ohnehin nur für die Einstellungen 1 und 2 eine Rolle. Verwandte Themen
................................................... Verwandte Them en
Vollbildanzeige (S. 536)
Caption- Eigenschaft Objekt.Caption As String Betroffene Objekte
................................................... Betro ffene Objekte Adodc, CheckBox, CommandButton, Data, Form, Frame, Label, MDIForm, Menu, OptionButton, PropertyPage, RemoteData, RptLabel, UserControl Beschreibung
................................................... Bes c hreibung
Für ein Formularobjekt bestimmt die Caption-Eigenschaft den Fenstertitel und für ein Steuerelement Objekt dessen Beschriftung. Der Wert der Eigenschaft kann zur Laufzeit jederzeit geändert werden. Anwendung
................................................... Anwendung
Die Entwicklungsumgebung setzt als Voreinstellung für die Caption-Eigenschaft immer den automatisch vergebenen Bezeichner des Steuerelements bzw. Formulars. Der Fenstertitel eines Formulars erscheint auch in der Taskleiste sowie im Task-Manager, sofern die Eigenschaft ShowInTaskBar auf True gesetzt ist. Beispiel
................................................... Beis piel
Caption = App.Title & " – " & sDateiname
334
Container- Eigenschaft
Container- Eigenschaft Objekt.Container Objekt.Container Objekt.Container Objekt.Container
As As As As
FormularTyp PictureBox Frame SSTab
Betroffene Objekte
................................................... Betro ffene Objekte Alle Steuerelemente Beschreibung
Die Eigenschaft Container ist eine reine Laufzeiteigenschaft. Ihr Wert verweist auf das Objekt, das als Container für das Steuerelement fungiert. Als Container kann ein Formularobjekt oder ein anderes Steuerelement des Typs PictureBox, Frame oder SSTab fungieren. Hinweis
................................................... Hinweis Der Container eines Steuerelements lässt sich zur Laufzeit zwar ändern, jedoch immer nur innerhalb des gleichen Formulars. Beachten Sie, dass sich die Position eines Steuerelements immer auf das Koordinatensystem des Containers bezieht. Dies kann sich mit dem Container ändern. Bei Änderung des Containers rechnet Visual Basic die Positionskoordinaten und Abmessungen allerdings automatisch um. Beispiel
................................................... Beis piel
Set Text1.Container = Form1 Form1.ScaleMode = vbInches Text1.Left = 1 Text1.Top = 1 Set Text3.Container = Picture1 Print Text1.Left Print Text1.Top
' Koordinatensystem mit Einheit Zoll
' Anderen Container setzen ' Ausgabe: 1440 ' Ausgabe: 1440
CausesValidation- Eigenschaft Objekt.CausesValidation As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Adodc, Animation, CommandButton, CheckBox, ComboBox, DataCombo, DataList, DataRepeater, DirListBox, DriveListBox, FileListBox, ListBox, ListView, MonthView, MSChart, OLE, OptionBox, PictureBox, RichTextBox, Slider, TextBox, TreeView, UpDown, VBControlExtender Beschreibung
................................................... Bes c hreibung
Die CausesValidation-Eigenschaft eröffnet einem Steuerelement die Möglichkeit, seinen Wert durch Behandlung des Validate-Ereignisses einer Gültigkeitsprüfung zu unterziehen, unmittelbar bevor es den Fokus abgibt. Damit das Steuerelement allerdings das Validate-Ereignis zu sehen bekommt, muss nicht nur seine CausesValidation-Eigenschaft auf True gesetzt sein, sondern auch die des Steuerelements, auf das der Fokus übergehen soll. Verliert ein Steuerelement mit gesetzter CausesValidation-Eigenschaft den Fokus an ein Steuerelement, dessen CausesValidation-Eigenschaft auf False gesetzt ist, tritt das Validate-Ereignis nicht sofort auf, sondern erst, wenn der Fokus wieder in Besitz eines Steuerelements mit gesetzter CausesValidation-
335
Gemeinsame Eigenschaften
................................................... Bes c hreibung
Gemeinsame Eigenschaften
Eigenschaft gehen soll. Setzt ein Steuerelement bei der Behandlung des Validate-Ereignisses den Cancel-Parameter auf True, behält es den Fokus bzw. erhält es diesen zurück. Anwendung
Gemeinsame Eigenschaften
................................................... Anwendung
Die CausesValidation-Eigenschaft eines Steuerelements muss immer im Zusammenhang mit den CausesValidation-Eigenschaften der anderen Steuerelemente auf einem Formular gesehen werden. Der etwas kompliziert anmutende Mechanismus hat aber seine Vorteile: Der Benutzer kann während der Eingabe eines Werts in ein Steuerelement mit Gültigkeitsprüfung auf andere Steuerelemente zugreifen, solange für diese die CausesValidation-Eigenschaft nicht gesetzt ist, und beispielsweise Hilfe anfordern, seine Eingabe verwerfen oder den Dialog ganz abbrechen.
DataChanged- Eigenschaft Objekt.Changed As Boolean Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, Column, ComboBox, DataCombo, DataGrid, DataList, DTPicker, Image, Label, ListBox, MaskEdBox, MonthView, OLE, PictureBox, RepeaterBinding, RichTextBox, TextBox, Beschreibung
................................................... Bes c hreibung
Die DataChanged-Eigenschaft eines Steuerelements drückt aus, ob sich der Wert der Standardeigenschaft inzwischen (lies: seit DataChanged zuletzt auf False gesetzt wurde) geändert hat (True) oder nicht (False). Eine besondere Rolle spielt die DataChanged-Eigenschaft, wenn das Steuerelement an eine Datenquelle gebunden ist und von dieser Daten bezieht. Jede Synchronisation des Steuerelements mit dem aktuellen Datensatz eines Recordsets setzt den Wert dieser Eigenschaft auf False, Änderungen der Standardeigenschaft durch den Benutzer oder durch Programmcode setzen ihn dagegen auf True. Im letzteren Fall kann eine automatische Wertübernahme beim nächsten Datensatzwechsel erfolgen. Anwendung
................................................... Anwendung
Ein Programm kann die DataChanged-Eigenschaft im Rahmen der Validate-Behandlung eines Steuerelements als Kriterium für die Gültigkeitsprüfung auswerten und gegebenenfalls auch auf False setzen, um Aktualisierungen des aktuellen Datensatzes mit dem Wert der Standardeigenschaft zu unterbinden. Nur wenn DataChanged auf True gesetzt ist und über die Edit-Methode des Recordset-Objekts der Bearbeitungsmodus eingeschaltet wurde, wird der Wert der Standardeigenschaft beim nächsten Datensatzwechsel oder beim expliziten Aufruf der UpdateMethode in den Datensatz zurückgeschrieben.
DataField- Eigenschaft Objekt.DataField As String Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, Column, ComboBox, DataCombo, DTPicker, Image, ImageCombo, Label, ListBox, MonthView, OLE, PictureBox, RepeaterBinding, RptFunction, RptTextBox, RichTextBox, TextBox,
336
DataField- Eigenschaft
Beschreibung
................................................... Bes c hreibung
Die DataField-Eigenschaft enthält den Feldnamen eines Datenfelds einer Tabelle oder eines Recordsets, wenn das Steuerelement Objekt als Datennutzer an eine Datenquelle (DataSource) bzw. ein Datenelement (DataMember) einer Datenquelle gebunden ist. Anwendung
................................................... Anwendung
Tipp
................................................... Tipp
Um einem Steuerelement ein in einer Abfrage berechnetes Feld zuzuordnen, muss die Abfrage einen Alias (alternativen Bezeichner) für dieses Feld vereinbaren. Beispiel
................................................... Beis piel
Der folgende Code arbeitet mit einem Textfeld Text1, das zur Entwurfszeit an ein Data-Steuerelement Data1 als Datenquelle gebunden wurde. Ein Klick auf die Schaltfläche FrachtkostenAnzeigen ändert das Recordset der Datenquelle sowie die Datenfeldbindung des Textfeldes. Const Abfrage1 = "SELECT AVG(Frachtkosten) AS Fracht FROM Bestellungen" Private Sub FrachtkostenAnzeigen_Click() Text1.DataField = "" ' weil RecordSource geändert wird Data1.RecordSource = Abfrage1 Data1.Refresh ' weil RecordSource geändert wurde Text1.DataField = "Fracht" ' berechnetes Feld End Sub
ADO-Steuerelemente lassen sich auch zur Laufzeit als Datenquelle setzen. In diesem Fall könnte die Behandlungsroutine so aussehen: Private Sub FrachtkostenAnzeigen_Click() Text1.DataField = "" ' alte Bindung ggf. aufheben Adodc1.RecordSource = Abfrage1 ' Refresh nicht nötig Set Text1.DataSource = Adodc1 Text1.DataField = "Fracht" ' berechnetes Feld End Sub
Da der gemeinsame Einsatz von Data- und Adodc-Steuerelementen im Zusammenhang mit der Jet-Engine Probleme bereiten kann, ist es besser, sich für die eine oder die andere Gattung zu entscheiden.
337
Gemeinsame Eigenschaften
Das standardmäßige Szenario für den Zugriff auf eine Datenquelle (lies: Datenbank) von Visual Basic sieht so aus, dass ein Formular oder eine Komponente mit Steuerelementen bestückt ist, deren Werte über die DataField-Eigenschaft an die Feldwerte eines einzelnen Datensatzes oder einer Folge von Datensätzen gebunden sind. Die Datensätze entstammen wiederum einer Tabelle oder einem beliebigen Recordset (lies: Ergebnis einer Abfrage), das ein Datensteuerelement unter Verwendung eines Daten-Providers (lies: einer geeigneten Schnittstelle) bei einem Datenbanksystem anfordert. Als Datenquellen kommen Objekte wie Data, RemoteData, Adodc oder DataEnvironment in Frage. Datenquellen, die durch die ersten beiden Steuerelementtypen repräsentiert werden, müssen bereits zur Entwurfszeit an den Datennutzer gebunden werden, die anderen beiden Objekttypen lassen sich auch zur Laufzeit binden. Die DataField-Eigenschaft kann jedoch ohne Einschränkungen zur Laufzeit gesetzt werden, gleich an welche Art von Datenquelle ein Steuerelement gebunden ist. Falls das Steuerelement bereits an ein Feld gebunden ist, sollte die Eigenschaft DataField vor einem Wechsel der Datenquelle oder des Recordsets in der Datenquelle auf die leere Zeichenfolge gesetzt werden.
Gemeinsame Eigenschaften
Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DataMember, DataFormat, DataSource Verwandte Themen
................................................... Verwandte Them en
Data-Datensteuerelement (Data) (S. 402)
DataFormat- Eigenschaft
Gemeinsame Eigenschaften
Objekt.DataFormat As IStdDataFormatDisp Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, Column, ComboBox, DataCombo, DataList, DataRepeater, DBList, DBCombo, DTPikker, Image, ImageCombo, Label, ListBox, MonthView, OLE, PictureBox, RepeaterBinding, RptFunction, RptTextBox, TextBox, Beschreibung
................................................... Bes c hreibung
Die DataFormat-Eigenschaft ordnet einem Steuerelement Objekt, das an eine Datenquelle gebunden ist, ein Datenformat in Form eines Datenformatobjekts zu. Das wie ein bilateraler Filter arbeitende Datenformatobjekt stellt die von der Datenquelle gelieferten Daten in dem gewählten Format dar und übersetzt in diesem Format gehaltene Eingaben auch wieder zurück in die von der Datenquelle benutzte interne Darstellung. Anwendung
................................................... Anwendung
Visual Basic ordnet jedem Steuerelement, das an eine Datenquelle gebunden ist, ein standardmäßiges Datenformatobjekt des Typs StdDataFormat zu. Diese Zuordnung ist integraler Bestandteil der Bindung und sorgt im Allgemeinen automatisch für eine geeignete Anpassung zwischen dem von der Datenquelle gelieferten und dem von dem Steuerelement erwarteten Wert. Wenn gefordert ist, dass ein Steuerelement seinen Wert in einem bestimmten Darstellungsformat anzeigt, etwa in einem Währungsformat oder einem bestimmten Datums-/ZeitFormat, kann dieses zur Entwurfszeit in der Eigenschaftsseite des DataFormat-Objekts ausgewählt werden. Der Aufruf der Eigenschaftsseite kann über das Eigenschaftsfenster erfolgen. Darüber hinaus hat das Datenformatobjekt eine Reihe von Eigenschaften, die sich zur Laufzeit setzen bzw. abfragen lassen. Die wichtigste davon ist die Format-Eigenschaft vom Typ String, die eine Zeichenfolge mit der Formatbeschreibung enthält. Beispiel
................................................... Beis piel
' Liefert Ausgaben der Art "18:02:04 Uhr, am 5. März 1992" Text1.DataFormat.Format = "h:mm:ss U\hr, a\m d.mmmm yyyy" Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DataField, DataMember, DataSource Verwandte Themen
................................................... Verwandte Them en
Data-Datensteuerelement (Data) (S. 402)
338
DataMember- Eigenschaft
DataMember- Eigenschaft Objekt.DataMember As String Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, Column, ComboBox, DataCombo, DataGrid, DataList, DataRepeater, DBList, DBCombo, DTPicker, Image, ImageCombo, Label, ListBox, MonthView, OLE, PictureBox, RepeaterBinding, RptFunction, RptTextBox, RichTextBox, TextBox Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Die DataMember-Eigenschaft spielt für die fortgeschrittene Programmierung mit ADO-Datenobjekten (ActiveX Data Objects) ein gewisse Rolle, wenn als Datenquelle eine DataEnvironmentKomponente (oder eine vergleichbare Komponente) benutzt wird. Einer DataEnvironment-Komponente lassen sich Befehle (Command-Objekte) und gespeicherte Prozeduren (PreparedCommandObjekte) für die Auswahl spezieller Recordsets zuordnen, die sich dann über die DataMemberEigenschaft abstrakt auswählen lassen. Beispiel
................................................... Beis piel
Text1_DataMember = "Command2" Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DataField, DataFormat, DataSource Verwandte Themen
................................................... Verwandte Them en
Data-Datensteuerelement (Data) (S. 402)
DataSource- Eigenschaft Objekt_DataSource = DatenquelleObjekt Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, Column, ComboBox, DataCombo, DataGrid, DataList, DataRepeater, DBList, DBCombo, DTPicker, Image, ImageCombo, Label, ListBox, MaskEdBox, MonthView, OLE, PictureBox, RepeaterBinding, RptFunction, RptTextBox, RichTextBox, TextBox Beschreibung
................................................... Bes c hreibung
Die DataSource-Eigenschaft bindet ein Steuerelement an eine sog. Datenquelle. Bei einer Datenquelle handelt es sich um ein Objekt, das eine Datenbankverbindung herstellen und die Repräsentation von Datensatzmengen (Recordset) übernehmen kann. Ist ein Steuerelement an eine Datenquelle gebunden, zeigt es zum einen den von dieser Datenquelle gelieferten Wert an, kann zum anderen aber auch Änderungen des Werts zurück an die Datenquelle liefern (sofern das verwendete Recordset-Objekt dies zulässt; vgl. »Data-Datensteuerelement (Data)«; S. 402).
339
Gemeinsame Eigenschaften
Die DataMember-Eigenschaft eines gebundenen Steuerelements spezifiziert, welches Datenelement der Datenquelle die Datensätze bereitstellt. Datenelemente sind vom Prinzip her benannte Recordsets, die in dem als Datenquelle fungierenden Objekt bereits vordefiniert sind und sich über die DataMember-Eigenschaft auswählen lassen. Hat die DataMember-Eigenschaft die leere Zeichenfolge als Wert, fungiert das standardmäßige Recordset der Datenquelle als Datenelement.
Gemeinsame Eigenschaften
An vordefinierten Datenquellen stehen in die beiden älteren Steuerelemente Data, RemoteData sowie das neuere ActiveX-Steuerelement Adodc und DataEnvironment-Komponenten zur Verfügung. Datenquellen, die durch die ersten beiden Steuerelementtypen repräsentiert werden, müssen bereits zur Entwurfszeit an den Datennutzer gebunden werden, die anderen beiden Objekttypen lassen sich auch zur Laufzeit binden. Anwendung
Gemeinsame Eigenschaften
................................................... Anwendung
Die Datenbankanbindung über ein Datensteuerelement kommt der Philosophie von Visual Basic am weitesten entgegen. Da die gesamte Logik für die Errichtung und Pflege der Datenbankverbindung in dem Datensteuerelement verkapselt ist, muss der Programmierer beim Entwurf eines datenbankbasierten Formulars (bzw. Komponente) nichts weiter machen, als ein Datensteuerelement in den Entwurfsbereich zu ziehen, dieses (zur Entwurfszeit oder zur Laufzeit) geeignet zu initialisieren und es den Steuerelementen, die für die Anzeige der Informationen aus der Datenbank gedacht sind, über die Eigenschaft DataSource als Datenquelle bekanntzugeben. Den Rest macht das Datensteuerelement: Es baut die Verbindung mit der Datenbank auf, wählt eine Datensatzmenge aus, pflegt einen über die Pfeilschaltflächen des Datensteuerelements gesteuerten Datensatzzeiger und synchronisiert die angebundenen Steuerelemente mit dem jeweils aktuellen Datensatz. Jedes der drei in Visual Basic verfügbaren Datensteuerelemente geht mit einem Datenzugriffsmodell einher. Die beiden älteren Datensteuerelemente Data und RemoteData sind speziell auf DAO (Data Access Objects = Datenzugriffsobjekte für den Datenzugriff über die Microsoft Jet Engine) bzw. auf RDO (Remote Data Objects = Remote-Datenzugriffsobjekte für den Datenzugriff über ODBC) ausgelegt. Sie werden inzwischen nur noch der Kompatibilität halber unterstützt, da seit Einführung der ActiveX-Datenzugriffsobjekte (ADO = ActiveX Data Objects) mit Visual Basic 6.0 ein vollständig COM-orientiertes Datenzugriffsmodell existiert. Für einfache Datenbankanwendungen tut es jedes der drei genannten Datensteuerelemente. Bei komplexeren Anforderungen an die möglichen Formen des Datenzugriffs sowie an Datenbankinteraktionen generell empfiehlt sich die Verwendung von Datenumgebungskomponenten (DataEnvironment), die eine Verkapselung maßgeschneiderter Modelle für die fortgeschrittene Datenbankinteraktion ermöglichen. Beispiel
................................................... Beis piel
Const Abfrage1 = "SELECT AVG(Frachtkosten) AS Fracht FROM Bestellungen" Private Sub FrachtkostenAnzeigen_Click() Text1.DataField = "" ' alte Bindung ggf. aufheben Adodc1.RecordSource = Abfrage1 ' Refresh nicht nötig Set Text1.DataSource = Adodc1 Text1.DataField = "Fracht" ' berechnetes Feld End Sub Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DataField, DataFormat, DataMember Verwandte Themen
................................................... Verwandte Them en
Data-Datensteuerelement (Data) (S. 402)
340
DisabledPicture- Eigenschaft
DisabledPicture- Eigenschaft Objekt.DisabledPicture As Picture Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, CommandButton, OptionButton Beschreibung
................................................... Bes c hreibung
Die DisabledPicture-Eigenschaft ermöglicht es, eine Bitmap anzugeben, die den inaktiven Zustand des Steuerelements in der benutzerdefinierten Darstellung zum Ausdruck bringt.
................................................... Anwendung
Schaltflächen, Optionsfelder und Kontrollkästchen unterstützen anstelle der standardmäßigen Darstellung auch die Möglichkeit, ihre drei Zustände in Form von benutzerdefinierten Bitmaps anzuzeigen. Zur Festlegung der Bitmaps sind die Eigenschaften Picture, DownPicture und DisabledPicture zuständig. Damit ein Steuerelement die Werte dieser Eigenschaften überhaupt beachtet, muss die zur Laufzeit schreibgeschützte Style-Eigenschaft bereits beim Formularentwurf auf vbButtonGraphical (1) gesetzt werden. Die DisabledPicture-Bitmap kommt immer dann zur Anzeige, wenn das Steuerelement sichtbar und die Enabled-Eigenschaft auf False gesetzt ist. Beispiel
................................................... Beis piel
Der folgende Code entstammt einem Formular, auf dem zwei Schaltflächen Command1 und Command2 sowie ein Bildausschnitt-Steuerelement PictureClip1 platziert wurden. Er demonstriert die benutzerdefinierte Darstellung für Command2. Das Bildausschnitt-Steuerelement liefert die drei Bitmaps, die für die Unterscheidung der Anzeigezustände notwendig sind. Die Schaltfläche Command1 ist dafür da, Command2 abwechselnd zu aktivieren und zu deaktivieren (dritter Zustand): Private Sub Command1_Click() Command2.Enabled = Not Command2.Enabled End Sub
' Aktivieren/Deaktivieren
Private Sub Form_Load() Command2.Picture = PictureClip1.GraphicCell(0) Command2.DownPicture = PictureClip1.GraphicCell(1) Command2.DisabledPicture = PictureClip1.GraphicCell(2) End Sub Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DownPicture, Picture
DownPicture- Eigenschaft Objekt.DownPicture As Picture Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, CommandButton, OptionButton Beschreibung
................................................... Bes c hreibung
Die DownPicture-Eigenschaft ermöglicht es, eine Bitmap anzugeben, die den gedrückten Zustand des Steuerelements in der benutzerdefinierten Darstellung zum Ausdruck bringt.
3 41
Gemeinsame Eigenschaften
Anwendung
Gemeinsame Eigenschaften
Anwendung
Gemeinsame Eigenschaften
................................................... Anwendung
Schaltflächen, Optionsfelder und Kontrollkästchen unterstützen anstelle der standardmäßigen Darstellung auch die Möglichkeit, ihre drei Zustände in Form von benutzerdefinierten Bitmaps anzuzeigen. Zur Festlegung der Bitmaps sind die Eigenschaften Picture, DownPicture und DisabledPicture zuständig. Damit ein Steuerelement die Werte dieser Eigenschaften überhaupt beachtet, muss die zur Laufzeit schreibgeschützte Style-Eigenschaft bereits beim Formularentwurf auf vbButtonGraphical (1) gesetzt werden. Zur Anzeige der DownPicture-Bitmap kommt es, wenn das Steuerelement sichtbar ist, die Enabled-Eigenschaft auf True gesetzt ist und der Benutzer mit der Maus oder der Tastatur das ClickEreignis des Steuerelements auslöst. Beispiel
................................................... Beis piel
Vgl. das Beispiel in »DisabledPicture-Eigenschaft« (S. 341). Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DisabledPicture, Picture
DragIcon- Eigenschaft Objekt.DragIcon As Picture Betroffene Objekte
................................................... Betro ffene Objekte Die meisten Steuerelementtypen Beschreibung
................................................... Bes c hreibung
Die DragIcon-Eigenschaft spezifiziert die Mauszeigerform, die zur Anzeige kommt, wenn das Steuerelement einer Drag&Drop-Operation unterworfen ist. Hat die Eigenschaft den Wert Nothing, bleibt die aktuelle Mauszeigerform unverändert, vielmehr erscheint aber der Umriss des gezogenen Steuerelements als visuelles Feedback. Anwendung
................................................... Anwendung
Als Werte für diese Eigenschaft sind nur Verweise auf Bitmaps geeignet, die in einem der Symbolformate CUR oder ICO vorliegen – insbesondere lassen sich also weder gewöhnliche Bilder (BMP, JPG, WMF etc.) noch animierte Cursorformen (ANI) als Mauszeigerform setzen. Beispiel
................................................... Beis piel
Text1.DragIcon = LoadPicture ("MyDragIcon.Ico") Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften MouseIcon, MousePointer Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501); Transparenz und Drag&Drop (S. 606)
342
DragMode- Eigenschaft
DragMode- Eigenschaft Objekt.DragMode As Integer Betroffene Objekte
................................................... Betro ffene Objekte Die meisten vordefinierten Steuerelementtypen Beschreibung
................................................... Bes c hreibung
Konstante
Beschreibung
vbManual (0)
Das Steuerelement geht auf Drag&Drop-Operationen nur ein, wenn es explizit durch Aufruf der Methode Drag dazu veranlasst wird (Voreinstellung).
vbAutomatic (1)
Das Steuerelement interpretiert das Drücken der linken Maustaste als Beginn einer Drag&Drop-Operation. Zudem kann eine Drag&Drop-Operation auch explizit durch Aufruf der Methode Drag eingeleitet werden.
Anwendung
................................................... Anwendung
Drag&Drop-Operationen stellen eine auf die Grenzen eines Programms beschränkte Form der grafisch orientierten Befehlsübermittlung zwischen Steuerelementen untereinander sowie von Steuerelement zu Formular dar. Im automatischen Modus beginnt der Benutzer eine Drag&Drop-Operation, indem er mit der linken Maustaste auf ein Steuerelement (Quellobjekt) klickt und dieses mit gehaltener Maustaste über ein anderes Steuerelement und/oder Formular zieht und ablegt (Zielobjekt). Das Loslassen der Maustaste steht für das Ablegen des Steuerelements und löst aufseiten des Zielobjekts das DragDrop-Ereignis aus, dessen Behandlung die mit der Operation verbundene Wirkung hervorruft. Wie die Wirkung im Einzelnen aussieht, dafür gibt es keine Vorschriften. Da das Zielobjekt eine echte Referenz auf das Quellobjekt erhält, kann sie von der einfachen Positionsänderung des gezogenen Steuerelements über die Befehlsauswahl bis hin zur Vernichtung des Quellobjekts (»in einem Papierkorb verschieben«) reichen. Beispiel
................................................... Beis piel
Der folgende Code zeigt die Implementation einer manuellen Drag&Drop-Operation. Der Benutzer kann eine auf dem Formular befindliche Schaltfläche Command1 mit der rechten Maustaste verschieben und mit der linken Maustaste weiterhin wie gewohnt das Click-Ereignis auslösen. Private StartX As Single Private StartY As Single Private Sub Command1_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If Button = vbRightButton Then StartX = X StartY = Y Command1.Drag vbBeginDrag End If End Sub
3 43
Gemeinsame Eigenschaften
Die DragMode-Eigenschaft legt fest, ob ein Steuerelement Drag&Drop-Operationen automatisch eingehen kann oder durch Aufruf der Drag-Methode dazu »überredet« werden muss. Die folgende Tabelle gibt einen Überblick über die möglichen Werte der Eigenschaft und deren Wirkung:
Gemeinsame Eigenschaften
Private Sub Form_DragDrop(Source As Control, X As Single, Y As Single) Source.Left = X – StartX Source.Top = Y – StartY End Sub Private Sub Form_Load() Command1.DragMode = 0 End Sub Verwandte Ereignisse
Gemeinsame Eigenschaften
................................................... Verwandte Ereignis s e DragDrop-Ereignis, DragOver-Ereignis Verwandte Themen
................................................... Verwandte Them en
Transparenz und Drag&Drop (S. 606)
DrawMode- Eigenschaft Objekt.DrawMode As Integer Betroffene Objekte
................................................... Betro ffene Objekte Form, Line, PictureBox, Printer, PropertyPage, RptLine, RptShape, Shape, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die DrawMode-Eigenschaft legt die Rasteroperation fest, die das Objekt für das Zeichnen von Linien und Füllbereichen anwendet. Der Aufzählungstyp DrawModeConstants definiert folgende Konstanten dafür: Konstante (Wert)
Beschreibung
vbBlackness (1)
Schwarzintensität
vbNotMergePen (2)
Stift mischen invers (invers zu 15)
vbMaskNotPen (3)
inversen Stift maskieren; Kombination der Farben, die der Hintergrund mit der invertierten Stiftfarbe gemeinsam hat
vbNotCopyPen (4)
Stift kopieren invers (invers zu 13)
vbMaskPenNot (5)
Stift und inverse Anzeige maskieren; Kombination der Farben, die der Stift mit der invertierten Anzeigefarbe gemeinsam hat
vbInvert (6)
Anzeigefarbe invers
vbXorPen (7)
Stift XOR Anzeigefarbe; Kombination der Farben, die im Stift und in der Anzeigefarbe, aber nicht in beiden vorhanden sind
vbNotMaskPen (8)
Stift maskieren invers (invers zu 9)
vbMaskPen (9)
Stift maskieren; Kombination der Farben, die Stift und Anzeigefarbe gemeinsam haben (invers zu 10)
vbNotMaskPen (10)
Stift maskieren invers (invers zu 9)
vbNop (11)
Keine Operation; Stift zeichnet nicht
vbMergeNotPen (12)
Inversen Stift mischen – Kombination der Anzeigefarbe und der invertierten Stiftfarbe
344
DrawMode- Eigenschaft
Konstante (Wert)
Beschreibung
vbCopyPen (13)
Stift kopieren (Voreinstellung); Stiftfarbe ist durch Eigenschaft ForeColor gegeben (invers zu 4)
vbMergePenNot (14)
Stift und inverse Anzeige mischen; Kombination der Stiftfarbe und der invertierten Anzeigefarbe
vbMergePen (15)
Stift mischen; Kombination aus Stift- und Anzeigefarbe (invers zu 2)
vbWhiteNess (16)
Stift zeichnet mit leuchtendem Weiß
................................................... Anwendung
Die DrawMode-Eigenschaft ist etwas für spezielle Effekte. So kann eine einfache Änderung der DrawMode-Eigenschaft recht beachtliche Veränderungen in der Ausgabe hervorrufen. Der voreingestellte Wert vbCopyPen (13) entspricht dem, was man sich landläufig unter »Zeichnen mit einem deckenden Stift in einer bestimmten Farbe« vorstellt. Die anderen Rasteroperationen verwenden teilweise eine feste oder invertierte Stiftfarbe und/oder mischen bzw. invertieren die Stiftfarbe mit der Anzeigefarbe (das ist die bestehende Farbe des Bildpunkts) – das Ergebnis ist also nicht in jedem Fall vorhersehbar, sondern hängt von den farblichen Gegebenheiten und der Logik der Rasteroperation ab. Auf Rang zwei in der Beliebtheitsskala der Rasteroperationen, gleich nach vbCopyPen, rangiert vbXorPen (7). Diese Rasteroperation ist ihre eigene Umkehroperation, das heißt, in diesem Modus versetzt ein erneuter Aufruf der genau gleichen Grafikoperation den Ausgabebereich in den Zustand vor dem ersten Aufruf zurück. Ausgaben lassen sich auf diese Weise zurücknehmen, ohne darunter gelegene Elemente zu zerstören. Diese Technik wird beispielsweise für die Programmierung mit »Gummibändern« verwendet (vgl. »Gummiband – Bereiche interaktiv auswählen«, S. 492). Beispiel
................................................... Beis piel
Das Beispielprojekt DrawModeDemo zeigt die Auswirkungen der DrawMode-Eigenschaft auf das Zeichnen von Linien und Füllbereichen sowie für Überlappungen mit bereits gezeichneten Elementen. Die Paint-Routine des Formulars zeichnet den linken Kreis mit der voreingestellten Rasteroperation vbCopyPen (13) und den rechten mit dem jeweils aktuellen Rasteroperation, die sich durch einen Klick auf den Formularbereich weiterschalten lässt. Dim DrawMode1 As Integer Private Sub Form_Click() DrawMode1 = (DrawMode1 Mod 16) + 1 ' Weiterschalten Refresh End Sub Private Sub Form_Load() Height = Width FillStyle = 0 DrawWidth = 15 DrawMode1 = 13 DrawMode1 = 1 AutoRedraw = False End Sub Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Dim p, r, g, b
3 45
Gemeinsame Eigenschaften
Anwendung
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
p = Point(X, Y) r = (p And &HFF) g = (p \ &H100 And &HFF) b = p \ &H10000 Caption = "DrawMode: " & DrawMode1 & ", Farbe unter Maus: (" _ & r & "," & g & "," & b & ")" End Sub Private Sub Form_Paint() ' Linker Kreis wird mit "normalen" Einstellungen gezeichnet Form_MouseMove 0, 0, 0, 0 Cls DrawMode = 13 FillColor = RGB(200, 255, 255) ForeColor = RGB(255, 0, 255) Me.Circle (ScaleHeight * 0.52, ScaleHeight * 0.5), Height * 0.4 ' Rechter Kreis wird mit verändertem Drawmode gezeichnet DrawMode = DrawMode1 FillColor = RGB(123, 145, 17) ForeColor = RGB(145, 17, 123) Me.Circle (ScaleHeight * 0.72, ScaleHeight * 0.5), Height * 0.4 End Sub
Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften BorderStyle, BorderWidth, DrawStyle, DrawWidth Verwandte Themen
................................................... Verwandte Them en
Gummiband – Bereiche interaktiv auswählen (S. 492)
DrawStyle- Eigenschaft Objekt.DrawStyle As Integer Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, Printer, PropertyPage, UserControl, UserDocument
346
Enabled- Eigenschaft
Beschreibung
................................................... Bes c hreibung
Die DrawStyle-Eigenschaft bestimmt einen von sieben Linienstilen für die Zeichenoperationen eines Objekts. Falls für eine Grafikoperation eine Linienbreite (DrawWidth) größer als 1 eingestellt ist, ignoriert das Objekt allerdings die Werte 1 bis 4 der DrawStyle-Eigenschaft und arbeitet statt dessen mit der Voreinstellung 0. Der Aufzählungstyp DrawStyleConstants definiert eine Reihe von Konstanten für die unterschiedlichen Linienstile: Beschreibung
vbSolid (0)
Durchgezogen (Voreinstellung)
vbDash (1)
Gestrichelt
vbDot (2)
Gepunktet
vbDashDot (3)
Folge aus Strichen und Punkten
vbDashDotDot (4)
Folge aus Strichen und zwei Punkten
vbInvisible (5)
Transparent
vbInsideSolid (6)
Innen ausgefüllt
Anwendung
................................................... Anwendung
Aufgrund ihrer Begrenztheit auf Linienbreiten von 1 Bildpunkt lässt sich mit der DrawStyleEigenschaft nicht allzu viel anfangen. Der Unterschied zwischen vbSolid und vbInsideSolid macht sich nur bemerkbar, wenn eine geschlossene Figur, beispielsweise ein Rechteck oder ein Kreis, gezeichnet wird. Für gewöhnliche Linien gibt es keinen Unterschied. In geschlossen Figuren sorgt vbInsideSolid dafür, dass die Linie vollständig innerhalb des angegebenen Bereichs (Höhe, Breite, doppelter Radius) verbleibt, so dass für optimierte Zeichenroutinen (Paint) jeweils mit den Bereichsgrenzen gerechnet werden kann. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften BorderStyle, BorderWidth, DrawMode, DrawWidth Verwandte Themen
................................................... Verwandte Them en
Gummiband – Bereiche interaktiv auswählen (S. 492)
Enabled- Eigenschaft Objekt.Enabled As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Formulare sowie die meisten vordefinierten Steuerelementtypen Beschreibung
................................................... Bes c hreibung
Die Enabled-Eigenschaft drückt den Aktivierungszustand von Objekt aus. Lautet ihr Wert False, ist das Objekt deaktiviert, das heißt, es erhält die Darstellung »deaktiviert« und nimmt den Fokus nicht mehr entgegen.
3 47
Gemeinsame Eigenschaften
Konstante (Wert)
Gemeinsame Eigenschaften
Anwendung
................................................... Anwendung
Die Enabled-Eigenschaft implementiert einen recht brauchbaren Mechanismus, der es ermöglicht, die Benutzerinteraktionen in Abhängigkeit vom jeweiligen Programmzustand auf die sinnvollen bzw. erlaubten Operationen einzuschränken. Da die meisten Steuerelemente ihre Deaktivierung auch durch eine entsprechend veränderte Darstellung anzeigen, erhält der Benutzer gleichzeitig ein visuelles Feedback für seinen Handlungspielraum.
FillColor- Eigenschaft
Gemeinsame Eigenschaften
Objekt.FillColor As Long Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, Printer, PropertyPage, Shape, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Eigenschaft FillColor ist ein Farbwert vom Typ Long, der die Füllfarbe für den Füllbereich beim Zeichnen geschlossener Figuren festlegt. Voreinstellung für diese Eigenschaft ist die Farbe »Schwarz« mit dem Wert 0. Zur Auswahl stehen neben den Systemfarben auch beliebige andere Farben, die sich entweder zur Entwurfszeit aus der Palette wählen oder zur Laufzeit über die Funktion RGB komponentenweise zu einem Farbwert komponieren lassen. Die Funktion QBColor liefert den Farbwert einer der 16 Grundfarben. Zudem definiert der Aufzählungstyp SystemColorConstants Konstanten für die Systemfarben (vgl. »BackColor-Eigenschaft und ForeColor-Eigenschaft«, S. 330). Voraussetzung für die Anzeige der Füllfarbe ist allerdings, dass die Eigenschaft FillStyle einen Wert ungleich vbTransparent (1) aufweist. Anwendung
................................................... Anwendung
FillColor spielt insbesondere eine Rolle, wenn Sie mit grafischen Methoden wie Circle oder Line arbeiten. Beim Zeichnen ausgefüllter Rechtecke können Sie wählen, ob Sie den Füllbereich mit der Vordergrundfarbe (ForeColor) oder mit der Füllfarbe (FillColor) und dem Füllmuster (FillStyle) zeichnen wollen, indem Sie den optionalen Parameter BF oder nur B angeben. Beispiel
................................................... Beis piel
Der folgende Code zeichnet ein gefülltes Rechteck mit taubenblauem diagonal gestreiften Füllmuster und schwarzem verdickten Rand. DrawWidth = 3 ForeColor = vbBlack FillColor = RGB(24, 135, 212) FillStyle = vbDownwardDiagonal Line (100, 100)-(1000, 1000), , B Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften BackColor, FillStyle, ForeColor
348
FillStyle- Eigenschaft
FillStyle- Eigenschaft Objekt.FillStyle As Integer Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, Printer, PropertyPage, Shape, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Konstante (Wert)
Beschreibung
vbFSSolid (0)
Ausgefüllt
vbFSTransparent (1)
Transparent (Voreinstellung)
vbHorizontalLine (2)
Horizontale Schraffur
vbVerticalLine (3)
Vertikale Schraffur
vbUpwardDiagonal (4)
Aufwärtsdiagonale Schraffur
vbDownwardDiagonal (5)
Abwärtsdiagonale Schraffur
vbCross (6)
Kreuzschraffur
vbDiagonalCross (7)
Diagonale Kreuzschraffur
Anwendung
................................................... Anwendung
Laut Voreinstellung wird die Füllfarbe ignoriert. FillStyle muss daher auf einen Wert ungleich 1 gesetzt werden, damit die Füllfarbe im Füllbereich sichtbar wird. Beispiel
................................................... Beis piel
Siehe das Beispiel zu »FillColor-Eigenschaft« (S. 348). Verwandte Befehle
................................................... Verwa ndte Befehle
BackColor, FillColor, ForeColor
Font- Eigenschaft Objekt.Font As Font Betroffene Objekte
................................................... Betro ffene Objekte Adodc, CheckBoxm, ComboBox, CommandButton, Data, DataCombo, DataGrid, DataList, DataReport, DirListBox, DriveListBox, FileListBox, Form, Frame, Label, MaskEdBox, MonthView, ImageCombo, ListBox, ListView, OptionButton, PictureBox, Printer, PropertyPage, RemoteData, RichTextBox, RptFunction, RptLabel, RptTextBox, Shape, SSTab, StatusBar, TabStrip, TextBox, TreeView, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Font-Eigenschaft enthält eine Referenz auf ein Font-Objekt, das die Schrift sowie die Schriftattribute für die Textausgabe genauer spezifiziert. Font-Objekte
3 49
Gemeinsame Eigenschaften
Die Eigenschaft Fillstyle legt ein Füllmuster für Füllbereiche fest, die mit Füllfarbe (FillColor) gezeichnet werden. Der Aufzählungstyp FillStyleConstants definiert folgende Konstanten für die verschiedenen Füllmuster:
Gemeinsame Eigenschaften
Anwendung
................................................... Anwendung
Gemeinsame Eigenschaften
Um die für ein Steuerelement geltende Schrift zu verändern, können Sie über die Font-Eigenschaft auf das aktuell geltende Font-Objekt zugreifen und dessen Eigenschaften neu setzen. Es besteht aber auch die Möglichkeit, die Schriftattribute mehrerer Steuerelemente über ein einzelnes Font-Objekt zu steuern, indem Sie die Font-Eigenschaften dieser Steuerelemente auf das gleiche Font-Objekt setzen. Dazu vereinbaren Sie entweder auf Modulebene ein neues Font-Objekt: Private fntGemeinsam As New StdFont ... fntGemeinsam.Name = "Arial Black" fntGemeinsam.Size = 14 ...
oder nutzen ein bereits bestehendes Font-Objekt, das zu einem der Steuerelemente gehört. Dann setzen Sie die Font-Eigenschaften der Steuerelemente auf dieses Objekt. Set Text1.Font = fntGemeinsam Set Text2.Font = fntGemeinsam Set Text3.Font = fntGemeinsam
Änderungen an fntGemeinsam wirken sich nun auf alle betroffenen Steuerelemente aus. Hinweis
................................................... Hinweis Die Schriftattribute »Fett«, »Kursiv«, »Durchgestrichen« oder »Unterstrichen« lassen sich sowohl über die Eigenschaften FontBold, FontItalic, FontStrikethru, FontUnderline als auch über die Eigenschaften Bold, Italic, Strikethru und Underline des Font-Objekts setzen. In gleicher Weise decken sich die Eigenschaften FontName und FontSize mit den Eigenschaften Name und Size des Font-Objekts. Beispiel
................................................... Beis piel
Text1.Font.Italic = True
ForeColor- Eigenschaft Siehe »BackColor-Eigenschaft und ForeColor-Eigenschaft«, S. 330.
HasDC- Eigenschaft Objekt.HasDC As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Form, MonthView, PictureBox, PropertyPage, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die HasDC-Eigenschaft spielt nur im Zusammenhang mit Aufrufen von Funktionen der Win32API eine Rolle. Sie beschreibt, ob Objekt über einen eigenen Gerätekontext verfügt (True) oder nicht (False). Anwendung
................................................... Anwendung
Falls ein Objekt keinen eigenen Gerätekontext besitzt, wie das beispielsweise bei fensterlosen Steuerelementen (vgl. Windowless-Eigenschaft) der Fall ist (unabhängig vom tatsächlichen Wert
350
hDC- Eigenschaft
der HasDC-Eigenschaft), benutzt es für seine Ausgaben den Gerätekontext des übergeordneten Objekts (Parent). Das kann dann zu Schwierigkeiten bis hin zu hässlichen Abstürzen bei der Ausführung von Win32-API-Funktionen führen.
hDC- Eigenschaft Objekt.hDC As Long Betroffene Objekte
................................................... Betro ffene Objekte CommonDialog, Form, MonthView, PictureBox, PropertyPage, UserControl, UserDocument
................................................... Bes c hreibung
Die hDC-Eigenschaft spielt nur im Zusammenhang mit Aufrufen von Funktionen der Win32-API eine Rolle. Ihr Wert ist eine Nummer, die den Gerätekontext von Objekt identifiziert. Eine Ausnahme bildet das CommonDialog-Steuerelement: Hier spezifiziert hDC den Gerätekontext des ausgewählten Druckers. Anwendung
................................................... Anwendung
Ein Gerätekontext ist eine Windows-Datenstruktur, die den Zustand eines Ausgabegerätes (Drucker, Fenster, Bildschirm) vollständig beschreibt. Er enthält die aktuellen Einstellungen über die verwendeten Farben, den aktuellen Stift, die Schrift usw. und im Falle des Bildschirmkontextes auch noch eine Bitmap (Image-Eigenschaft), die den aktuellen Zustand der Ausgabe repräsentiert und (bei gesetzter AutoRedraw-Eigenschaft) für die Aktualisierung der Anzeige benutzt wird. Falls ein Objekt keinen eigenen Gerätekontext besitzt (HasDC-Eigenschaft), wie das beispielsweise bei fensterlosen Steuerelementen (vgl. Windowless-Eigenschaft) der Fall ist (unabhängig vom tatsächlichen Wert der HasDC-Eigenschaft), benutzt es für seine Ausgaben den Gerätekontext des übergeordneten Objekts (Parent). Das kann jedoch zu Schwierigkeiten bis hin zu hässlichen Abstürzen bei der Ausführung von Win32-API-Funktionen führen.
Height- Eigenschaft und Width- Eigenschaft Objekt.Height As Single Objekt.Width As Single Betroffene Objekte
................................................... Betro ffene Objekte Alle Formulararten, Komponenten und Steuerelemente mit sichtbarer Darstellung Beschreibung
................................................... Bes c hreibung
Die Eigenschaften Height und Width beschreiben die vertikale und horizontale Abmessung eines Objekts. Bei Form-Objekten, Printer-Objekten und dem Screen-Objekt werden die Werte dieser Eigenschaften standardmäßig in der Maßeinheit Twips ausgedrückt. Bei Steuerelementen und Komponenten, die in einem Container (in einem Formular, Bildfeld, Rahmen etc.) platziert wurden, sind die Abmessungen immer auf die Maßeinheiten bezogen, wie sie aktuell im Koordinatensystem des Containers gelten. Anwendung
................................................... Anwendung
Die Abmessungen eines Steuerelements oder eines Formulars lassen sich nicht nur zur Entwurfszeit, sondern auch zur Laufzeit dynamisch anpassen, indem Sie die Eigenschaften Height und/oder Width auf geeignete Werte setzen. Um bei der Anpassung von Steuerelementen keine
3 51
Gemeinsame Eigenschaften
Beschreibung
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Überraschungen zu erleben, sollten Sie allerdings im Hinterkopf behalten, dass sich die Maßeinheiten in einem Containerobjekt jederzeit durch einen Wechsel des Koordinatensystems (ScaleMode) oder durch eine Skalierung der Koordinatenachsen (ScaleHeight und ScaleWidth) ändern können. Bei Formularobjekten, deren BorderStyle-Eigenschaft auf vbSizable (2) gesetzt wurde, können sich Wertänderungen für Height und Width auch aufgrund von Benutzerinteraktionen ergeben. Jede Wertänderung dieser Eigenschaften, gleich ob sie vom Programmcode aus oder auf Veranlassung des Benutzers geschehen ist, generiert ein Resize-Ereignis. Es ist wichtig, den Unterschied zwischen den Eigenschaften Height und Width und den Eigenschaften ScaleHeight und ScaleWidth zu begreifen. Erstere sind auf die äußeren Abmessungen des Darstellungsbereichs eines Objekts bezogen, während letztere die Abmessungen des ClientBereichs, also die »inneren« Abmessungen des Objekts, ausdrücken. Mehr noch: Wertänderungen bei Height und Width ändern die äußeren und inneren Abmessungen des Objekts, Wertänderungen bei ScaleHeight und ScaleWidth dagegen nur die Maßgrundlage und nicht die Abmessungen. Beispielsweise gibt ein neuer Wert für die ScaleHeight-Eigenschaft eines Formulars an, in wie viele Einheiten der Client-Bereich fortan in vertikaler Richtung unterteilt sein soll; da dies die Metrik ändert, ändert sich auch die Eigenschaft ScaleMode implizit auf vbUser (0). Anmerkungen
................................................... Anm erkungen Beim Bildausschnittobjekt (PictureClip) sind die Eigenschaften Height und Width schreibgeschützt. Da das Bildausschnittobjekt selbst keine sichtbare Darstellung hat, drücken diese Eigenschaften die Abmessungen der dem Objekt zugeordneten Bitmap (in Bildpunkten) aus. Während die Abmessungen des PictureBox-Objekts (wie alle Steuerelemente) in den Maßeinheiten des Containerobjekts gehalten sind, liegt den Eigenschaften Height und Width eines zugewiesenen Picture-Objekts immer die Maßeinheit HiMetric (hundertstel Millimeter) zugrunde. Um ein PictureBox-Objekt an die Abmessungen eines Picture-Objekts anzupassen, müssen die Maßeinheiten mittels der Methoden ScaleX und ScaleY umgerechnet werden. Picture1.Width = ScaleX(Picture1.Picture.Height, vbHimetric, vbUser)
Für das Screen-Objekt sind die beiden Eigenschaften schreibgeschützt. Bei DriveListBox- und ComboBox-Steuerelementen, deren Style-Eigenschaft auf vbComboDropdown (0) oder auf vbComboDropdownList (2) gesetzt wurde, wird die Height-Eigenschaft vom System errechnet und ist zur Laufzeit schreibgeschützt. Beispiel
................................................... Beis piel
Häufig ergibt sich das Problem, den Client-Bereich eines Formulars auf eine bestimmte Größe trimmen zu müssen, etwa um ein Bild einzupassen. Auf direktem Wege ist das nicht möglich, da ScaleHeight und ScaleWidth ja keine Abmessungen, sondern nur Maßeinheiten ändern. Die Lösung ist simpel – wenn man sie kennt. Angenommen die Variablen sNeueHöhe und sNeuBreite enthalten die neuen Abmessungen des Client-Bereichs, dann leistet der folgende Code das Gewünschte: ScaleMode = vbTwips ' gleiche Maßeinheiten für innen und außen Height = Height – ScaleHeight + sNeueHöhe Width = Width – ScaleWidth + sNeueBreite Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften ScaleHeight, ScaleMode, ScaleWidth
352
HelpContextID- Eigenschaft und WhatsThisHelpID- Eigenschaft
HelpContextID- Eigenschaft und WhatsThisHelpID- Eigenschaft Objekt.HelpContextID As Long Objekt.WhatsThisHelpID As Long Betroffene Objekte
................................................... Betro ffene Objekte Formulare, Komponenten und Steuerelemente mit sichtbarer Darstellung Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Visual Basic unterstützt vier verschiedene Techniken, wie Sie Benutzern Ihrer Anwendungen Hilfe zukommen lassen können: 1. QuickInfo – blendet den Wert der Eigenschaft ToolTipText eines Steuerelements in einem kleinen Fensterchen ein, wenn die Maus in den Bereich des Steuerelements gelangt und dort ca. eine halbe Sekunde verweilt. 2. Statusanzeige – die Behandlungsroutine der MouseMove-Methode gibt bei Eintritt der Maus in den Steuerelementbereich einen Hilfetext in der Statusleiste (StatusBar) aus. 3. Direkthilfe – bei aktiviertem Direkthilfemodus blendet der nächste Klick auf ein Steuerelement ein Popup-Hilfefenster mit einem Hilfetext zu diesem Steuerelement ein. Der über die Eigenschaft WhatsThisHelp indizierte Hilfetext entstammt der Datei App.HelpFile. Damit sich die Direkthilfe überhaupt aktivieren lässt, muss die WhatsThisHelp-Eigenschaft des Containerformulars auf True gesetzt sein. Die Aktivierung des Direkthilfemodus kann dann durch Aufruf der WhatsThisMode-Methode des Formulars geschehen oder durch einen Klick auf die Hilfeschaltfläche in der Titelleiste des Formulars (dazu muss die Eigenschaft WhatsThisButton des Formulars auf True gesetzt sein, und es dürfen keine MINIMIEREN-/MAXIMIEREN-Schaltflächen vorhanden sein). 4. Kontextbezogene Hilfe – die Hilfetaste (F1) aktiviert das Windows-Hilfesystem und bringt darin den über die Eigenschaft HelpContextID indizierten Hilfetext aus der Datei App.HelpFile zur Anzeige. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften MaxButton, MinButton, ToolTipText, WhatsThisHelp, WhatsThisButton
3 53
Gemeinsame Eigenschaften
Die Eigenschaften HelpContextID und WhatsThisHelpID ordnen einem Objekt Hilfethemen in der zur Anwendung gehörigen Hilfedatei (App.HelpFile) zu. HelpContextID spezifiziert den Index des Hilfethemas, wenn der Benutzer die kontextbezogene Hilfe (Windows-Hilfesystem) über die Taste (F1) aktiviert. WhatsThisHelpID spezifiziert den Index des Hilfethemas, wenn der Benutzer die Direkthilfe zu einem Steuerelement anfordert. Hat HelpContextID den Wert 0 (Voreinstellung), bedeutet das, dass für das Objekt kein Thema in der Allgemeinhilfe definiert ist. In diesem Fall versucht das Laufzeitsystem, das Hilfethema des Containerobjekts aufzurufen. Falls bis zum obersten Container alle HelpContextID-Eigenschaften den Wert 0 haben, kommt die SUCHEN-Funktion des Hilfesystems zum Aufruf. Hat WhatsThisHelpID den Wert 0 (Voreinstellung), bedeutet das, dass keine Direkthilfe für das Objekt verfügbar ist. In diesem Fall wird der Direkthilfemodus beendet, ohne dass etwas passiert.
Gemeinsame Eigenschaften
hWnd- Eigenschaft Objekt.hWnd As Long Betroffene Objekte
................................................... Betro ffene Objekte Formulare, Komponenten und Steuerelemente mit sichtbarer Darstellung, nicht jedoch OLE Beschreibung
................................................... Bes c hreibung
Gemeinsame Eigenschaften
Die zur Laufzeit schreibgeschützte hWnd-Eigenschaft enthält die Zugriffsnummer für das Fenster des Objekts – den sog. Fenster-Handle. Anwendung
................................................... Anwendung
Der Fenster-Handle eines Steuerelements spielt für die Visual-Basic-Programmierung nur dann eine Rolle, wenn Funktionen der Win32-API zum Aufruf kommen. Warnung
................................................... Wa rnung
Der Wert dieser Eigenschaft kann sich zur Laufzeit ändern (etwa im Zuge eines Unload-Aufrufs). Beispiel
................................................... Beis piel
Vgl. das Beispiel zu »Printer-Objekt« (S. 284). Verwandte Themen
................................................... Verwandte Them en
Routinen aus DLLs und der Windows-API einsetzen (S. 185)
Image- Eigenschaft Image As Picture Betroffene Objekte
................................................... Betro ffene Objekte Band, Button, Form, Node, PictureBox, PropertyPage, Tab, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Image-Eigenschaft stellt die Beschreibung einer beständigen im Speicher gelegenen Bitmap dar. Bei Objekten mit eigenem Gerätekontext (hDC) handelt es sich dabei um die beständige Bitmap im Gerätekontext. Die Image-Eigenschaft ist ihrerseits ein Objekt und besitzt fünf Eigenschaften sowie eine Methode: Eigenschaft
Beschreibung
Handle
Long-Wert, der die zugeordnete Bitmap identifiziert
Width, Height
Long-Werte, die die Breite und Höhe der Bitmap in der Einheit HiMetric (0,01 mm) ausdrücken. Die Werte müssen meist mit ScaleX bzw. ScaleY umgerechnet werden.
hPal
Long-Wert, der einen Handle auf die Palette darstellt, die für die Bitmap verwendet wird (nur für Aufrufe der Win32-API interessant)
354
Image- Eigenschaft
Eigenschaft
Beschreibung
Type
Integer-Wert, der das Grafikformat der beschriebenen Bitmap wiedergibt. Die möglichen Werte sind: vbPicTypeNone (0) Bild ist leer vbPicTypeBitMap (1)
Bild hat BMP-Format
vbPicTypeMetaFile (2)
Bild hat WMF-Format
vbPicTypeIcon (3)
Bild hat ICO-Format
vbPicTypeEMetaFile (4)
Bild hat EMF-Format
Sub Objekt.Image.Render(hDC As Long, x As Long, y As Long, cx As Long,_ cy As Long, xSrc As Long, ySrc As Long, cxSrc As Long, _ cySrc As Long, prcWBounds As Any) Die vielen Parameter sind alle erforderlich. In hDC muss der Gerätekontext des Ausgabebereichs übergeben werden (wenn das Zielobjekt keinen eigenen hat, dann der des Containerobjekts). Die Parameter x, y, cx, cy beschreiben die Position und Abmessungen des Bildes im Ausgabebereich bezogen auf das darin geltende Koordinatensystem. Die Parameter xSrc, ySrc, cxSrc, cySrc beschreiben den zu zeichnenden Bildausschnitt (Position und Abmessungen) der über Handle zugänglichen Quell-Bitmap – als Koordinatensystem gilt hier HiMetric. Für den Parameter prcWBounds ist der Wert 0 anzugeben, wenn die Bitmap nicht im WMF-Format vorliegt – ansonsten ein Wert des Typs RECTL (eine aus vier Long-Werten bestehende Struktur, die den linken oberen und rechten unteren Punkt beschreibt), der die Standardabmessungen für die Vektorgrafik definiert. Anwendung
................................................... Anwendung
Die Image-Eigenschaft ermöglicht den Umgang mit Bildern, die in einem Gerätekontext repräsentiert sind. Bei Formularen entscheidet die AutoRedraw-Eigenschaft darüber, ob die über die ImageEigenschaft beschriebene Bitmap Ziel der Grafikoperationen Circle, Pset, Line und Print ist und für die Auffrischung des Client-Bereichs herangezogen wird oder ob die Paint-Routine die Ausgaben an der Bitmap des Gerätekontextes vorbei direkt in den Client-Bereich zeichnet. Die beständige Bitmap des Gerätekontextes existiert in jedem Fall, unabhängig vom Wert der AutoRedrawEigenschaft, nur dass sie im einen Fall sowohl die über die Picture-Eigenschaft bereitgestellte Bitmap enthält als auch Grafikausgaben und im anderen Fall nur die Bitmap. Beispiel
................................................... Beis piel
Der genannte Unterschied lässt sich leicht nachweisen, indem man die Picture-Eigenschaft des Formulars auf eine Bitmap setzt und etwa einen Kreis darüber zeichnet. Da es möglich ist, die beständige Bitmap des Gerätekontextes über die Image-Eigenschaft auszulesen, kann man sie beispielsweise der Picture-Eigenschaft eines Bildfelds als Wert zuweisen. Im ersten Fall (AutoRedraw = True) sieht man dann die Bitmap samt Kreis und im andern Fall nur den Kreis. Private Sub Form_Click() Picture = LoadPicture("Test.bmp") Circle (400, 400), 400 Refresh Picture1 = Image ' Bitmap aus Gerätekontext in Bildfeld kopieren End Sub
3 55
Gemeinsame Eigenschaften
Die Methode trägt den Bezeichner Render und hat folgenden Prototyp:
Gemeinsame Eigenschaften
Index- Eigenschaft Objektarray(Index As Integer) As Objekt Beschreibung
Gemeinsame Eigenschaften
................................................... Bes c hreibung
Bei der Index-Eigenschaft handelt es sich um eine reine Entwurfseigenschaft, die zur Laufzeit nicht als Eigenschaft, sondern gegebenenfalls als Array-Index in Erscheinung tritt. Bleibt im Eigenschaftsfenster das Feld für ihren Wert leer, legt der Entwurfseditor den unter der Eigenschaft Name spezifizierten Bezeichner für das Objekt fest, ohne die Index-Eigenschaft weiter zu beachten. Trägt man dagegen eine (nicht negative) Ganzzahl als Wert für die Index-Eigenschaft ein, legt der Entwurfseditor unter dem in der Eigenschaft Name spezifizierten Bezeichner ein dynamisches Steuerelemente-Array an, dem sich beliebig viele Steuerelemente gleichen Typs zur Entwurfszeit, aber auch noch zur Laufzeit (via Load) hinzufügen lassen. Anwendung
................................................... Anwendung
Der Entwurfseditor schlägt die Einrichtung eines Steuerelemente-Arrays von sich aus vor, wenn Sie ein Steuerelement mit noch nicht gesetzter Index-Eigenschaft über die Zwischenablage vervielfältigen. Da er in diesem Fall die Index-Eigenschaften der im Array zusammengefassten Objekte auch pflegt, sei Ihnen diese Vervielfältigungsmethode ans Herz gelegt. Das erste Steuerelement (von dem die Kopie ausging) erhält den Index 0, das zweite den Index 1 usw. Sie können ein dynamisches Steuerelemente-Array aber auch »manuell« anlegen, indem Sie für ein bereits platziertes Steuerelement einen beliebigen Startindex eintragen und dann zur Entwurfszeit oder zur Laufzeit (mittels Load) weitere Steuerelemente gleichen Typs mit gleichem Namen in denselben Container platzieren. Obwohl die Zählung üblicherweise bei 0 beginnt, gibt es keine Vorschriften für den Startindex, er darf nur nicht negativ sein. Auch darf die Zählung Lücken aufweisen – solange zur Laufzeit (außer in der Load-Anweisung) nicht auf die fehlenden Indizes verwiesen wird. Der Einsatz von Steuerelemente-Arrays erfordert zwar ein wenig zusätzliche Logik, führt aber meist zu einem kompakteren Programmcode. Das Besondere an Steuerelemente-Arrays ist nämlich, dass eine Ereignisbehandlungsroutine immer für alle Steuerelemente des Arrays zuständig ist – ihr Name wird daher auch mit dem Array-Bezeichner gebildet. Ein zusätzlicher Parameter namens Index in der Parameterliste der Prozedur gibt Auskunft darüber, welchem Steuerelement aus dem Array das Ereignis gilt. Hinweis
................................................... Hinweis Um mit einem Steuerelemente-Array arbeiten zu können, muss mindestens ein Steuerelement des gewünschten Typs zur Entwurfszeit im Bereich des Formulars (bzw. der Komponente) platziert werden. Beispiel
................................................... Beis piel
Die folgende Routine erweitert ein bestehendes Schaltflächen-Array bei jedem Aufruf um eine weitere Schaltfläche. Ausgehend von einem Formular, auf dem eine einzelne Schaltfläche mit dem Namen Command1, der Index-Eigenschaft 1 und der Caption-Eigenschaft "Befehl 1" platziert wurde, erfolgt der Aufruf der Routine interessanterweise (jedoch, ohne dass dies dem Code etwas Besonderes verleihen würde), sobald der Benutzer auf eine der bereits existierenden Schaltflächen klickt. Private Sub Command1_Click(Index As Integer) Dim i As Integer i = Command1.UBound Load Command1(i + 1)
356
Left- Eigenschaft und Top- Eigenschaft
Command1(i + 1).Top = Command1(i).Top + Command1(i).Height Command1(i + 1).Caption = "Befehl " & (i + 1) Command1(i + 1).Visible = True End Sub
Left- Eigenschaft und Top- Eigenschaft Objekt.Left As Single Objekt.Top As Single Betroffene Objekte
Formulare, Komponenten und Steuerelemente mit sichtbarer Darstellung Beschreibung
................................................... Bes c hreibung
Die Eigenschaften Left und Top bestimmen die Position der linken oberen Ecke eines Objekts in seinem Container. Bei Form-Objekten werden die Werte dieser Eigenschaften standardmäßig in der Maßeinheit Twips ausgedrückt, wobei der Ursprung des Screen-Objekts in der linken oberen Ecke des Bildschirms liegt. Bei Steuerelementen und Komponenten, die in einem Container (in einem Formular, Bildfeld, Rahmen etc.) platziert wurden, sind die Werte als Koordinaten im aktuellen Koordinatensystem des Containerobjekts zu interpretieren (vgl. »ScaleMode-Eigenschaft«, S. 369). Anwendung
................................................... Anwendung
Die Position eines Steuerelements oder eines Formulars lässt sich nicht nur zur Entwurfszeit, sondern auch zur Laufzeit dynamisch anpassen, indem Sie die Eigenschaften Left und/oder Top auf geeignete Werte setzen. Um bei der Positionierung von Steuerelementen keine Überraschungen zu erleben, sollten Sie allerdings im Hinterkopf behalten, dass sich das Koordinatensystem in einem Containerobjekt, das über die Eigenschaft ScaleMode verfügt, jederzeit ändern kann. Bei Formularobjekten können sich Wertänderungen für Left und Top auch aufgrund von Benutzerinteraktionen ergeben. Beachten Sie auch, dass das Laufzeitsystem zur Entwurfszeit gesetzte Vorgaben für diese Eigenschaften nur berücksichtigt, wenn die Eigenschaft StartUpPosition auf vbStartUpManual (0) gesetzt wurde. Bei anderen Einstellungen positioniert Windows das Fenster entweder frei (nach der internen Logik für die Fensteranordnung) oder mittig, bezogen auf das übergeordnete Fenster oder den Bildschirm. Hinweise
................................................... Hinweis e Bereits positionierte Steuerelemente behalten bei einem Wechsel des Koordinatensystems (Skalierung oder Verschiebung) ihre physikalischen Positionen und Abmessungen bei, da die Eigenschaften Left, Top, Height und Width implizit eine umgekehrte Koordinatentransformation durchmachen. Die Eigenschaften ScaleLeft und ScaleTop haben mit der Position eines Objekts nichts zu tun, sondern mit der Position des Ursprungs des Koordinatensystems. Sie drücken die Koordinaten der linken oberen Ecke des Client-Bereichs aus – ändert man ihre Werte, bewirkt das eine Ursprungsverschiebung. Beispiel
................................................... Beis piel
Das Beispielprojekt TVTennis erinnert stark an den historischen Vorläufer. Der Ball, ein ImageSteuerelement, das mit einem Smiley-Bild initialisiert wurde, bewegt sich im Formularbereich und wird an den Wänden reflektiert. Die Bewegung passt sich an Größenänderungen des Formulars an.
3 57
Gemeinsame Eigenschaften
................................................... Betro ffene Objekte
Gemeinsame Eigenschaften
Option Explicit Private StepX As Integer Private StepY As Integer
Gemeinsame Eigenschaften
Private Sub Form_Load() StepX = 400 * Rnd StepY = 400 * Rnd End Sub Private Sub Timer1_Timer() Image1.Left = (Image1.Left + StepX) Image1.Top = (Image1.Top + StepY) If Image1.Left > ScaleWidth – Image1.Width Then StepX = -StepX Image1.Left = 2 * ScaleWidth – 2 * Image1.Width – Image1.Left End If If Image1.Left < 0 Then StepX = -StepX Image1.Left = -Image1.Left End If If Image1.Top > ScaleHeight – Image1.Height Then StepY = -StepY Image1.Top = 2 * ScaleHeight – 2 * Image1.Height – Image1.Top End If If Image1.Top < 0 Then StepY = -StepY Image1.Top = -Image1.Top End If End Sub Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften Height, ScaleHeight, ScaleLeft, ScaleMode, ScaleTop, ScaleWidth, Width Verwandte Themen
................................................... Verwandte Them en
Bildlauf – ein kleiner Betrachter für große Bilder (S. 545), HexView – eine schnelle Textansicht für große Dateien (S. 551)
MaskColor- Eigenschaft Objekt.MaskColor As Long Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, CommandButton, ImageList, OptionButton, UserControl Beschreibung
................................................... Bes c hreibung
Die Eigenschaft MaskColor ist ein Farbwert vom Typ Long, der eine Transparenzfarbe für die dem Objekt zugeordnete(n) Bitmap(s) festlegt. Zur Auswahl stehen neben den Systemfarben auch beliebige andere Farben, die sich entweder zur Entwurfszeit aus der Palette wählen oder zur Laufzeit über die Funktion RGB komponentenweise zu einem Farbwert komponieren lassen. Die Funktion QBColor liefert den Farbwert einer der 16 Grundfarben. Zudem definiert der Auf-
358
MouseIcon- Eigenschaft
zählungstyp SystemColorConstants Konstanten für die Systemfarben (vgl. »BackColor-Eigenschaft und ForeColor-Eigenschaft«, S. 330). Bei Schaltflächen, Optionsfeldern und Kontrollkästchen erscheinen transparente Bereiche der Bitmap in der für das Steuerelement gesetzten Hintergrundfarbe (BackColor); bei benutzerdefinierten Steuerelementen scheint in transparenten Bereichen durch, was dahinter liegt – beispielsweise ein anderes Steuerelement oder ein Hintergrundbild des Containers. Anwendung
................................................... Anwendung
Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften BackColor, BackStyle, DisabledPicture, DownPicture, MaskPicture, Picture Verwandte Themen
................................................... Verwandte Them en
Transparenz und Drag&Drop (S. 606)
MouseIcon- Eigenschaft Objekt.MouseIcon As Picture Betroffene Objekte
................................................... Betro ffene Objekte Alle Formulare, Komponenten und Steuerelemente mit sichtbarer Darstellung Beschreibung
................................................... Bes c hreibung
Die MouseIcon-Eigenschaft spezifiziert eine benutzerdefinierte Mauszeigerform für ein Objekt. Sie kommt zur Anzeige, sobald der Mauszeiger in den sichtbaren Bereich des Objekts gerät, unter der Voraussetzung dass die MousePointer-Eigenschaft auf vbCustom (99) gesetzt ist. Hat die Eigenschaft den Wert Nothing, bleibt die aktuelle Mauszeigerform unverändert.
3 59
Gemeinsame Eigenschaften
Für die Beachtung der Transparenzfarbe bei Schaltflächen, Optionsfeldern und Kontrollkästchen gibt es drei Voraussetzungen: Die Eigenschaft Style muss auf vbGraphical (1) gesetzt sein, die UseMaskColor-Eigenschaft muss auf True gesetzt sein und für die benutzerdefinierte Darstellung der Zustände (Picture, DisabledPicture, DownPicture) müssen Bitmaps angegeben sein, deren transparente Bereiche in der für MaskColor gesetzten Farbe gehalten sind. Sind diese Voraussetzungen erfüllt, machen sich Änderungen der Hintergrundfarbe des Steuerelements in den transparenten Bereichen der Bitmaps bemerkbar – es handelt sich hier also um Pseudotransparenz. Von echter Transparenz spricht man, wenn hinter dem Steuerelement gelegene Bereiche – ein Hintergrundbild und andere Steuerelemente mit niedrigerer Z-Ordnung – an den transparenten Stellen zu sehen sind. Sie lässt sich nur mit benutzerdefinierten Steuerelementen, also Komponenten des Typs UserControl, realisieren und erfordert dreierlei: Setzen der BackStyle-Eigenschaft auf vbTransparent (0); Setzen der MaskColor-Eigenschaft auf die Transparenzfarbe; Setzen der Eigenschaften Picture und MaskPicture auf eine Bitmap, deren transparente Bereiche in der für MaskColor gesetzten Farbe gehalten sind. Auch beim ImageList-Steuerelement legt die MaskColor-Eigenschaft eine Transparenzfarbe zur Erstellung einer Maske für die transparente Anzeige fest. Die Methoden Overlay und Draw arbeiten mit dieser Eigenschaft und implizit auch Steuerelemente wie TreeView und ListView (bzw. ListItem).
Gemeinsame Eigenschaften
Anwendung
................................................... Anwendung
Als Werte für diese Eigenschaft sind nur Verweise auf Bitmaps geeignet, die in einem der Symbolformate CUR oder ICO vorliegen – insbesondere lassen sich also weder gewöhnliche Bilder (BMP, JPG, WMF etc.) noch animierte Cursorformen (ANI) als Mauszeigerform setzen. Beispiel
................................................... Beis piel
Gemeinsame Eigenschaften
Command1.MouseIcon = LoadPicture ("MeinIcon.Ico") Command1.MousePointer = vbCustom Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften DragIcon, MousePointer
MousePointer- Eigenschaft Objekt.MousePointer As Integer Betroffene Objekte
................................................... Betro ffene Objekte Alle Formulare, Komponenten und Steuerelemente mit sichtbarer Darstellung Beschreibung
................................................... Bes c hreibung
Die MousePointer-Eigenschaft bestimmt, welche Mauszeigerform zur Anzeige kommt, wenn der Mauszeiger in den sichtbaren Bereich des Objekts gerät. Zur Auswahl stehen die 16 vom System her zur Verfügung gestellten Mauszeigerformen sowie eine benutzerdefinierte Mauszeigerform, wenn die Eigenschaft MouseIcon auf ein geeignetes Symbol verweist. Der Aufzählungstyp MousePointerConstants definiert Konstanten für die einzelnen Mauszeigerformen. Konstante (Wert)
Beschreibung
vbDefault (0)
Wie Containerobjekt (Voreinstellung)
vbArrow (1)
Mauspfeil
vbCrosshair (2)
Kreuz
vbIbeam (3)
I-Form
vbIconPointer (4)
Symbol
vbSizePointer (5)
Größenänderung (Kreuz mit Pfeilspitzen)
vbSizeNESW (6)
Größenänderung aufwärts diagonal
vbSizeNS (7)
Größenänderung vertikal
vbSizeNWSE (8)
Größenänderung abwärts diagonal
vbSizeWE (9)
Größenänderung horizontal
vbUpArrow (10)
Aufwärtspfeil
vbHourglass (11)
Sanduhr
vbNoDrop (12)
»Nicht ablegen« (Verbotsschild)
vbArrowHourglass (13)
Mauspfeil mit Sanduhr
vbArrowQuestion (14)
Mauspfeil mit Fragezeichen (Hilfepfeil)
360
MultiLine- Eigenschaft
Konstante (Wert)
Beschreibung
vbSizeAll (15)
Größenänderung alle (Kreuz mit Pfeilspitzen)
vbCustom (99)
Benutzerdefinierter Mauszeiger (MouseIcon-Eigenschaft)
Anwendung
................................................... Anwendung
Beispiel
................................................... Beis piel
Command1.MouseIcon = LoadPicture ("MeinIcon.Ico") Command1.MousePointer = vbCustom
MultiLine- Eigenschaft Objekt.MultiLine As Boolean Betroffene Objekte
................................................... Betro ffene Objekte TextBox Beschreibung
................................................... Bes c hreibung
Die MultiLine-Eigenschaft bestimmt, ob für den Wert eines Textfeldes nur eine einzelne Zeile zur Verfügung steht (False) oder ob ein Umbruch auf mehrere Zeilen möglich ist (True). Ist keine horizontale Bildlaufleiste (ScrollBars) vorhanden, führt das Textfeld im mehrzeiligen Modus einen dynamischen Zeilenumbruch durch, der sich nach der jeweils aktuellen Breite (Width) des Objekts richtet. Hinweis
................................................... Hinweis Entgegen anders lautenden Informationen in der Online-Hilfe zu Visual Basic wirkt sich der Wert der MultiLine-Eigenschaft nicht auf die Ausrichtung des Textes (Alignment) in einem Textfeld aus. Vielmehr wirkt sich der Wert der Alignment-Eigenschaft auf die Art aus, wie ein Textfeld den Umbruch vornimmt. Verwandte Befehle
................................................... Verwa ndte Befehle
ScrollBars
Name- Eigenschaft Objekt.Name As String Betroffene Objekte
................................................... Betro ffene Objekte Alle Formulare, Komponenten und Steuerelemente Beschreibung
................................................... Bes c hreibung
Die zur Laufzeit schreibgeschützte Name-Eigenschaft gibt den im Code verwendeten Bezeichner eines Objekts als Zeichenfolge wieder.
3 61
Gemeinsame Eigenschaften
Indem Sie die Mauszeigerform für ein Objekt zur Laufzeit ändern, können Sie dem Benutzer ein visuelles Feedback über momentan ablaufende Geschehnisse oder aktivierte Funktionen anzeigen. Standardoperationen sollten auch durch Standardsymbole (wie in der Tabelle aufgeführt) symbolisiert werden. In speziellen Situationen steht es Ihnen frei, die MousePointer-Eigenschaft auf vbCustom (99) zu setzen und über die MouseIcon-Eigenschaft ein eigenes Symbol bereitzustellen.
Gemeinsame Eigenschaften
Anwendung
Gemeinsame Eigenschaften
................................................... Anwendung
Der Entwurfseditor von Visual Basic benennt Komponenten, Formulare und Steuerelemente automatisch nach einem festen Schema: vereinfachte Typbezeichnung plus Ordinalzahl der Instanzenzählung. Somit erhält das erste Textfeld in einem Formular den Bezeichner »Text1«, das dritte Optionsfeld den Bezeichner »Option3« usw. Wenn Sie lieber mit aussagekräftigeren Bezeichnern arbeiten, können Sie den Wert der Name-Eigenschaft zur Entwurfszeit jederzeit auf einen anderen gültigen Variablenbezeichner setzen. Falls der Bezeichner eines Steuerelements bereits für ein anderes Steuerelement gleichen Typs vergeben wurde, schlägt Ihnen der Entwurfseditor vor, beide Steuerelemente in einem dynamischen Array zu organisieren, das den gewählten Bezeichner erhält. Die Unterscheidung der Objekte geschieht dann über die IndexEigenschaft. Zwei Formulare können dagegen zur Entwurfszeit nicht denselben Namen erhalten. Da Visual Basic ein Formularmodul aber als Datentyp behandelt, können Sie zur Laufzeit beliebig viele Instanzen davon ins Leben rufen. Wenn es ein Array sein muss, bitte sehr, dann vereinbaren Sie eben ein Array mit diesem Typ. (Ja, wenn Sie so wollen, können Sie sogar den Typbezeichner als Array-Namen vereinbaren). Wenn nun noch die erste Laufzeitinstanz des Formulars (die alle weiteren hervorbringt) zu einem Array-Element machen, haben Sie vom Konstrukt her etwas Ähnliches wie bei einem Steuerelemente-Array: ' Innerhalb des Moduls Form1 Dim Form1(2) As New Form1 Private Sub Form_Click() Set Form1(0) = Me Form1(1).Show Form1(2).Show End Sub
... ' Drei Instanzen werden gebraucht ' Vorhandene Instanz eingliedern ' Weitere Instanzen anlegen
Hinweis
................................................... Hinweis Der Entwurfseditor von Visual Basic verwendet automatisch vergebene Bezeichner auch noch für einige andere Eigenschaften als Voreinstellung – so für Caption, LinkTopic und Text. Warnung
................................................... Wa rnung
Wenn Sie im Nachhinein die Groß-/Kleinschreibung eines Formularbezeichners ändern, das Formularmodul abspeichern und später erneut für die Bearbeitung öffnen, erhalten Sie eine Namenskonflikt-Fehlermeldung, die Sie nur wieder loswerden, wenn Sie die alte Schreibweise des Namens wieder einführen oder gleich einen anderen Bezeichner wählen. Der Fehler kommt daher, dass Visual Basic Änderungen der Groß-/Kleinschreibung nicht in die Projektdatei übernimmt und beim erneuten Laden des Moduls glaubt, einen »falschen« Bezeichner vorzufinden.
OLEDropAllowed- und OLETypeAllowed- Eigenschaften Objekt.OleDropAllowed As Boolean Objekt.OleTypeAllowed As Integer Betroffene Objekte
................................................... Betro ffene Objekte OLE, UserControl
362
OLEDropMode- Eigenschaft
Beschreibung
................................................... Bes c hreibung
Die OLEDropAllowed-Eigenschaft bestimmt, ob ein Steuerelement als Ziel einer OLEDrag&Drop-Operation das Ablegen eines OLE-Objekts erlaubt (True) oder nicht (False; Voreinstellung). Die OLETypeAllowed-Eigenschaft bestimmt, welche Operation(en) das Steuerelement für das Ablegen eines OLE-Objekts unterstützt. Der Aufzählungstyp OLEContainerContants definiert drei Konstanten für die zulässigen Werte dieser Eigenschaft. Beschreibung
vbOLELinked (0)
Für abgelegtes OLE-Objekt kann nur eine Verknüpfung eingerichtet werden
vbOLEEmbedded (1)
Abgelegtes OLE-Objekt kann nur eingebettet werden
vbOLEEither (2)
Abgelegtes OLE-Objekt kann verknüpft oder eingebettet werden
Anwendung
................................................... Anwendung
Für OLE-Drag&Drop-Operationen sind zwei Szenarien zu unterscheiden: Das erste beinhaltet die gewöhnliche Datenübertragung zwischen zwei Steuerelementen oder Komponenten im Sinne einer Kopier- oder Verschiebeoperation (mehr dazu im Praxisteil unter »OLEDrag&Drop«, S. 501). Das zweite beinhaltet das Einbetten oder Verknüpfen eines von einem OLE-Server stammenden OLE-Objekts in einem OLE-Container. Um das zweite Szenario geht es hier. Wird ein Objekt, das als OLE-Container fungieren kann und OLE-Drag&Drop-Operationen zulässt, Ziel einer solchen Operation, kann es sich dafür entscheiden, das Objekt einzubetten oder nur eine Verknüpfung auf das Objekt einzurichten. Im ersten Fall verschiebt oder kopiert ((Umschalt) gedrückt) die Operation das Objekt als solches in den OLE-Container, und der Container ermöglicht fortan die Bearbeitung des Objekts »vor Ort« – also in seinem Fenster. Im zweiten Fall verbleibt das OLE-Objekt da, wo es ist, und der OLE-Container speichert nur eine Referenz darauf. In beiden Fällen wird das Objekt im OLE-Container angezeigt (was übrigens der für das OLE-Objekt zuständige OLE-Server übernimmt), nur gespeichert und bearbeitet wird es an verschiedenen Stellen. Lässt ein OLE-Container sowohl das Verknüpfen als auch das Einbetten zu, kann der Benutzer die Art der Operation mittels Funktionstasten gestalten. Drückt er keine Funktionstaste, wird das Objekt verschoben und eingebettet; drückt er (Umschalt), wird es kopiert und eingebettet; drückt er (Umschalt)+(Strg), wird es verknüpft. Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
OLEDropMode- Eigenschaft Objekt.OleDropMode As Integer Betroffene Objekte
................................................... Betro ffene Objekte Animation, CheckBox, ComboBox, CommandButton, CoolBar, Data, DataCombo, DataList, DateTimePicker, DirListBox, DriveListBox, FileListBox, Frame, Form, Image, ImageCombo, Label, ListBox, ListView, MaskEdBox, MDIForm, MMControl, MSChart, MSFlexGrid, MSHFlexGrid, OptionButton, PictureBox, ProgressBar, PropertyPage, RichTextBox, Slider, SSTab, StatusBar, TabStrip, TextBox, TreeView, ToolBar, UpDown, UserControl, UserDocument
3 63
Gemeinsame Eigenschaften
Eigenschaft
Gemeinsame Eigenschaften
Beschreibung
................................................... Bes c hreibung
Gemeinsame Eigenschaften
Die OLEDropMode-Eigenschaft bestimmt, wie sich ein Objekt verhält, wenn es Zielobjekt einer OLE-Drag&Drop-Operation wird. Der Aufzählungstyp OLEDropConstants definiert dafür folgende Konstanten: Konstante (Wert)
Beschreibung
vbDropNone (0), ccDropNone (0) cc2DropNone (0), cc3DropNone (0) mciDropNone (0)
Das Objekt lehnt die Durchführung der Operation ab und zeigt dies durch eine wie ein Verbotsschild aussehende Mauszeigerform an.
vbDropManual (1), ccDropManual (1) cc2DropManual (1), cc3DropManual (1) mciDropManual (1),
Das Objekt geht auf den Vorgang ein und löst die OLE-Ereignisse OLEDragOver und OLEDrop für die weitere Ausgestaltung der Operation aus.
vbDropAutomatic (2) ccDropAutomatic (2) cc2DropAutomatic (2) cc3DropAutomatic (2) mciDropAutomatic (2)
Das Objekt wickelt die Operation automatisch ab, sofern ein Datenformat im Angebot steht, mit dem es etwas anfangen kann. (Dieser Wert wird nicht von allen Objekten unterstützt, die über eine OLEDropMode-Eigenschaft verfügen.)
Anwendung
................................................... Anwendung
Für die meisten der einfacheren Steuerelemente von Visual Basic (etwa Label, TextBox, PictureBox, Image etc.) bietet sich der automatische Modus an, da die den Objektwerten zugrunde liegenden Datentypen von den standardmäßigen OLE-Datentypen gut abgedeckt werden. Sollen die Daten allerdings in einem speziellen Format oder gar in mehreren Formaten bei einer OLEDrag&Drop-Operation übertragen werden, ist der manuelle Modus unverzichtbar, weil nur er die notwendige Handhabe für den programmseitigen Eingriff in die Operation bietet. Komplexere Steuerelemente wie Form, ListBox oder TreeView unterstützen gar keinen automatischen Modus, da er hier auch keinen Sinn ergeben würde. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften OLEDragMode Verwandte Methoden
................................................... Verwa ndte Metho den OLEDragDrop, OLEDragOver Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
Parent- Eigenschaft Objekt.Parent As Formular Beschreibung
................................................... Bes c hreibung
Die zur Laufzeit schreibgeschützte Parent-Eigenschaft eines Objekts enthält einen Verweis auf das übergeordnete Objekt.
364
Picture- Eigenschaft
Anwendung
................................................... Anwendung
Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften Container
Picture- Eigenschaft Objekt.Picture As Picture Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, CommandButton, Form, MDIForm, Image, OptionButton, OLE, PictureBox, PictureClip, PropertyPage, RptImage, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Picture-Eigenschaft legt ein Bild fest, das im Bereich eines Steuerelements oder Formulars zur Anzeige kommt. Für das OLE-Container-Steuerelement steht diese Eigenschaft zur Entwurfszeit nicht zur Verfügung und ist zur Laufzeit schreibgeschützt. Sie wird von der Quellanwendung, die für das eingebettete Objekt zuständig ist, gepflegt. Für Kontrollkästchen, Optionsfelder und Schaltflächen gibt die Picture-Eigenschaft die Bitmap an, die den aktivierten, nichtgedrückten (bzw. nichtmarkierten) Zustand des Steuerelements in der benutzerdefinierten Darstellung zum Ausdruck bringt. Anwendung
................................................... Anwendung
Die Anzeige eines Bildes innerhalb eines Steuerelements oder Formulars ermöglicht die visuell ansprechende Gestaltung des dem Objekt zur Verfügung stehenden Anzeigebereichs (vgl. auch »Paint-Ereignis«, S. 253). Wird die Picture-Eigenschaft (bzw. vergleichbare Eigenschaften) eines Steuerelements bereits zur Entwurfszeit gesetzt, speichert Visual Basic die entsprechende Bitmap zunächst als binären Anhang in einer separaten Datei (FRX-Datei für Formulare). Bei Erstellung der kompilierten Fassung erhält die EXE-Datei dann alle binären Anhänge als Ressourcen, so dass die Quelldatei generell nicht weiter bereitgestellt werden muss. Anders jedoch, wenn die Bitmap erst zur Laufzeit mittels LoadPicture eingelesen wird. In diesem Fall muss die entsprechende Grafikdatei natürlich dauerhaft verfügbar sein. Mit dem Bildausschnitt-Steuerelement (PictureClip) sowie dem Bildliste-Steuerelement (ImageList) stehen sehr leistungsfähige Werkzeuge für den flexiblen Umgang mit Bildern verschiedenster Formate zur Verfügung. Für Steuerelemente des Typs Image und PictureBox fungiert die Picture-Eigenschaft als Standardeigenschaft. Schaltflächen, Optionsfelder und Kontrollkästchen unterstützen anstelle der standardmäßigen Darstellung auch die Möglichkeit, ihre drei Zustände in Form von benutzerdefinierten Bitmaps
3 65
Gemeinsame Eigenschaften
Während die Container-Eigenschaft eine Aussage darüber macht, in welchem anderen Objekt ein Steuerelement angeordnet ist, regelt die Parent-Eigenschaft das Besitzverhältnis und lässt sich als »Ist-Datenfeld-von«-Eigenschaft lesen. So kann ein Textfeld beispielsweise ein Rahmenfeld (Frame) oder ein Bildfeld (PictureBox) als Container haben, während es einem Formularobjekt (Form) untergeordnet ist. Die Parent-Eigenschaft ist manchmal recht hilfreich, wenn ein Objekt eine Methode oder Eigenschaft seines übergeordneten Objekts aufrufen will, ohne dieses mit Namen zu kennen. Ein solche Situation liegt beispielsweise vor, wenn eine Funktion/Prozedur nichts weiter als eine Referenz auf ein bestehendes Objekt übergeben bekommt.
Gemeinsame Eigenschaften
anzuzeigen. Zur Festlegung der Bitmaps sind die Eigenschaften Picture, DownPicture und DisabledPicture zuständig. Damit ein Steuerelement die Werte dieser Eigenschaften überhaupt beachtet, muss allerdings bereits beim Formularentwurf die zur Laufzeit schreibgeschützte Style-Eigenschaft auf vbButtonGraphical (1) gesetzt worden sein. Die Picture-Bitmap kommt beim aktivierten Steuerelement (Enabled-Eigenschaft auf True) im Zustand »Normal« (lies: weder »gedrückt« noch »markiert«) zur Anzeige. Beispiel
Gemeinsame Eigenschaften
................................................... Beis piel
Picture = LoadPicture("Form.jpg") ' Formular Picture1 = LoadPicture("PicBox.jpg") ' PictureBox-Steuerelement Image1 = LoadPicture("Image.jpg") ' Image-Steuerelement Command1.Picture = LoadPicture("Schmiley.jpg") ' ben.def.Schaltfläche Verwandte Befehle
................................................... Verwa ndte Befehle
DisabledPicture, DownPicture Verwandte Themen
................................................... Verwandte Them en
Transparenz und Drag&Drop (S. 606)
RightToLeft- Eigenschaft Objekt.RightToLeft As Boolean Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, ComboBox, CommandButton, Form, MDIForm, Label, ListBox, OptionButton, PictureBox, PropertyPage, RptTextBox, RptLabel, TextBox, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die RightToLeft-Eigenschaft bestimmt, ob ein Steuerelement auf einem bidirektionalen System Text von rechts nach links (True) oder von links nach rechts (False; Voreinstellung) anzeigt. Anwendung
................................................... Anwendung
Für diese Eigenschaft müssen Sie sich nur interessieren, wenn Sie internationale Anwendungen, beispielsweise für den arabischen Raum, programmieren, wo die Leserichtung von Text nicht von links nach rechts, sondern von rechts nach links ist.
ScaleLeft- Eigenschaft und ScaleTop- Eigenschaft Objekt.ScaleLeft As Single Objekt.ScaleTop As Single Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, Printer, PropertyPage, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Eigenschaften ScaleLeft und ScaleTop beschreiben die Koordinaten des linken oberen Bildpunkts des Client-Bereichs im aktuellen Koordinatensystem des Objekts.
366
ScaleLeft- Eigenschaft und ScaleTop- Eigenschaft
Anwendung
................................................... Anwendung
Ändert man die Werte dieser Eigenschaften, bewirkt das eine Ursprungsverschiebung (Translation) des Koordinatensystems, und als Seiteneffekt erhält die ScaleMode-Eigenschaft den Wert vbUser (0). In allen vordefinierten Koordinatensystemen liegt der Ursprung in der linken oberen Ecke des Client-Bereichs, so dass umgekehrt diese Eigenschaften als Seiteneffekt den Wert 0 erhalten, wenn die ScaleMode-Eigenschaft auf einen Wert ungleich vbUser (0) gesetzt wird. Tipps
................................................... Tipps
Scale (-2 * Pi, 1) – (2 * Pi, -1) Beispiel
................................................... Beis piel
Das folgende einfache Programm gibt die Funktion der dreigliedrigen Sinusreihe für die Approximation der Rechteckkurve im Intervall [-2π, 2π] aus. Da die Paint-Routine das Koordinatensystem immer so wählt, dass der Kurvenausschnitt exakt in den Client-Bereich des Formulars passt, kann der Benutzer die Fenstergröße nach Belieben verändern. Private Sub Form_Paint() Dim Pi, x, y Pi = Atn(1) * 4 ScaleHeight = -2 ScaleWidth = 4 * Pi ScaleLeft = -2 * Pi ScaleTop = 1 For x = -2 * Pi To 2 * Pi Step Pi / 200 y = Sin(x) + 1 / 3 * Sin(3 * x) + 1 / 5 * Sin(5 * x) PSet (x, y) Next x End Sub Private Sub Form_Resize() Refresh End Sub Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften ScaleMode, ScaleHeight, ScaleWidth
3 67
Gemeinsame Eigenschaften
Die richtige Wahl des Koordinatensystems kann so manches Problem vereinfachen und lästige Umrechnereien ersparen. Da Zeichenoperationen meist auf ein virtuelles Koordinatensystem bezogen sind, bietet es sich an, den in diesem Koordinatensystem benutzten Ausschnitt so auf den Ausgabebereich abzubilden, dass die virtuellen Koordinaten mit den Bereichskoordinaten zusammenfallen. Dazu setzen Sie zunächst die Eigenschaften ScaleHeight, ScaleWidth auf die Ausdehnung und die Orientierung (Vorzeichen der Werte) des Ausschnitts und verschieben dann den Ursprung, in dem Sie ScaleLeft, ScaleTop geeignet setzen. Am einfachsten setzen Sie ein neues Koordinatensystem jedoch mittels der Scale-Methode. Sie übergeben der Methode einfach den linken oberen und den rechten unteren Punkt des Ausschnitts, der im Client-Bereich sichtbar sein soll. Anstelle der im Beispiel verwendeten Befehlsfolge ließe sich somit auch schreiben:
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Approximation der Rec htec kkurve
im
Intervall [ - 1 , 1] x[ - 2
π, π 2
]
Verwandte Methoden
................................................... Verwa ndte Metho den Scale, ScaleX, ScaleY
ScaleHeight- Eigenschaft und ScaleWidth- Eigenschaft Objekt.ScaleHeight As Single Objekt.ScaleWidth As Single Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, Printer, PropertyPage, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die Eigenschaften ScaleHeight und ScaleWidth beschreiben die Abmessungen des ClientBereichs des Objekts in Koordinaten des aktuellen Koordinatensystems. Anwendung
................................................... Anwendung
Beachten Sie, dass sich über die Scale-Eigenschaften keine Größenänderungen durchführen lassen. Ändert man die Werte dieser Eigenschaften, ändert sich lediglich die Maßeinheit für die jeweilige Richtung. Das heißt, es passiert eine Streckung bzw. Stauchung (Skalierung) der Koordinatenachsen, wobei der linke obere Punkt des Client-Bereichs Fixpunkt ist. Als Seiteneffekt erhält die ScaleMode-Eigenschaft den Wert vbUser (0). Für die vordefinierten Koordinatensysteme sind feste Maßeinheiten definiert, so dass umgekehrt ScaleHeight und ScaleWidth als Seiteneffekt neue Werte erhalten, wenn die ScaleMode-Eigenschaft auf einen Wert ungleich vbUser (0) gesetzt wird. Standardmäßig ist die vertikale Achse des Koordinatensystems eines Objekts von oben nach unten und die horizontale Achse von links nach rechts orientiert. Um die Orientierung zu ändern, müssen Sie der entsprechenden Eigenschaft nur ein anderes Vorzeichen verpassen, indem Sie ihren Wert mit -1 multiplizieren. Tipp
................................................... Tipp
Die richtige Wahl des Koordinatensystems kann so manches Problem vereinfachen und schlimmere Rechnereien ersparen. Da Zeichenoperationen meist auf ein virtuelles Koordinatensystem bezogen sind, bietet es sich an, den in diesem Koordinatensystem benutzten Ausschnitt so auf den Ausgabebereich abzubilden, dass die virtuellen Koordinaten mit den Bereichskoordinaten zusammenfallen. Dazu setzen Sie ScaleHeight und ScaleWidth auf die Ausdehnung und Orientierung des Bereichs und verschieben den Ursprung, indem Sie ScaleLeft, ScaleTop auf die Koordinaten des linken oberen Punkts setzen.
368
ScaleMode- Eigenschaft
Am einfachsten setzen Sie ein neues Koordinatensystem jedoch mittels der Scale-Methode. Sie übergeben der Methode einfach den linken oberen und den rechten unteren Punkt des Ausschnitts, der im Client-Bereich sichtbar sein soll. Scale (-2 * Pi, 1) – (2 * Pi, -1) Beispiel
................................................... Beis piel
Siehe »ScaleHeight-Eigenschaft und ScaleWidth-Eigenschaft«, S. 368. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften Verwandte Methoden
................................................... Verwa ndte Metho den Scale, ScaleX, ScaleY
ScaleMode- Eigenschaft Objekt.ScaleMode As Integer Betroffene Objekte
................................................... Betro ffene Objekte Form, PictureBox, Printer, PropertyPage, UserControl, UserDocument Beschreibung
................................................... Bes c hreibung
Die ScaleMode-Eigenschaft bestimmt das Koordinatensystem eines Objekts. Zur Auswahl stehen elf Koordinatensysteme: ein benutzerdefiniertes sowie zehn vordefinierte. Die vordefinierten haben allesamt den Ursprung in der linken oberen Ecke des Client-Bereichs, sind in der vertikalen Richtung von oben nach unten orientiert und unterscheiden sich eigentlich nur in den für die Koordinatenachsen geltenden Maßeinheiten. Der Aufzählungstyp ScaleModeConstants definiert dafür die folgenden Konstanten: Konstante (Wert)
Beschreibung
vbUser (0)
Benutzerdefiniertes Koordinatensystem, das über die ScaleMethode bzw. über die Eigenschaften ScaleHeight, ScaleLeft, ScaleTop, ScaleWidth näher spezifiziert wird
vbTwips (1)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Twips« (Voreinstellung); 56,69286 Twips entsprechen einem Millimeter und 0,176389 Millimeter einem Twip
vbPoints (2)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Punkt«; 1 Punkt entspricht 0,3527781 mm, 2,834643 Punkte entsprechen einem Millimeter und 72 Punkt einem Zoll
vbPixels (3)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Bildpunkt«; bei einer Auflösung von 1200×1068 entspricht 1 Bildpunkt logisch 0,2116669 mm, und 4,724405 Bildpunkte entsprechen einem logischen Millimeter (die physikalischen Abmessungen hängen von der Geometrie des Bildschirms ab)
3 69
Gemeinsame Eigenschaften
ScaleMode, ScaleLeft, ScaleTop
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Konstante (Wert)
Beschreibung
vbCharacters (4)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Zeichen« (die horizontale und vertikale Skalierung kann hier unterschiedlich sein und hängt im Allgemeinen von den physikalischen Gegebenheiten sowie dem Betriebsmodus des Ausgabegeräts ab)
vbInches (5)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Zoll«; 1 Zoll entspricht 25,4 Millimeter und ein Millimeter 0,03937 Zoll
vbMillimeters (6)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Millimeter»
vbCentimeters (7)
Vordefiniertes Koordinatensystem mit der Maßeinheit »Zentimeter»
vbHimetric (8)
Vordefiniertes Koordinatensystem mit der Maßeinheit »hundertstel Millimeter«; Visual Basic unterstützt dieses Koordinatensystem (zur Zeit noch) nicht für Steuerelemente und Formulare! Es ist aber bei Picture-Objekten (und da ausschließlich) anzutreffen (die Umrechnung mit ScaleX und ScaleY ist möglich und häufig auch erforderlich)
vbContainerPosition (9)
Wird von Visual Basic (zur Zeit noch) nicht unterstützt
vbContainerSize (10)
Wird von Visual Basic (zur Zeit noch) nicht unterstützt
Anwendung
................................................... Anwendung
Mit einem Wert ungleich 0 für die ScaleMode-Eigenschaft arbeiten Sie, wenn Sie eine bestimmte Skalierung auf einem Ausgabegerät einführen wollen. So ist beispielsweise die Skalierung Millimeter (vbMillimeters) sehr hilfreich, um maßstabsgetreue metrische Zeichnungen auf einem Drucker auszugeben. Um ein benutzerdefiniertes Koordinatensystem einzustellen, arbeiten Sie am besten mit der Methode Scale. Die Methode, die in ihren Parametern eine Beschreibung des sichtbaren Ausschnitts in Form eines Koordinatenpaars erwartet, setzt ScaleMode auf den Wert vbUser (0) und richtet das Koordinatensystem so ein, dass das angegebene Koordinatenpaar auf den linken oberen und den rechten unteren Punkt im Client-Bereich abgebildet wird. Tipp
................................................... Tipp
Da es die Druckwerke einiger Drucker meist nicht so ganz genau mit den Größenverhältnissen nehmen (Toleranzen im Bereich von 1 % sind normal), lässt sich die Skalierung im Einzelfall nachbessern, indem man ein Quadrat fester Länge ausgibt (bei A4 ist beispielsweise die Kantenlänge 190 mm gut geeignet): Printer.ScaleMode = vbMillimeters Printer.Line(0,0)-(190, 190) Printer.EndDoc
dieses dann nachmisst und unter Berücksichtigung von Korrekturfaktoren ein benutzerdefiniertes Koordinatensystem einführt: Printer.ScaleWidth = Printer.ScaleWidth * (MesswertBreiteInMM / 190) Printer.ScaleHeight = Printer.ScaleHeight * (MesswertHöheInMM / 190)
370
ShowTips- Eigenschaft
Beispiel
................................................... Beis piel
Der folgende Code gibt den Namen, die Papiergröße und die bedruckbare Fläche (ClientBereich) des Standarddruckers aus. Da sich ScaleMode nur auf den Client-Bereich auswirkt, müssen die Eigenschaften Height und Width mittels der Methoden ScaleX und ScaleY in die geltenden Maßeinheiten umgerechnet werden.
Gemeinsame Eigenschaften
With Printer .ScaleMode = vbMillimeters .PaperSize = vbPRPSA4 Print .DeviceName Print .ScaleX(.Height, vbTwips, vbMillimeters), Print .ScaleX(.Width, vbTwips, vbMillimeters) Print .ScaleHeight, .ScaleWidth End With
Papiergröße und bedruckbarer Bereich des Standarddruckers Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften ScaleHeight, ScaleWidth, ScaleLeft, ScaleTop Verwandte Methoden
................................................... Verwa ndte Metho den Scale, ScaleX, ScaleY
ShowTips- Eigenschaft Objekt.ShowTips As Boolean Betroffene Objekte
................................................... Betro ffene Objekte TabStrip, StatusBar, ToolBar Beschreibung
................................................... Bes c hreibung
Die ShowTips-Eigenschaft bestimmt, ob die in der Eigenschaft ToolTipText definierte Zeichenfolge als QuickInfo für das Steuerelement zur Anzeige kommt (True) oder nicht (False). Das QuickInfo-Fensterchen erscheint, wenn die Maus in den Bereich des Steuerelements gelangt und dort ca. eine halbe Sekunde verweilt. Anwendung
................................................... Anwendung
Visual Basic unterstützt vier verschiedene Techniken, um für den Benutzer einer Anwendung Hilfe bereitzustellen: QuickInfo, Statusanzeige, Direkthilfe und kontextbezogene Hilfe. Die ersten beiden Techniken bieten dem Benutzer unaufgefordert und in knapper Form Hilfestellung für den Umgang mit der Benutzerumgebung. Um eine QuickInfo für ein Steuerelement bereitzustellen, weisen Sie der Eigenschaft ToolTipText eine Zeichenfolge mit dem Hilfetext zu und setzen – sofern vorhanden – die ShowTips-Eigenschaft auf True. Die Zeichenfolge sollte nicht zu lang sein, da die Anzeige einzeilig ist.
371
Gemeinsame Eigenschaften
Style- Eigenschaft Objekt.Style As Integer Betroffene Objekte
................................................... Betro ffene Objekte Band, Button, CheckBox, CommandButton, ComboBox, DataCombo, ListBox, OptionButton, SSTab, StatusBar, TabStrip, TreeView Beschreibung
Gemeinsame Eigenschaften
................................................... Bes c hreibung
Die Style-Eigenschaft bestimmt den Darstellungsstil eines Steuerelements. Die Tabelle gibt einen Überblick über die Konstanten, die für die Stile der einzelnen Steuerelemente definiert sind. Konstante (Wert)
Gilt für Objekt
Beschreibung
cc3BandNormal (0)
Band
Der Benutzer kann Größe des Bandes ändern (Voreinstellung).
cc3BandFixedSize (1)
Band
Die Bandgröße ist unveränderlich.
sbrNormal (0)
StatusBar
Die Statusleiste enthält mehrere Bereiche in Form von Panel-Objekten (Voreinstellung).
sbrSimple (1)
StatusBar
Die Statusleiste enthält nur einen Bereich (PanelObjekt) und Text wird durch Setzen der SimpleText-Eigenschaft ausgegeben.
sbrText (0)
Panel
Der Statusleistenbereich kann Text und/oder ein Bild anzeigen (Voreinstellung).
sbrCaps (1)
Panel
Der Statusleistenbereich zeigt den Zustand der Feststellfunktion für (Umschalt) an.
sbrNum (2)
Panel
Der Statusleistenbereich zeigt den Zustand der Feststellfunktion für (Num) an.
sbrIns (3)
Panel
Der Statusleistenbereich zeigt den Zustand der Funktion Einfügen/Überschreiben an.
sbrScrl (4)
Panel
Der Statusleistenbereich zeigt den Zustand der Feststellfunktion für (Rollen) an.
sbrTime (5)
Panel
Der Statusleistenbereich zeigt die Systemzeit an.
sbrDate (6)
Panel
Der Statusleistenbereich zeigt das Systemdatum an.
sbrKana (7)
Panel
Statusleistenbereich zeigt den Zustand der Feststellfunktion für (Kana) an (nur für japanische Version des Betriebssystems relevant).
ssStyle_ TabbedDialog (0)
SSTab
Die in den Dialogfeldern mit Registerdarstellung erscheinenden Register sehen genauso aus wie in den Anwendungen von Microsoft Office für Microsoft Windows 3.1. Die Schrift im Register der aktiven Registerkarte erscheint fett (Voreinstellung).
372
Style- Eigenschaft
Gilt für Objekt
Beschreibung
ssStyle_ PropertyPage (1)
SSTab
Die in den Dialogfeldern erscheinenden Register sind im Stil von Windows 9x gehalten. Die TabMaxWidth-Eigenschaft wird ignoriert und die Beschriftung des ausgewählten Registers auch nicht fett dargestellt.
tabTabs (0)
TabStrip
Die Registerkarten erscheinen wie Register in einem Notizbuch (Voreinstellung).
tabButtons (1)
TabStrip
Die Registerkarten enthalten eine Schaltfläche als Register.
tabFlatButtons (2)
TabStrip
Die Registerkarten enthalten eine Schaltfläche als Register, die nur im gedrückten Zustand in 3DDarstellung gezeichnet werden, ansonsten in 2DDarstellung.
tbrDefault (0)
Button
Die Schaltfläche ist Befehlsschaltfläche (Voreinstellung).
tbrCheck (1)
Button
Die Schaltfläche ist Schalter.
tbrButtonGroup (2)
Button
Die Schaltfläche ist Element einer Schaltergruppe, in der immer nur ein Schalter »gedrückt« sein kann.
tbrSeparator (3)
Button
Die Schaltfläche ist Trennlinie.
tbrPlaceholder (4)
Button
Die Schaltfläche sieht aus wie eine Trennlinie, ist aber Platzhalter und von der Breite her veränderbar.
tbrDropDown (5)
Button
Der Schaltfläche ist ein Menü (MenuButtonObjekte) zugeordnet.
tbrStandard (0)
ToolBar
Symbolleiste hat standardmäßige Darstellung (Voreinstellung).
tbrTransparent (1)
ToolBar
Schaltflächen und Symbolleiste sind durchsichtig, Schaltfläche enthält Beschriftung unter Bitmap, und Hot Tracking ist aktiviert.
tbrRight (2)
ToolBar
Wie tbrTransparent, die Beschriftung erscheint jedoch rechts neben der Bitmap.
tvwTextOnly (0)
TreeView
Knotenobjekte (Node) werden als reiner Text angezeigt.
tvwPictureText (1)
TreeView
Knotenobjekte (Node) werden als Text mit Bild angezeigt.
tvwPlusMinusText (2)
TreeView
Knotenobjekte (Node) werden als Text mit Plus-/ Minussymbol (Teilbaum sichtbar/unsichtbar) angezeigt.
tvwPlusPicture Text (3)
TreeView
Knotenobjekte (Node) werden als Text mit Plus-/ Minussymbol und Bild angezeigt.
373
Gemeinsame Eigenschaften
Konstante (Wert)
Gemeinsame Eigenschaften
Gemeinsame Eigenschaften
Konstante (Wert)
Gilt für Objekt
Beschreibung
tvwTreelinesText (4)
TreeView
Knotenobjekte (Node) werden als Text mit Abhängigkeitslinien (unter Beachtung der LineStyle-Eigenschaft) angezeigt.
tvwTreelinesPicture Text (5)
TreeView
Knotenobjekte (Node) werden als Text mit Bild und Abhängigkeitslinien (unter Beachtung der LineStyle-Eigenschaft) angezeigt.
tvwTreelinesPlus MinusText (6)
TreeView
Knotenobjekte (Node) werden als Text mit Plus-/ Minussymbol und Abhängigkeitslinien (unter Beachtung der LineStyle-Eigenschaft) angezeigt
tvwTreelinesPlus MinusPictureText (7)
TreeView
Knotenobjekte (Node) werden als Text mit Plus-/ Minussymbol, Bild und Abhängigkeitslinien (unter Beachtung der LineStyle-Eigenschaft) angezeigt.
vbButtonStandard (0)
CheckBox, OptionButton, CommandButton
Das Steuerelement wird im Stil von Windows 9x dargestellt.
vbButtonGraphical (1)
CheckBox, OptionButton, CommandButton
Das Steuerelement wird mit benutzerdefinierten Grafiken (für die Zustände »normal«, »gedrückt« und »inaktiv«) dargestellt.
vbListBoxStandard (0)
ListBox
Das Listenfeld wird als einfaches Listenfeld mit Texteinträgen dargestellt.
vbListBoxCheckBox (1)
ListBox
Das Listenfeld wird als Listenfeld mit ankreuzbaren Einträgen (Kontrollkästchen neben den Texteinträgen) dargestellt.
vbComboDropDown (0) dbcDropDownCombo (0)
ComboBox, DataCombo
Das Kombinationsfeld wird als Textfeld mit Pfeilschaltfläche dargestellt. Der Benutzer kann einen Wert in das Textfeld eingeben oder die anhängende Liste öffnen und einen Eintrag daraus wählen (Voreinstellung).
vbComboSimple (1) dbcSimpleCombo (1)
ComboBox, DataCombo
Das Kombinationsfeld wird als Textfeld über einem Listenfeld dargestellt. Die Liste bleibt ständig sichtbar. Ihre Höhe wird durch die HeightEigenschaft bestimmt.
vbCombo DropDownList (2) dbcDropDownList (2)
ComboBox, DataCombo
Das Kombinationsfeld wird als Textfeld mit Pfeilschaltfläche dargestellt. Der Benutzer kann keine Eingaben in das Textfeld vornehmen, sondern muss einen Eintrag aus der anhängenden Liste wählen.
Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften BorderStyle
37 4
TabIndex- Eigenschaft
TabIndex- Eigenschaft Objekt.TabIndex As Integer Betroffene Objekte
................................................... Betro ffene Objekte Alle sichtbaren Steuerelemente, nicht jedoch Data, Line, Shape, Menu Beschreibung
................................................... Bes c hreibung
Anwendung
................................................... Anwendung
Die durch die TabIndex-Eigenschaft festgelegte Tabulatorordnung bestimmt die Aktivierreihenfolge der Steuerelemente, wenn der Benutzer mit (Tab) bzw. (Umschalt)+(Tab) navigiert. Der Entwurfseditor von Visual Basic legt die Tabulatorordnung nach der Reihenfolge des Einfügens der Steuerelemente in das Formular (bzw. in die Komponente) fest und setzt dabei die TabIndexEigenschaft, mit der Zählung von 0 beginnend, auf den entsprechenden Wert. Auch Steuerelemente, die den Fokus nicht entgegennehmen können – weil sie nicht dafür konzipiert sind oder ihre TabStop-Eigenschaft auf False gesetzt ist –, spielen eine wichtige Rolle für die Tabulatorordnung, da sie Zugriffstasten definieren können. Eine Zugriffstaste ((Alt) plus unterstrichenes Zeichen in der Beschriftung) ermöglicht es dem Benutzer, den Fokus per Tastatur auf ein bestimmtes Steuerelement zu verschieben. Sie definieren eine Zugriffstaste für ein Steuerelement, indem Sie dem entsprechenden Zeichen in der Beschriftung des Steuerelements (CaptionEigenschaft) ein »&«-Zeichen voranstellen. Falls ein Steuerelement, das den Fokus erhalten kann, selbst keine Beschriftung besitzt, sondern auf ein Bezeichnungsfeld (Label) angewiesen ist, lässt sich die Zugriffstaste über die Caption-Eigenschaft des Bezeichnungsfelds festlegen, sofern dessen UseMnemonic-Eigenschaft auf True gesetzt ist. Dabei ist es wichtig, dass das Bezeichnungsfeld in der Tabulatorordnung vor dem besagten Steuerelement kommt, das heißt, dass der Wert seiner TabIndex-Eigenschaft kleiner ist. (Natürlich sollte in der Tabulatorordnung zwischen dem Steuerelement und seinem Bezeichnungsfeld kein weiteres Steuerelement sitzen, das den Fokus annehmen kann). Durch Verwendung mehrerer Bezeichnungsfelder lassen sich so sogar problemlos mehrere Zugriffstasten für ein und dasselbe Steuerelement definieren. Unsichtbare oder deaktivierte Steuerelemente verbleiben in der Tabulatorreihenfolge, werden aber bei der Fokusweitergabe übersprungen. Beim Entwurf eines Formulars lohnt es sich, gleich beim Einfügen der Steuerelemente auf die richtige Reihenfolge zu achten – insbesondere also Bezeichnungsfelder vor den zugehörigen Steuerelementen zu platzieren. Natürlich lässt sich die TabIndex-Eigenschaft jederzeit auch nachträglich ändern. Dafür sollten Sie wissen, dass der Entwurfseditor von Visual Basic die TabIndex-Werte zweier Steuerelemente automatisch austauscht, wenn Sie einem Steuerelement den Wert eines anderen zuordnen. In seltenen Fällen werden Sie vielleicht die Aktivierreihenfolge zur Laufzeit ändern wollen – ein automatischer Austausch findet dann aber nicht statt, so dass Sie die TabIndex-Werte aller Steuerelemente neu setzen müssen, die eine andere Position in der Tabulatorordnung erhalten sollen. Vom Prinzip her ist es zwar unproblematisch, zwei oder mehreren Steuerelementen den gleichen TabIndex-Wert zuzuordnen, allerdings wird die Aktivierreihenfolge unter diesen Elementen dann zu einem Produkt des Zufalls. »Mut zur Lücke« bei der Tabulatorordnung wird zwar nicht bestraft, die Ordnung sollte aber nach Möglichkeit fortlaufend sein (und mit 0 oder 1 beginnen), weil nicht nur der Entwurfseditor, sondern auch das Laufzeitsystem (so beim Laden einer neuen Steuerelementinstanz mit Load) bemüht ist, eine fortlaufende Ordnung
375
Gemeinsame Eigenschaften
Die TabIndex-Eigenschaft ordnet einem Objekt eine Position in der Tabulatorordnung des Containers zu und regelt insbesondere die Fokusweitergabe bei Verwendung der Tabulatortaste. Die Zählung beginnt üblicherweise bei 0 kann aber auch mit 1 begonnen werden.
Gemeinsame Eigenschaften
durchzusetzen. Wenn Sie einem Steuerelemente-Array mittels Load ein weiteres Element hinzufügen, erhält dieses vom Laufzeitsystem automatisch die jeweils letzte Position in der Tabulatorordnung. Die ZOrder-Methode hat nichts mit der TabIndex-Eigenschaft zu tun. Sie regelt die Zeichenreihenfolge der Steuerelemente. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften
Gemeinsame Eigenschaften
Caption
TabStop- Eigenschaft Objekt.TabStop As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Adodc, Animation, CheckBox, ComboBox, CommandButton, DataCombo, DataGrid, DataList, DataRepeater, DateTimePicker, DirListBox, DriveListBox, FileListBox, HScrollBar, ImageCombo, ListView, ListBox, MaskEdBox, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, OLE, OptionButton, PictureBox, RichTextBox, Slider, SSTab, TabStrip, TextBox, TreeView, UpDown, VScrollBar Beschreibung
................................................... Bes c hreibung
Die TabStop-Eigenschaft bestimmt, ob ein Element den Fokus durch Weiterschaltung mit (Tab) oder (Umschalt)+(Tab) oder per Zugriffstaste erhalten kann (True; Voreinstellung) oder nicht (False). Anwendung
................................................... Anwendung
Der Benutzer hat mehrere Möglichkeiten, den Eingabefokus auf ein bestimmtes Steuerelement zu setzen: per Tabulatortaste, per Zugriffstaste, per Mausklick und per Pfeiltasten. Die ersten beiden Möglichkeiten unterliegen dem Einfluss der TabStop-Eigenschaft, die anderen beiden nicht. Steuerelemente, deren Visible-Eigenschaft oder Enabled-Eigenschaft auf False gesetzt ist, können den Fokus überhaupt nicht erhalten. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften Visible, Enabled
Tag- Eigenschaft Objekt.Tag As String Betroffene Objekte
................................................... Betro ffene Objekte Alle Formulare, Komponenten und Steuerelemente Beschreibung
................................................... Bes c hreibung
Die Tag-Eigenschaft wird von Visual Basic nicht beachtet und steht daher für benutzerdefinierte Zwecke zur Verfügung. Anwendung
................................................... Anwendung
Die Tag-Eigenschaft ist recht hilfreich, wenn es darum geht, ohne viel Aufwand und ohne den Wert von Eigenschaften wie Caption zu verändern, zusätzliche Informationen an ein Objekt zu »heften«. So kann man diese Eigenschaft beispielsweise dafür verwenden, unterschiedliche
37 6
ToolTipText- Eigenschaft
Instanzen eines Formulars unterschiedlich zu benennen, um sie auseinander halten zu können. Vom Prinzip her würde sich für den Zweck der reinen Unterscheidung auch die hWnd-Eigenschaft anbieten, doch diese kann sich zur Laufzeit bekanntlich auch ändern.
ToolTipText- Eigenschaft Objekt.ToolTipText As String Betroffene Objekte
................................................... Betro ffene Objekte
Beschreibung
................................................... Bes c hreibung
Die ToolTipText-Eigenschaft bestimmt den Text für die Anzeige der QuickInfo. Anwendung
................................................... Anwendung
Visual Basic unterstützt vier verschiedene Techniken, um für den Benutzer einer Anwendung Hilfe bereitzustellen: QuickInfo, Statusanzeige, Direkthilfe, und kontextbezogene Hilfe. Die ersten beiden Techniken bieten dem Benutzer unaufgefordert und in knapper Form Hilfestellung für den Umgang mit der Benutzerumgebung. Um eine QuickInfo für ein Steuerelement bereitzustellen, weisen Sie der Eigenschaft ToolTipText eine Zeichenfolge mit dem Hilfetext zu und setzen – sofern vorhanden – die ShowTips-Eigenschaft auf True. Die Zeichenfolge sollte nicht zu lang sein, da die Anzeige einzeilig ist. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften HelpContextID, ShowTips, WhatsThisButton, WhatsThisHelp, WhatsThisHelpID
UseMaskColor- Eigenschaft Objekt.UseMaskColor As Boolean Betroffene Objekte
................................................... Betro ffene Objekte CheckBox, CommandButton, OptionButton, ImageList Beschreibung
................................................... Bes c hreibung
Die UseMaskColor-Eigenschaft bestimmt, ob die für die MaskColor-Eigenschaft gesetzte Farbe für die Maskierung transparenter Bereiche verwendet wird (True) oder nicht (False). Anwendung
................................................... Anwendung
Bei Schaltflächen, Optionsfeldern und Kontrollkästchen mit benutzerdefinierter Darstellung ermöglicht die UseMaskColor-Eigenschaft das Ein- und Ausschalten der Pseudotransparenz (vgl. »MaskColor-Eigenschaft«, S. 358). Gleiches gilt für Steuerelemente, die anders als die genannten Steuerelemente standardmäßig mit Bildern eines ImageList-Objekts arbeiten. Sie sind darauf angewiesen, dass die UseMaskColor-Eigenschaft des ImageList-Objekts gesetzt ist, die sich dann immer für alle Bilder in der Liste auswirkt.
377
Gemeinsame Eigenschaften
Adodc, Animation, Button, CheckBox, ComboBox, CommandButton, CoolBar, Data, DataCombo, DataGrid, DataList, DataRepeater, DateTimePicker, DirListBox, DriveListBox, FileListBox, FlatScrollBar, Frame, Image, ImageCombo, Label, ListItem, ListSubItem, ListView, ListBox, MaskEdBox, MMContol, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, OptionButton, Panel, PictureBox, ProgressBar, RemoteData, RichTextBox, Slider, SSTab, StatusBar, Tab, TabStrip, TextBox, TreeView, UpDown
Gemeinsame Eigenschaften
Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften MaskColor
Visible- Eigenschaft Objekt.Visible As Boolean Betroffene Objekte
Gemeinsame Eigenschaften
................................................... Betro ffene Objekte Adodc, Animation, Band, Button, ButtonMenu, CheckBox, ComboBox, CommandButton, Data, DataCombo, DataGrid, DataList, DataRepeater, DateTimePicker, DirListBox, DriveListBox, FileListBox, FlatScrollBar, Form, Frame, HScrollBar, Image, ImageCombo, Label, Line, ListView, ListBox, MaskEdBox, MDIForm, MMControl, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, Node, OLE, OptionButton, Panel, PictureBox, ProgressBar, RemoteData, RichTextBox, RptFunction, RptLine, RptImage, RptLabel, RptShape, RptTextBox, RptSection, Shape, Slider, SSTab, StatusBar, TabStrip, TextBox, ToolBar, TreeView, UpDown, VScrollBar Beschreibung
................................................... Bes c hreibung
Die Visible-Eigenschaft bestimmt, ob ein Objekt sichtbar ist (True) oder nicht (False). Unsichtbare Objekte können den Fokus nicht erhalten. Anwendung
................................................... Anwendung
Um ein Formular aus- oder einzublenden, können Sie wahlweise die Methoden Show und Hide aufrufen oder die Visible-Eigenschaft auf False bzw. True setzen. Wenn Sie eine neue Instanz für ein Steuerelemente-Array zur Laufzeit anlegen, »erbt« diese die meisten Eigenschaften der Instanz mit dem niedrigsten Index. hWnd erhält natürlich einen anderen Wert, und die Visible-Eigenschaft trägt standardmäßig den Wert False. Verwandte Eigenschaften
................................................... Verwa ndte Eigens c ha ften Enabled
WhatsThisHelp- Eigenschaft Objekt.WhatsThisHelp As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Animation, DataGrid, Form, MDIForm, MSFlexGrid Beschreibung
................................................... Bes c hreibung
Die WhatsThisHelp-Eigenschaft bestimmt, ob die Hilfetaste (F1) die Direkthilfe in einem PopupFenster (True) oder die kontextbezogene Hilfe im Windows-Hilfesystem (False) anzeigt. Anwendung
................................................... Anwendung
Vgl. »HelpContextID-Eigenschaft und WhatsThisHelpID-Eigenschaft«, S. 353.
WhatsThisHelpID- Eigenschaft Siehe »HelpContextID-Eigenschaft und WhatsThisHelpID-Eigenschaft«, S. 353.
37 8
Width- Eigenschaft
Width- Eigenschaft Siehe »Height-Eigenschaft und Width-Eigenschaft«, S. 351.
Gemeinsame Methoden
Methode
Beschreibung
Drag
Leitet eine Drag&Drop-Operation für das Steuerelement manuell ein
LinkExecute
Versendet ein DDE-Kommando an das Quellobjekt einer bestehenden DDE-Verbindung
LinkPoke
Ändert den Wert des als Datenlieferant fungierenden Steuerelements aufseiten des Quellobjekts einer bestehenden DDE-Verbindung
LinkRequest
Fordert das Quellobjekt einer bestehenden DDE-Verbindung auf, den Wert des Zielobjekts zu aktualisieren
LinkSend
Schickt dem Zielobjekt einer bestehenden DDE-Verbindung ein LinkNotify-Ereignis, damit dieses seine LinkRequest-Methode zur erneuten Synchronisation aufruft
Move
Ändert Position und Abmessungen des Objekts innerhalb des Containers
OleDrag
Leitet eine OLE-Drag&Drop-Operation für ein Steuerelement ein
Refresh
Veranlasst das Objekt, seinen Zustand sowie seine Darstellung zu aktualisieren
SetFocus
Fordert den Fokus für das Steuerelement an
ShowWhatsThis
Zeigt die Direkthilfe für das Steuerelement an
ZOrder
Setzt das Steuerelement an die vorderste oder hinterste Position der Anzeigereihenfolge
Drag- Methode Sub Objekt.Drag(Action As Integer) Betroffene Objekte
................................................... Betro ffene Objekte Adodc, Animation, CheckBox, ComboBox, CommandButton, CoolBar, Data, DataCombo, DataGrid, DataList, DataRepeater, DateTimePicker, DirListBox, DriveListBox, FileListBox, FlatScrollBar, Frame, HScrollBar, Image, ImageCombo, Label, ListView, ListBox, MaskEdBox, MMControl, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, OLE, OptionButton, PictureBox, ProgressBar, RemoteData, RichTextBox, Slider, SSTab, StatusBar, TabStrip, TextBox, ToolBar, TreeView, UpDown, VScrollBar
379
Gemeinsame Methoden
Auch bei den Methoden haben die Steuerelemente einiges an Gemeinsamkeiten zu bieten, die meisten Steuerelemente besitzen jedoch ungleich weniger Methoden als Eigenschaften. Natürlich relativiert sich diese Aussage, wenn man bedenkt, dass die Eigenschaften COM-konformer Objekte nicht als schlichte Datenelemente mit öffentlichem Geltungsbereich implementiert sind, sondern über Property-Methoden, die für den entsprechenden prozeduralen Unterbau sorgen. Mithin sind Eigenschaften also auch Methoden. Die folgende Tabelle gibt einen Überblick über die Methoden, die bei der Besprechung der einzelnen Steuerelemente sowie des Formularobjekts nicht extra diskutiert werden:
Gemeinsame Methoden
Beschreibung
................................................... Bes c hreibung
Die Drag-Methode dient der codeseitigen Steuerung von Drag&Drop-Operationen für Objekt im manuellen oder automatischen Modus (vgl. DragMode). Für den Parameter Action sind über den Aufzählungstyp DragConstants drei Werte definiert: vbBeginDrag (1) startet eine Drag&Drop-Operation; vbEndDrag (2) beendet die aktuelle Drag&Drop-Operation; vbCancel (0) bricht die aktuelle Drag&Drop-Operation ab. Wird Drag im Verlauf einer Drag&DropOperation mit dem Wert vbEndDrag aufgerufen, erhält das unter dem Mauszeiger befindliche Objekt ein DragDrop-Ereignis.
Gemeinsame Methoden
Anwendung
................................................... Anwendung
Die explizite Steuerung von Drag&Drop-Vorgängen ist im Allgemeinen nur erforderlich, wenn ein Objekt, dessen DragMode-Eigenschaft auf vbManual (0; Voreinstellung) gesetzt ist, eine Drag&Drop-Operation eingehen soll. Das kann beispielsweise der Fall sein, wenn eine Steuerung der Operation mit der Tastatur oder der rechten Maustaste erwünscht ist. Beispiel
................................................... Beis piel
Der folgende Code implementiert Drag&Drop mit der rechten Maustaste für ein Bezeichnungsfeld: Private Sub Label1_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If Button = vbRightButton Then Label1.Drag vbBeginDrag End Sub Verwandte Methoden
................................................... Verwa ndte Metho den DragDrop, DragIcon, DragMode, DragOver Verwandte Themen
................................................... Verwandte Them en
Transparenz und Drag&Drop (S. 606)
LinkExecute- Methode Sub Objekt.LinkExecute (Command As String) As Boolean Betroffene Objekte
................................................... Betro ffene Objekte Label, PictureBox, TextBox Beschreibung
................................................... Bes c hreibung
Die Methode LinkExecute ermöglicht es dem Zielobjekt einer bestehenden DDE-Verbindung, eine Kommandozeichenfolge an das in einer anderen Anwendung gelegene Quellobjekt (Formular) zu senden. Aufseiten des Quellobjekts löst die Methode ein LinkExecute-Ereignis aus. Der erste Parameter des Ereignisses übermittelt die Zeichenfolge, den zweiten Parameter muss das Quellobjekt bei erfolgreicher Behandlung auf 0 setzen, sonst tritt beim Zielobjekt ein Laufzeitfehler auf. Anwendung
................................................... Anwendung
Um die LinkExecute-Methode ausführen zu können, muss zuvor eine DDE-Verbindung mit der Quellanwendung eröffnet worden sein. Für den Verbindungsaufbau ist es nötig, die Eigenschaft LinkTopic mit einer geeigneten Verbindungsinformation zu versorgen und danach die Eigen-
380
LinkPoke- Methode
schaft LinkMode auf einen Wert ungleich 0 zu setzen. Falls kein Laufzeitfehler 282 auftritt, kann das Zielobjekt davon ausgehen, dass die Verbindung besteht, und mit der Übermittlung von DDE-Kommandos beginnen. Da es keinen feststehenden Kommandosatz für DDE-Verbindungen gibt, unterliegt die Ausgestaltung der Kommandos sowie deren Interpretation allein der Fantasie des Programmierers. Beispiel
................................................... Beis piel
' Im Modul der Quellobjekts Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer) If CmdStr = "Beenden" Then Cancel = False ' Kommando erkannt! Unload Me ' Kommando ausführen End If End Sub Verwandte Methoden
................................................... Verwa ndte Metho den LinkClose, LinkError, LinkExecute, LinkItem, LinkMode, LinkNotify, LinkOpen, LinkPoke, LinkRequest, LinkSend, LinkTopic Verwandte Themen
................................................... Verwandte Them en
DDE-Verbindungen (S. 495)
LinkPoke- Methode Sub Objekt.Poke() Betroffene Objekte
................................................... Betro ffene Objekte Label, PictureBox, TextBox Beschreibung
................................................... Bes c hreibung
Die Methode LinkPoke ermöglicht es dem Zielobjekt einer bestehenden DDE-Verbindung, den Wert seiner Standardeigenschaft dem als Datenlieferant fungierenden Steuerelement aufseiten der Quellanwendung aufzuoktroyieren – lies: eine Synchronisation in umgekehrter Richtung vorzunehmen. Anwendung
................................................... Anwendung
In der Regel übermittelt bei einer DDE-Verbindung der Datenlieferant des Quellobjekts seinen Wert an das Zielobjekt. In speziellen Situation kann es jedoch erforderlich sein, diese Beziehung umzukehren und LinkPoke einzusetzen. Beachten sie aber, dass nicht alle DDE-Serveranwendungen den Einsatz von LinkPoke akzeptieren. Die Standardeigenschaften der betroffenen Steuerelemente sind: Text für das Textfeld, Picture für das Bildfeld und Caption für das Bezeichnungsfeld.
3 81
Gemeinsame Methoden
' Im Modul des Zielobjekts ... Text1.LinkExecute("Beenden") ...
Gemeinsame Methoden
Verwandte Methoden
................................................... Verwa ndte Metho den LinkClose, LinkError, LinkExecute, LinkItem, LinkMode, LinkNotify, LinkOpen, LinkRequest, LinkSend, LinkTopic Verwandte Themen
................................................... Verwandte Them en
DDE-Verbindungen (S. 495)
Gemeinsame Methoden
LinkRequest- Methode Sub Objekt.LinkRequest() Betroffene Objekte
................................................... Betro ffene Objekte Label, PictureBox, TextBox Beschreibung
................................................... Bes c hreibung
Die Methode LinkRequest fordert die Quellanwendung einer bestehenden DDE-Verbindung auf, den Wert des Zielobjekts mit dem Wert des Datenlieferanten zu synchronisieren. Anwendung
................................................... Anwendung
Der Aufruf der LinkRequest-Methode findet im Allgemeinen in Reaktion auf das LinkNotifyEreignis statt. Je nach Wert der LinkMode-Eigenschaft des Zielobjekts gibt es verschiedene Szenarien für die Synchronisation zwischen Quelle und Ziel. Hat LinkMode den Wert vbLinkAutomatic (1) und handelt es sich bei dem zu synchronisierenden Wert um eine Zeichenfolge, sorgt die Quellanwendung für die automatische Synchronisation, sobald sich aufseiten der Quelle eine Wertänderung ergibt – ein Aufruf von LinkRequest ist dann nur erforderlich, wenn der Wert aufseiten des Zielobjekts etwa durch Benutzeraktivitäten verloren gegangen ist. Wenn es sich im Automatikmodus bei dem zu synchronisierenden Wert um ein Bild handelt oder LinkMode den Wert vbLinkNotify (3) hat, schickt die Quellanwendung dem Zielobjekt ein LinkNotifyEreignis, damit dieses je nach Bedarf die Synchronisation explizit mittels LinkRequest vornehmen kann. Hat LinkMode den Wert vbLinkManual (2), liegt es allein am Zielobjekt, die Synchronisation mit LinkRequest anzustoßen; eine Benachrichtigung über Wertänderungen findet nicht statt. Verwandte Methoden
................................................... Verwa ndte Metho den LinkClose, LinkError, LinkExecute, LinkItem, LinkMode, LinkNotify, LinkOpen, LinkPoke, LinkSend, LinkTopic Verwandte Themen
................................................... Verwandte Them en
DDE-Verbindungen (S. 495)
LinkSend- Methode Sub Objekt.LinkSend() Betroffene Objekte
................................................... Betro ffene Objekte Label, PictureBox, TextBox
382
Move- Methode
Beschreibung
................................................... Bes c hreibung
Die LinkSend-Methode ermöglicht es dem Quellobjekt einer bestehenden DDE-Verbindung, das Zielobjekt über eine Wertänderung des als Datenlieferant fungierenden Steuerelements zu informieren. Die Benachrichtigung erfolgt in Form des LinkNotify-Ereignisses. Anwendung
................................................... Anwendung
Verwandte Methoden
................................................... Verwa ndte Metho den LinkClose, LinkError, LinkExecute, LinkItem, LinkMode, LinkNotify, LinkOpen, LinkPoke, LinkSend, LinkTopic Verwandte Themen
................................................... Verwandte Them en
DDE-Verbindungen (S. 495)
Move- Methode Sub Objekt.Move(Left, [Top], [Width], [Height]) Betroffene Objekte
................................................... Betro ffene Objekte Alle sichtbaren Steuerelemente und Formularobjekte Beschreibung
................................................... Bes c hreibung
Die Move-Methode erlaubt es, die Position sowie die Abmessungen des Steuerelements zu verändern. Der Parameter Left ist obligatorisch, die anderen drei Parameter sind optional. Anwendung
................................................... Anwendung
Vom Prinzip her macht es keinen Unterschied, ob Sie die Eigenschaften Left, Top, Width oder Height explizit auf andere Werte setzen oder die Move-Methode dafür verwenden, die MoveMethode wird allerdings etwas schneller ausgeführt, wenn mehr als eine Eigenschaft einen neuen Wert erhalten soll.
OLEDrag- Methode Sub Objekt.OLEDrag() Betroffene Objekte
................................................... Betro ffene Objekte Animation, CheckBox, ComboBox, CommandButton, CoolBar, Data, DataCombo, DataList, DateTimePicker, DirListBox, DriveListBox, FileListBox, Form, Frame, Image, ImageCombo, Label, ListView, ListBox, MaskEdBox, MDIForm, MMControl, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, OptionButton, PictureBox, ProgressBar, PropertyPage, RichTextBox, Slider, SSTab, StatusBar, TabStrip, TextBox, ToolBar, TreeView, UpDown, UserControl, UserDocument
3 83
Gemeinsame Methoden
Änderungen in Textwerten signalisiert das Quellobjekt automatisch. Der Einsatz der LinkSendMethode ist also nur im Zusammenhang mit Bildern notwendig, deren ständige Synchronisation nur in seltenen Fällen wirklich erwünscht ist. Das Zielobjekt reagiert auf das von der LinkSend-Methode ausgelöste LinkNotify-Ereignis bei Bedarf mit einem LinkRequest-Aufruf, der schließlich die Synchronisation bewirkt.
Gemeinsame Methoden
Beschreibung
................................................... Bes c hreibung
Die OLEDrag-Methode ermöglicht die codeseitige Einleitung von OLE-Drag&Drop-Operationen im manuellen oder automatischen Modus (vgl. OLEDragMode) und löst insbesondere aufseiten des Quellobjekts das OLEStartDrag-Ereignis aus. Anwendung
Gemeinsame Methoden
................................................... Anwendung
Im Gegensatz zur Drag-Methode ist der Aufruf von OLEDrag parameterlos, da die weitere Steuerung der Operation durch OLE-Ereignisse geschieht und ein Abbruch oder gezieltes Beenden der Operation vonseiten des Quellobjekts her nicht vorgesehen ist. Das Quellobjekt kann die Operation allenfalls »sabotieren«, indem es auf das OLESetData-Ereignis hin keine Daten bereitstellt. Da eine begonnene OLE-Drag&Drop-Operation durch Loslassen der Maustaste abgeschlossen wird, dürfte es wenig Sinn machen, OLEDrag in einem anderen Szenario als während der Behandlung eines MouseDown-Ereignisses aufzurufen – schließlich muss der Benutzer die Maustaste irgendwann loslassen, was dann den Abschluss der Operation sicherstellt. Beispiel
................................................... Beis piel
Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) StatusBar1.SimpleText = "OLE-Drag gestartet" Text1.OLEDrag StatusBar1.SimpleText = "" End Sub Verwandte Methoden
................................................... Verwa ndte Metho den OLECompleteDrag, OLEDragMode, OLEDragOver, OLEDropMode, OLEGiveFeedback, OLESetData, OLEStartDrag Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
Refresh- Methode Sub Objekt.Refresh() Betroffene Objekte
................................................... Betro ffene Objekte Adodc, CheckBox, ComboBox, CommandButton, CoolBar, Data, DataCombo, DataGrid, DataList, DataRepeater, DataReport, DateTimePicker, DBGrid, DBCombo, DBList, DirListBox, DriveListBox, FlatScrollBar, FileListBox, Form, Frame, HScrollBar, Image, ImageCombo, Label, Line, ListView, ListBox, MaskEdBox, MMControl, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, OLE, OptionButton, PictureBox, ProgressBar, PropertyPage, RemoteData, RichTextBox, Shape, Slider, StatusBar, TabStrip, TextBox, ToolBar, TreeView, UserControl, UserDocument, VScrollBar Beschreibung
................................................... Bes c hreibung
Die Refresh-Methode aktualisiert die Darstellung eines Steuerelements bzw. Formulars. Bei Datensteuerelementen bewirkt Refresh eine explizite Aktualisierung des Recordset-Objekts sowie aller abhängigen Steuerelemente.
384
SetFocus- Methode
Anwendung
................................................... Anwendung
Warnung
................................................... Wa rnung
Der Einsatz von Refresh innerhalb einer Paint-Routine kann zu endlosen Ereignisketten führen (zur Rettung eines Projekts für den Fall der Fälle, vgl. »Schleifen«, S. 40). Beispiel
................................................... Beis piel
Die folgende Routine demonstriert den Unterschied für ein Listenfeld List1. Wenn Sie den Refresh-Aufruf auskommentieren, erfolgt die Aktualisierung der Anzeige erst nach Beendigung der Schleife. Private Sub Form_Click() Print Time For i = 1 To 4 List1.AddItem "Eintrag" & i, 0 Next i List1.Refresh ' umgehende Anzeige For i = 1 To 10000000 ' Zeitverzögerung a = Sqr(1) Next Print Time End Sub
SetFocus- Methode Sub Objekt.SetFocus() Betroffene Objekte
................................................... Betro ffene Objekte Adodc, Animation, CheckBox, ComboBox, CommandButton, DataCombo, DataGrid, DataList, DataRepeater, DataReport, DateTimePicker, DBGrid, DBCombo, DBList, DirListBox, DriveListBox, FlatScrollBar, FileListBox, Form, HScrollBar, ImageCombo, ListView, ListBox, MaskEdBox, MMControl, MonthView, MSChart, MSFlexGrid, MSHFlexGrid, OLE, OptionButton, PictureBox, PropertyPage, RichTextBox, Slider, TabStrip, TextBox, TreeView, UpDown, UserControl, UserDocument, VScrollBar
3 85
Gemeinsame Methoden
Im Allgemeinen frischen Steuerelemente nach einer Wertänderung ihre Darstellung von selbst auf, sobald sich die Gelegenheit dafür ergibt. Die Priorität für diesen Vorgang ist allerdings nicht sehr hoch. Wenn jedoch wichtigere Ereignisse auf Behandlung warten (und das sind fast alle, außer Timer-Ereignissen) oder die Behandlung des aktuellen Ereignisses noch einiges an Laufzeit beanspruchen wird, lässt sich mittels Refresh eine umgehende Aktualisierung der Darstellung erreichen. Bei Formularen, deren AutoRedraw-Eigenschaft nicht auf True gesetzt wurde, bewirkt Refresh unter anderem die Ausführung der Paint-Routine. Die Methode sollte daher immer zum Aufruf kommen, wenn der Client-Bereich komplett neu gezeichnet werden soll, beispielsweise nach einer Änderung des Koordinatensystems oder im Zuge einer Resize-Behandlung. Für die Datensteuerelemente Data, RemoteData und Adodc sind Refresh-Aufrufe jedes Mal dann notwendig, wenn sich eine der Eigenschaften DatabaseName, RecordSource, ReadOnly, Exclusive oder Connect geändert hat und ein neues Recordset erstellt werden muss.
Gemeinsame Methoden
Beschreibung
................................................... Bes c hreibung
Die SetFocus-Methode gibt den Fokus ungeachtet der Tabulatorreihenfolge direkt an das Steuerelement Objekt weiter und löst dabei folgende Ereigniskette aus: Validate (abhängig vom Wert der CausesValidation-Eigenschaft) und LostFocus bei dem Objekt, das den Fokus verliert, sowie GotFocus bei Objekt. Anwendung
Gemeinsame Methoden
................................................... Anwendung
Das Objekt, das den Fokus abgeben soll, kann die Weitergabe verhindern, indem es bei der Validate-Behandlung den Cancel-Parameter auf True setzt. Umgekehrt resultiert ein Laufzeitfehler, wenn die Enabled-Eigenschaft des Empfängerobjekts auf False gesetzt ist. Beachten Sie jedoch, dass der Fokusempfang trotz gesetzter Locked-Eigenschaft möglich ist, denn auch wenn der Benutzer den Wert nicht ändern kann, Markierungen kann er vornehmen. Warnung
................................................... Wa rnung
Der unvorsichtige Einsatz von SetFocus kann zu endlosen Ereignisketten führen, wenn sich Steuerelemente den Fokus wechselseitig im Rahmen der GotFocus-Behandlung zuschanzen. (Zur Rettung des Projekts für den Fall der Fälle: vgl. »Schleifen«, S. 40.)
ShowWhatsThis- Methode Sub Objekt.ShowWhatsThis() Betroffene Objekte
................................................... Betro ffene Objekte Alle sichtbaren Steuerelemente Beschreibung
................................................... Bes c hreibung
Zeigt die Direkthilfe für das Steuerelement im Popup-Hilfefenster an. Der Hilfetext ist über die Eigenschaft WhatsThisHelpID indiziert und entstammt der in App.HelpFile spezifizierten Datei. Damit die Methode in Aktion tritt, muss die WhatsThisHelp-Eigenschaft des Formulars auf True gesetzt sein.
................................................... Verwa ndte Eigens c ha ften HelpContextId, App.HelpFile
WhatsThisButton,
WhatsThisHelp,
WhatsThisHelpID,
WhatsThisMode,
Verwandte Themen
................................................... Verwandte Them en
HelpContextID-Eigenschaft und WhatsThisHelpID-Eigenschaft (S. 353)
ZOrder- Methode Sub Objekt.ZOrder([Position]) Betroffene Objekte
................................................... Betro ffene Objekte Alle Steuerelemente mit sichtbarer Darstellung, Formulare, MDI-Formulare Beschreibung
................................................... Bes c hreibung
Unter Z-Ordnung versteht man die Reihenfolge, in der die Objekte eines Containers innerhalb der jeweiligen Grafikebene gezeichnet werden. Die ZOrder-Methode setzt Objekt an die oberste oder unterste Position in der Z-Ordnung des zugehörigen Containers. Fehlt der Parameter
386
Standardsteuerelemente
Position oder ist er 0, platziert die Methode das Objekt ganz nach vorn, so dass es potenziell andere verdecken kann. Ist der Wert 1, platziert die Methode das Objekt nach hinten, so dass es potenziell von allen anderen verdeckt werden kann. Anwendung
................................................... Anwendung
Beispiel
................................................... Beis piel
' Z-Ordnung wiederherstellen For i = 31 To 0 Step -1 figur(i).ZOrder Next i Verwandte Themen
................................................... Verwandte Them en
Schach – klare Sicht auf Hintergründliches (S. 607)
Standardsteuerelemente CheckBox, ComboBox, CommandButton, Data, DirListBox, DriveListBox, FileListBox, Frame, HScrollBar, Image, Label, Line, ListBox, OLE, OptionButton, PictureBox, Shape, TextBox, Timer, VScrollBar Beschreibung
................................................... Bes c hreibung
Die Standardsteuerelemente sind in der standardmäßigen Werkzeugsammlung von Visual Basic enthalten und lassen sich ohne weitere Vorbereitung direkt für den Entwurf von Formularen, Benutzersteuerelementen, Eigenschaftsseiten und Benutzerdokumenten einsetzen – vorausgesetzt, die Werkzeugsammlung wurde über den Menübefehl ANSICHT/WERKZEUGSAMMLUNG eingeblendet. Um ein Steuerelement in den Entwurfsbereich etwa eines Formulars zu platzieren, klicken Sie zuerst auf das entsprechende Symbol in der Werkzeugleiste und ziehen dann im Entwurfsfenster mit der Maus einen Bereich auf, den das Steuerelement später einnehmen soll.
Auswahl eines Steuerelementtyps in der Werkzeugsammlung von Visual Basic
387
Standardsteuerelemente
Für die Steuerelemente eines Formulars sind drei Reihenfolgen zu unterscheiden: die Tabulatorreihenfolge, die Einfügereihenfolge und die Z-Ordnung oder Anzeigereihenfolge. Die Tabulatorreihenfolge ergibt sich aus der TabIndex-Eigenschaft der Steuerelemente, die den Fokus erhalten können, und regelt die Weitergabe des Fokus bei Betätigung der Tabulatortaste. Die Einfügereihenfolge ergibt sich aus der Reihenfolge, in der die Steuerelemente auf dem Formular (Container) platziert wurden, unter Berücksichtigung aller nachträglichen Vertauschungen über das Menü FORMAT/REIHENFOLGE. Sie bestimmt die Reihenfolge, in der Visual Basic die einzelnen Steuerelemente deklariert, und spiegelt sich (umgekehrt) in der Elementreihenfolge der Auflistung Controls wider. Die nur zur Laufzeit existierende Z-Ordnung ergibt sich zunächst aus der Einfügereihenfolge und regelt, in welcher Reihenfolge ein Formular (Container) die Steuerelemente zeichnet. Falls sich die Bereiche zweier Steuerelemente überschneiden, wird dasjenige mit der niedrigeren Z-Ordnung zuerst gezeichnet – und damit von dem anderen ganz oder teilweise verdeckt.
Standardsteuerelemente
Standardsteuerelemente
Abgesehen von dem Zeitgeber-Steuerelement (Timer), das zur Laufzeit nicht sichtbar ist, legen Sie über den Bereich die spätere Größe und Position des Steuerelements fest. Um Größe oder Position eines bereits eingefügten Steuerelements danach noch einmal zu ändern, klicken Sie das betreffende Steuerelement einfach an und ziehen den Bereich an die gewünschte Position bzw. in die gewünschte Größe. Die folgende Abbildung zeigt die Entwurfsansicht eines Formulars, auf dem (ein wenig wahllos) alle Standardsteuerelemente zu sehen sind.
Formular, auf dem (wahllos) alle Standardsteuerelemente platziert wurden
Die Steuerelemente auf dem Formular sind in drei Spalten organisiert. In der linken Spalte sind zwei Kontrollkästchen (CheckBox) in einem Figur-Steuerelement (Shape) enthalten, darunter drei Optionsfelder (OptionButton) in einem Rahmensteuerelement (Frame), dann ein Datensteuerelement (Data) und schließlich ein Zeitgeber-Steuerelement (Timer), das zur Laufzeit nicht sichtbar ist und folglich an beliebiger Stelle platziert sein kann. Die mittlere Spalte beginnt mit zwei Textfeldern (TextBox), darunter ein Kombinationsfeld (ComboBox) sowie ein Listenfeld (ListBox), daneben eine vertikale Bildlaufleiste (VScrollBar), darunter eine horizontale Bildlaufleiste (HScrollBar) und schließlich ein Anzeige-Steuerelement (Image). Die optische Abtrennung der nächsten Spalte übernimmt ein Liniensteuerelement (Line). Die rechte Spalte beginnt mit einem Beschriftungssteuerelement (Label) über einem Bildfeld-Steuerelement (PictureBox) neben einer Schaltfläche (CommandButton) über einem OLE-Container-Steuerelement (OLE). Darunter dann ein Laufwerklistenfeld (DriveListBox), ein Verzeichnislistenfeld (DirListBox) und schließlich ein Dateilistenfeld (FileListBox). Steuerelement
Objektdatentyp
Beschreibung
Anzeige
Image
Ermöglicht die Anzeige eines Bildes
Befehlsschaltfläche
CommandButton
Ermöglicht die Ausführung einer Aktion bzw. eines Befehls
Bezeichnungsfeld
Label
Ermöglicht Beschriftungen
Bildfeld
PictureBox
Stellt ein Fenster für die Anzeige von Bildern sowie die Ausgabe von Text und Grafik bereit
388
Standardsteuerelemente
Objektdatentyp
Beschreibung
Bildlaufleiste horizontal
HScrollBar
Übernimmt die analoge Darstellung der Position und des prozentualen Anteils eines horizontalen Ausschnitts bezogen auf ein größeres Ganzes und ermöglicht die Veränderung der horizontalen Position über eine Bildlaufmarke
Bildlaufleiste vertikal
VScrollBar
übernimmt die analoge Darstellung der Position und des prozentualen Anteils eines vertikalen Ausschnitts bezogen auf ein größeres Ganzes und ermöglicht die Veränderung der vertikalen Position über eine Bildlaufmarke
Dateilistenfeld
FileListBox
Zeigt eine Liste der Dateien im gegebenen Verzeichnis an und ermöglicht die Auswahl
Daten
Data
Ermöglicht den Datenbankzugriff auf Basis der Microsoft Jet Engine oder der ODBC-Schnittstelle
Figur
Shape
Ermöglicht die Anzeige verschiedener geometrischer Figuren – Kreis, Ellipse, Rechteck, Quadrat, abgerundetes Rechteck, abgerundetes Quadrat
Kombinationsfeld
ComboBox
Kombination aus Textfeld und Listenfeld
Kontrollkästchen
CheckBox
Ermöglicht die Auswahl einer Option
Laufwerklistenfeld
DriveListBox
Zeigt eine Liste der logischen Laufwerke des Systems an und ermöglicht die Auswahl
Linie
Line
Ermöglicht die Anzeige einer Linie
Listenfeld
ListBox
Ermöglicht die Anzeige einer Zeichenfolgenliste sowie die Auswahl daraus
OLE-Container
OLE
Ermöglicht die Anzeige und Bearbeitung eingebetteter oder verknüpfter Objekte anderer Anwendungen
Optionsfeld
OptionButton
Ermöglicht die Auswahl einer Option unter vielen
Rahmen
Frame
Ermöglicht die sichtbare Gruppierung von Steuerelementen
Textfeld
TextBox
Ermöglicht die Ein- und Ausgabe von Text
Verzeichnislistenfeld
DirListBox
Zeigt das hierarchische Umfeld des eingestellten Verzeichnisses für ein gegebenes Laufwerk an und ermöglicht die Auswahl eines beliebigen Verzeichnisses auf diesem Laufwerk
Zeitgeber
Timer
Ermöglicht die zeitgebundene, periodische Ausführung von Code
Visual Basic vereinbart für jedes Steuerelement implizit ein Objekt und schlägt dafür einen Bezeichner in der Name-Eigenschaft vor. Sofern das Steuerelement eine Beschriftung oder eine
389
Standardsteuerelemente
Steuerelement
Standardsteuerelemente
Standardsteuerelemente
Zeichenfolge als Wert hat, setzt Visual Basic den gewählten Bezeichner dafür ein – das zeigt die Abbildung recht schön. Die meisten Eigenschaften eines Steuerelementobjekts lassen sich bereits zur Entwurfszeit im Eigenschaftenfenster definieren (viele der Entwurfseigenschaften sind zur Laufzeit sogar schreibgeschützt), manche aber auch erst zur Laufzeit. Die Abbildung zeigt das Eigenschaftenfenster eines Textfeldes.
Eigenschaftenfenster mit den Entwurfseigenschaften eines Textfeldes
Anzeige- Steuerelement (Image) Image1 As Image Beschreibung
................................................... Bes c hreibung
Das Anzeige-Steuerelement dient der Anzeige von Bildern, die als Bitmap in einem der Formate BMP, JPG, JPEG, GIF, WMF, EMF, ICO oder CUR vorliegen. Die Standardeigenschaft des Steuerelements ist Picture.
390
Anzeige- Steuerelement ( Image)
Eigenschaften
................................................... Eigens c ha ften Appearance, BorderStyle, Container, DataChanged, DataField, DataFormat, DataMember, DataSource, DragIcon, DragMode, Enabled, Height, Index, Left, MouseIcon, MousePointer, Name, OLEDragMode, OLEDropMode, Parent, Picture, Stretch, Tag, ToolTipText, Top, Visible, WhatsThisHelpID, Width Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, ShowWhatsThis, ZOrder Ereignisseza
Click, DblClick, DragDrop, DragOver, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag Anwendung
................................................... Anwendung
Bestimmung dieses Steuerelements ist die ressourcenschonende und schnelle Anzeige von Bildern in verschiedenen Grafikformaten. Hat die Eigenschaft Stretch den Wert False, behält das Bild seine vordefinierte Größe, und es hängt von der Bereichsgröße des Steuerelements ab, ob es vollständig oder nur teilweise (von links oben aus gesehen) dargestellt werden kann. Andernfalls wird das Bild unter Inkaufname einer horizontalen Streckung oder Stauchung in den Bereich des Steuerelements eingepasst. Wenn Sie der Eigenschaft Picture zur Entwurfszeit ein Bild zuordnen, speichert Visual Basic eine Kopie des Bildes als binären Anhang der Programmdatei bzw. in der kompilierten Version als Teil der ausführbaren Datei. Wenn Sie eine aktuelle Fassung des Bildes zur Laufzeit laden wollen (Verknüpfung), müssen Sie das Bild mit der LoadPicture-Funktion laden und dem Anzeige-Steuerelement zuweisen. Warnung
................................................... Wa rnung
Den Eigenschaften Height und Width des Datentyps Picture liegt die Maßeinheit vbHiMetric zugrunde. Wenn Sie die Bereichsgröße eines Anzeige-Steuerelements an die Abmessungen eines Bildes anpassen wollen, müssen Sie die Methoden ScaleX und ScaleY für die Umrechnung der Maße in die Maßeinheiten des Containers bemühen. Beispiel
................................................... Beis piel
Der folgende Code demonstriert, wie man ein Bild in ein Anzeige-Steuerelement lädt und dessen Bereichsgröße an die Abmessungen der Bitmap anpasst. Dim pic As Picture Set pic = LoadPicture(App.Path + "\MeinBild.bmp") Image1.Width = ScaleX(pic.Width, vbHimetric, ScaleMode) Image1.Height = ScaleY(pic.Height, vbHimetric, ScaleMode) Image1 = pic Verwandte Steuerelemente
................................................... Verwandte Steuerelemente ImageList, PictureBox, RptImage
3 91
Standardsteuerelemente
................................................... Ereignis s e
Standardsteuerelemente
Befehlsschaltfläche- Steuerelement (CommandButton) Command1 As CommandButton
Beschreibung
Standardsteuerelemente
................................................... Bes c hreibung
Das Befehlsschaltfläche-Steuerelement ist als Visualisierung für die Funktion des einfachen beschrifteten Tasters gedacht. Klickt der Benutzer darauf oder betätigt er die Schaltfläche mit der Tastatur, ändert sich für die Zeitdauer der Betätigung seine Darstellung sowie der Wert der Value-Eigenschaft, und das Click-Ereignis tritt auf. Eigenschaften
................................................... Eigens c ha ften Appearance, BackColor, CausesValidation, Cancel, Caption, Container, Default, DisabledPicture, DownPicture, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, MaskColor, MouseIcon, MousePointer, Name, OLEDropMode, Parent, Picture, RightToLeft, Style, TabIndex, TabStop, Tag, ToolTipText, Top, UseMaskColor, Value, Visible, WhatsThisHelpID, Width Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Click, DragDrop, DragOver, GotFocus, KeyDown, KeyUp, KeyPress, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Validate Anwendung
................................................... Anwendung
Für gewöhnlich wird die Befehlsschaltfläche dafür genutzt, Aktionen bzw. Befehle explizit durch einen Klick mit der Maus auszulösen. So für die Befehle »OK«, »Abbrechen« und »Übernehmen« in Dialogfeldern, aber auch für andere formularspezifische Kommandos. Vom Prinzip her ließen sich dafür natürlich auch andere Steuerelemente verwenden, die eine Click-Behandlung ermöglichen, doch die Befehlsschaltfläche ist speziell auf diese Aufgabe zugeschnitten. Insbesondere besitzt sie die Eigenschaften Default und Cancel, deren Werte darüber entscheiden, ob auch die Tasten (Eingabe) oder (Esc) das Click-Ereignis auslösen können. Für die beiden Eigenschaften gelten folgende Regeln: 1. In einem Formular kann immer nur die Default-Eigenschaft einer einzigen Befehlsschaltfläche auf True gesetzt sein. Das macht sie zur Standardschaltfläche. Analoges gilt für die Cancel-Eigenschaft. 2. Setzt man die Default-Eigenschaft einer Schaltfläche auf True, wird sie zur Standardschaltfläche und gleichzeitig ändert sich die Default-Eigenschaft der bisherigen Standardschaltfläche auf False. Analoges gilt für die Cancel-Eigenschaft. 3. Es kann immer nur eine Befehlsschaltfläche in einem Formular auf die Eingabetaste reagieren. Das ist entweder die Schaltfläche, die den Fokus besitzt, oder, falls keine der Schaltflächen in dem Formular den Fokus besitzt, die Standardschaltfläche. Analoges gilt für die
392
Bezeichnungsfeld- Steuerelement (Label)
Cancel-Eigenschaft. Den Fokusbesitz zeigt eine Schaltfläche durch einen zusätzlichen gestrichelten Innenrand an. Ist keine der Schaltflächen im Besitz des Fokus, lässt sich die Standardschaltfläche an einer verdickten Randlinie (vgl. Abbildung) erkennen.
Beispiel
................................................... Beis piel
Die Click-Routinen der Schaltflächen Abbrechen und Beenden schließen beide das Formular. OK ist Standardschaltfläche und reagiert auf die Eingabetaste, während Abbrechen auf die Taste (Esc) reagiert. OK_Click verwertet im Gegensatz zu Abbrechen_Click die Eingaben des Benutzers. ... OK.Default = True Abbrechen.Cancel = True ... Private Sub OK_Click() VerwerteEingaben Unload Me End Sub Private Sub Abbrechen_Click() Unload Me End Sub
' Eingaben des Benutzers verwerten
' Eingaben werden verworfen
Verwandte Steuerelemente
................................................... Verwandte Steuerelemente Button, CheckBox, OptionButton
Bezeichnungsfeld- Steuerelement (Label) Label1 As Label Beschreibung
................................................... Bes c hreibung
Das Bezeichnungsfeld-Steuerelement hat als Standardeigenschaft eine Zeichenfolge, die es in seinem Bereich gegebenenfalls umbrochen anzeigt. Eine Bearbeitung der Zeichenfolge durch Benutzer ist nicht möglich.
3 93
Standardsteuerelemente
Die Caption-Eigenschaft ermöglicht die Beschriftung der Schaltfläche. Um eine Zugriffstaste für das Steuerelement zu vereinbaren, stellen Sie dem entsprechenden Buchstaben in der Beschriftung das Zeichen »&« voran. Er wird zur Laufzeit durch Unterstreichung kenntlich gemacht (vgl. Abbildung). Befehlsschaltflächen kennen zwei unterschiedliche Darstellungen: die Standarddarstellung im Stil von Windows 9x und die benutzerdefinierte Darstellung. Um dem Steuerelement ein benutzerdefiniertes Aussehen zu verleihen, können Sie den Eigenschaften Picture und DownPicture sowie gegebenenfalls DisabledPicture geeignete Bilder zuordnen. Falls Sie eine pseudotransparente Darstellung wünschen, bei der die über eine Transparenzfarbe (MaskColor) definierten transparenten Bereiche der Bilder in Hintergrundfarbe erscheinen, müssen Sie die Eigenschaft UseMaskColor auf True setzen. Die Style-Eigenschaft entscheidet darüber, welche der Darstellungen zur Anzeige kommt. (Ein Beispiel dafür findet sich im Abschnitt »DisabledPictureEigenschaft«, S. 341.)
Standardsteuerelemente
Eigenschaften
................................................... Eigens c ha ften Alignment, Appearance, AutoSize, BackColor, BackStyle, BorderStyle, Caption, Container, DataChanged, DataField, DataFormat, DataMember, DataSource, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontUnderline, ForeColor, Height, Index, Left, LinkItem, LinkMode, LinkTimeout, LinkTopic, MouseIcon, MousePointer, Name, OLEDropMode, Parent, RightToLeft, TabIndex, Tag, ToolTipText, Top, UseMnemonic, Visible, WhatsThisHelpID, WordWrap Methoden
Standardsteuerelemente
................................................... Metho den Drag, LinkExecute, LinkPoke, LinkRequest, LinkSend, Move, OLEDrag, Refresh, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Change, Click, DblClick, DragDrop, DragOver, GotFocus, KeyDown, KeyUp, KeyPress, LinkClose, Link, Error, LinkNotify, LinkOpen, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag Anwendung
................................................... Anwendung
Das Bezeichnungsfeld-Steuerelement ist als Mittel für die »externe« Beschriftung von Steuerelementen gedacht, wenn diese selbst keine Möglichkeit dafür vorsehen, also keine Caption-Eigenschaft besitzen. Zur Gestaltung der Textausgabe können Sie die Schriftattribute über die jeweiligen Font-Eigenschaften setzen. Für die Beschriftung von Bildern (beispielsweise in Image-Steuerelementen) kann es vorteilhaft sein, einen durchsichtigen Bereichshintergrund für das Bezeichnungsfeld einzustellen. Setzen Sie dazu die Eigenschaft BackStyle auf vbTransparent (0). Der Wert des Steuerelements lässt sich zur Laufzeit nach Belieben und mit sofortiger Wirkung durch einfache Zuweisung einer anderen Zeichenfolge ändern. Dies kann auch automatisch passieren, wenn Sie das Steuerelement über die Link-Eigenschaften zum Ziel einer DDE-Verknüpfung erklären oder es über die Data-Eigenschaften an ein Feld in einer Datenbank binden. Im Zuge einer Wertänderung kann es allerdings passieren, dass nicht die gesamte Zeichenfolge im Bereich des Steuerelements darstellbar ist – restliche Zeichen werden dann abgeschnitten, wenn die AutoResize-Eigenschaft nicht auf True gesetzt ist. Sie müssen den Bereich daher entweder von vornherein großzügig bemessen oder Platz für die automatische Ausdehnung einkalkulieren. Zudem lässt sich die WordWrap-Eigenschaft auf True setzen, um einen automatischen Umbruch zu erhalten. Beachten Sie aber, dass sich der Bereich des Feldes dann in beide Richtungen (nach unten und nach rechts/links, bevorzugt aber nach unten) ausdehnen kann, je nachdem wie der Umbruch zustande kommt. Oft ist es dann besser, ein Textfeld mit Bildlaufleisten zu benutzen. Textfelder lassen sich übrigens hervorragend als Bezeichnungsfelder »verkleiden«, wenn man die Möglichkeit der Bearbeitung mittels der Locked-Eigenschaft unterbindet und die Eigenschaften BorderStyle und BackColor geeignet setzt. Nur ein transparenter Hintergrund lässt sich so nicht realisieren. Beispiel
................................................... Beis piel
Das folgende kleine Programm benutzt ein Bezeichnungsfeld Label1 und ein Timer-Steuerelement Timer1 für die animierte Wiedergabe einer Textsequenz mit Fade-out-Effekt. (Das vollständige Beispielprojekt FadeOut wird im Abschnitt »AutoSize-Eigenschaft«, S. 329, diskutiert.)
394
Bildfeld- Steuerelement (PictureBox)
Dim Texte() Dim i Private Sub Form_Load() Texte = Array("Rauchen", "schadet", "Ihrer", "Gesundheit") Label1 = Texte(0) End Sub
Standardsteuerelemente
Private Sub Timer1_Timer() Label1.Font.Size = Label1.Font.Size + 1.1 If Label1.FontSize > 40 Then Label1.FontSize = 8 i = (i + 1) Mod (UBound(Texte) + 1) Label1 = Texte(i) End If End Sub Verwandte Steuerelemente
................................................... Verwandte Steuerelemente TextBox, RptLabel, RptTextBox
Bildfeld- Steuerelement (PictureBox) Picture1 As PictureBox Beschreibung
................................................... Bes c hreibung
Die Standardeigenschaft des Bildfeld-Steuerelements ist Picture. Damit ist es für die Anzeige von Bildern prädestiniert. Neben der Anzeige von Bildern in beliebiger Skalierung (Verzerrung des Seitenverhältnisses möglich) kennt es aber auch die gleichen Grafikmethoden wie das Formular und ermöglicht insbesondere die Ausgabe von Text. Darüber hinaus kann es als Container für andere Steuerelemente fungieren. Eigenschaften
................................................... Eigens c ha ften Align, Appearance, AutoRedraw, AutoSize, BackColor, BorderStyle, ClipControls, CausesValidation, Container, CurrentX, CurrentY, DataChanged, DataField, DataFormat, DataMember, DataSource, DragIcon, DragMode, DrawMode, DrawStyle, DrawWidth, Enabled, FillColor, FillStyle, Font, FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontTransparent, FontUnderline, ForeColor, hDC, Height, HelpContextID, hWnd, Image, Index, Left, LinkItem, LinkMode, LinkTimeout, LinkTopic, MouseIcon, MousePointer, Name, OLEDragMode, OLEDropMode, Parent, Picture, RightToLeft, ScaleHeight, ScaleLeft, ScaleMode, ScaleTop, ScaleWidth, TabIndex, TabStop, Tag, ToolTipText, Top, Visible, WhatsThisHelpID, Width Methoden
................................................... Metho den Circle, Cls, Drag, Line, LinkExecute, LinkPoke, LinkRequest, LinkSend, Move, OLEDrag, PaintPicture, Point, PSet, Print, Refresh, Scale, ScaleX, ScaleY, SetFocus, ShowWhatsThis, TextHeight, TextWith, ZOrder Ereignisse
................................................... Ereignis s e
Change, Click, DblClick, DragDrop, DragOver, GotFocus, KeyDown, KeyUp, KeyPress, LinkClose, LinkError, LinkNotify, LinkOpen, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Paint, Resize, Validate
3 95
Standardsteuerelemente
Anwendung
Standardsteuerelemente
................................................... Anwendung
Das Bildfeld-Steuerelement besitzt im Wesentlichen die gleiche Ausstattung wie das Formular – darunter insbesondere die Methoden für die Ausgabe von Bildern (PaintPicture), Text (TextHeight, TextWidth, Print) und Grafik (Circle, Line, PSet, Point) sowie natürlich auch ein eigenes Koordinatensystem (Scale, ScaleX, ScaleY), nicht zu vergessen die Kombination PaintMethode und AutoRedraw-Eigenschaft sowie das Modell der Ausgabe auf drei Ebenen (vgl. »Paint-Ereignis«, S. 253). Auch kann das Bildfeld als Container für andere Steuerelemente fungieren, etwa für die Gruppierung von Optionsfeldern und/oder Kontrollkästchen. Obwohl das Bildfeld wirklich viel vom Formular hat, bleibt es doch ein Steuerelement und kann als Quelle für OLE-Drag&Drop-Operationen oder DDE-Verbindungen fungieren. Trotz dieser reichhaltigen Ausstattung ist das Bildfeld aber – wie der Name schon vermuten lässt – in erster Linie als Steuerelement für die flexible Ausgabe von Bildern gedacht. Während das Anzeige-Steuerelement (Image) nur auf die reine, dafür aber schnelle und ressourcenschonende Ausgabe von Bildern spezialisiert ist und auf die Möglichkeiten, die sich durch Skalierung, Streckung oder Rasteroperationen eröffnen, verzichten muss, bietet das Bildfeld all diesen Komfort. Das Bildfeld-Steuerelement lässt sich als einziges Standardsteuerelement neben dem Datensteuerelement (Data) auf einem MDI-Formular platzieren. Es verhält sich dann wie eine Leiste und klebt zusammen mit anderen Leisten (ToolBar, CoolBar, ProgressBar, nicht jedoch StatusBar) in voller Breite am oberen Rand des Client-Bereichs. Sie können es dann beispielsweise dafür benutzen, sich eine benutzerdefinierte Symbolleiste zu basteln. Beispiel
................................................... Beis piel
Das für seinen Leistungsumfang eher zierlich geratene Projekt BilderViewer lässt sich als vollwertiger Bildbetrachter verwenden und wartet sogar mit OLE-Funktionalität auf. Im Formular finden Sie zwei Steuerelemente: ein Bildfeld Picture1, das die zentrierte und – in Bezug auf die aktuelle Formulargröße – maximierte Bildausgabe übernimmt, und ein Standarddialoge-Steuerelement CommonDialog1 für die unkomplizierte Eingabe eines Dateinamens. Neue Bilder lassen sich entweder über den Menübefehl DATEI/ÖFFNEN oder per OLE-Drag&Drop einfügen. Bei Größenänderungen des Formulars passt sich der Inhalt entsprechend an. ' Projekt: Viewer für Bilder Dim Pic As Picture Private Sub Form_Load() CommonDialog1.Filter = "Bilder (JPG, GIF, BMP)|*.jpg;*.gif;*.bmp" Picture1.Left = 0 Picture1.Top = 0 Picture1.Width = ScaleWidth Picture1.Height = ScaleHeight mnuDateiÖffnen_Click End Sub Private Sub Form_Resize() Picture1.Refresh End Sub
' Bildfeld neu einpassen
Private Sub mnuDateiÖffnen_Click() CommonDialog1.ShowOpen ' Bilddatei in Erfahrung bringen If CommonDialog1.FileName "" Then
396
Bildfeld- Steuerelement (PictureBox)
Set Pic = LoadPicture(CommonDialog1.FileName) Picture1.Refresh ' Bild und Bildfeld einpassen End If End Sub
Standardsteuerelemente
Private Sub Picture1_OLEDragDrop(Data As DataObject, Effect As Long, _ Button As Integer, Shift As Integer, X As Single, Y As Single) ' Datei von Explorer-Fenster? If Data.GetFormat(vbCFFiles) Then Set Pic = LoadPicture(Data.Files(1)) Picture1.Refresh End If ' Gewöhnliches Bildobjekt? If Data.GetFormat(vbCFDIB) Or Data.GetFormat(vbCFBitmap) Then Set Pic = Data.GetData(vbCFDIB) End If End Sub Private Sub Picture1_Paint() Dim PicWidth, PicHeight If Not Pic Is Nothing Then ' Bildfeld maximieren und zentrieren und ' Bild in maximaler Größe verzerrungsfrei einpassen PicWidth = ScaleX(Pic.Width, vbHimetric, vbTwips) PicHeight = ScaleY(Pic.Height, vbHimetric, vbTwips) If PicHeight / PicWidth > ScaleHeight / ScaleWidth Then Picture1.Height = ScaleHeight ' Maximieren Picture1.Width = ScaleHeight / PicHeight * PicWidth Picture1.Left = (ScaleWidth – Picture1.Width) / 2 ' Zentrieren Picture1.Top = 0 Else Picture1.Width = ScaleWidth Picture1.Height = ScaleWidth / PicWidth * PicHeight Picture1.Top = (ScaleHeight – Picture1.Height) / 2 Picture1.Left = 0 End If ' Bild einpassen Picture1.PaintPicture Pic, 0, 0, Picture1.ScaleWidth, _ Picture1.ScaleHeight End If End Sub Verwandte Steuerelemente
................................................... Verwandte S teuerelemente Image, Form, RptImage, UserControl, UserDocument Verwandte Themen
................................................... Verwa ndte Them en
Formulare (S. 306)
3 97
Standardsteuerelemente
Standardsteuerelemente
Fenster der Anwendung BilderViewer
Bildlaufleisten- Steuerelemente (HScrollBar, VScrollBar) VScroll1 As VScrollBar HScroll1 As HScrollBar Beschreibung
................................................... Bes c hreibung
Es gibt eine 16- und eine 32-Implementation der Bildlaufleiste, und Visual Basic 6.0 arbeitet (leider) noch mit der 16-Bit-Version, was gewisse Einschränkungen mit sich bringt. Die Bildlaufleisten-Steuerelemente HScrollBar und VScrollBar sind speziell für die analoge Visualisierung und Manipulation von Ausschnittsdarstellungen eingerichtet. Standardeigenschaft der Bildlaufleiste ist die Value-Eigenschaft. Sie ist vom Typ Integer und bestimmt die aktuelle Position der Bildlaufmarke. Den Wertebereich für die Bildlaufmarke legen die Eigenschaften Min und Max fest. Die Eigenschaften sind vom Typ Integer und müssen im Intervall 0 bis 32767 liegen, wobei Min kleiner als Max zu wählen ist. Darüber hinaus gestatten die Eigenschaften LargeChange und SmallChange die Definition von Werten für den Vorschub der Bildlaufmarke alternativ zur Ziehoperation. LargeChange ist für den Bildvorschub zuständig, der mit den Tasten (Bild-Auf) und (Bild-Ab) sowie durch Mausklicks in den Schaftbereich der Leiste zwischen Bildlaufmarke und Pfeilsymbole ausgelöst wird. SmallChange gibt den Wert für den »kleinen Vorschub« (Zeilenvorschub) mittels der Pfeiltasten (Auf), (Ab), (Links) und (Rechts) sowie der Pfeilsymbole an. Die Ausdehnung der Bildlaufmarke hängt von LargeChange ab, gibt aber das Größenverhältnis zwischen Ausschnitt und vollem Bereich (leider) nicht proportional wieder. Während der Benutzer die Bildlaufmarke auf eine andere Position zieht, signalisiert das Steuerelement Scroll-Ereignisse. Am Ende des Ziehvorgangs sowie bei diskreten Positionsänderungen per Tastatur oder Mausklick tritt das Change-Ereignis auf. Eigenschaften
................................................... Eigens c ha ften CausesValidation, Container, DragIcon, DragMode, Enabled, Height, HelpContextID, hWnd, Index, LargeChange, Left, Max, Min, MouseIcon, MousePointer, Name, Parent, RightToLeft, SmallChange, TabIndex, TabStop, Tag, Top, Value, Visible, WhatsThisHelpID, Width Methoden
................................................... Metho den Drag, Move, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Change, DragDrop, DragOver, GotFocus, KeyDown, KeyUp, KeyPress, LostFocus, Scroll, Validate
398
Bildlaufleisten- Steuerelemente ( HScrollBar, VScrollBar)
Anwendung
................................................... Anwendung
1. Definition des Wertebereichs – wählen Sie den Wertebereich (über die Eigenschaften Min und Max) nach Möglichkeit so, dass er den Wertebereich der Problemstellung entweder direkt wiedergibt oder zumindest entweder durch reine Translation (lies: Verschiebung) oder durch reine Skalierung (lies: Streckung/Stauchung) auf den Problembereich abzubilden ist. Skalierung und Translation sind mit viel Rechnerei verbunden. 2. Definition der Seitengröße – setzen Sie die Eigenschaft LargeChange auf die Breite des sichtbaren Ausschnitts, oder bei Verwendung des Steuerelements als Schieberegler auf eine geeignete Intervalllänge. Ein guter Wert für SmallChange ist in den meisten Fällen ein Zehntel von LargeChange. 3. Interpretation des Standardwerts – der Standardwert (Value) drückt die Position der Bildlaufmarke zwischen Min und Max aus, wobei die Breite der Marke sozusagen »herausgelogen« wird. Aus diesem Grund müssen Sie für die Definition von Max von der oberen Bereichsgrenze die Seitengröße LargeChange abziehen! Wird das Steuerelement dagegen wie ein Schieberegler benutzt, setzen Sie Max auf die obere Bereichsgrenze, ohne etwas abzuziehen. 4. Positionierung und Größenanpassung der Bildlaufleiste – wird die Bildlaufleiste in einer größenveränderlichen Komponente platziert, muss sie in den meisten Fällen in der verantwortlichen Resize-Routine oder dem entsprechenden Äquivalent gepflegt werden. Bei Größenänderungen einer Bildlaufleiste (Width und Height) bleibt die Breite der Bildlaufmarke prozentual erhalten. Insbesondere bleiben die Eigenschaften Min, Max, SmallChange und LargeChange sowie Value unverändert. 5. Pflege des Standardwerts – der Standardwert, der die Position der Bildlaufmarke bestimmt, wird vom Steuerelement selbst gepflegt. Seine Auswertung geschieht im Rahmen der ChangeBehandlung. Sie können den Wert mit sofortiger Wirkung auch explizit unter Beachtung von Min und Max setzen (jede Änderung des Werts generiert ein Change-Ereignis), nur nicht innerhalb der Scroll-Behandlung, da das nächste Scroll-Ereignis das Ergebnis sofort wieder zunichte macht. Beispiel
................................................... Beis piel
Die folgende weitgehend dem Projekt HexView entstammende Resize-Routine sorgt dafür, dass die Bildlaufleisten VScroll1 und HScroll1 am rechten bzw. unteren Rand im Client-Bereich des Formulars verbleiben und gegebenenfalls ausgeblendet werden, wenn der Client-Bereich für die Anzeige des Dokuments ausreicht. Die globalen Variablen DocWidth und DocHeight geben hier die Abmessungen des gesamten Dokuments wieder: Private Sub Form_Load() VScroll1.Top = 0 HScroll1.Left = 0 ...
' oben ankleben ' links ankleben
Private Sub Form_Resize()
3 99
Standardsteuerelemente
Der Einsatz der Bildlaufleiste bietet sich überall da an, wo es um die Auswahl eines Werts aus einem Wertebereich mit analoger Darstellung geht. Das kann eine Tonhöhe (Frequenzwert aus einem gegebenen Frequenzbereich) sein, eine Lautstärke oder ein Winkel für die perspektivische Darstellung. Beachten Sie aber, dass Sie mit dem Schieberegler-Steuerelement (Slider) ein Steuerelement zur Verfügung haben, das auf Analogregelung spezialisiert ist. Die Bildlaufleiste hat keine Skala, ist aber im Gegensatz zum Schieberegler in der Lage, die Ausdehnung des angezeigten Teilbereichs über die Breite der Bildlaufmarke zu visualisieren. Die Programmierung der Bildlaufleiste (gleich ob vertikal oder horizontal) hat mehrere Aspekte:
Standardsteuerelemente
Standardsteuerelemente
If Not WindowState = vbMinimized Then Height = IIf(Height < 1200, 1200, Height) Width = IIf(Width < 1000, 1000, Width) HScroll1.Visible = ScaleWidth < DocWidth ' Sichtbarkeit VScroll1.Visible = ScaleHeight < DocHeight ' Sichtbarkeit ' Abmessungen der Bildlaufleisten VScroll1.Left = ScaleLeft + ScaleWidth – VScroll1.Width VScroll1.Height = ScaleHeight + HScroll1.Height * HScroll1.Visible HScroll1.Top = ScaleTop + ScaleHeight – HScroll1.Height HScroll1.Width = ScaleWidth + VScroll1.Width * VScroll1.Visible ' vertikale Bildlaufparameter anpassen If VScroll1.Visible Then VScroll1.Max = DocHeight – ScaleHeight VScroll1.LargeChange = ScaleHeight * 0.95 VScroll1.SmallChange = VScroll1.LargeChange / 10 End If ' horizontale Bildlaufparameter anpassen If HScroll1.Visible Then HScroll1.Max = DocWidth – ScaleWidth HScroll1.LargeChange = ScaleWidth * 0.95 HScroll1.SmallChange = HScroll1.LargeChange / 10 End If Refresh End If End Sub Verwandte Steuerelemente
................................................... Verwandte Steuerelemente Slider, UpDown Verwandte Themen
................................................... Verwandte Them en
HexView – eine schnelle Textansicht für große Dateien (S. 551); Bildlauf – ein kleiner Betrachter für große Bilder (S. 545)
Dateilistenfeld- Steuerelement (FileListBox) File1 As FileListBox
Beschreibung
................................................... Bes c hreibung
Bei dem Dateilistenfeld-Steuerelement handelt es sich um ein Listenfeld, das darauf spezialisiert ist, den Inhalt des über die Path-Eigenschaft spezifizierten Verzeichnisses unter Beachtung eines Namensfilters (Pattern) sowie der über die Eigenschaften Archive, ReadOnly, System, Hidden und Normal spezifizierten Attribute in seiner Liste anzuzeigen. Über die Eigenschaft MultiSelect lässt sich zur Laufzeit festlegen, ob der Benutzer nur einen einzelnen Dateinamen (vbMultiSelectNone = 0), mehrere Dateinamen in einem Block
400
Dateilistenfeld- Steuerelement ( FileListBox)
(vbMultiSelectSimple = 1) oder mehrere (vbMultiSelectExtended = 2) auswählen kann.
einzelne
Dateinamen
bzw.
Blöcke
Eigenschaften
................................................... Eigens c ha ften
Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Click, DblClick, DragDrop, DragOver, GotFocus, KeyDown, KeyPress, KeyUp, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, PathChange, PatternChange, Scroll, Validate Anwendung
................................................... Anwendung
Das Dateilistenfeld ist wie das Verzeichnislistenfeld (DirListBox) und das Laufwerklistenfeld (DriveListBox) noch ein Relikt aus der Zeit, als Anwendungen den Benutzer mit eigenen Varianten für Dialoge wie »Datei öffnen«, »Speichern unter« usw. auf die Probe stellten. Inzwischen dürfte es nur noch in ganz besonderen Problemfeldern zum Einsatz kommen, da die seit Windows 9x vorliegende Implementation der Standarddialoge wenig Wünsche offen lässt, was die interaktive Dateiauswahl betrifft. Freilich wird eine Anwendung, die sich beispielsweise auf die Konvertierung von Dateien im Batch-Modus spezialisiert, noch in irgendeiner Form vom Dateilistenfeld profitieren können. Von der Programmierung eigener Versionen der Standarddialoge sei aber eher abgeraten, da es der Benutzer sicher nicht danken wird. Um die im Listenfeld angezeigte Dateiauswahl zu spezifizieren, setzen Sie zunächst die Eigenschaft Path auf das gewünschte Verzeichnis. Dieses muss existieren und wird meist von einem Verzeichnislistenfeld-Steuerelement geliefert. Im zweiten Schritt setzen Sie die Eigenschaft Pattern auf ein Suchmuster im Stil von »*.bmp« oder »a??0012.dat«. Alternativ können Sie die komplette Spezifikation (Pfad plus Suchmuster) auch über die Eigenschaft FileName setzen. In diesem Fall extrahiert das Steuerelement die Werte für Path und Pattern und setzt FileName auf den Namen der ersten Datei in der Auswahl. Ist die Dateiauswahl jedoch leer, tritt ein Laufzeitfehler auf. Jede Änderung von Path bzw. Pattern tut das Steuerelement über die Ereignisse PathChange bzw. PatternChange kund. Wenn Sie wollen, dass der Benutzer mehrere Einträge im Listenfeld auswählen kann, setzen Sie MultiSelect auf 1 oder 2. Die Analyse der Auswahl des Benutzers wird meist im Zuge der Behandlung von Validate oder LostFocus vorgenommen und beinhaltet die Auswertung des Boolean-Arrays Selected (Basis 0), das so viele Elemente hat, wie es Einträge im Listenfeld gibt, und für jedes Element die Zugehörigkeit zur aktuellen Auswahl anzeigt – True bedeutet: das Element gehört zur Auswahl. Die zugehörigen Einträge lassen sich unter dem jeweiligen Index über die List-Eigenschaft gewinnen. Warnung
................................................... Wa rnung
Der verkapselte Teil der OLESetData-Behandlung durch das Steuerelement ist fehlerhaft implementiert. Als Quellkomponente in einer OLE-Drag&Drop-Operation setzt die Komponente in
401
Standardsteuerelemente
Appearance, Archive, BackColor, CausesValidation, Container, DragIcon, DragMode, Enabled, FileName, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, Hidden, hWnd, Index, Left, List, ListCount, ListIndex, Locked, MouseIcon, MousePointer, MultiSelect, Name, Normal, OLEDragMode, OLEDropMode, Parent, Path, Pattern, ReadOnly, Selected, System, TabIndex, TabStop, Tag, Top, ToolTipText, TopIndex, Visible, WhatsThisHelpID, Width
Standardsteuerelemente
der Files-Auflistung nämlich einen fehlerhaften Pfad, wenn die Auswahl dem Wurzelverzeichnis eines Laufwerks angehört: Aus irgendeinem Grund enthält er einen Schrägstrich zu viel – zum Beispiel »C:\\«. Beispiel
................................................... Beis piel
Der folgende Code demonstriert die Auswertung einer Mehrfachauswahl:
Standardsteuerelemente
Private Sub Form_Load() File1.FileName = "c:\Windows\*.dll" End Sub Private Sub File1_LostFocus() For i = 0 To File1.ListCount – 1 If File1.Selected(i) Then Print File1.List(i) End If Next End Sub Verwandte Steuerelemente
................................................... Verwandte Steuerelemente CommonDialog, DirListBox, DriveListBox, ListBox Verwandte Themen
................................................... Verwandte Them en
Listenfeld-Steuerelement (ListBox) (S. 412)
Data- Datensteuerelement (Data) Data1 As Data
Beschreibung
................................................... Bes c hreibung
Das Datensteuerelement Data bildet neben den Steuerelementen RemoteData und Adodc die Grundlage für automatisierte Verbindungen zwischen Steuerelementen und Datenbanken. Aus Sicht eines gewöhnlichen Steuerelements kann Data als Datenquelle auftreten, die es automatisch mit Werten aus einer Datenbank versorgt und Eingaben des Benutzers zurück an die Datenbank leitet. Data legt ein Datenbankobjekt (Database) an, um die Datenbankverbindung zu öffnen, sowie ein Recordset-Objekt für die Repräsentation der Datensätze, sobald es für ein anderes Steuerelement als Datenquelle in Aktion treten muss. Einen Überblick über die für den Datenbankzugriff spezifischen Eigenschaften und Ereignisse des Datensteuerelements entnehmen Sie den folgenden Tabellen. Eigenschaften
................................................... Eigens c ha ften Align, Appearance, BackColor, BOF, Caption, Connect, Database, DatabaseName, DefaultCursorType, DefaultType, DragIcon, DragMode, EditMode, Enabled, EOF, ForeColor, Exclusive, Font, FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontTransparent, FontUnderline, ForeColor, Height, Index, Left, MouseIcon, MousePointer, Name, OLEDrop-
402
Data- Datensteuerelement (Data)
Mode, Options, Parent, ReadOnly, Recordset, RecordsetType, RecordSource, RightToLeft, Tag, ToolTipText, Top, Visible, WhatsThisHelpID, Width Beschreibung
Database
Verweis auf Database-Objekt, das das Steuerelement unter Beachtung der Eigenschaften DataBaseName, Connect, Exclusive und ReadOnly für eine Verbindung generiert
DatabaseName
Zeichenfolge mit dem Namen der Datenbank
Connect
Zeichenfolge mit Informationen über den Datenbanktyp sowie (durch ein Semikolon getrennt) gegebenenfalls erforderliche zusätzliche Parameter. Zur Auswahl stehen: "Access" (Voreinstellung), "dBASE III;", "dBASE IV;", "dBASE 5;", "Excel 3.0;", "Excel 4.0;", "Excel 5.0;", "Excel 8.0;", "Lotus WK1;", "Lotus WK3;", "Lotus WK4;", "FoxPro 2.0;", "FoxPro 2.5;", "FoxPro 2.6;", "FoxPro 3.0;", "Paradox 3.x;", "Paradox 4.x;", "Paradox 5.x;" und "Text;"
BOF
Boolean-Wert, der anzeigt, ob die Position des aktuellen Datensatzes vor dem ersten Datensatz im Recordset-Objekt liegt
EOF
Boolean-Wert, der anzeigt, ob die Position des aktuellen Datensatzes hinter dem letzten Datensatz im Recordset-Objekt liegt
DefaultCursorType
Integer-Wert der bestimmt, welchen Cursortyp das Recordset-Objekt verwendet. Zur Auswahl stehen vbUseDefaultCursor (0; Voreinstellung; Auswahl bleibt dem Treiber überlassen), vbUseODBC (1; Verwendung der ODBC-Cursorbibliothek) und vbUseServerSideCursor (2, Verwendung von Server-Cursorn)
DefaultType
Integer-Wert, der bestimmt, ob die Microsoft Jet-Engine oder die ODBC-Treiber für den Datenzugriff verwendet werden sollen. Voreinstellung ist dbUseJet (2). Wenn Sie dbUseODBC (1) einstellen, müssen Sie die Connect-Eigenschaft auf "Text;" gefolgt von der Verbindungszeichenfolge für die ODBC-Verbindung setzen.
EditMode
Integer-Wert, der den Bearbeitungsstatus des aktuellen Datensatzes anzeigt. Folgende Werte stehen zur Auswahl: dbEditNone (0) für »keine Bearbeitung« (Voreinstellung), dbEditInProgress (1) für »Datensatz wird bearbeitet« und dbEditAdd (2) für »Datensatz wird gerade hinzugefügt«. Die Eigenschaft ist bei der Behandlung von Gültigkeitsfehlern nützlich.
Exclusive
Boolean-Wert, der bestimmt, ob die Datenbank im exklusiven Einbenutzermodus (True) oder im Mehrbenutzermodus (False; Voreinstellung) geöffnet wird
ReadOnly
Boolean-Wert, der bestimmt, ob die Datenbank für den reinen Lesezugriff (True) oder für den Schreib-/Lesezugriff (False; Voreinstellung) geöffnet wird
Recordset
Verweis auf das Recordset-Objekt, das die Datensätze für die Datenbankverbindung zusammenstellt, verwaltet und repräsentiert
RecordsetType
Integer-Wert, der den Typ des Recordset-Objekts bestimmt. Zur Auswahl stehen: vbRSTypeTable (0), vbRCTypeDynaset (1) und vbRSTypeSnapshot.
403
Standardsteuerelemente
Eigenschaft
Standardsteuerelemente
Eigenschaft
Beschreibung
RecordSource
Zeichenfolge mit dem Namen der Tabelle, Abfrage oder einer SQLAnweisung, die Datensätze für das Recordset-Objekt liefert.
Methoden
................................................... Metho den
Standardsteuerelemente
Drag, Move, OLEDrag, Refresh, ShowWhatsThis, UpdateControls, UpdateRecord, ZOrder Methode
Beschreibung
UpdateControls
Überträgt die Werte aus dem aktuellen Datensatz des Recordset-Objekts in die mit dem Datensteuerelement verbundenen Steuerelemente. Der explizite Aufruf dieser Methode ermöglicht es, die Steuerelemente auf die ursprünglichen Werte des Datensatzes zurückzusetzen, wenn die Eingaben des Benutzers verworfen werden sollen.
UpdateRecord
Überträgt die Werte der mit dem Datensteuerelement verbundenen Steuerelemente in den aktuellen Datensatz des Recordset-Objekts und speichert diesen in der Datenbank. Falls das Recordset-Objekt vom Typ Snapshot ist, kann die Methode die Werte nicht zurück in die Datenbank schreiben, sondern synchronisiert die Steuerelemente mittels UpdateControls wieder mit dem ursprünglichen Datensatz.
Ereignisse
................................................... Ereignis s e
DragDrop, DragOver, Error, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Reposition, Resize, Validate Ereignis
Beschreibung
Validate
Tritt auf, bevor der Datensatzzeiger des Recordsets auf einen anderen Datensatz gesetzt wird
Reposition
Tritt auf, nachdem der Datensatzzeiger des Recordsets auf einen anderen Datensatz gesetzt wurde.
Anwendung
................................................... Anwendung
Im Lauf der Zeit hat Microsoft verschiedene Schnittstellenstandards für die datenbankgestützte Programmierung vorgestellt: Data Access Objects (DAO), Remote Data Objects (RDO) und ActiveX Data Objects (ADO). Jede Schnittstelle hat ihre eigene Philosophie, ihre eigene Programmierwelt und – nicht zuletzt – ihr eigenes Datensteuerelement. Traditionell ist das DataSteuerelement für die DAO-Schnittstelle der Microsoft Jet-Engine (bis DAO 3.51) zuständig, während das RemoteData-Steuerelement den rein SQL-orientierten Datenbankzugriff über die ODBC-Schnittstellen-Treiber nach dem Client/Server-Modell abwickelt. Seit Einführung der ActiveX Data Objects und des dazu gehörigen ADO-Steuerelements mit Visual Basic 6.0 empfiehlt Microsoft allerdings die Umstellung auf die ADO-Technologie, da diese nicht nur die anderen beiden Technologien umfasst, sondern auch weiterentwickelt und künftig sogar ersetzen soll. Trotz der Zukunftspläne von Microsoft wird das Data-Steuerelement aber so schnell nicht von der Bildfläche verschwinden; dafür ist es zu bequem und zu weit verbreitet. Datensteuerelemente stellen gewissermaßen den »Königsweg« für die Entwicklung datenbankgestützter Anwendungen dar. Sie können als Datenquellen für andere Steuerelemente (etwa
404
Data- Datensteuerelement (Data)
Beispiel
................................................... Beis piel
Der folgende Code demonstriert den Umgang mit dem Datensteuerelement Data1 anhand des Textfeldes Text1, das zur Entwurfszeit mit diesem gebunden wurde. Ein Klick auf die Schaltfläche FrachtkostenAnzeigen ändert das Recordset der Datenquelle sowie die Datenfeldbindung des Textfeldes.
405
Standardsteuerelemente
TextBox, Image oder ListBox) fungieren und ermöglichen die einfache Steuerung der Datensatzauswahl. Aus Sicht der Programmierung verkapseln sie alles, was mit Datenbankkommunikation als solches zu tun hat. Sie stellen die Verbindung mit dem Datenbanksystem her und kümmern sich um die Abwicklung datenbankbezogener Kommandos. Insbesondere fordern sie Datensatzmengen (Recordsets) an, pflegen Sperren für Datensätze sowie einen Datensatzzeiger und betreiben das Zurückschreiben geänderter Datensätze. Von der äußeren Gestalt her nehmen sich die drei Datensteuerelemente nichts. Von der programmtechnischen Seite her gibt es aber doch einige Unterschiede. Ein Data-Steuerelement muss den Steuerelementen, die es versorgt, bereits zur Entwurfszeit als Datenquelle (DataSource) zugeordnet werden – ein Nachteil, den das ADO-Steuerelement nicht mehr hat. Damit das Datensteuerelement seinen Dienst aufnehmen kann, benötigt es zum einen in der Eigenschaft DataBaseName den Dateinamen der Datenbank, aus der es seine Datensätze beziehen soll, und zum anderen in der Eigenschaft RecordSource eine Spezifikation der zusammenzustellenden Datensatzmenge – jeweils als Wert vom Typ String. Die Aufgabe der Repräsentation der zusammengestellten Datensatzmenge fällt dem Recordset-Objekt des Steuerelements zu. Es kann einen von drei Typen haben, der über die RecordsetType-Eigenschaft spezifiziert wird: Tabelle, Dynaset oder Snapshot. Für ein Recordset-Objekt vom Typ Tabelle setzen Sie RecordsetType auf vbRSTypeTable (0) und RecordSource auf den Namen einer Tabelle, die in der Datenbank als lokale Tabelle oder als eingebundene externe Tabelle bekannt ist. Einer der größten Vorteile dieses Objekttyps ist, dass er die jeweils vorhanden Indizes der Tabellen ausnutzen und damit schneller als die anderen Typen sortieren und filtern kann. Für die Objekttypen Dynaset und Snapshot setzen Sie RecordsetType auf vbRSTypeDynaset (1; Voreinstellung) bzw. auf vbRSTypeSnapshot (2) und RecordSource auf den Namen einer in der Datenbank bekannten Abfrage oder auf eine explizite SQLAnweisung, die eine Datensatzmenge als Ergebnis liefert. Der Unterschied zwischen diesen beiden Objekttypen besteht im Wesentlichen darin, dass ein »Snapshot« eine statische Ansammlung von Datensätzen darstellt, die nach ihrer Zusammenstellung keine Verbindung zu den untergelegten Tabellen mehr unterhält und somit weder eine Aktualisierung der Tabellen ermöglicht noch spätere Aktualisierungen der Tabellen widerspiegelt. Ein »Dynaset« hält die Verbindung mit den untergelegten Tabellen aufrecht und reicht Aktualisierungen (in beiden Richtungen) durch. Das Datensteuerelement baut die Datenbankverbindung auf, sobald es der ersten Aktualisierungsanforderung eines mit ihm verbundenen Steuerelements nachkommen muss. Falls die Datenbankbindung bereits zur Entwurfszeit vollständig spezifiziert wurde, passiert dies gleich beim Laden des Formulars, auf dem die beiden Steuerelemente platziert wurden. Ansonsten sorgt ein expliziter Aufruf der Refresh-Methode dafür. Der weitere Umgang mit dem Datensteuerelement hängt natürlich von der Aufgabenstellung ab. Er ist unkritisch, solange nichts weiter passiert als die Aktualisierung der verbundenen Datenfelder (UpdateControls) oder des aktuellen Datensatzes (UpdateRecord) sowie die Durchsetzung von Gültigkeitsregeln im Rahmen der Validate-Behandlung. Auch eine Änderung des Recordsets (vgl. Beispiel) oder ein Wechsel der Datenbank zur Laufzeit ist nicht schwierig, führt aber bereits in das Fahrwasser der DAO-Programmierung. Weitergehende Kenntnisse im Bereich des Datenbank-Designs sind gefordert, wenn es um die Zusammenstellung von SQLAnweisungen geht, die über reine SELECT-Abfragen hinausgehen.
Standardsteuerelemente
Const Abfrage1 = "SELECT AVG(Frachtkosten) AS Fracht FROM Bestellungen" Private Sub FrachtkostenAnzeigen_Click() Text1.DataField = "" ' Weil RecordSource geändert wird Data1.RecordSource = Abfrage1 Data1.Refresh ' Weil RecordSource geändert wurde Text1.DataField = "Fracht" ' Berechnetes Feld End Sub Verwandte Steuerelemente
Standardsteuerelemente
................................................... Verwandte Steuerelemente Adodc, RemoteData
Figur- Steuerelement (Shape) Shape1 As Shape
Beschreibung
................................................... Bes c hreibung
Das Figur-Steuerelement verkörpert ein grafisches Element, das es ermöglicht, Verzierungen in Form von Steuerelementen auf einem Formular oder Benutzersteuerelement anzubringen. Die Art der Verzierung wird über die Eigenschaft Shape spezifiziert und kann die Form eines Rechtecks, Quadrats, Kreises, Ellipse, Rechtecks mit abgerundeten Ecken oder Quadrats mit abgerundeten Ecken haben. Der Aufzählungstyp ShapeConstants definiert dafür die Konstanten: vbShapeRectangle (0); vbShapeSquare (1); vbShapeCircle (3); vbShapeOval (2); vbShapeRoundedRectangle (4); vbShapeRoundedSquare (5). Die Form kann ausgefüllt oder transparent sein und lässt sich über eine Reihe von Eigenschaften (Linienstil, Linienfarbe, Füllmuster, Füllfarbe etc.) gestalten. Unterbrochene Linien, wie sie ein Wert größer 1 für die BorderStyle-Eigenschaft hervorbringt, zeichnet das Steuerelement allerdings durchgezogen, wenn die BorderWidth-Eigenschaft einen Wert ungleich 1 hat. Eigenschaften
................................................... Eigens c ha ften BackColor, BackStyle, BorderColor, BorderStyle, BorderWidth, Container, DrawMode, FillColor, FillStyle, ForeColor, Height, Index, Left, Name, Parent, Shape, Tag, Visible, Width Methoden
................................................... Metho den Move, Refresh, ZOrder Ereignisse
................................................... Ereignis s e
Keine Anwendung
................................................... Anwendung
Der Umgang mit dem Steuerelement ist unkompliziert, da seine Gestaltung bereits zur Entwurfszeit erfolgen kann und so Ergebnis eines interaktiven Vorgangs ist. Kreise und Rechtecke
406
Kombinationsfeld- Steuerelement ( ComboBox)
könnte man natürlich auch über die Paint-Routine des Parent-Objekts zeichnen, bei den abgerundeten Formen wird es bereits etwas schwieriger. In jedem Fall hilft das Steuerelement, den Code zu reduzieren. Verwandte Steuerelemente
................................................... Verwandte Steuerelemente Line, RptLine, RptShape Verwandte Themen
................................................... Verwandte Them en
Paint-Ereignis (S. 253)
Combo1 As ComboBox
Beschreibung
................................................... Bes c hreibung
Bei dem Kombinationsfeld-Steuerelement handelt es sich um ein Textfeld mit anhängendem Listenfeld. Der Wert des Textfelds (Text) ist gleichzeitig der Standardwert des Steuerelements. Darstellung und Verhalten des Steuerelements richten sich nach der zur Laufzeit schreibgeschützten Style-Eigenschaft. Der Aufzählungstyp ComboBoxConstants definiert dafür drei Konstanten: Konstante (Wert)
Beschreibung
vbComboDropdown (0) (Voreinstellung)
Dropdown-Kombinationsfeld – der Benutzer muss das Listenfeld über die Pfeilschaltfläche des Textfelds aufklappen, um darin eine Auswahl zu treffen. Das Textfeld lässt beliebige Eingaben zu (vgl. Abbildung links).
vbComboSimple (1)
Einfaches Kombinationsfeld – das Listenfeld ist ständig unterhalb des Textfelds sichtbar, und das Textfeld lässt beliebige Eingaben zu (vgl. Abbildung: Mitte).
vbComboDropdownList (2)
Dropdown-Liste – der Benutzer muss das Listenfeld über die Pfeilschaltfläche des Textfelds aufklappen, und das Textfeld nimmt nur Listeneinträge als Eingaben an (vgl. Abbildung rechts).
Vom Textfeld erhält das Steuerelement unter anderem die Eigenschaften DataChanged, Locked, SelLength, SelStart, SelText sowie insbesondere das Changed-Ereignis, und vom Listenfeld stammen die Eigenschaften List, ListCount, ListIndex, Sorted, die Methoden AddItem, Clear, RemoveItem sowie das Scroll-Ereignis – mehr darüber in den Abschnitten »Textfeld-Steuerelement (TextBox)« (S. 427) und »Listenfeld-Steuerelement (ListBox)« (S. 412).
407
Standardsteuerelemente
Kombinationsfeld- Steuerelement (ComboBox)
Standardsteuerelemente
Eigenschaften
................................................... Eigens c ha ften Appearance, BackColor, CausesValidation, Container, DataChanged, DataField, DataFormat, DataMember, DragIcon, DragMode, DataSource, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, List, ListCount, ListIndex, Locked, MouseIcon, MousePointer, Name, NewIndex, OLEDragMode, OLEDropMode, Parent, RightToLeft, SelLength, SelStart, SelText, Sorted, Style, TabIndex, TabStop, Tag, Text, Top, ToolTipText, TopIndex, Visible, WhatsThisHelpID, Width
Standardsteuerelemente
Methoden
................................................... Metho den AddItem, Clear, Drag, Move, OLEDrag, Refresh, RemoveItem, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Change, Click, DblClick, DragDrop, DragOver, DropDown, GotFocus, KeyDown, KeyPress, KeyUp, LostFocus, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Scroll, Validate Anwendung
................................................... Anwendung
Das Einsatzgebiet des Kombinationsfelds ist groß. Wo immer die Eingabe von Text bei vorhandener Nachschlageliste stattfinden soll, ist das Kombinationsfeld die richtige Wahl. Die Pflege und der Umgang mit der Nachschlageliste sieht nicht anders aus als beim Listenfeld. Gleiches gilt auch für das Textfeld, mit dem einzigen Unterschied, dass dieses im Stil Dropdown-Liste jeden Tastenanschlag des Benutzers als Anfangsbuchstabe des auszuwählenden Listeneintrags interpretiert und den ersten passenden Listeneintrag als Wert übernimmt. Eine Wiederholung des Tastenanschlags ändert die Auswahl in den gegebenenfalls nächsten passenden Listeneintrag mit dem gleichen Anfangsbuchstaben. Das Textfeld sowie die Listeneinträge sind auf eine Länge von 1024 Zeichen beschränkt. Zur Auswertung der Benutzereingaben implementieren Sie am besten Behandlungsroutinen für die Ereignisse LostFocus und/oder Validate. Beispiel
................................................... Beis piel
Die folgende LostFocus-Behandlung sorgt dafür, dass sich das Kombinationsfeld Combo1 in seiner Liste immer die letzten fünf unterschiedlichen Eingaben merkt. Const MaxElements = 5 Private Sub Combo1_LostFocus() For i = 0 To Combo1.ListCount – 1 If Combo1.List(i) = Combo1 Then Exit Sub Next i Combo1.AddItem Combo1, 0 If Combo1.ListCount >= MaxElements + 1 Then Combo1.RemoveItem Combo1.ListCount – 1 End If End Sub Verwandte Steuerelemente
................................................... Verwandte Steuerelemente DirListBox, DriveListbox, ImageCombo, ListBox, TextBox
408
Kontrollkästchen- Steuerelement (CheckBox)
Kontrollkästchen- Steuerelement (CheckBox) Check1 As CheckBox
Beschreibung
................................................... Bes c hreibung
Eigenschaften
................................................... Eigens c ha ften Alignment, Appearance, BackColor, Caption, CausesValidation, Container, DataChanged, DataField, DataFormat, DataMember, DataSource, DisabledPicture, DownPicture, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, MaskColor, MouseIcon, MousePointer, Name, OLEDragMode,OLEDropMode, Parent, Picture, RightToLeft, Style, TabIndex, TabStop, Tag, ToolTipText, Top, UseMaskColor, Value, Visible, WhatsThisHelpID, Width Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Click, DragDrop, DragOver, GotFocus, KeyDown, KeyUp, KeyPress, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Validate Anwendung
................................................... Anwendung
Ursprüngliche Bestimmung dieses Steuerelements ist die optische Repräsentation von Werten des Typs Boolean. Zwischen diesen beiden Werten schaltet das Steuerelement auch hin und her, wenn der Benutzer mit der Maus darauf klickt. Inzwischen hat sich das Steuerelement durch Hinzunahme eines dritten Werts zu einem TriState-Steuerelement gemausert. Mit welcher Interpretation Sie den dritten Wert, der nur vom Programmcode aus gesetzt werden kann, versehen, bleibt Ihnen überlassen. Von der Intuition her steht der dritte Zustand für ein »Jein«. Gängige Interpretationen sind: »Standardeinstellung wird übernommen«, »Nicht alle abhängigen Optionen sind angekreuzt«, »Zustand hat keine Wirkung«. Jede Änderung der Value-Eigenschaft, gleich ob mit der Maus oder vom Programmcode aus, bringt das Click-Ereignis hervor. Da Value die Standardeigenschaft des CheckBox-Objekts ist, muss nur der Objektbezeichner notiert werden, um diese Eigenschaft anzusprechen. Um eine Zugriffstaste für das Steuerelement zu vereinbaren, stellen Sie dem entsprechenden Buchstaben in der Beschriftung (Caption) das Zeichen »&« voran. Er wird zur Laufzeit durch Unterstreichung kenntlich gemacht. Das Kontrollkästchen kennt zwei unterschiedliche Darstellungen: die Standarddarstellung im Stil von Windows 9x (vgl. Abbildung) und eine benutzerdefinierte Darstellung. Die Style-
409
Standardsteuerelemente
Das Kontrollkästchen-Steuerelement visualisiert die Funktion eines Schalters. Es besteht aus einem Kästchen, das sich mit einem Häkchen versehen (»ankreuzen«) lässt, sowie einer Beschriftung. Für die Standardeigenschaft Value des Objekts sind drei Werte definiert: vbFalse (0), vbTrue (1) und vbUseDefault (2).
Standardsteuerelemente
Standardsteuerelemente
Eigenschaft entscheidet darüber, welche der Darstellungen zur Anzeige kommt. In der benutzerdefinierten Darstellung sieht das Kontrollkästchen zunächst wie eine Befehlsschaltfläche aus, hält aber im Gegensatz zu dieser den gedrückten Zustand bis zum nächsten Mausklick. Um dem Steuerelement ein benutzerdefiniertes Aussehen zu verleihen, können Sie den Eigenschaften Picture und DownPicture sowie gegebenenfalls DisabledPicture geeignete Bilder zuordnen. Falls Sie eine pseudotransparente Darstellung wünschen, bei der die über eine Transparenzfarbe (MaskColor) definierten transparenten Bereiche der Bilder in Hintergrundfarbe erscheinen, müssen Sie die Eigenschaft UseMaskColor auf True setzen. (Ein analoges Beispiel für Schaltflächen findet sich im Abschnitt »DisabledPicture-Eigenschaft«, S. 341.) In Datenbankanwendungen lässt sich das Steuerelement über seine Data-Eigenschaften an ein Feld des Typs Boolean binden. Beispiel
................................................... Beis piel
Der folgende Code arbeitet mit einer Befehlsschaltfläche Command1 und einem Kontrollkästchen Check1. Jeder Klick auf die Schaltfläche oder auf das Kontrollkästchen ändert den Zustand des Kontrollkästchens. Der TriState-Zustand lässt sich nur über die Schaltfläche hervorbringen. Private Sub Check1_Click() MsgBox "klicke de klicke de klick" End Sub Private Sub Command1_Click() Check1 = (Check1 + 1) Mod 3 End Sub Verwandte Steuerelemente
................................................... Verwandte Steuerelemente Button, CommandButton, OptionButton
Laufwerklistenfeld- Steuerelement (DriveListBox) Drive1 As DriveListBox
Beschreibung
................................................... Bes c hreibung
Das Laufwerklistenfeld-Steuerelement ermöglicht die Auswahl eines logischen Laufwerks des Systems. Standardeigenschaft des Steuerelements ist Drive, eine Zeichenfolge, die den ausgewählten Texteintrag wiedergibt. Ändert sich die Standardeigenschaft aufgrund einer Benutzerinteraktion, tritt das Ereignis Change auf. Eigenschaften
................................................... Eigens c ha ften Appearance, BackColor, CausesValidation, Container, DragIcon, DragMode, Drive, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, List, ListCount, ListIndex, MouseIcon, MousePointer, Name, OLEDragMode, OLEDropMode, Parent, TabIndex, TabStop, Tag, Top, ToolTipText, TopIndex, Visible, WhatsThisHelpID, Width
41 0
Linie- Steuerelement (Line)
Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Change, DragDrop, DragOver, DropDown, GotFocus, KeyDown, KeyPress, KeyUp, LostFocus, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Scroll, Validate Anwendung
................................................... Anwendung
Beispiel
................................................... Beis piel
Der folgende Code zeigt, wie einfach die Synchronisation zwischen Laufwerklistenfeld, Verzeichnislistenfeld und Dateilistenfeld ist: Private Sub Dir1_Change() File1 = Dir1 ' File1.Path = Dir1.Path End Sub Private Sub Drive1_Change() Dir1 = Drive1 ' Dir1.Path = Drive1.Drive End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
DirListBox, FileListBox, ImageCombo, ListBox, TextBox
Linie- Steuerelement (Line) Line1 As Line Beschreibung
................................................... Bes c hreibung
Das Linie-Steuerelement verkörpert ein grafisches Element, das es ermöglicht, Linienverzierungen auf einem Formular oder Benutzersteuerelement anzubringen. Das Erscheinungsbild der Linie wird durch die Eigenschaften BorderColor, BorderStyle, BorderWidth und DrawMode bestimmt, die Endpunkte im Koordinatensystem des Containers durch die Eigenschaften X1, Y1, X2, Y2. Unterbrochene Linien, wie sie ein Wert größer 1 für die BorderStyle-Eigenschaft hervorbringt, kennt das Steuerelement nur, wenn die BorderWidth-Eigenschaft den Wert 1 hat. Eigenschaften
................................................... Eigens c ha ften BorderColor, BorderStyle, BorderWidth, Container, DrawMode, Parent, Tag, Visible, X1, X2, Y1, Y2
41 1
Standardsteuerelemente
Genau genommen müsste dieses Steuerelement die Bezeichnung »DriveCombo« tragen, da es nicht vom Listenfeld abstammt, sondern vom Kombinationsfeld- bzw. ImageCombo-Steuerelement. Die Standardeigenschaft Drive lässt sich ohne Nachbearbeitung direkt der Standardeigenschaft Path eines DirListBox-Steuerelements zuweisen, da dieses Steuerelement (genau wie das DriveListBox-Steuerelement) den Laufwerksbuchstaben automatisch extrahiert (sofern ein Leerzeichen und ein Text in eckigen Klammern folgen) und auf das für dieses Laufwerk geltende aktuelle Verzeichnis umschaltet. Die Standardeigenschaft Path eines Verzeichnislistenfelds lässt sich wiederum in die Path-Eigenschaft eines Dateilistenfelds übernehmen, so dass sich die drei Steuerelemente über eine einfache Aktualisierungskette bequem synchronisieren lassen.
Standardsteuerelemente
Methoden
................................................... Metho den Refresh, ZOrder Ereignisse
................................................... Ereignis s e
Keine Anwendung
Standardsteuerelemente
................................................... Anwendung
Der Umgang mit dem Steuerelement ist unkompliziert, da seine Gestaltung bereits zur Entwurfszeit erfolgen kann und so Ergebnis eines interaktiven Vorgangs ist. Natürlich könnte man Linien mit den Eigenschaften des Steuerelements auch über die Paint-Routine des ParentObjekts zeichnen, doch die Verwendung des Steuerelements ist zumindest für statische Linien, die als Verzierung gedacht sind, erheblich einfacher und spart zudem Code. Verwandte Steuerelemente
................................................... Verwandte Steuerelemente Shape, RptShape Verwandte Themen
................................................... Verwandte Them en
Paint-Ereignis (S. 253)
Listenfeld- Steuerelement (ListBox) List1 As ListBox
Beschreibung
................................................... Bes c hreibung
Das Listenfeld-Steuerelement zeigt eine Liste mit Texteinträgen an, in der ein Benutzer seine Auswahl treffen kann. Wird die Sorted-Eigenschaft zur Entwurfszeit auf True gesetzt, fügt das Steuerelement neue Einträge in aufsteigender alphabetischer Ordnung in die über die ListEigenschaft zugängliche Liste ein (und zeigt sie auch so an). Je nach Wert der MultiSelectEigenschaft erlaubt das Listenfeld die Einfach- oder Mehrfachauswahl von Einträgen. Standardeigenschaft des Steuerelements ist Text. Sie ist vom Typ String und hat immer den Wert des zuletzt markierten Listenelements. Zur Laufzeit gibt die ListIndex-Eigenschaft immer die Position des zuletzt markierten Eintrags in der Liste wieder. Eigenschaften
................................................... Eigens c ha ften Appearance, BackColor, CausesValidation, Columns, Container, DataChanged, DataField, DataFormat, DataMember, DataSource, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, IntegralHeight, ItemData, Left, List, ListCount, ListIndex, MouseIcon, MousePointer, MultiSelect, Name, NewIndex, OLEDragMode, OLEDropMode, Parent, RightToLeft, Selected, SelCount, Sorted, Style, TabIndex, TabStop, Tag, Text, Top, ToolTipText, TopIndex, Visible, WhatsThisHelpID, Width
41 2
Listenfeld- Steuerelement ( ListBox)
Beschreibung
Columns
Integer-Wert, der bestimmt, welche Art von Bildlauf das Listenfeld unter Anzeige der entsprechenden Bildlaufleisten durchführt – horizontal oder vertikal – und in wie viele Spalten es seine Anzeige aufteilt. Voreinstellung ist der Wert 0 für den vertikalen Bildlauf, jeder andere Wert größer 0 hat den horizontalen Bildlauf zur Folge und bestimmt die Spaltenanzahl (vgl. in der Abbildung links und Mitte). Die Eigenschaft kann zur Laufzeit nur verändert werden, wenn sie zur Entwurfszeit auf einen Wert größer 0 gesetzt wurde.
IntegralHeight
Boolean-Wert, der bestimmt, ob das Steuerelement Einträge am unteren Ende abschneiden kann (False) oder ob es nur vollständige Einträge anzeigt (True; Voreinstellung)
ItemData
Long-Array, das es ermöglicht, jedem Eintrag einen benutzerdefinierten Long-Wert zuzuordnen – etwa für die Indizierung von Elementen in anderen Listen oder Arrays
List
Objekt, das die Listeneinträge speichert und den Zugriff darauf nach dem Prinzip des Array-Zugriffs ermöglicht. Die Array-Elemente lassen sich als Rechts- und Linkswerte verwenden, das List-Objekt selbst jedoch weder noch. Die Methoden AddItem und RemoveItem erweitern bzw. verkürzen die Liste, und Clear löscht sie.
ListCount
Integer-Wert, der ausdrückt, wie viele Einträge die Liste enthält
ListIndex
Integer-Wert, der den Index des zuletzt ausgewählten Listeneintrags wiedergibt
MultiSelect
Zur Laufzeit schreibgeschützter Integer-Wert, der bestimmt, ob der Benutzer nur einen einzelnen Eintrag (vbMultiSelectNone = 0), einen Block von Einträgen (vbMultiSelectSimple = 1) oder mehrere einzelne Einträge bzw. Blöcke (vbMultiSelectExtended = 2) auswählen kann
NewIndex
Zur Laufzeit schreibgeschützter Integer-Wert, der wiedergibt, welches Element als letztes in die Liste eingefügt wurde
SelCount
Integer-Wert, der ausdrückt, wie viele Einträge der Benutzer markiert hat
Selected
Boolean-Array, dessen Elemente den einzelnen Einträgen in der Liste zugeordnet sind und beschreiben, ob der zugehörige Listeneintrag markiert ist (True) oder nicht (False). Hat Style den Wert vbListBoxCheckBox (1), bestimmt diese Eigenschaft, ob das Kontrollkästchen des Eintrags ein Häkchen enthält.
Sorted
Zur Laufzeit schreibgeschützter Boolean-Wert, der bestimmt, ob das Listenfeld seine Einträge aufsteigend sortiert (True) oder nicht (False). Deutsche Umlaute werden nicht richtig eingeordnet, da das Steuerelement ungeachtet der Ländereinstellungen die amerikanische Sortierordnung verwendet. Beachten Sie auch, dass der Aufruf der AddItem-Methode bei expliziter Angabe eines Index die Sortierung durcheinander bringen kann.
Style
Zur Laufzeit schreibgeschützter Integer-Wert, der bestimmt, ob vor den Einträgen der Liste Kontrollkästchen erscheinen (vbListBoxStandard = 0; Voreinstellung) oder nicht (vbListBoxCheckBox = 1). Wenn diese Eigenschaft auf 1 gesetzt ist, muss die MultiSelect-Eigenschaft den Wert 0 haben (vgl. in der Abbildung links und rechts).
41 3
Standardsteuerelemente
Eigenschaft
Standardsteuerelemente
Standardsteuerelemente
Eigenschaft
Beschreibung
TopIndex
Integer-Wert, der den Index des Eintrags bestimmt, welcher als oberstes Element in der vertikal orientierten (Columns = 0) Liste erscheint – vorausgesetzt, es folgen noch genügend Einträge, die den sichtbaren Teil des Listenfensters füllen. Hat die Columns-Eigenschaft einen Wert größer 0, bewirkt die TopIndex-Eigenschaft nur, dass das entsprechende Element sicher angezeigt wird, es ist im Allgemeinen aber nicht der oberste Eintrag in der Darstellung.
Methoden
................................................... Metho den AddItem, Clear, Drag, Move, OLEDrag, Refresh, RemoveItem, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Click, DblClick, DragDrop, DragOver, GotFocus, ItemCheck, KeyDown, KeyPress, KeyUp, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Scroll, Validate Anwendung
................................................... Anwendung
Das Listenfeld-Steuerelement visualisiert den Inhalt eines Zeichenfolgenarrays und ermöglicht, je nach Wert der MultiSelect-Eigenschaft, die Auswahl einer oder mehrerer Zeichenfolgen durch einfaches Markieren mit der Maus oder der Tastatur. Wurde die Style-Eigenschaft beim Entwurf auf »1 – Kontrollkästchen« gesetzt (was erfordert, dass MultiSelect den Wert 0 hat), geschieht die Auswahl über das Setzen von Häkchen in die links neben den Listeneinträgen erscheinenden Kontrollkästchen. Dieser Modus erlaubt grundsätzlich die Mehrfachauswahl. Um die Liste zu erweitern oder zu verkürzen, benutzen Sie die Methoden AddItem und RemoveItem. Die Clear-Methode löscht die gesamte Liste. Die Prototypen dieser Methoden lauten: Sub Objekt.AddItem (Eintrag As String[, Index As Integer]) Sub Objekt.RemoveItem (Index As Integer) Sub Objekt.Clear
Fehlt der Parameter Index beim Aufruf von AddItem, hängt die Methode einen neuen Eintrag in Abhängigkeit von der Sorted-Eigenschaft als letztes Element an die unsortierte Liste oder sortiert ihn ein. Ist ein Index spezifiziert, fügt die Methode das neue Element an der Position Index ein und verschiebt die nachfolgenden Einträge um eine Position nach hinten, ohne Rücksicht auf eine gegebenenfalls bestehende Sortierung. Die Angabe der Position 0 bewirkt, dass der neue Eintrag zum ersten Element in der Liste wird. Zugänglich werden die Einträge über die List-Eigenschaft. Der Zugriff erfolgt wie bei einem Zeichenfolgenarray unter Angabe eines nullbasierten Indexwerts – »en bloc«-Zuweisungen, bei denen die List-Eigenschaft selbst als Linkswert oder als Rechtswert auftritt, sind jedoch nicht möglich. Über die Eigenschaft ListCount erfahren Sie, wie viele Elemente die Liste hat. Laut Voreinstellung hat die MultiSelect-Eigenschaft den Wert »0 – Kein«, so dass der Benutzer zu einem Zeitpunkt immer nur einen Eintrag markieren kann. Die Reaktion auf Benutzereingaben ist in diesem Fall über die Click-Behandlung möglich, da das Steuerelement dieses Ereignis grundsätzlich bei jeder Änderung der Markierung signalisiert, gleich ob diese auf das Konto der Maus oder der Tastatur geht. Wenn Sie wollen, dass der Benutzer mehrere Einträge im Listenfeld auswählen kann, setzen Sie MultiSelect auf 1 oder 2. Die Analyse der Auswahl des Benutzers wird dann meist im Zuge der
41 4
OLE- Container- Steuerelement (OLE)
Beispiel
................................................... Beis piel
Der folgende Code initialisiert ein Listenfeld List1 mit den Namen der auf dem System installierten Schriften und zeigt das Bezeichnungsfeld Label1 in der jeweils ausgewählten Schrift an. Private Sub Form_Load() For i = 0 To Screen.FontCount List1.AddItem Screen.Fonts(i) Next End Sub Private Sub List1_Click() Label1.FontName = List1.Text End Sub Verwandte Steuerelemente
................................................... Verwandte Steuerelemente ComboBox, CommonDialog, DirListBox, DriveListBox, ImageCombo, ListView
OLE- Container- Steuerelement (OLE) OLE1 As OLE Beschreibung
................................................... Bes c hreibung
Das OLE-Container-Steuerelement eröffnet einem Visual-Basic-Programm die gesamte Funktionalität OLE-fähiger Anwendungen. Es fungiert als Container für OLE-Objekte und kann verknüpfte oder eingebettete Objekte darstellen und für die Bearbeitung aktivieren. Bei einem verknüpften Objekt arbeitet das Steuerelement nur mit einem Verweis auf den Speicherort für das Objekt und kommt mit dessen aktuellen Datenstrukturen überhaupt nicht in Berührung. Für seine Darstellung im Fenster des Steuerelements liefert das Objekt ein im Metafile-Format gehaltenes Bild, und die Bearbeitung kann nur in einem Fenster der für das Objekt zuständigen OLE-Quellanwendung stattfinden. Zudem speichert die Methode SaveToFile nur die Verknüpfungsinformation, das Objekt selbst muss von der Quellanwendung aus gespeichert werden.
41 5
Standardsteuerelemente
Behandlung von Validate oder LostFocus vorgenommen. Sie beinhaltet die Auswertung des Boolean-Arrays Selected (Basis 0), das so viele Elemente hat, wie es Einträge im Listenfeld gibt, und für jedes Element die Zugehörigkeit zur aktuellen Auswahl anzeigt – True bedeutet: das Element gehört zur Auswahl. Die zugehörigen Einträge lassen sich unter dem jeweiligen Index über die List-Eigenschaft gewinnen. Der Wert von SelCount informiert darüber, wie viele Einträge markiert sind. Ein Listenfeld-Steuerelement blendet automatisch eine Bildlaufleiste ein, wenn nicht alle Einträge im Listenfenster auf einmal darstellbar sind (vgl. Abbildung). Wurde die Columns-Eigenschaft beim Entwurf auf 0 gesetzt, führt das Steuerelement einen vertikalen Bildlauf durch. Dabei pflegt es die Eigenschaft TopIndex, so dass deren Wert immer den Index des zuoberst gelegenen Eintrags wiedergibt. Indem Sie diese Eigenschaft auf die Position eines bestimmten Eintrags setzen, erzwingen Sie einen entsprechenden Bildlauf. An spezifischen Ereignissen signalisiert das Steuerelement: ItemCheck und Scroll. ItemCheck kann nur auftreten, wenn die Style-Eigenschaft auf 1 gesetzt wurde. Das Ereignis hat einen Integer-Parameter, der die Position eines Listeneintrags ausdrückt und besagt, dass der Benutzer das Kontrollkästchen des Eintrags gesetzt oder gelöscht hat. Das parameterlose ScrollEreignis tritt auf, wenn der Benutzer oder das Setzen der TopIndex-Eigenschaft einen Bildlauf verursacht hat.
Standardsteuerelemente
Standardsteuerelemente
Ein eingebettetes Objekt ist dagegen mit allen seinen Datenstrukturen im OLE-Container enthalten und kann von diesem beispielsweise auch komplett mittels SaveToFile gespeichert werden. Für die Bearbeitung des Objekts stehen zwei Modi zur Auswahl: die Bearbeitung in einem Fenster der OLE-Quellanwendung und die Vorortbearbeitung im Fenster des OLE-ContainerSteuerelements. Im ersten Modus, der mit dem Verb Öffnen (-2) aktiviert wird, erhält der Benutzer ein neues Fenster der Quellanwendung mit dem Objekt und kann dieses darin bearbeiten und gegebenenfalls sogar (ohne Auswirkung auf das Objekt im Steuerelement) als Kopie extern speichern. Wenn er das Fenster schließt, übernimmt das Steuerelement im Allgemeinen automatisch alle vorgenommenen Änderungen und zeigt diese auch an. Im zweiten Modus, der mit dem Verb Bearbeiten (-1) – und meist auch mit dem Standardverb – aktiviert wird, kann der Benutzer das Objekt vor Ort, das heißt im Fenster des Steuerelements, bearbeiten, wobei die OLE-Quellanwendung die Kontrolle über das Fenster des Steuerelements übernimmt, sein Menü im Formular anzeigt usw. (vgl. Abbildung). Eigenschaften
................................................... Eigens c ha ften Action, Appearance, AppIsRunning, AutoActivate, AutoVerbMenu, BackColor, BorderStyle, CausesValidation, Class, Container, Data, DataChanged, DataField, DataText, DisplayType, DragIcon, DragMode, Enabled, FileNumber, Format, ForeColor, Height, HelpContextID, HostName, hWnd, Index, Left, lpOleObject, MiscFlags, MouseIcon, MousePointer, Name, Object, ObjectAcceptFormats, ObjectAcceptFormatsCount, ObjectGetFormats, ObjectGetFormatsCount, ObjectVerbFlags, ObjectVerbs, ObjectVerbsCount, OLEDropAllowed, OLEType, OLETypeAllowed, Parent, PasteOK, Picture, SizeMode, SourceDoc, SourceItem, TabIndex, TabStop, Tag, Top, UpdateOptions, Verb, Visible, WhatsThisHelpID, Width
41 6
OLE- Container- Steuerelement (OLE)
Eigenschaft
Beschreibung
Action
Integer-Wert, der eine Operation des Steuerelements auslöst, sobald er gesetzt wird. Die Aktivierung von Operationen über die Action-Eigenschaft unterstützt das Steuerelement nur noch zum Erhalt der Kompatibilität. Inzwischen steht für jede Operation eine Methode zur Verfügung. Folgende Werte lösen folgende Operationen aus (in Klammern die äquivalente Methode): 0 (CreateEmbed) Eingebettetes Objekt erstellen (SourceDoc benennt gegebenenfalls eine Datei, Class den Objekttyp) Verknüpftes Objekt aus dem Inhalt einer Datei erstellen (SourceDoc benennt Datei, SourceItem gegebenenfalls Element/Bereich innerhalb des Objekts)
4 (Copy)
Objekt in Zwischenablage kopieren
5 (Paste)
Kopie des Objekts in Zwischenablage in Steuerelement einfügen
6 (Update)
Darstellung des Objekts (als Bitmap) im Steuerelement aktualisieren
7 (DoVerb)
Objekt für Operation öffnen (Verb spezifiziert Operation)
9 (Close)
Objekt schließen und Verbindung mit OLE-Server-Anwendung trennen
10 (Delete)
Objekt löschen und von diesem belegte Ressourcen freigeben
11 (SaveToFile)
Objekt in der geöffneten Binärdatei mit der Dateinummer FileNumber speichern
12 (ReadFromFile)
Objekt aus der geöffneten Binärdatei mit der Dateinummer FileNumber laden
14 (InsertObjDlg)
Dialog OBJEKT EINFÜGEN ausführen
15 (PasteSpecialDlg) Dialog EINFÜGEN ausführen 17 (FetchVerbs)
ObjectVerbs und ObjectVerbsCount aktualisieren
18 (SaveToOle1File) Objekt im OLE-1.0-Format in geöffneter Binärdatei mit Dateinummer FileNumber speichern AppIsRunning
Boolean-Wert, der eine Aussage darüber macht, ob die für das im Container enthaltene OLE-Objekt zuständige Quellanwendung in Ausführung ist (True) oder nicht (False). Ein Setzen der Eigenschaft bewirkt, dass die Anwendung explizit gestartet bzw. beendet wird.
AutoActivate
Integer-Wert, der bestimmt, auf welche Art das im Container enthaltene OLE-Objekt (sowie die dafür zuständige Server-Anwendung) aktiviert wird. Der Aufzählungstyp VBOLEContainerConstants definiert dafür die Konstanten: vbOLEActivateManual (0) Das Objekt lässt sich nur vom Code aus durch Aufruf der DoVerb-Methode aktivieren.
41 7
Standardsteuerelemente
1 (CreateLink)
Standardsteuerelemente
Eigenschaft
Beschreibung
AutoActivate (Forts.)
vbOLEActivateGetFocus (1)
Standardsteuerelemente
vbOLEActivateDoubleclick (2)
vbOLEActivateAuto (3)
Falls das Objekt die Aktivierung per Mausklick unterstützt, wird es automatisch aktiviert, sobald das OLE-Steuerelement den Fokus erhält. (Voreinstellung) Das Objekt wird durch einen Doppelklick oder (falls das OLE-Steuerelement den Fokus besitzt) durch die Taste (Eingabe) aktiviert. Das OLE-Steuerelement sieht das DblClick-Ereignis nicht! Das Objekt wird automatisch aktiviert, wenn das OLE-Steuerelement den Fokus erhält oder der Benutzer in das Steuerelement doppelklickt. (Das OLE-Steuerelement sieht das DblClick-Ereignis nicht!)
AutoVerbMenu
Boolean-Wert, der bestimmt, ob das Objekt auf einen rechten Mausklick hin ein Kontextmenü mit den für es definierten Verben (lies: Befehlen) anzeigt (True; Voreinstellung) oder nicht (False)
Class
Zeichenfolge, die den Klassennamen des eingebetteten Objekts zurückgibt
Data
Long-Wert als Handle für Speicherobjekt, das für die Datenübermittlung im spezifizierten Format (Format-Eigenschaft) herangezogen wird
DataText
Zeichenfolge, die als bidirektionaler Puffer für die textorientierte Kommunikation mit dem OLE-Objekt fungiert
DisplayType
Integer-Wert, der angibt, ob das OLE-Objekt als Inhalt (vbOLEDisplayContent = 0; Voreinstellung) oder als Symbol (vbOLEDisplayIcon = 1) im Steuerelement angezeigt wird. Der Wert dieser Eigenschaft bestimmt die Voreinstellung des Kontrollkästchens ALS SYMBOL ANZEIGEN in den Dialogfeldern INHALTE EINFÜGEN und OBJEKT EINFÜGEN, wenn diese zur Laufzeit mittels der Methoden InsertObjDlg bzw. PasteSpecialDlg angezeigt werden. Falls Sie ein OLE-Objekt mit den Methoden CreateEmbed oder CreateLink zur Laufzeit erstellen, legen Sie mit der DisplayType-Eigenschaft (unwiderruflich) fest, ob das Objekt als Inhalt oder als Symbol im Steuerelement angezeigt werden soll.
FileNumber
Integer-Wert, der für die Werte 11, 12, 18 der Action-Eigenschaft die Dateinummer einer im binären Modus geöffneten Datei spezifiziert. Wird nur von Action verwendet, die Methoden SaveToFile, ReadFromFile, SaveToOle1 machen davon keinen Gebrauch.
Format
Zeichenfolge, die das Datenformat für den Versand oder Erhalt objektspezifischer Daten beschreibt. Die als nullbasierte Zeichenfolgen-Arrays definierten Eigenschaften ObjectAcceptFormats (Empfang) und ObjectGetFormats (Versand) stellen die von dem jeweiligen Objekttyp unterstützten Formate zur Auswahl.
HostName
Zeichenfolge, die auf den Namen der Visual-Basic-Anwendung gesetzt werden kann, um der OLE-Quellanwendung die Ausgabe dieses Namens in der Titelleiste zu ermöglichen (was jedoch nicht alle OLE-Server tun)
LpOLEObject
Adresse des OLE-Objekts (wird von verschiedenen in ActiveX-DLLs gelegenen Routinen verlangt)
41 8
OLE- Container- Steuerelement (OLE)
Beschreibung
MiscFlags
Integer-Wert, der als Bitvektor generelle Verhaltensattribute des OLEObjekts steuert. Das Bit vbOLEMiscFlagMemStorage (1) verhindert, dass das Objekt nur im Hauptspeicher und nicht in einer temporären Datei gespeichert wird, und das Bit vbOLEMiscFlagDisableInPlace (2) bewirkt, dass das Objekt keine Vorortbearbeitung im Fenster des Steuerelements unterstützt.
ObjectAcceptFormatsCount
Schreibgeschützter Integer-Wert, der die Elementanzahl der Eigenschaft ObjectAcceptFormats wiedergibt
ObjectGetFormats
Schreibgeschütztes Zeichenfolgen-Array (nullbasiert), dessen Elemente die Bezeichnungen der von dem OLE-Objekt lieferbaren Datenformate wiedergeben. Für ein Bitmap-Objekt sind das beispielsweise: »CF_METAFILEPICT«, »CF_DIB«; »CF_BITMAP"
ObjectGetFormatsCount
Schreibgeschützter Integer-Wert, der die Elementanzahl der Eigenschaft ObjectGetFormats wiedergibt
ObjectVerbFlags
Long-Array mit Bitvektoren, die die Anzeigezustände der im Array ObjectVerbs enthaltenen Menüeinträge beschreiben. Der Aufzählungstyp VBOLEContainerConstants definiert dafür die Flags: vbOLEFlagGrayed (1) Menüelement ist abgeblendet vbOLEFlagDisabled (2)
ObjectVerbs
Menüelement ist deaktiviert
vbOLEFlagChecked (8)
Menüelement trägt Häkchen
vbOLEFlagSeparator (2048)
Menüelement ist Trennlinie
schreibgeschütztes Zeichenfolgen-Array (nullbasiert), dessen Elemente die Menüeinträge für die von dem Objekt (im jeweiligen Zustand) unterstützten Verben (lies: Kommandos) darstellen. OLE-Objekte unterstützen darüber hinaus eine Reihe von Standardverben, die eine Entsprechung durch einen Menüeintrag haben können, aber nicht müssen. Der Aufzählungstyp VBOLEContainerConstants definiert dafür die Konstanten: vbOLEPrimary (0) Standardaktion des Objekts vbOLEShow (-1)
Objekt wird zum Bearbeiten angezeigt und aktiviert (nach Möglichkeit für die Vorortbearbeitung)
vbOLEOpen (-2)
Öffnet Objekt in separatem Fenster der OLEQuellanwendung
vbOLEHide (-3)
bei eingebetteten Objekten wird die OLE-Quellanwendung ausgeblendet
vbOLEUIActivate (-4)
Aktiviert die Benutzeroberfläche der OLE-Quellanwendung des Objekts (nach Möglichkeit für die Vorortbearbeitung in der Zielanwendung)
vbOLEInPlaceActivate (-5)
Macht das Objekt für die Vorortberarbeitung verfügbar, so dass der Benutzer in das Objekt klicken und es sofort bearbeiten kann
vbOLEDiscardUndoState (-6) Bringt die OLE-Quellanwendung des Objekts dazu, alle gespeicherten Bearbeitungsschritte rückgängig zu machen
41 9
Standardsteuerelemente
Eigenschaft
Standardsteuerelemente
Eigenschaft
Beschreibung
ObjectVerbsCount
Schreibgeschützter Integer-Wert, der die Elementanzahl der Eigenschaft ObjectVerbs wiedergibt
OLEDropAllowed Boolean-Wert, der bestimmt, ob das Steuerelement das Ablegen von Objekten im Rahmen von OLE-Drag&Drop-Operationen in seinem Fenster erlaubt (True) oder nicht (False)
Standardsteuerelemente
OLEType
Schreibgeschützter Integer-Wert, der eine Aussage über das im Steuerelement befindliche Objekt macht. vbOLELinked (0) Objekt ist verknüpft vbOLEEmbedded (1) Objekt ist eingebettet vbOLENone (3) Steuerelement enthält kein Objekt
OLETypeAllowed Integer-Wert, der bestimmt, welche Art von OLE-Objekten das Steuerelement unterstützt. vbOLELinked (0) verknüpfte OLE-Objekte vbOLEEmbedded (1) eingebettete OLE-Objekte vbOLEEither (2) beide Arten (der Befehl EINFÜGEN sollte mittels PasteSpecialDlg das Dialogfeld EINFÜGEN aufrufen) PasteOK
Boolean-Wert, der bestimmt, ob der Inhalt der Zwischenablage in das Steuerelement eingefügt werden kann (True) oder nicht (False) (Der Aktivierungszustand des Menübefehls EINFÜGEN sollte sich nach dem Wert dieser Eigenschaft richten.)
SizeMode
Integer-Wert, der den Zusammenhang zwischen den Abmessungen des Steuerelements und denen des OLE-Objekts festlegt. vbOLESizeClip (0) OLE-Objekt wird in der originalen Größe angezeigt, die Darstellung wird jedoch am Rand des Steuerelements beschnitten (Voreinstellung) vbOLESizeStretch (1) Darstellung des OLE-Objekts wird gestreckt oder gestaucht (und dabei gegebenenfalls verzerrt), damit sie den Fensterbereich des Steuerelements vollständig ausfüllt vbOLESizeAutoSize (2) Abmessungen des Steuerelements werden automatisch an die orignale Größe des OLE-Objekts angepasst (das Steuerelement-Objekt erhält ein Resize-Ereignis!) vbOLESizeZoom (3) Darstellung des OLE-Objekts wird gestreckt oder gestaucht (dabei jedoch nicht verzerrt), damit sie den Fensterbereich des Steuerelements möglichst vollständig ausfüllt
SourceDoc
Zeichenfolge, die für den Wert 1 der Action-Eigenschaft (Objekt verknüpfen) den Dateinamen der Verknüpfung bereitstellt und für den Wert 0 (Objekt einbetten) den Dateinamen der Datei mit dem einzubettenden OLE-Objekt. Im Zusammenhang mit den inzwischen verfügbaren Methoden CreateLink bzw. CreateEmbed hat der Wert von SourceDoc jedoch keine Bedeutung mehr. Zur Laufzeit gibt die SourceItem-Eigenschaft eine leere Zeichenfolge zurück, während die SourceDoc-Eigenschaft den vollständigen Pfad zu der verknüpften Datei, gefolgt von einem Ausrufezeichen (!) und dem Wert des SourceItem-Parameters enthält. Beispiel: "C:\MeinText!Textmarke1"
420
OLE- Container- Steuerelement (OLE)
Beschreibung
SourceItem
Zeichenfolge, die für den Wert 1 der Action-Eigenschaft (Objekt verknüpfen) das einzufügende Element (bzw. Elementbereich) des Objekts benennt, ansonsten (insbesondere im Zusammenhang mit den inzwischen verfügbaren Methoden CreateLink bzw. CreateEmbed) jedoch keine Funktion mehr hat (vgl. SourceDoc)
UpdateOptions
Integer-Wert, der bestimmt, wie ein verknüpftes Objekt aktualisiert wird, wenn sich seine Daten aufgrund von Fremdeinwirkungen ändern: vbOLEAutomatic (0) Automatisch (Voreinstellung). Die Darstellung des Objekts wird sofort aktualisiert, sobald sich die verknüpften Daten ändern
Verb
vbOLEFrozen (1)
Die Darstellung des Objekts ist gegenüber Änderungen des Objektzustands eingefroren. Eine Aktualisierung findet nur statt, wenn das Objekt von der Quellanwendung aus gespeichert wird
vbOLEManual (2)
Für die Aktualisierung der Darstellung des Objekts ist ein Aufruf der Update-Methode erforderlich
Integer-Wert, der für den Wert 7 der Action-Eigenschaft die auszuführende Operation angibt; wird von DoVerb ignoriert und dient nur noch dem Erhalt der Kompatibilität
................................................... Methoden Methoden
Close, Copy, CreateEmbed, CreateLink, Delete, DoVerb, Drag, FetchVerbs, InsertObjDlg, Move, Paste, PasteSpecialDlg, ReadFromFile, Refresh, SaveToFile, SaveToOle1File, SetFocus, ShowWhatsThis, Update, ZOrder Die Prototypen der nicht an anderer Stelle vorgestellten Methoden des Steuerelements sind: Sub Objekt.Copy() Sub Objekt.CreateEmbed(SourceDoc As String, [Class As String]) Sub Objekt.CreateLink(SourceDoc As String, [SourceItem As String]) Sub Objekt.Delete() Sub Objekt.DoVerb(Verb As Integer) Sub Objekt.FetchVerbs Sub Objekt.InsertObjDlg Sub Objekt.Paste Sub Objekt.PasteSpecialDlg Sub Objekt.ReadFromFile (FileNumber As Integer) Sub Objekt.SaveToFile (FileNumber As Integer) Methode
Beschreibung
Copy
Fügt eine Kopie des in der Zwischenablage befindlichen Objekts als OLEObjekt in das Steuerelement ein
421
Standardsteuerelemente
Eigenschaft
Standardsteuerelemente
Standardsteuerelemente
Methode
Beschreibung
CreateEmbed
Fügt ein OLE-Objekt als eingebettetes Objekt in das Steuerelement ein. Der obligatorische Parameter SourceDoc spezifiziert die Dokumentdatei, in der das Objekt gespeichert ist. Um ein neues Objekt anzulegen, erhält SourceDoc beim Aufruf die leere Zeichenfolge und der Class-Parameter den Namen der dem Objekt zugrunde zu legenden (registrierten) OLE-Klasse.
CreateLink
Fügt das in der Dokumentdatei mit dem Namen SourceDoc befindliche Objekt als verknüpftes Objekt in das Steuerelement ein. Über den optionalen Parameter SourceItem lässt sich das Objekt auf eines seiner Elemente bzw. einen Elementbereich einschränken. Nach dem erfolgreichen Öffnen des Objekts hinterlegt die Methode die vollständige Verknüpfungsinformation in der Eigenschaft SourceDoc nach dem Muster "C:\TEXT.DOC!MARKE1" für ein Word-Dokument oder "C:\TABS\LOHN.XLS!Z2S1:Z22S5" für eine Excel-Tabelle. Der Darstellung des Objekts im Steuerelement liegt das Metafile-Format zugrunde, da die Quelldaten dafür nicht verfügbar sind. Gespeichert wird nicht das Objekt selbst (dieses kann nur im Bearbeitungsmodus über die Quellanwendung gespeichert werden), sondern nur die in der Eigenschaft SourceDoc enthaltene Verknüpfungsinformation.
Delete
Löscht das dem Steuerelement zugeordnete OLE-Objekt explizit und gibt insbesondere die von diesem belegten Ressourcen frei. Erfolgt der DeleteAufruf für das Objekt nicht, wird es zusammen mit dem Steuerelementobjekt beim Schließen des Formulars abgebaut.
DoVerb
Weist das Objekt an, die Aktion Verb auszuführen. Als Werte für Verb stehen die Standardverben sowie die zu dem jeweiligen Objekt (und seinem aktuellen Zustand) gehörigen Verben zur Verfügung (vgl. ObjectVerbs). Verben aus dem ObjectVerbs-Array sind über ihren Index anzugeben.
FetchVerbs
Aktualisiert die Eigenschaft ObjectVerbs
InsertObjDlg
Ruft das Dialogfeld OBJEKT EINFÜGEN auf, das es dem Benutzer ermöglicht, interaktiv ein OLE-Objekt als verknüpftes oder eingebettetes Objekt in das Steuerelement einzufügen. Der Funktionsumfang des Dialogfelds richtet sich nach dem Wert der Eigenschaft OLETypeAllowed.
Paste
Kopiert das in dem Steuerelement enthaltene OLE-Objekt in die Zwischenablage
PasteSpecialDlg
Ruft das Dialogfeld EINFÜGEN auf, das es ermöglicht, den Inhalt der OLE-Zwischenablage als eingebettetes oder verknüpftes OLE-Objekt in das Steuerelement einzufügen. Der Funktionsumfang des Dialogfelds richtet sich nach dem Wert der Eigenschaft OLETypeAllowed.
ReadFromFile
Liest ein OLE-Objekt aus der bereits mit der Dateinummer FileNumber geöffneten Binärdatei und fügt es in das Steuerelement als eingebettetes oder verknüpftes Objekt ein. Das Objekt muss zuvor (mit der Methode SaveToFile) im OLE-Format in der Binärdatei gespeichert worden sein, sonst kommt es zu einem Laufzeitfehler.
422
OLE- Container- Steuerelement (OLE)
Methode
Beschreibung
SaveToFile
Speichert das im Steuerelement enthaltene OLE-Objekt in einer zuvor im binären Modus geöffneten Datei mit der Dateinummer FileNumber. Wenn es sich bei dem Objekt um ein verknüpftes Objekt handelt (OLEType = 0), speichert die Methode nur den in der Eigenschaft SourceDoc enthaltenen Verweis auf das Objekt.
SaveToOle1File
Wie SaveToFile, speichert das Objekt jedoch im OLE 1.0-Format
Ereignisse
Click, DblClick, DragDrop, DragOver, GotFocus, KeyDown, KeyPress, KeyUp, LostFocus, MouseDown, MouseMove, MouseUp, ObjectMove, Resize, Updated Private Sub Objekt_ObjectMove(Left As Single, Top As Single, _ Width As Single, Height As Single) Das Ereignis ObjectMove tritt auf, wenn der Benutzer eine Größenänderung beim aktiviertem OLE-Objekt vornimmt. Sie können das Ereignis behandeln, um die Größe des Steuerelements an die des Objekts anzupassen. Falls keine Behandlungsroutine existiert oder diese nicht die vom Objekt angeforderten Abmessungen einstellt, passt das Objekt seine Abmessungen wieder an die des Steuerelements an. Anwendung
................................................... Anwendung
Das OLE-Container-Steuerelement zählt zu den anspruchsvolleren Steuerelementen, deren Möglichkeiten schon beinahe ins Unerschöpfliche gehen, weil es einem Visual-Basic-Programm gewissermaßen die gesamte Welt des OLE 2.0 erschließt. Der Zugang zu diesem Steuerelement ist dennoch einfach. Platziert man es im Entwurfsmodus beispielsweise auf einem Formular, konfrontiert einen Visual Basic (nach einer kurzen »Bedenkzeit«) mit dem Dialogfeld OBJEKT EINFÜGEN, das eine Auswahl des für das Steuerelement vorgesehenen verknüpften Objekts bzw. des Typs für ein neu zu erstellendes eingebettetes Objekt gestattet. Sie können den Dialog auch abbrechen, wenn Sie vorhaben, dem Steuerelement erst zur Laufzeit ein OLE-Objekt zuzuordnen – etwa über die Zwischenablage. Um dem Steuerelement zur Laufzeit ein OLE-Objekt zuzuordnen, haben Sie verschiedene Möglichkeiten. Zunächst einmal können Sie den alten, von Microsoft jedoch nicht mehr empfohlenen Weg über die Action-Eigenschaft gehen: Setzen Sie dazu im ersten Schritt die Eigenschaften SourceDoc, SourceItem sowie erforderlichenfalls Class auf geeignete Werte. Im zweiten Schritt setzen Sie die Action-Eigenschaft auf den Wert 0, um ein eingebettetes OLE-Objekt aus der Datei SourceDoc zu laden bzw. ein neues Objekt des Typs Class zu generieren, oder auf den Wert 1, um ein verknüpftes OLE-Objekt einzufügen, das in der Datei SourceDoc gespeichert und gegebenenfalls durch SourceItem genauer spezifiziert ist. Der von Microsoft empfohlene Weg sieht dagegen den Aufruf der Methoden CreateEmbed und CreateLink vor, deren Parameter die gleichen Namen wie die von Action benutzten Eigenschaften tragen und auch die gleichen Funktionen haben, so dass die Eigenschaften unbeachtet bleiben. Einen dritten Weg eröffnet die Methode InsertObjDlg (respektive der Code 14 für die Action-Eigenschaft). Sie ruft das (bereits vom Entwurfsmodus her bekannte) Dialogfeld OBJEKT EINFÜGEN auf, in dem der Benutzer das OLE-Objekt interaktiv als eingebettetes oder verknüpftes Objekte genauer spezifizieren kann. Um zu erfahren, welche Art von Objekt der Benutzer in dem Dialog eingefügt hat, empfiehlt sich eine Auswertung der OLEType-Eigenschaft. Ein anderer Weg, wie ein OLE-Steuerelement zu einem OLE-Objekt kommt, ist der über die Zwischenablage. Wenn Sie den Kopiervorgang mit der Paste-Methode (im Standardformat)
423
Standardsteuerelemente
................................................... Ereignis s e
Standardsteuerelemente
Standardsteuerelemente
abwickeln wollen, sollten Sie prüfen, ob der Aufruf erfolgreich sein kann. Dazu stellen Sie erst einmal klar, ob die Zwischenablage das gewünschte Format liefern kann (vgl. ClipBoardObjekt), setzen dann die OLETypeAllowed-Eigenschaft auf die gewünschte Objektart und rufen schließlich Paste in Abhängigkeit vom Wert der Eigenschaft PasteOK auf. Sie können aber auch die Methode PasteDlgSpecial aufrufen, um dem Benutzer im Rahmen des Dialogfelds EINFÜGEN die Wahl zu überlassen, in welcher Form (und gegebenenfalls in welchem Format) er das Objekt einfügen möchte. Umgekehrt können Sie mittels Copy natürlich auch eine Kopie des OLE-Objekts in die Zwischenablage übertragen. Völlig automatisch geht die Geschichte, wenn der Benutzer das Objekt im Rahmen einer OLEDrag&Drop-Operation in das Steuerelement zieht. Einzige Voraussetzung: OLEDropAllowed muss True sein. Zu guter Letzt können Sie das Objekt aber auch mittels ReadFromFile direkt aus einer bereits im binären Modus geöffneten Datei einlesen. Die Kombination SaveToFile und ReadFromFile ermöglicht es, OLE-Objekte in eigenen Dateien zu speichern, um diese gegebenenfalls in einer späteren Sitzung wieder einzulesen. Um dem OLE-Objekt ein Kommando aus der Liste der Standardverben sowie seiner eigenen Verben (ObjectVerbs) zu übermitteln, benutzen Sie die Methode DoVerb. Wenn Sie das OLEObjekt des Steuerelements OLE1 beispielsweise für die Vorortbearbeitung aktivieren wollen, schreiben Sie: OLE1.DoVerb -4
Anstelle von -4 könnten Sie auch den Index des Befehls »Bearbeiten« im Kontextmenü des Objekts (ObjectVerbs) angeben. Dieser ist meist 0, da er im Allgemeinen die Standardoperation des Objekts darstellt. Natürlich kann der Benutzer die Aktivierung auch wie üblich auch per Doppelklick vornehmen (vgl. AutoActivate) Beispiel
................................................... Beis piel
OLE1.AutoActivate = 3 OLE1.OLETypeAllowed = vbOLEEmbedded If OLE1.PasteOK Then OLE1.PasteSpecialDlg ... If OLE1.OLEType 3 Then OLE1.DoVerb -4
' nur einbetten ' Aus Zwischenablage ... ' Objekt vorort bearbeiten
................................................... Verwandte Objekte ClipBoard Verwandte Themen
................................................... Verwandte Them en
OLE-Drag&Drop (S. 501)
Optionsfeld- Steuerelement (OptionButton) Option1 As OptionButton
424
Optionsfeld- Steuerelement (OptionButton)
Beschreibung
................................................... Bes c hreibung
Das Optionsfeld-Steuerelement visualisiert die Auswahl einer spezifischen Option unter mehreren möglichen Optionen. Im selben Container situierte Optionsfelder bilden automatisch eine Optionsgruppe, in der sich die Mitglieder gegenseitig auslösen, so dass maximal immer nur ein Optionsfeld markiert und damit auch ausgewählt sein kann. Standardeigenschaft des Optionsfelds ist Value, ein Boolean-Wert mit der Voreinstellung False. Eigenschaften
................................................... Eigens c ha ften
Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Click, DblClick, DragDrop, DragOver, GotFocus, KeyDown, KeyPress, KeyUp, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Validate Anwendung
................................................... Anwendung
Das Optionsfeld bildet aus logischer Sicht das Gegenstück zum Kontrollkästchen. Während letzteres als Schalter für logisch voneinander unabhängige Attribute fungiert, ist das Optionsfeld für die Darstellung sich gegenseitig ausschließender Attribute konzipiert. Es hat daher wenig Sinn, einzelne Optionsfelder isoliert zu verwenden. Vielmehr werden Optionsfelder immer gruppiert. Falls ein Formular oder eine Komponente mehrere logisch voneinander unabhängige Gruppierungen anzeigen soll, müssen die Gruppierungen in je eigenen ContainerSteuerelementen (Frame, PictureBox, SSTab) platziert sein (vgl. Abbildung). Je Gruppierung sollten Sie eine Standardoption festlegen, ein Optionsfeld, dessen Value-Eigenschaft Sie am besten bereits zur Entwurfszeit auf True setzen. Jede Änderung der Value-Eigenschaft, gleich ob mit der Maus, mit einer Zugriffstaste oder vom Programmcode aus, bringt das Click-Ereignis hervor. Da Value die Standardeigenschaft des OptionButton-Objekts ist, muss nur der Objektbezeichner notiert werden, um diese Eigenschaft anzusprechen. Um eine Zugriffstaste für das Steuerelement zu vereinbaren, stellen Sie dem entsprechenden Buchstaben in der Beschriftung (Caption) das Zeichen »&« voran. Er erscheint zur Laufzeit unterstrichen. Zur einfachen Auswertung vereinbaren Sie Optionsfeldgruppen am besten als SteuerelementeArrays. Der Index-Parameter des Click-Ereignisses liefert dann nämlich vorteilhafterweise den Array-Index des betroffenen Optionsfelds: Option1_Click(Index As Integer) Select Case Index Case 0: ' Erstes Attribut ... Case 1: ' Zweites Attribut ... End Select End Sub
425
Standardsteuerelemente
Alignment, Appearance, BackColor, Caption, CausesValidation, Container, DataFormat, DisabledPicture, DownPicture, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, MaskColor, MouseIcon, MousePointer, Name, OLEDropMode, Parent, RightToLeft, Style, TabIndex, TabStop, Tag, Top, ToolTipText, UseMaskColor, Value, Visible, WhatsThisHelpID, Width
Standardsteuerelemente
Standardsteuerelemente
Das Optionsfeld kennt zwei unterschiedliche Darstellungen: die Standarddarstellung im Stile von Windows 9x (vgl. Abbildung) und eine benutzerdefinierte Darstellung. Die Style-Eigenschaft entscheidet darüber, welche der Darstellungen zur Anzeige kommt. In der benutzerdefinierten Darstellung sieht das Optionsfeld zunächst wie eine Befehlsschaltfläche aus, hält aber im Gegensatz zu dieser den gedrückten Zustand, bis es von einem anderen Optionsfeld ausgelöst wird. Um dem Steuerelement ein benutzerdefiniertes Aussehen zu verleihen, können Sie den Eigenschaften Picture und DownPicture sowie gegebenenfalls DisabledPicture geeignete Bilder zuordnen. Falls Sie eine pseudotransparente Darstellung wünschen, bei der die über eine Transparenzfarbe (MaskColor) definierten transparenten Bereiche der Bilder in Hintergrundfarbe erscheinen, müssen Sie die Eigenschaft UseMaskColor auf True setzen. (Ein analoges Beispiel für Schaltflächen findet sich im Abschnitt »DisabledPicture-Eigenschaft«, S. 341.) Beispiel
................................................... Beis piel
Im folgenden Beispiel dient eine Optionsfeldgruppe zur Auswahl der Form für das Figur-Steuerelement Shape1. Private Sub Option1_Click(Index As Integer) Shape1.Shape = Index End Sub
Verwandte Befehle
................................................... Verwa ndte Befehle
Button, CheckBox, CommandButton
Rahmen- Steuerelement (Frame) Frame1 As Frame Beschreibung
................................................... Bes c hreibung
Das Rahmen-Steuerelement ist eines der drei Steuerelemente, die als Container für andere Steuerelemente auftreten können. Die beiden anderen sind: PictureBox und SSTab. Es kann daher nicht nur für die visuelle, sondern insbesondere auch für die funktionelle Gruppierung anderer Steuerelemente benutzt werden. Standardeigenschaft des Steuerelements ist die Caption-Eigenschaft, die der Entwurfseditor mit dem automatisch generierten Namen des Steuerelements vorbesetzt. Eigenschaften
................................................... Eigens c ha ften Appearance, BackColor, Caption, ClipControls, Container, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, MouseIcon, MousePointer, Name, OLEDropMode, Parent, RightToLeft, TabIndex, Tag, Top, ToolTipText, Visible, WhatsThisHelpID, Width
426
Textfeld- Steuerelement ( TextBox)
Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, ShowWhatsThis, Refresh, ZOrder Ereignisse
................................................... Ereignis s e
Click, DblClick, DragDrop, DragOver, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag Anwendung
................................................... Anwendung
Verwandte Steuerelemente
................................................... Verwandte Steuerelemente PictureBox, SSTab
Textfeld- Steuerelement (TextBox) Text1 As TextBox Beschreibung
................................................... Bes c hreibung
Das Textfeld-Steuerelement ist auf die interaktive Ein- und Ausgabe von Text eingerichtet. Die Standardeigenschaft Text des Steuerelements ist vom Typ String und kann (nahezu) beliebig lange Zeichenfolgen enthalten. Um die Länge zu beschränken, lässt sich über die MaxLengthEigenschaft eine maximale Zeichenanzahl setzen. Mittels der Locked-Eigenschaft lässt sich das Steuerelement für Benutzereingaben sperren. Neben der voreingestellten einzeiligen Anzeige unterstützt das Steuerelement auch die mehrzeilige Anzeige mit automatischem Umbruch auf der Basis von Leerzeichen. Dazu ist die MultiLine-Eigenschaft beim Entwurf auf True zu setzen. Falls der Fensterbereich des Textfelds für die Anzeige des Werts nicht ausreicht, lassen sich zur besseren Navigation über die ScrollBars-Eigenschaft Bildlaufleisten hinzufügen. In einer eingeschränkten Fassung ist das Textfeld auch als Bestandteil der Steuerelemente ComboBox, DBCombo, DataGrid sowie als »Partner« (Buddy) des UpDown-Steuerelements anzutreffen. Über seine Link-Eigenschaften, -Methoden und -Ereignisse kann das Steuerelement als Quelloder Zielsteuerelement für DDE-Verbindungen benutzt werden – mehr dazu unter den entsprechenden Eigenschaften und Ereignissen. Die Data-Eigenschaften ermöglichen die Anbindung des Textfelds an ein Datenbankfeld – mehr dazu unter »Data-Datensteuerelement (Data)«, S. 402. Eigenschaft
Beschreibung
HideSelection
Boolean-Wert, der bestimmt, ob eine Markierung bei Fokusverlust sichtbar bleibt (False) oder nicht (True; Voreinstellung)
427
Standardsteuerelemente
Eine der Regeln, die der Entwurfseditor auferlegt, lautet: Ein Steuerelement kann seinen Container nicht wechseln. Um ein Steuerelement in einem Rahmen zu platzieren, müssen Sie das Steuerelement also bereits im Rahmen anlegen. Zur Laufzeit sieht das anders aus: Indem Sie die Container-Eigenschaft eines Steuerelement auf ein Frame-Objekt setzen, platzieren Sie es in dessen Rahmen (beachten Sie aber, dass sich dadurch das für das Steuerelement geltende Koordinatensystem ändern kann). Die Hauptanwendung des Rahmen-Steuerelements ist und bleibt aber die Gruppierung von Optionsfeldern. Da in einem Container immer nur ein Optionsfeld markiert sein kann, weil sich alle in einem Container befindlichen Optionsfelder gegenseitig auslösen, müssen funktional voneinander unabhängige Gruppierungen auf verschiedene Container verteilt werden. Unter den verfügbaren Container-Steuerelementen ist das Rahmen-Steuerelement die perfekte Wahl, weil es zudem eine passende Beschriftung der Gruppierung ermöglicht.
Standardsteuerelemente
Standardsteuerelemente
Eigenschaft
Beschreibung
Locked
Boolean-Wert, der bestimmt, ob der Benutzer Eingaben in das Textfeld vornehmen kann (False; Voreinstellung) oder nicht (True). Ein für die Eingabe gesperrtes Textfeld nimmt zwar den Fokus an und erlaubt die Navigation im Text, reagiert aber nicht auf Tastatureingaben, die den aktuellen Wert ändern würden.
MaxLength
Long-Wert, der bestimmt, wie viele Zeichen der Wert des Textfelds maximal enthalten darf. Wird die Eigenschaft auf dem voreingestellten Wert 0 belassen, kann Text wie jeder andere Wert vom Typ String (nahezu) beliebig lang werden. Wird die MaxLength-Eigenschaft im Nachhinein kleiner als die Länge des aktuellen Text-Werts gesetzt, ändert dies die Anzeige nicht, und der Benutzer kann nach wie vor den gesamten Wert bearbeiten. Die neue Beschränkung tritt jedoch alsbald in Kraft, wenn der Benutzer Zeichen löscht.
MultiLine
Zur Laufzeit schreibgeschützter Boolean-Wert, der bestimmt, ob die Darstellung des Standardwerts auf eine Zeile beschränkt bleibt (False; Voreinstellung) oder auch mehrere Zeilen umfassen kann. Falls das Textfeld eine horizontale Bildlaufleiste besitzt (ScrollBars-Eigenschaft), richtet sich der Umbruch nach dem Vorkommen von Zeilenvorschubzeichen (vbCrLf), ansonsten führt das Steuerelement einen automatischen Umbruch auf der Basis von Leerzeichen durch.
PasswordChar
String-Wert der Länge 1, der das Platzhalterzeichen für die Kennworteingabe bestimmt. Wird die Eigenschaft auf einen Wert ungleich der leeren Zeichenfolge (Voreinstellung) gesetzt, aktiviert dies den Modus »Kennworteingabe«: Der Benutzer sieht dann für jedes eingegebene Zeichen ein Platzhalterzeichen und kann den Wert nicht mehr in die Zwischenablage übernehmen. Das Textfeld ignoriert diese Eigenschaft allerdings bei mehrzeiliger Anzeige (vgl. MultiLine).
ScrollBars
Integer-Wert, der bestimmt, ob das Textfeld im mehrzeiligen Modus (vgl. MultiLine) Bildlaufleisten anzeigt und automatisch verwaltet. Der Aufzählungstyp ScrollBarConstants definiert dafür die Konstanten: vbSBNone (0) für keine Bildlaufleisten; vbHorizontal (1) für waagrechte Bildlaufleiste; vbVertical (2) für senkrechte Bildlaufleiste; vbBoth (3) für waagrechte und senkrechte Bildlaufleiste. Bei Anzeige der waagrechten Bildlaufleiste erfolgt kein automatischer Umbruch auf der Basis von Leerzeichen.
SelLength
Long-Wert, der die Länge der Markierung ab der Position SelStart beschreibt. Ist der Wert größer als die Anzahl der restlichen Zeichen ab SelLength, korrigiert das Steuerelement den Wert auf die Anzahl der restlichen Zeichen.
SelStart
Long-Wert, der die Position des Zeichens in Text beschreibt, an der die Markierung beginnt. Ein Ändern dieser Eigenschaft setzt SelLength auf 0. Ist der neue Wert für SelStart größer als die Länge von Text, korrigiert ihn das Steuerelement auf die aktuelle Länge des Textes, so dass er auf die Position hinter dem letzten Zeichen verweist.
428
Textfeld- Steuerelement ( TextBox)
Eigenschaft
Beschreibung
SelText
String-Wert, der den markierten Teil von Text wiedergibt oder neu definiert. Setzt man diese Eigenschaft, passiert Folgendes: Ist die aktuelle Länge der Markierung 0 (SelLength), wird der neue Wert an der Position SelStart eingefügt. Ansonsten ersetzt der neue Wert die Markierung, ohne dass die Längen eine Rolle spielen.
Eigenschaften
................................................... Eigens c ha ften
Methoden
................................................... Metho den Drag, LinkExecute, LinkPoke, LinkRequest, LinkSend, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Change, Click, DblClick, DragDrop, DragOver, GotFocus, KeyDown, KeyPress, KeyUp, LinkClose, LinkError, LinkNotify, LinkOpen, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Validate Anwendung
................................................... Anwendung
Das Textfeld-Steuerelement ersetzt die klassische Input-Anweisung von Basic. Es eignet sich für die Ein- und Ausgabe beliebiger Werte mit String-Repräsentation und erfreut durch eine brauchbare Implementation der Tastaturschnittstelle. Um den Wert des Textfelds zu setzen oder abzufragen, genügt es, den Bezeichner des Textfeldobjekts zu notieren. Visual Basic nimmt nach Möglichkeit eine automatische Typumwandlung vor. Mit jeder Änderung von Text tritt das Change-Ereignis auf. Es zeigt an, dass eine Tastatureingabe, eine DDE-Aktualisierung, eine Datensatzaktualisierung oder eine Wertänderung vom Programmcode aus geschehen ist. Wenn Sie eine Gültigkeitsprüfung für den Fall des Fokusverlusts etablieren wollen, behandeln Sie das Validate-Ereignis. Dazu muss jedoch die CausesValidation-Eigenschaft nicht nur des Textfelds, sondern auch des Steuerelements, das den Fokus erhält, auf True gesetzt sein. Wenn Sie ein Textfeld für die Kennworteingabe verwenden wollen, setzen Sie die Eigenschaft PasswordChar auf ein Zeichen, das als Platzhalterzeichen für eingegebene Zeichen erscheinen soll. Tipp
................................................... Tipp
Anstelle eines Textfelds können Sie einmalige Eingaben auch über die InputBox-Funktion abwickeln: a$ = InputBox ("Bitte Startwert eingeben")
429
Standardsteuerelemente
Alignment, Appearance, BackColor, BorderStyle, CausesValidation, Container, DataChanged, DataField, DataFormat, DataMember, DataSource, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, HideSelection, hWnd, Index, Left, LinkItem, LinkMode, LinkTimeout, LinkTopic, Locked, MaxLength, MouseIcon, MousePointer, MultiLine, Name, OLEDragMode, OLEDropMode, Parent, PasswordChar, RightToLeft, ScrollBars, SelLength, SelStart, SelText, TabIndex, TabStop, Tag, Text, Top, ToolTipText, Visible, WhatsThisHelpID, Width
Standardsteuerelemente
Beispiel
................................................... Beis piel
Standardsteuerelemente
Das Beispielprojekt EuroDMTestProjekt zeigt die Implementation eines Benutzersteuerelements mit zwei Textfeldern, die sich gegenseitig im Rahmen ihrer Change-Behandlung aktualisieren. Der Zweck der auf Modulebene vereinbarten Zustandsvariable Changing besteht darin, einer endlosen Rekursion vorzubeugen, die ansonsten aufgrund der gegenseitigen Wertänderung der Steuerelemente resultieren würde.
Fenster eines
Formulars,
auf
dem
das
Benutz ersteuerelement
' Projekt: Euro/DM-TestProjekt Const sKurs = 1.95583 Dim Changing As Boolean Property Let Euro(Value As Currency) tfEuro = Value End Property Property Get Euro() As Currency Euro = tfEuro End Property Property Let DM(Value As Currency) tfDM = Value End Property Property Get DM() As Currency DM = tfDM End Property Private Sub tfDM_Change() If Not Changing Then Changing = True tfEuro = Round(Val(tfDM) / sKurs, 2) Else Changing = False End If End Sub Private Sub tfEuro_Change() If Not Changing Then Changing = True tfDM = Round(Val(tfEuro) * sKurs, 2) Else Changing = False End If End Sub
430
EuroDM platz iert
wurde
Verzeichnislistenfeld- Steuerelement ( DirListBox)
Verwandte Steuerelemente
................................................... Verwandte Steuerelemente ComboBox, DataList, DBCombo, MaskEDBox, RichTextBox, RptTextBox
Verzeichnislistenfeld- Steuerelement (DirListBox) Dir1 As DirListBox
................................................... Bes c hreibung
Das Verzeichnislistenfeld-Steuerelement visualisiert die hierarchische Einbettung eines Verzeichnisses im Verzeichnisbaum des jeweiligem Laufwerks und bietet die Möglichkeit der interaktiven Auswahl eines jeden beliebigen Verzeichnisses auf dem gegebenen Laufwerk. Standardeigenschaft des Steuerelements ist Path. Eigenschaften
................................................... Eigens c ha ften Appearance, BackColor, CausesValidation, Container, DragIcon, DragMode, Enabled, Font, FontBold, FontItalic, FontName, FontSize, FontStrikethru, FontUnderline, ForeColor, Height, HelpContextID, hWnd, Index, Left, List, ListCount, ListIndex, MouseIcon, MousePointer, MultiSelect, Name, OLEDragMode, OLEDropMode, Parent, Path, TabIndex, TabStop, Tag, Top, ToolTipText, TopIndex, Visible, WhatsThisHelpID, Width Methoden
................................................... Metho den Drag, Move, OLEDrag, Refresh, SetFocus, ShowWhatsThis, ZOrder Ereignisse
................................................... Ereignis s e
Change, Click, DragDrop, DragOver, GotFocus, KeyDown, KeyPress, KeyUp, LostFocus, MouseDown, MouseMove, MouseUp, OLECompleteDrag, OLEDragDrop, OLEDragOver, OLEGiveFeedback, OLESetData, OLEStartDrag, Scroll, Validate Anwendung
................................................... Anwendung
Das Verzeichnislistenfeld (DirListBox) ist wie das Dateilistenfeld und das Laufwerklistenfeld (DriveListBox) noch ein Relikt aus der Zeit, als Anwendungen den Benutzer mit eigenen Varianten für Dialoge wie »Datei öffnen«, »Speichern unter« usw. auf die Probe stellen mussten, weil es die Standarddialoge (CommonDialog) noch nicht gab. Seine aktuelle Daseinsberechtigung bezieht das Verzeichnislistenfeld allerdings aus der Tatsache, dass das Standarddialoge-Steuerelement (COMLDG32.OCX) den Benutzer dazu zwingt, eine Datei auszuwählen, und die reine Verzeichnisauswahl nicht zulässt. Visual Basic initialisiert die Path-Eigenschaft des Steuerelements mit dem aktuellen standardmäßigen Arbeitsverzeichnis, das im Allgemeinen mit App.Path übereinstimmt, beim Aufruf aber auch explizit gesetzt worden sein kann (vgl. auch »CurDir-Funktion«, S. 134). Der Laufwerksanteil von Path lässt sich nur mit Programmcode ändern. Sie können den Wert wahlweise als Laufwerkspfad oder als UNC-Pfad angeben, um Netzwerkressourcen ohne Laufwerkszuordnung darzustellen. Sehr weit kommt man damit jedoch nicht, da es schwierig ist, in Visual Basic
43 1
Standardsteuerelemente
Beschreibung
Standardsteuerelemente
Standardsteuerelemente
Netzwerkfreigaben in Erfahrung zu bringen, die keinem Netzlaufwerk zugeordnet sind – ein Grund mehr, letztlich doch mit den Standarddialogen zu arbeiten. Um dem Benutzer die Möglichkeit der interaktiven Änderung zu geben, können Sie in der Nähe des Verzeichnislistenfelds zusätzlich ein Laufwerklistenfeld (DriveBox) platzieren und dessen Change-Behandlung die Path-Eigenschaft des Verzeichnislistenfelds ändern lassen. Die Implementation der Steuerelemente ist aufeinander abgestimmt, so dass die geklammerte Volumenbezeichnung des Laufwerks im Wert von Drive herausgefiltert wird. Private Sub Drive1_Change() Dir1 = Drive1 ' Volumenbezeichnung wird gefiltert End Sub
Eine Möglichkeit für das Herausfiltern von Verzeichnissen mit bestimmten Attributen bietet das Steuerelement nicht. Da über die Eigenschaften List, ListCount, ListIndex jedoch alle Einträge für die angezeigten Verzeichnisse in Form absoluter Pfade verfügbar sind, lassen sich die Attribute recht einfach gesondert über die Funktion GetAttr ermitteln. Mit dem Unterschied, dass die List-Eigenschaft schreibgeschützt ist und auch sonst keine Möglichkeiten gegeben sind, die Einträge des Listenfelds zu ändern, verhält sich das Laufwerklistenfeld ansonsten wie ein gewöhnliches Listenfeld, insbesondere was die Mehrfachauswahl (MultiSelect) und den Bildlauf betrifft. Änderungen im Verzeichnissystem spiegelt das Steuerelement nicht automatisch wider, vielmehr ist ein Refesh-Aufruf dafür erforderlich. Warnung
................................................... Wa rnung
Der Wert "\\." für Path bringt das Steuerelement sowie die gesamte Entwicklungsumgebung von Visual Basic sicher zum Absturz. Beispiel
................................................... Beis piel
Private Sub Dir1_Change() CurDir = Dir1 ' standardmäßiges Arbeitsverzeichnis setzen End Sub Verwandte Befehle
................................................... Verwa ndte Befehle
DriveListBox, FileListbox, ListBox, ListView
Zeitgeber- Steuerelement (Timer) Timer1 As Timer Beschreibung
................................................... Bes c hreibung
Unter den Standardsteuerelementen ist das Zeitgeber-Steuerelement das einzige, das keine sichtbare Darstellung besitzt. Vielmehr implementiert das Steuerelement einen einfachen Mechanismus, der periodisch das Timer-Ereignis produzieren kann. Die Periodendauer wird über die Eigenschaft Interval gesetzt. Hat diese Eigenschaft den Wert 0, löst das Steuerelement keine Timer-Ereignisse aus, ansonsten legt der Wert die Anzahl der Millisekunden zwischen zwei Timer-Ereignissen fest. Eigenschaften
................................................... Eigens c ha ften Enabled, Index, Interval, Name, Parent, Tag
432
ActiveX- Steuerelemente (OCX) Windows- Standardsteuerelemente
Methoden
................................................... Metho den Keine Ereignisse
................................................... Ereignis s e
Timer Anwendung
................................................... Anwendung
Beispiel
................................................... Beis piel
Vgl. das Beispiel in »AutoSize-Eigenschaft« (S. 329). Verwandte Themen
................................................... Verwandte Them en
Date-Funktion und Date-Anweisung (S. 116); Time-Funktion und Time-Anweisung (S. 123); Timer-Funktion (S. 124)
ActiveX- Steuerelemente (OCX) WindowsStandardsteuerelemente Beschreibung
................................................... Bes c hreibung
Die Standardsteuerelemente stellen einen durchaus geglückten Versuch von Microsoft dar, die Benutzeroberflächen und -schnittstellen von Windows-Anwendungen weitgehend zu standardisieren. Bei den Windows-Standardsteuerelementen (Common Controls) handelt es sich gewissermaßen um den zweiten Aufguss, der inzwischen (seit Windows 95) nicht nur in 32-Bit-Implementation vorliegt und komplett an das Design von Windows 9x angepasst wurde, sondern auch mit dem Component Object Model (COM) kompatibel ist. Windows-Standardsteuerelemente sind somit echte ActiveX-Steuerelemente – während die Standardsteuerelemente schlicht ein Teil von Windows sind. Da die Benutzeroberfläche von Windows, der Explorer, der Internet-Explorer, alle Systemprogramme sowie die gesamte Palette der Microsoft-Produkte massiv von diesen Steuerelementen Gebrauch machen, sind sie gewissermaßen zum unverzichtbaren Bestandteil für die gesamte Welt der Windows-Programmierung geworden – frei nach dem Motto, »sag's mit Steuerelementen«. Kopieraktionen oder andere zeitaufwändige Operationen
43 3
ActiveX- Steuerelemente (OCX) – Windows- Standardsteuerelemente
Die Anwendungsmöglichkeiten des Zeitgeber-Steuerelements sind so vielseitig, wie die Problemstellungen, die etwas mit Zeit und periodischen Aufgaben zu tun haben. Erwarten Sie aber nicht zu viel von dem Steuerelement. Zunächst einmal ist das Zeitintervall nicht sehr genau. Das liegt zum einen daran, dass das Steuerelement als Zeitbasis den Systemzeitgeber verwendet, der unter Windows 9x nur 18,2-mal pro Sekunde und unter Windows NT 50-mal pro Sekunde tickt, eine Altlast aus der Zeit von MS-DOS. (Es hat also wenig Sinn, den Wert kleiner als 6 unter Windows 9x bzw. kleiner als 2 unter Windows NT zu setzen.) Zum anderen können sich Timer-Ereignisse verspäten oder auch verloren gehen, da Windows anderen Ereignissen gegenüber Timer-Ereignissen einen gewissen Vorrang einräumt und Timer-Ereignisse sich grundsätzlich nicht ansammeln. Zum dritten: Obwohl die Eigenschaft Interval vom Typ Long ist, akzeptiert das Steuerelement dafür keine Werte größer als 65.535 (16 Bit), was das maximale Zeitintervall auf ca. 65 Sekunden beschränkt. Um längere Zeiträume zu implementieren, müssen Sie eine Logik verwenden, bei der die Timer-Routine in regelmäßigen Abständen die Systemzeit ausliest oder ihre eigenen Aufrufe zählt. Ein Beispiel dafür finden Sie im Abschnitt »LongTimer – der Timer mit Ausdauer« (S. 599) des Praxisteils.
ActiveX- Steuerelemente (OCX) – Windows- Standardsteuerelemente
ActiveX- Steuerelemente ( OCX) Windows- Standardsteuerelemente
verkürzen dem Benutzer die Wartezeit durch Animationen und Fortschrittsanzeigen. Listenansichten und Strukturansichten standardisieren die Darstellung komplexer Informationen und ihrer Zusammenhänge. Statusleisten und Symbolleisten dürfen inzwischen in ernstzunehmenden Programmen ebenso wenig fehlen wie Eigenschaftsdialoge. Da ist es nicht verwunderlich, dass Microsoft in regelmäßigen Abständen Aktualisierungen an der Implementation sowie im Design der Steuerelemente vorstellt und die Sammlung zunehmend erweitert. Unter Visual Basic 6.0 sind die Windows-Standardsteuerelemente aktuell in zwei unterschiedlichen Versionen vertreten: in der Version 5.0 sowie in der Version 6.0. Der Grund dafür liegt natürlich an der Aufrechterhaltung der Kompatibilität mit älteren Anwendungen und Projekten. Für neue Projekte sollten Sie ausschließlich mit der neueren Version arbeiten. Wenn Sie ein älteres, noch mit Visual Basic 5.0 erstelltes Projekt laden, legt Ihnen Visual Basic 6.0 die automatische Aktualisierung der Windows-Standardsteuerelemente ans Herz – ein Vorgang, der problemfrei über die Bühne geht. Die Aktualisierungsaufforderung unterbleibt, wenn im Eigenschaftsfenster des Projekts EIGENSCHAFTEN VON Projektname das Kontrollkästen ACTIVEX-STEUERELEMENTE AKTUALISIEREN deaktiviert ist. Um zu prüfen, welche Version der Steuerelemente ein Projekt verwendet, rufen Sie das Dialogfeld KOMPONENTEN über den Menübefehl PROJEKT/KOMPONENTEN auf und schauen, welche Komponenten ein Häkchen auf der Registerkarte STEUERELEMENTE haben. Um einzelne Windows-Standardsteuerelemente in einem neuen Projekt nutzen zu können, rufen Sie das Dialogfeld KOMPONENTEN über den Menübefehl PROJEKT/KOMPONENTEN auf und setzen auf der Registerkarte STEUERELEMENTE vor die entsprechende Komponente ein Häkchen. (Beachten Sie den OCX-Dateinamen der Komponente unterhalb des Listenfelds für die markierte Komponente.)
Auswahl der Windows- Standardsteuerelemente
Sie müssen nicht alle drei Komponenten auswählen. Wenn Sie beispielsweise nur mit dem CoolBar-Steuerelement arbeiten wollen, reicht die Auswahl des Eintrags Microsoft Windows Common Controls-3 6.0 (SP3). Nachdem Sie die Auswahl übernommen bzw. das Dialogfeld geschlossen haben, finden Sie für jedes Steuerelement eine zusätzliche Schaltfläche in der Werkzeugleiste und können damit genauso wie mit den Standardsteuerelementen von Visual Basic arbeiten.
43 4
ActiveX- Steuerelemente (OCX) Windows- Standardsteuerelemente
Werkzeugsammlung nac h Auswahl der Windows- Standardsteuerelemente
Steuerelement
Komponentendatei (Version)
Bestimmung des Steuerelements
ImageList
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Abbildungsliste, die anderen Steuerelementen (beispielsweise ImageCombo, TreeView, ToolBar) Bilder für die Anzeige bereitstellt
Animation
COMCT232.OCX (5.0) MSCOMCTL2.OCX (6.0)
Spielt unkomprimierte AVI-Dateien ohne Ton ab
CoolBar
MSCOMCTL3.OCX (6.0)
Konfigurierbare Symbolleiste im Stile des Internet Explorer (erfordert Installation des Internet Explorer mindestens in der Version 3.0)
DTPicker
MSCOMCTL2.OCX (6.0)
Ermöglicht die interaktive Datums-/Zeitauswahl
UpDown
COMCT232.OCX (5.0) MsComctl2.ocx (6.0)
Drehfeld (auch AufAb-Steuerelement genannt) mit Pfeilschaltflächen für das Hoch- oder Herunterzählen eines Werts im anhängenden Textfeld (Buddy)
FlatScrollBar
MSCOMCTL2.OCX (6.0)
Flache Bildlaufleiste, die nur bei Aktivierung eine 3D-Darstellung aufweist, ansonsten »flach« aussieht
ProgressBar
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Fortschrittsleiste für die animierte Fortschrittsanzeige bei längeren Operationen
ImageCombo
MSCOMCTL.OCX (6.0)
Kombinationsfeld mit bebilderten Texteinträgen
MonthView
MSCOMCTL2.OCX (6.0)
Kalender-Steuerelement für die interaktive Datums- und Zeitraumauswahl
ListView
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Listenansicht für die Anzeige von Texteinträgen mit zugeordneten Bildern (Symbolen) in vier unterschiedlichen Ansichten und sortierbaren Spalten
TabStrip
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Element für die Darstellung von Registerkarten in Eigenschaftsdialogen
43 5
ActiveX- Steuerelemente (OCX) – Windows- Standardsteuerelemente
In der Version 5.0 waren zehn Windows-Standardsteuerelemente im Angebot, die in zwei OCX-Dateien (ComCtl32.ocx, ComCt232.ocx) enthalten waren und die Unterstützung einer DLL (ComCtl32.dll) benötigten. In der Version 6.0 sind es bereits 15 Steuerelemente, die sich auf drei OCX-Dateien (MsComctl.ocx, MsComct2.ocx, MsComct3.ocx) verteilen, und eine DLL ist nicht mehr erforderlich. Die folgende Tabelle gibt einen Überblick über die Steuerelemente.
ActiveX- Steuerelemente (OCX) – Windows- Standardsteuerelemente
ActiveX- Steuerelemente ( OCX) Windows- Standardsteuerelemente
Steuerelement
Komponentendatei (Version)
Bestimmung des Steuerelements
Slider
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Schieberegler mit Skala für die Visualisierung analoger Einstellungen
StatusBar
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Statusleiste für die Anzeige von Statusinformationen am unteren Rand eines Formulars
TreeView
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Strukturansicht für die Darstellung hierarchischer Abhängigkeiten und Strukturen
ToolBar
COMCTL32.OCX (5.0) MSCOMCTL.OCX (6.0)
Symbolleiste für die Gruppierung von Befehlsschaltflächen am (meist oberen) Formularrand
Die vorliegende Ausgabe dieser Referenz stellt hier gewissermaßen exemplarisch nur das Windows-Standardsteuerelement ImageList ausführlicher vor, da es als Bildlieferant für verschiedene Szenarien fungieren kann.
Abbildungsliste- Steuerelement (ImageList) ImageList1 As ImageList Beschreibung
................................................... Bes c hreibung
Das Abbildungsliste-Steuerelement hat wie das Zeitgeber-Steuerelement zur Laufzeit keine sichtbare Darstellung, sondern dient in erster Linie anderen Steuerelementen, die über eine ImageList-Eigenschaft verfügen, als Lieferant von Bildressourcen. Als Struktur für die Speicherung der Bilder verwendet das Steuerelement eine ListImages-Auflistung mit dem Elementtyp ListImage. Zur Erweiterung der Auflistung gibt es eine AddMethode und zum Löschen die Methoden Remove bzw. Clear. Der Zugriff bzw. Verweis auf ein einzelnes Bild erfolgt wahlweise unter Angabe des in der Index-Eigenschaft des entsprechenden ListImage-Objekts festgelegten Index (Basis ist 1) oder des in der Key-Eigenschaft vom Typ String festgelegten Namens. Die Overlay-Methode des Steuerelements generiert zusammengesetzte Symbole durch Übereinanderblendung zweier Bilder der Bildliste unter Berücksichtigung einer Transparenzfarbe. Eigenschaften
................................................... Eigens c ha ften BackColor, hImageList, ImageHeigth, ImageWidth, Index, ListImages, MaskColor, Name, Object, Parent, Tag, UseMaskColor Eigenschaft
Beschreibung
BackColor
Wird von der Methode Overlay sowie von ListImage.Draw als Hintergrundfarbe für resultierende transparente Bereiche verwendet, wenn UseMaskColor und MaskColor passend gesetzt sind
hImageList
Zur Laufzeit schreibgeschützter Long-Wert mit dem Handle des Steuerelements (wird nur für Win32-API-Aufrufe benötigt)
ImageHeight ImageWidth
Integer-Werte, die die Breite und Höhe (in Bildpunkten) der Symbole festlegt, die mit ListImage.DrawIcon, ListImage.Draw und Overlay generiert werden. Die Werte sind schreibgeschützt, wenn die Bildliste Einträge enthält.
43 6
Abbildungsliste- Steuerelement ( ImageList)
Beschreibung
ListImages
Auflistung mit Elementtyp ListImage und Basis 1
MaskColor
Long-Wert, der die Transparenzfarbe für die Maskierung transparenter Bereiche ausdrückt. Wird von Overlay, ListImage.Draw und ListImage.DrawIcon verwendet, wenn UseMaskColor auf True gesetzt ist.
Object
Verweis auf das nackte (Steuerelement-)Objekt, das dem Visual-BasicObjekt zugrunde gelegt ist. Wird in speziellen Fällen für die Auflösung von Namensbereichkonflikten benötigt, wenn das Visual-Basic-Objekt eine Eigenschaft oder Methode des untergelegten Objekts durch eine gleichnamige Eigenschaft oder Methode »verdeckt«.
UseMaskColor
Boolean-Wert, der bestimmt, ob die in MaskColor festgelegte Farbe als Transparenzfarbe für Berechnung von Symbolen durch Overlay, ListImage.Draw und ListImage.DrawIcon verwendet wird
................................................... Methoden Methoden
Function Objekt.Overlay(Index1 | Key1, Index2 | Key2) As Picture Sub Objekt.ListImages.Add (Index As Integer, Key As String, _ Picture As Picture) Sub Objekt.ListImages.Remove(Index | Key) Sub Objekt.ListImages.Clear() Sub Objekt.ListImage(Index | Key).ExtractIcon() Methode
Beschreibung
Overlay
Liefert eine Komposition aus zwei Bildern der Bildliste als Symbol. Zur Auswahl der Bilder kann wahlweise die Index- oder Key-Eigenschaft der Bilder übergeben werden, wobei das im zweiten Parameter genannte Bild über das andere gelegt wird. Die Methode beachtet die Eigenschaften ImageHeight, ImageWidth sowie insbesondere, falls UseMaskColor auf True gesetzt ist, MaskColor und BackColor.
Remove
Entfernt das über die Index- oder Key-Eigenschaft spezifizierte Bild aus der Abbildungsliste
Add
Fügt das Bild Picture in die Abbildungsliste ein und ordnet ihm den Namen Key zu. Ist für Index kein Wert spezifiziert, wird das Bild als letztes Bild in die Liste eingefügt, ansonsten an der durch Index spezifizierten Position (Zählung beginnt bei 1).
Clear
Entfernt alle Bilder aus der Abbildungsliste
ExtractIcon
Liefert das Listenelement als Symbol unter Beachtung der Eigenschaften ImageHeight, ImageWidth sowie UseMaskColor. Als Transparenzfarbe fungiert die Farbe MaskColor. Falls UseMaskColor auf False gesetzt ist, generiert die Methode das Symbol im markierten Zustand (Hintergrundfarbe invertiert). Die maximale Symbolgröße, mit der die Methode zurechtkommt, ist 144 Bildpunkte.
43 7
ActiveX- Steuerelemente (OCX) – Windows- Standardsteuerelemente
Eigenschaft
ActiveX- Steuerelemente ( OCX) Windows- Standardsteuerelemente
Anwendung
ActiveX- Steuerelemente (OCX) – Windows- Standardsteuerelemente
................................................... Anwendung
Es gibt fünf Windows-Standardsteuerelemente, die speziell auf die Zusammenarbeit mit einem ImageList-Objekt ausgelegt sind und von diesem ihre Bilder beziehen: CoolBar, ImageCombo, TabStrip, TreeView und Toolbar. Sie können das Steuerelement aber auch für eigene Zwecke einsetzen, wenn sie mehrere Bilder verwalten müssen. Am einfachsten ist der Umgang mit einer Abbildungsliste, wenn Sie die Eigenschaften bereits zur Entwurfszeit interaktiv gestalten. Öffnen Sie dazu den Eigenschaftsdialog des im Entwurfsbereich platzierten Steuerelements über das Kontextmenü und aktivieren Sie die Registerkarte ABBILDUNGEN. Bilder, die Sie zur Entwurfszeit einfügen, speichert Visual Basic in der unkompilierten Fassung automatisch in einer binären Anhangsdatei (FRX, CTX etc.) und in der kompilierten Fassung als Ressource in der Exe-Datei. Wenn Sie die Eigenschaften ImageHeight und ImageWidth nicht explizit vorher (auf der Registerkarte ALLGEMEIN) setzen, richten sie sich nach den Abmessungen (in Bildpunkten) des zuerst eingefügten Bildes – und lassen sich später auch nicht mehr ändern. Um ein Bild zur Laufzeit mit einem Namen ansprechen zu können (was im Zusammenspiel mit anderen Steuerelementen recht vorteilhaft ist), setzen Sie die Key-Eigenschaft des jeweiligen Listenelements.
Eigensc haftsdialog eines Abbildungsliste- Steuerelements
Das Abbildungsliste-Steuerelement akzeptiert diverse Grafikformate (DIB, BMP, ICO, CUR, GIF, JPG) und hat vom Prinzip her auch keine Probleme damit, wenn die Bilder unterschiedliche Größen aufweisen. Im Zusammenspiel mit den genannten Windows-Standardsteuerelementen sorgt nämlich die Methode ExtractIcon für die Umwandlung in das Symbolformat, passt die Größe automatisch auf ImageHeight und ImageWidth an und nimmt gegebenenfalls eine Maskierung vor, wenn UseMaskColor den Wert True hat und MaskColor auf eine geeignete Transparenzfarbe gesetzt wurde. Beachten Sie, dass die Symbolgröße auf 144×144 Bildpunkte limitiert ist. Das Steuerelement lässt sich natürlich auch erst zur Laufzeit initialisieren. Sie können die Bilder für die Listeneinträge dann einzelnen aus bereitgestellten Grafikdateien laden, sollten es aber nicht versäumen, die Eigenschaften ImageHeight und ImageWidth vorher passend zu setzen. With ImageList1 .ImageHeight = 50 .ImageWidth = 150 .ListImages.Add , "Bild01", LoadPicture(App.Path & "Bild01.jpg") .ListImages.Add , "Bild02", LoadPicture(App.Path & "Bild02.jpg") ' ... usw.
43 8
Weitere ActiveX- Steuerelemente
.ListImages.Add , "Bild21", LoadPicture(App.Path & "Bild21.jpg") .MaskColor = vbWhite .UseMaskColor = True .BackColor = vbRed End With
PictureClip1.Rows = 3 PictureClip1.Cols = 7 PictureClip1.Picture = LoadPicture(App.Path & "Bilder.jpg") ImageList1.ImageHeight = 50 ImageList1.ImageWidth = 150 Dim Key As String, i As Integer For i = 0 To 20 Key = "Bild" & Right("0" & CStr(i + 1), 2) ImageList1.ListImages.Add , Key, PictureClip1.GraphicCell(i) Next i
Für den Zugriff auf ein einzelnes Bild gibt es mehrere Möglichkeiten. Um das Bild in der ursprünglichen Form wiederzugewinnen, schreiben Sie: Picture1 = ImageList1.ListImages(Index).Picture
Um das Bild als Symbol mit den Abmessungen ImageHeight und ImageWidth zu erhalten, schreiben Sie: Picture1 = ImageList1.ListImages(Index).ExtractIcon
Um das Bild als Symbol mit den Abmessungen ImageHeight und ImageWidth zu erhalten, das mit einem zweiten Bild überlagert ist, schreiben Sie: Picture1 = ImageList1.Overlay (Index, IndexZweitesBild)
Um das Bild in Symbolgröße in ein Formular Form1 an die Position 1000, 1000 zu zeichnen, schreiben Sie: Picture1 = ImageList1.ListImages(Index).Draw Form1.hDC, 1000, 1000 Verwandte Steuerelemente
................................................... Verwandte S teuerelemente PictureClip
Weitere ActiveX- Steuerelemente Neben den Windows-Standardsteuerelementen gehört zum Lieferumfang der Professional Edition von Visual Basic noch eine beachtliche Sammlung weiterer Steuerelemente, von denen jedes für sich eine eigene mehr oder weniger komplexe Programmierwelt mit sich bringt. So steckt beispielsweise hinter dem ADO-Steuerelement die gesamte Welt der ActiveX Data Objects, der neuen Datenbankschnittstelle von Microsoft, die dem Modell des verallgemeinerten unternehmensweiten Datenzugriffs (Universal Data Access) entsprungen ist und eine Erweiterung des
43 9
Weitere ActiveX- Steuerelemente
Eine bewährte Technik ist es, das Bildausschnitt-Steuerelement (PictureClip) als Bildquelle für das Abbildungsliste-Steuerelement einzusetzen. Gerade, wenn eine größere Anzahl von Symbolen oder Bitmaps gleicher Größe benötigt wird, lassen sich die Bildressourcen dann sehr vorteilhaft in einer einzigen externen Datei zusammenfassen, die auch im Nachhinein noch geändert werden kann:
Weitere ActiveX- Steuerelemente
Weitere ActiveX- Steuerelemente
ODBC-Standards für relationale und nichtrelationale Datenbanksysteme. Das Steuerelement unterstützt neben OLE DB auch den Datenzugriff über die älteren Datenbankschnittstellen ODBC und DAO. Hinzu kommt natürlich noch die schier unüberschaubare Fülle an ActiveX-Steuerelementen, die von Drittherstellern vertrieben werden und deren Programmierschnittstellen von beachtlicher Komplexität sein können. Früher als OLE-Steuerelemente bezeichnet, laufen diese Steuerelemente heute unter der Bezeichnung ActiveX-Steuerelemente und genügen dem COM-Standard, so dass sie sich nicht nur als Benutzeroberflächenobjekte für das gewöhnliche Design von Visual-Basic-Formularen und -Benutzersteuerelementen mit den üblichen Möglichkeiten der Datenbankanbindung eignen, sondern darüber hinaus für die Belebung und Ausgestaltung von HTML-Seiten (die im Internet-Explorer angezeigt werden) zur Verfügung stehen. Um ein ActiveX-Steuerelement in die Werkzeugsammlung zu laden, rufen Sie das Dialogfeld KOMPONENTEN über den Menübefehl PROJEKT/KOMPONENTEN AUF und setzen auf der Registerkarte STEUERELEMENTE vor den Namen der Komponentendatei ein Häkchen. Die folgende Tabelle gibt einen Überblick über die wichtigsten ActiveX-Steuerelemente: Steuerelement
Komponentendatei
Bestimmung des Steuerelements
Adodc
Microsoft ADO Data Control 6.0 (SP3) (OLE DB) MSADODC.OCX
Datensteuerelement für Datenbankanbindungen an OLE-Datenbankdateien auf Basis der ActiveX Data Objects (ADO-Schnittstelle). Die verschiedenen OLE-DB-Provider machen das Steuerelement zum vollständigen Ersatz für die älteren Datensteuerelemente Data und RemoteData.
CommonDialog
Microsoft Common Dialog Control 6.0 (SP3) COMDLG.OCX
Steuerelement ohne sichtbare Darstellung, das die Windows-Standarddialoge Öffnen, Speichern unter, Drucken, Schriftart, Farbe als eigenständige Dialogfelder anzeigen kann.
DataCombo
Microsoft DataList Controls 6.0 (SP3) (OLE DB) MSDATLST.OCX
Für ADO optimierte, codekompatible Variante von DBCombo
DataGrid
Microsoft DataGrid Control 6.0 (SP3) (OLE DB) MSDATGRD.OCX
Für ADO optimierte, codekompatible Variante von DBGrid
DataList
Microsoft DataList Controls 6.0 (SP3) (OLE DB) MSDATLST.OCX
Für ADO optimierte, codekompatible Variante von DBList
DataRepeater
Microsoft DataRepeater Control 6.0 (OLE DB) MSDATREP.OCX
Für ADO konzipiertes Steuerelement, das die ressourcensparende Wiederholung eines Steuerelements (meist Benutzersteuerelement) mit Datenbankbindung zur Anzeige fortlaufender Datensätze eines Recordset-Objekts einer Datenquelle (Adodc, Data, RemoteData) ermöglicht
440
Weitere ActiveX- Steuerelemente
Komponentendatei
Bestimmung des Steuerelements
DBCombo
Microsoft Data Bound List Controls 6.0 DBLIST32.OCX
Speziell auf die Arbeit mit Datenbankinformationen optimierte Variante des Kombinationsfelds (vgl. ComboBox), dessen Listeneinträge automatisch von einem Recordset-Objekt einer Datenquelle (Data, RemoteData) mit den Werten eines einzelnen Datenfelds aufgefüllt und gepflegt werden
DBGrid
Microsoft Data Bound Speziell auf die Arbeit mit Datenbankinformationen Grid Control 5.0 (SP3) ausgelegtes Datenblatt-Steuerelement, das die Datensätze eines Recordset-Objekts einer DatenDBGRID32.OCX quelle (Adodc, Data, RemoteData) als Tabellenblatt darstellt und die interaktive Bearbeitung ermöglicht
DBList
Microsoft Data Bound List Controls 6.0 DBLIST32.OCX
Speziell auf die Arbeit mit Datenbankinformationen optimierte Variante des Listenfelds (vgl. ListBox), dessen Listeneinträge automatisch von einem Recordset-Objekt einer Datenquelle (Adodc, Data, RemoteData) mit den Werten eines einzelnen Datenfelds aufgefüllt und gepflegt werden
Inet
Microsoft Internet Transfer Control 6.0 MSINET.OCX
Steuerelement ohne sichtbare Darstellung, das eine Implementation der beiden wichtigsten Internetprotokolle HTTP und FTP für das Abrufen von HTML-Dokumenten aus dem Internet sowie die Ausführung von FTP-Befehlen bereitstellt
MaskEdBox
Microsoft Masked Edit Textfeld (vgl. TextBox), das auf die Eingabe von Werten mit spezifischen Formaten spezialisiert ist. Control 6.0 (SP3) Die Formatbeschreibung erfolgt als Zeichenfolge MSMASK32.OCX mit Formatsymbolen
MMControl
Microsoft Multimedia Control 6.0 (SP3) MCI32.OCX
Ermöglicht die Steuerung von Aufnahme- und Wiedergabegeräten über die MCI-Schnittstelle des Systems
MSChart
Microsoft Chart Control 6.0 (SP3) (OLEDB) MSCHRT20.OCX
Ermöglicht die grafische Darstellung von Diagrammen auf Basis eines DataGrid-Steuerelements
MSComm
Microsoft Comm Con- Ermöglicht die direkte Kommunikation über die seriellen Schnittstellen des Systems trol 6.0 MSCOMM32.OCX
MSFlexGrid
Microsoft FlexGrid Control 6.0 (SP3) MSFLXGRD.OCX
Tabellenblatt für die tabellarische Anzeige von Daten (Text und Bilder) in verschiedenen Sortierungen und Formaten
441
Weitere ActiveX- Steuerelemente
Steuerelement
Weitere ActiveX- Steuerelemente
Weitere ActiveX- Steuerelemente
Steuerelement
Komponentendatei
Bestimmung des Steuerelements
MSHFlexGrid
Microsoft Hierachical FlexGrid Control 6.0 (SP3) MSHFLXGD.OCX
Tabellenblatt für die tabellarische Anzeige hierarchisch gruppierter Daten (Text und Bilder) in verschiedenen Sortierungen und Formaten. Das Steuerelement ist speziell für die Zusammenarbeit mit dem ADO-Steuerelement konzipiert und ermöglicht die Anzeige relational abhängiger Datensatzgruppen.
PictureClip
Microsoft PictureClip Control
Bildausschnitt-Steuerelement, das die Extraktion von Teilbildern einer gegebenen Bitmap unter Angabe eines Reihen-/Spaltenindex oder eines Begrenzungsrechtecks unterstützt
RichTextBox
Microsoft Internet Control SHDOCVW.DLL
Erweiterte Variante des Textfelds (TextBox) für die Darstellung und Bearbeitung von formatierten Texten im RTF-Format.
WebBrowser
Microsoft Internet Control SHDOCVW.DLL
Browser-Fenster mit einem großen Teil der Funktionalität des Internet Explorer, das die Navigation im Internet, Intranet sowie auf dem lokalen System ermöglicht
WinSock
Microsoft Winsock Control 6.0 MSWINSCK.OCX
Steuerelement ohne sichtbare Darstellung, das den Port-basierten Verbindungsaufbau mit im TCP/IPNetzwerk gelegenen Servern und den Datenaustausch über Datagramme (UDP) sowie verbindungsorientiert (TCP) ermöglicht.
Die vorliegende Ausgabe dieser Referenz stellt in der Folge nur die zwei sehr grundlegenden ActiveX-Steuerelemente PictureClip und CommonDialog ausführlicher vor.
Bildausschnitt- Steuerelement (PictureClip) ImageList1 As ImageList Beschreibung
................................................... Bes c hreibung
Das zur Laufzeit unsichtbare Bildausschnitt-Steuerelement bietet zwei verschiedene Techniken an, Teilbilder als eigenständige Bitmaps aus einer größeren Bitmap zu gewinnen. Zum einen lässt sich die Bitmap über die Eigenschaften Rows und Cols gleich einem Gitter in gleich große Grafikzellen unterteilen, die das Steuerelement dann über die Array-Eigenschaft GraphicCell verfügbar macht. Zum anderen liefert die Clip-Eigenschaft frei definierbare Teilbilder der Bitmap. Schließlich ermöglicht das Steuerelement auch noch die Skalierung der Grafikzellen bzw. Teilbilder auf frei definierbare Abmessungen. Eigenschaften
................................................... Eigens c ha ften CellHeight, CellWidth, Clip, ClipHeight, ClipWidth, ClipX, ClipY, Cols, GraphicCell, Height, hWnd, Index, Name, Object, Parent, Picture, Rows, StretchX, StretchY, Tag, Width,
442
Bildausschnitt- Steuerelement ( PictureClip)
Beschreibung
CellHeight CellWidth
Integer-Werte, die Höhe und die Breite des Bildausschnitts (Clip-Eigenschaft) in Bildpunkten ausdrücken. Diese Werte werden bei Änderung der Eigenschaften Cols bzw. Rows automatisch aktualisiert und sind zur Laufzeit schreibgeschützt.
Clip
Picture-Wert, der den durch ClipX, ClipY, ClipHeight, ClipWidth beschriebenen Bildausschnitt liefert
ClipHeight ClipWidth
Höhe und Breite des von Clip gelieferten Bildausschnitts
ClipX ClipY
Koordinaten der linken oberen Ecke des von Clip gelieferten Bildausschnitts in Bildpunkten
Cols
Integer-Wert für die Anzahl der Spalten, in die das Steuerelement das Gesamtbild (Picture) für die Bildung von Zellen aufteilt
GraphicCell
eindimensionales Array (0-basiert) mit Elementtyp Picture, das die implizit über Rows und Cols definierten Grafikzellen liefert
Picture
Gesamtbild, aus dem das Steuerelement seine Ausschnitte liefert
Rows
Integer-Wert für die Anzahl der Zeilen, in die das Steuerelement das Gesamtbild (Picture) für die Bildung von Zellen aufteilt
StretchX StretchY
Breite und Höhe in Bildpunkten, auf die das Steuerelement alle GraphicCell-Elemente skaliert. Die Voreinstellungen für diese Werte sind die Werte von CellHeight und CellWidth.
Anwendung
................................................... Anwendung
Wer in seinen Programmen viel mit Bildern zu tun hat, wird ein Lied davon singen können, wie aufwändig und lästig die Bereitstellung von Bildressourcen sein kann, gleich ob dies zur Entwurfszeit oder zur Laufzeit geschieht. Wenn zig Einzeldateien nicht nur einzeln geladen, sondern auch gepflegt sein wollen, ist es meist günstiger, mehrere Bilder in einer einzelnen Bilddatei zusammenzufassen und erst zur Laufzeit wieder zu extrahieren – zumal wenn die Bilder wie im Falle von Symbolleisten, Puzzle-Elementen oder Spielfiguren, um nur einige Anwendungsbeispiele zu nennen, noch die gleichen Abmessungen besitzen. Wird die Picture-Eigenschaft des Steuerelements bereits zur Entwurfszeit über das Eigenschaftsfenster gesetzt, speichert Visual Basic die entsprechende Bitmap zunächst als binären Anhang in einer separaten Datei (FRX-Datei für Formulare). In der kompilierten Fassung enthält die EXE-Datei alle binären Anhänge als Ressourcen, so dass die Quelldatei nicht weiter bereitgestellt werden muss. Anders jedoch, wenn die Bitmap erst zur Laufzeit mittels LoadPicture eingelesen wird. In diesem Fall muss die entsprechende Grafikdatei weiterhin verfügbar sein. PictureClip1.Picture = LoadPicture(App.Path + "\figuren.bmp")
Die Aufteilung in einzelne Zellen können Sie zur Entwurfszeit oder zur Laufzeit vornehmen, indem Sie die Eigenschaften Rows und Cols geeignet setzen. Wenn die Bitmap nebeneinander 13 Einzelbilder für die Abbildungsliste einer Symbolleiste enthält, schreiben Sie: PictureClip1.Rows = 1 PictureClip1.Cols = 13
443
Weitere ActiveX- Steuerelemente
Eigenschaft
Weitere ActiveX- Steuerelemente
Falls die zu extrahierenden Teilbilder noch einer Skalierung bedürfen, können Sie StretchX und StretchY auf die gewünschte Zielgröße in Bildpunkten setzen, bevor der Zugriff über die GraphicCell-Eigenschaft erfolgt (bei Skalierung ist es generell besser, wenn verkleinert wird).
Weitere ActiveX- Steuerelemente
PictureClip1.StretchX = 16 PictureClip1.StretchY = 16 For i = 0 To 12 ImageList1.ListImages.Add , , PictureClip1.GraphicCell(i) Toolbar1.Buttons(i).Image = i ' gleich zu ordnen Next i
Um einen beliebigen Bildausschnitt zu erhalten, arbeiten Sie mit der Clip-Eigenschaft, nachdem Sie die Koordinaten des linken oberen Punkts sowie die Abmessungen des gewünschten Teilbildes gesetzt haben. With PictureClip1 .ClipHeight = ch: .ClipWidth = cw: .ClipLeft = cl: .ClipTop = ct Object.Picture = PictureClip1.Clip End With Beispiel
................................................... Beis piel
Der folgende Codeauszug aus dem Beispielprojekt Schach des Praxisteils zeigt die Initialisierung von Steuerelementen mit den Bildern der Schachfiguren. With PictureClip1 .Picture = LoadPicture(App.Path + "\Schachfiguren.bmp") .Rows = 2 .Cols = 6 End With For i = 0 To 31 ' Element mit Index 0 ist "Same" If i > 0 Then Load figur(i) Set figur(i).MaskPicture = PictureClip1.GraphicCell(FigIdx(i)) Set figur(i).Picture = PictureClip1.GraphicCell(FigIdx(i)) Next i Verwandte Steuerelemente
................................................... Verwandte Steuerelemente ImageList
Standarddialoge- Steuerelement (CommonDialog) CommonDialog1 As CommonDialog Beschreibung
................................................... Bes c hreibung
Das Standarddialoge-Steuerelement enthält die Implementation der wichtigsten Dialoge für die Windows-Programmierung: Öffnen, Speichern unter, Schriftart, Farbauswahl Drucken und Drucker einrichten. Entsprechend verfügt das Steuerelement für den Aufruf eines jeden Dialogs eine eigene Show-Methode (einzig Drucken und Drucker einrichten werden über die gleiche Methode aufgerufen) sowie eine Fülle von Eigenschaften, die zum einen die Konfiguration der Dialoge vor dem Aufruf und zum anderen die Entgegennahme der Benutzereingaben nach dem Aufruf ermöglichen. Die Voreinstellungen sind so gewählt, dass die Vorbereitungen für den Aufruf der Dialoge minimal sind. Darüber hinaus gestattet es die Flags-Eigenschaft, jeden ein-
444
Standarddialoge- Steuerelement ( CommonDialog)
zelnen Dialog vor dem Aufruf speziell zu konfigurieren sowie die spezifische Einstellungen des Benutzers in Erfahrung zu bringen, um den vollen Funktionsumfang des Steuerelements auszunutzen. Eigenschaften
................................................... Eigens c ha ften
Eigenschaft
Beschreibung
Action
Aus Gründen der Abwärtskompatibilität nach wie vor unterstützte Eigenschaft, deren Setzen die Anzeige eines Standarddialogs bewirkt; die möglichen Werte sind: 0 – keine Aktion; 1 – Öffnen; 2 – Speichern unter; 3 – Farbe; 4 – Schriftart; 5 – Drucker; 6 – Aufruf des Hilfesystems
CancelError
Boolean-Wert, der bestimmt, ob das Steuerelement einen Fehler signalisiert, wenn der Benutzer die Schaltfläche ABBRECHEN anklickt (True) oder nicht (False; Voreinstellung)
Color
Long-Wert, der die aktuelle Farbauswahl des Standarddialogs Farbe vorgibt bzw. liefert
Copies
Integer-Wert, der die Kopienanzahl des Standarddialogs Drucker vorgibt bzw. liefert
DefaultExt
String-Wert für die standardmäßige Dateierweiterung des von den Standarddialogen Öffnen, Schriftart und Speichern unter gelieferten Dateinamens; das Steuerelement ergänzt die Erweiterung, falls sie fehlt
DialogTitle
String-Wert für den Titel des aufgerufenen Standarddialogs
FileName
String-Wert, der den ausgewählten Dateinamen samt Pfad für die Dialoge Öffnen, Schriftart und Speichern unter vorgibt bzw. liefert
FileTitle
Schreibgeschützter String-Wert, der den über die Dialoge Öffnen, Schriftart und Speichern unter ausgewählten Dateinamen ohne Pfad liefert
Filter
String-Wert, der einen Dateiauswahlfilter für die Dialogfelder Öffnen, Schriftart und Speichern unter vorgibt. Ein Filter setzt sich aus einem Filtereintrag für die Liste DATEITYP und einer Suchspezifikation (Platzhalter * und ? erlaubt) getrennt durch das Zeichen »|« zusammen. Um mehrere Filter für einen Eintrag zur Auswahl zu stellen, sind die Suchspezifikationen durch ein Semikolon zu trennen. Beispiel: "Bilder (JPG, GIF, BMP)|*.jpg;*.gif;*.bmp". Mehrere Filter werden gleichfalls durch das Zeichen »|« getrennt. Beispiel: "JPG|*.jpg|GIF|*.gif|BMP|*.bmp".
445
Weitere ActiveX- Steuerelemente
Action, CancelError, Color, Copies, DefaultExt, DialogTitle, FileName, FileTitle, Filter, FilterIndex, Flags, Font, FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontUnderline, FromPage, hDC, HelpCommand, HelpContext, HelpFile, HelpKey, Index, InitDir, Left, Max, Min, MaxFileSize, Name, Object, Orientation, Parent, PrinterDefault, Top, ToPage
Weitere ActiveX- Steuerelemente
Weitere ActiveX- Steuerelemente
Eigenschaft
Beschreibung
FilterIndex
Integer-Wert, der einen in der Eigenschaft Filter definierten Filter über seine Position auswählt bzw. den Index des vom Benutzer verwendeten Filters liefert; Voreinstellung ist 1; ungültige Indizes interpretiert das Steuerelement gleichfalls als 1
Flags
Long-Wert, der als Bitvektor Optionen für die einzelnen Dialoge festlegt bzw. liefert. Die einzelnen Flags ermöglichen eine zusätzliche Konfiguration der Dialoge, insbesondere der Zustände der Kontrollkästchen und Optionsfelder. (Die Bedeutung der einzelnen Flags entnehmen Sie der Online-Hilfe zu Visual Basic.)
FontBold, FontItalic, FontName, FontSize, FontStrikeThru, FontUnderline
Schrifteigenschaften für den Dialog Schriftart
FromPage ToPage
Integer-Werte, die den Seitenbereich für den Dialog Drucken vorgeben bzw. liefern (Achtung: Die Vorgaben für den Dialog müssen mit den Eigenschaften Min und Max vereinbar sein, sonst meldet der Dialog einen Initialisierungsfehler.)
HelpCommand
Integer-Wert, der als Bitvektor Kommandos für einen eventuellen Aufruf des Hilfesystems vorgibt bzw. liefert (die Bedeutung der einzelnen Flags entnehmen Sie der Online-Hilfe zu Visual Basic)
HelpContext
Long-Wert, der eine Kontext-Kennung für den Aufruf des Hilfesystems ausgibt (Voraussetzung: HelpCommand wird auf cdlHelpContext gesetzt)
HelpFile
String-Wert mit dem Zugriffspfad für die Hilfedatei. Wenn leer, wird die Visual-Basic-Hilfedatei benutzt.
HelpKey
String-Wert, der ein Stichwort für den Aufruf des Hilfesystems spezifiziert (Voraussetzung: HelpCommand wird auf cdlHelpKey gesetzt)
InitDir
String-Wert, der das Anfangsverzeichnis für die Auswahl eines Dateinamens bestimmt. Wenn leer, wird das standardmäßige Arbeitsverzeichnis (CurDir) verwendet. Um eine Änderung des Standardverzeichnisses durch den Dialog zu verhindern, setzen Sie das Flag cdlOFNNoChangeDir (&H8).
Max Min
Integer-Werte, die die maximale/minimale Seitenzahl für den Dialog Drucken bzw. die maximale Zeichengröße für den Dialog Schriftart spezifizieren. Wenn 0, kann keine Seitenauswahl im Dialog Drucken stattfinden
MaxFileSize
Integer-Wert, der die maximale Länge des Dateinamens für die Eigenschaft FileName festlegt. Vorgabe ist 256. Der Wert lässt sich zwischen 1 und 32.768 wählen.
Orientation
Integer-Wert, der die Papierausrichtung im Dialog DRUCKER EINRICHTEN vorgibt bzw. liefert: cdlPortrait (1) steht für Hochformat, cdlLandscape (2) für Querformat
446
Standarddialoge- Steuerelement ( CommonDialog)
Eigenschaft
Beschreibung
PrinterDefault
Boolean-Wert, der bestimmt, ob der Dialog Drucken den ausgewählten Drucker zum Standarddrucker des Systems erklärt (True) oder nicht (False)
Methoden
................................................... Metho den AboutBox, ShowColor, ShowFont, ShopHelp, ShowOpen, ShowPrinter, ShowSave Beschreibung
AboutBox
Zeigt den Infodialog des Standarddialogs an
ShowColor
Zeigt den Standarddialog Farbe an. Nach dem Aufruf enthält die Eigenschaft Color die Farbauswahl des Benutzers.
ShowFont
Zeigt den Standarddialog Schriftart an. Der erfolgreiche Aufruf setzt voraus, dass eines der Flags cdlCFScreenFonts (&H1), cdlCFBoth (&H3) oder cdlCFPrinterFonts (&H29) gesetzt wurde. Nach dem Aufruf enthält die Eigenschaft Font die Schriftauswahl des Benutzers.
ShowHelp
Ruft das Windows-Hilfesystem mit der über die Eigenschaft HelpFile gesetzten Hilfedatei auf
ShowOpen
Zeigt den Standarddialog Öffnen an. Nach dem Aufruf enthalten die Eigenschaften FileName sowie FileTitle den vom Benutzer gewählten Dateinamen. Der Wert des Kontrollkästchens SCHREIBSCHUTZ lässt sich über das Flag cdlOFNNoReadOnlyReturn ermitteln
ShowPrinter
Zeigt den Standarddialog Drucken an. Nach dem Aufruf enthält hDC den Gerätekontext des gewählten Druckers, FromPage und ToPage enthalten den zu druckenden Seitenbereich, Orientation enthält die Papierausrichtung, und Copies enthält die Anzahl der zu druckenden Kopien. Die Werte der Optionsfelder sowie Kontrollkästchen lassen sich über die Flags-Eigenschaft setzen und in Erfahrung bringen. Wird die Flags-Eigenschaft vor dem Aufruf auf cdlPDPrintSetup (&H40) gesetzt, erscheint nicht der Dialog Drucken, sondern Drucker einrichten.
ShowSave
Zeigt den Standarddialog Speichern unter an. Nach dem Aufruf enthalten die Eigenschaften FileName sowie FileTitle den vom Benutzer gewählten Dateinamen.
Anwendung
................................................... Anwendung
Die Standarddialoge dürften zweifelsohne zu den segensreichsten Werkzeugen gehören, die Visual Basic einem Programmierer an die Hand gibt. Man erkennt das allein schon daran, dass es kaum Programme gibt, die nicht in der einen oder anderen Form davon Gebrauch machen. Wer von dem Steuerelement nichts Ungewöhnliches erwartet, es also nicht bis auf das Letzte ausreizen will, wird überrascht sein, wie pflegeleicht die Programmierung damit ist. Der Perfektionist hingegen, der die völlige Kontrolle anstrebt, wird nicht umhinkommen, sich mit der Flags-Eigenschaft, der Fülle der für jeden einzelnen Dialog definierten Bitwerte und der mit Bitvektoren üblicherweise verbundenen Bitkrämerei herumschlagen zu müssen.
447
Weitere ActiveX- Steuerelemente
Methode
Weitere ActiveX- Steuerelemente
Weitere ActiveX- Steuerelemente
Öffnen Um die Standarddialoge Öffnen bzw. Speichern unter anzuzeigen, rufen Sie die Methode ShowOpen bzw. ShowSave auf oder setzen die Eigenschaft Action auf 1 bzw. 2. Beide Dialoge geben das von CurDir gelieferte aktuelle Arbeitsverzeichnis vor, falls über die Eigenschaft InitDir kein anderes Verzeichnis spezifiziert ist. Den ausgewählten Dateinamen samt Pfad finden Sie nach dem Aufruf in der Eigenschaft FileName, während FileTitle nur den nackten Dateinamen wiedergibt. Wenn Sie nicht wollen, dass die Dialoge das aktuelle Arbeitsverzeichnis ändern, setzen Sie in der Flags-Eigenschaft das Flag cdlOFNNoChangeDir (&H8). Das Kontrollkästchen für die Schreibschutzeinstellung wird man über das Flag cdlOFNHideReadOnly (&H4) los, was für den Dialog Speichern unter geschehen sollte, um Verwirrungen des Benutzers vorzubeugen. Um sicherzustellen, dass der Benutzer eine bestehende Datei auswählt, setzen Sie das Flag cdlOFNFileMustExist (&H1000), was gleichzeitig die Erstellung eines neuen Verzeichnisses (cdlOFNPathMustExist = &H800) über den Dateinamen unterbindet (nichtsdestotrotz kann der Benutzer weiterhin über das Symbol NEUER ORDNER Verzeichnisse erstellen). CommonDialog1.Flags = cdlOFNNoChangeDir + _ cdlOFNHideReadOnly + cdlOFNFileMustExist CommonDialog1.ShowOpen Dateiname = CommonDialog1.FileName
Soll der Benutzer mehrere Dateien auswählen können, setzen Sie das Flag cdlOFNAllowMultiselect (&H200). Hierbei ergibt sich aber aus historischen Gründen ein kleines Problem: Da das Steuerelement das Ergebnis einer Mehrfachauswahl gleichfalls in der Eigenschaft FileName zurückliefert und dabei zur Aufrechterhaltung der Kompatibilität den Pfad und die ausgewählten Dateinamen jeweils durch ein Leerzeichen getrennt hintereinander setzt, erhalten Sie eine veraltete Version des Dialogfelds, die nur kurze Dateinamen anzeigt und liefert (ansonsten würden sich Fehler einschleichen, wenn ein Dateiname Leerzeichen enthält). Auch müssen Sie explizit einen Filter vorgeben, damit der Benutzer überhaupt eine Auswahl sieht. In der gewohnten Gestalt des Dialogfelds (also mit langen Dateinamen) lässt sich die Mehrfachauswahl vornehmen, wenn zusätzlich das Flag cdlOFNExplorer (&H80000) gesetzt wird. Im Textfeld DATEINAME des Dialogs erscheinen die Dateinamen bei Mehrfachauswahl dann in Anführungszeichen, und im Wert der Eigenschaft FileName sind Pfad und Dateinamen jeweils durch Nullzeichen voneinander getrennt. Für die Analyse splitten Sie den Wert am besten mit der Funktion Split in ein Array auf. Das Array-Element mit dem Index 0 enthält dann den Pfadnamen und die restlichen Array-Elemente die pfadlosen langen Dateinamen der Mehrfachauswahl: Dim Dateinamen() As String CommonDialog1.Flags = cdlOFNAllowMultiselect + cdlOFNExplorer CommonDialog1.ShowOpen Dateinamen = Split(CommonDialog1.FileName, Chr(0))
Leider ist der Dialog für die Mehrfachauswahl nicht sauber genug implementiert: der Puffer für die Eigenschaft FileName kann auch bei Mehrfachauswahl nicht viel mehr als 200 Zeichen aufnehmen, was bei größeren Auswahlen schnell zu Pufferfehlern führt, die das Dialogfeld dummerweise nicht immer meldet! Bleibt zu hoffen, dass sich dies im nächsten Updates ändert.
Drucken Der Aufruf des Standarddialogs Drucken erfolgt über die Methode ShowPrinter oder durch Setzen der Action-Eigenschaft auf 5. In dem Dialogfeld kann der Benutzer wählen, ob er alle Seiten des fraglichen Dokuments, die aktuelle Auswahl oder einen bestimmten Seitenbereich drucken will. Voreinstellung der Flags-Eigenschaft ist cdlPDAllPages (alle Seiten). Da diese Konstante
448
Standarddialoge- Steuerelement ( CommonDialog)
Schriftart Für den Aufruf des Standarddialogs Schriftart sorgt die Methode ShowFont bzw. das Setzen der Action-Eigenschaft auf 4. Zur Vorbereitung des Aufrufs ist es erforderlich, dem Dialog über die Flags-Eigenschaft kundzutun, welche Schriftarten im Angebot stehen sollen. Für die primäre Auswahl ist eines der folgenden Flags obligatorisch: cdlCFScreenFonts (1) für die Auswahl der Bildschriftarten; cdlCFPrinterFonts (2) für die Auswahl der Druckerschriftarten, die mit dem Gerätekontext des aktuellen Standarddruckers kompatibel sind; cdlCFBoth (3) für alle auf dem System installierten Schriften. Für die weitere Verfeinerung der Auswahl setzen Sie zusätzliche Flags wie: cdlCFFixedPitchOnly (&H4000) für nichtproportionale Schriften; cdlCFTTOnly (&H40000) für TrueType-Schriften; cdlCFScaleableOnly (&H20000) für frei skalierbare Schriften; cdlCFANSIOnly (&H400) für Schriften, die mit dem Windows-Zeichensatz konform sind; cdlCFNoVectorFonts (&H800) für Bitmap-Schriften; cdlCFWYSIWYG (&H8000) für Schriften, die für die Bildschirm- und die Druckerausgabe geeignet sind; cdlCFNoSimulation für originale, nicht von der GDI generierte Schriften. Beachten Sie, dass die Attribute sich teilweise gegenseitig ausschließen, so dass es zum Laufzeitfehler 24574 »Keine Schriftarten vorhanden« kommen kann, wenn die Auswahl leer ist. Zudem können Sie das Flag cdlCFForceFontExist (&H10000) setzen, damit das Dialogfeld die Existenz der vom Benutzer eingegebenen Schrift überprüft. Für eine Gültigkeitsprüfung der Schriftgröße setzen Sie die Eigenschaften Min und Max auf geeignete Werte sowie das Flag cdlCFLimitSize (&H2000). Zu guter Letzt können Sie über die Flags cdlCFNoFaceSel (&H80000), cdlCFNoSizeSel (&H200000) und cdlCFNoStyleSel
449
Weitere ActiveX- Steuerelemente
den Wert 0 hat, kann sie nicht für die Maskierung der Flags-Eigenschaft verwendet werden, sondern ergibt sich daraus, dass weder das Bit cdlPDPageNums (2) für den Seitenbereich noch cdlPDSelection (1) für die Auswahl gesetzt ist. Um dem Benutzer die Seitenauswahl zu ermöglichen, müssen allerdings die Eigenschaften Min und Max vor dem Aufruf auf einen Wert größer 0 gesetzt werden. Das Dialogfeld stellt dann sicher, dass der vom Benutzer angegebene Seitenbereich gültig ist, und liefert die Eingaben in den Eigenschaften FromPage und ToPage zurück. Den Wert des Drehfelds KOPIEN gibt die Copies-Eigenschaft wieder, während der Zustand des Kontrollkästchens SORTIEREN nur durch Maskierung der Flags-Eigenschaft mit cdlPDCollate (&H10) in Erfahrung zu bringen ist und der des Kontrollkästchens AUSDRUCK IN DATEI durch Maskierung mit cdlPDPrintToFile (&H20). Da das Dialogfeld auch die Auswahl des Druckers ermöglicht, stellt sich die Frage, wie damit zu verfahren ist. Die Antwort fällt für den Visual-Basic-Programmierer eher ernüchternd aus: Unerfreulicherweise gibt es keine Eigenschaft, die den Namen des gewählten Druckers preisgeben würde. Lediglich ein Gerätekontext bzw. Informationskontext lässt sich ihm über die Eigenschaft hDC entlocken, vorausgesetzt die Flags-Eigenschaft wurde vor dem Aufruf auf cdlPCReturnDC (&H100) bzw. cdlPCReturnIC (&H100) gesetzt. Beide Informationen führen in die Tiefen der GDI und erfordern gute Kenntnisse im Bereich der Win32-API-Programmierung. Dennoch, es bleibt ein Ausweg, ein unschöner, aber durchaus praktikabler: Setzt man die Eigenschaft DefaultPrinter des Steuerelements auf True, erklärt der Druckerdialog den ausgewählten Drucker automatisch zum Standarddrucker. Vorausgesetzt die TrackDefault-Eigenschaft des Printer-Objekts wurde nicht auf False gesetzt, macht das Printer-Objekt diese Änderung mit und gestattet fortan den Ausdruck auf dem gewählten Gerät. Um den ursprünglichen Standarddrucker wieder zurückzusetzen, ist allerdings ein weiterer Aufruf des Druckerdialogs nötig, sonst bleibt der gewählte Drucker dem System erhalten – unschön, wie gesagt. Anstelle von Drucken kann ShowPrinter auch den Dialog Drucker einrichten aufrufen, der es dem Benutzer ermöglicht, die Druckereinstellungen der auf dem System installierten Drucker interaktiv zu ändern. Dazu muss das Flag cdlPDPrintSetup (&H40) gesetzt werden. Die Wirkung ist gleichfalls systemweit, sofern die DefaultPrinter-Eigenschaft auf True gesetzt ist.
Weitere ActiveX- Steuerelemente
Weitere ActiveX- Steuerelemente
(&H100000) vorgeben, ob das Dialogfeld die aktuellen Werte der Eigenschaften FontName, FontSize, FontItalic und FontBold als Vorgabe markiert oder nicht. Die Eingaben des Benutzers finden sich nach dem Aufruf in den FontXX-Eigenschaften. With CommonDialog1 .FontName = FontName .FontSize = FontSize .Flags = cdlCFScreenFonts .ShowFont FontName = .FontName FontSize = .FontSize Print FontName End With
Da das Steuerelement unverständlicherweise nicht über eine Font-Eigenschaft verfügt, lassen sich verschiedene Schriftstile, die das Dialogfeld für die eine oder andere Schrift anbietet, in Visual Basic leider gar nicht auswerten.
Farbauswahl Der Standarddialog Farbe wird über die Methode ShowColor bzw. durch Setzen der ActionEigenschaft auf 3 angezeigt. Das Dialogfeld hat zwei Ansichten: eine Standardansicht sowie eine erweiterte Ansicht. Sind die Flags cdlCCFullOpen (&H2) und cdlCCPreventFullOpen (&H4) nicht gesetzt, erscheint das Dialogfeld zunächst in Standardansicht, gestattet dem Benutzer aber das Umschalten in die erweiterte Ansicht (was sich durch cdlCCPreventFullOpen verhindern lässt). In der Standardansicht kann der Benutzer seine Farbauswahl aus 48 vordefinierten Grundfarben sowie 16 benutzerdefinierten Farben treffen. In der erweiterten Ansicht hat er die Möglichkeit, selbst Farben aus dem vollen TrueColor-Spektrum zu definieren. Damit das Dialogfeld den Wert der Color-Eigenschaft als Vorgabe für die Farbauswahl kenntlich macht, setzen Sie das Flag cdlCCRGBInit (&H1). Nach dem Aufruf enthält die Color-Eigenschaft die Farbauswahl des Benutzers. With CommonDialog1 .Color = RGB(0, 128, 0) .Flags = cdlCCFullOpen + cdlCCRGBInit .ShowColor BackColor = .Color End With
450
Teil 2: Praxisteil
451
Ältere Basic- Programme nach Visual Basic portieren Wer ein älteres in Basic geschriebenes Programm unter Visual Basic zur Ausführung bringen will, wird nicht umhinkommen, einige Anpassungen vorzunehmen, um das Programm überhaupt erst einmal ans Laufen zu bringen. Und bis es dann wirklich in jeder Hinsicht das Gewünschte macht, ist zuweilen noch einiges an Schweiß erforderlich. Vom Kern her ist Visual Basic der Sprache BASIC treu geblieben – wie sollte es auch anders sein. Natürlich, Visual Basic ist von der Ausdruckskraft her um einiges reicher geworden als etwa die mit QuickBasic oder QBasic vorliegenden Implementationen der Sprache. Verloren gegangen ist aber nichts, sieht man davon ab, dass verschiedene Konzepte im Fahrwasser der Windows-Programmierung generell einen anderen Zugang benötigen, wie beispielsweise die Ein- und Ausgabe, der Umgang mit Farben, mit langen Dateinamen oder die Unicode-Darstellung von Zeichenfolgen. Insbesondere aber an den Kontrollstrukturen sowie den Datentypen und ihren Operationen hat sich außer allfälligen Komplettierungen und der Bequemlichkeit dienenden Erweiterungen nichts geändert. Mit anderen Worten, von der algorithmischen Seite her ist für die Portierung sicher am allerwenigsten zu befürchten. Auch die traditionellen Funktionen der Sprache Basic für die Manipulation von Zeichenketten sowie für mathematische Berechnungen machen verhältnismäßig wenig Schwierigkeiten, wenngleich die Umwandlung von Zeichenketten in Zahlen und zurück aufgrund der von Visual Basic beachteten länderspezifischen Zahlendarstellung sicher Ärger machen wird. Der schwierigste Teil ist aber unbestritten die Bildschirmausgabe gleich gefolgt von der Eingabe. Die folgende Tabelle bietet einen Überblick über das Problempotenzial spezifischer Bereiche. Bereich
Macht Probleme?
Kontrollstrukturen und Algo- Keine Probleme zu befürchten rithmen Konstanten, Variablen, Bezeichner
Weitgehend problemlos; globale Variablen bedürfen der Überarbeitung und implizit deklarierte lokale Variablen der Kontrolle auf Namenskonflikte
Datentypen und Operationen Kaum Probleme zu befürchten Mathematische Funktionen
Problemlos, neue Funktionen machen vieles einfacher, zum Beispiel die Rundung, finanzmathematische Funktionen
Selbst definierte Funktionen und Prozeduren
Weitgehend problemfrei; Shared-Vereinbarungen (globale Variablen) müssen überarbeitet werden; Namenskonflikte bei impliziter Variablendeklaration möglich
Zeichenfolgenfunktionen
Problembehaftet, da Visual Basic länderspezifische Darstellung bei Zahlenwandlung beachtet, Unicode vs. ASCII-Code, auch die Codetabellen für die Zeichenkodierung sind leicht unterschiedlich
Dateioperationen
Weitgehend problemlos, zuweilen bereitet jedoch die Verarbeitung langer Dateinamen Schwierigkeiten
Eingabe
Problematisch – bei der Portierung ist einiges an konzeptuellen Änderungen einzuarbeiten
453
Wie importiert man den Quelltext?
Wie importiert man den Quelltext?
Bereich
Macht Probleme?
Zeichenausgabe
Sehr problematisch – Print-Anweisung verändert; Print Using fehlt, Zeilenorientierung, Cursorplatzierung anders, Schriftdefinitionen, Farbmodell anders
Grafik
Problematisch, da Veränderungen bei Koordinatensystem und Farbmodell einzuarbeiten sind und die Grafikausgabe die Position der Textausgabe beeinflusst
Fehlerbehandlung
Problemlos, weil unverändert.
Wie importiert man den Quelltext? Legen Sie ein neues Projekt des Typs »Standard-EXE« an und laden Sie den Quelltext des zu portierenden Programms als Standardmodul. Das geht entweder über den Menübefehl PROJEKT/MODUL HINZUFÜGEN oder schlicht durch Ziehen der BAS-Datei von einem Explorer-Fenster in das Projektfenster. Um keine Verfälschungen der Zeichencodes bei der Konversion vom DOS-Textformat nach Windows zu erhalten, können Sie den Programmtext über ein Textverarbeitungsprogramm dezidiert als MSDOS-Text importieren und über die Zwischenablage nach Visual Basic transferieren.
Einfache Programme In keiner anderen Programmiersprache werden mehr Programmskizzen geschrieben, die irgendwelche kleinen Berechnungen anstellen und das Ergebnis ausgegeben, als in Basic. Meist fehlt einfach ein passender Interpreter, um diese Programme wieder zum Leben zu erwecken. Auch wenn man diese Programme vom Prinzip her wie komplexe Programme nach Visual Basic portieren könnte, lohnt sich der Aufwand in den meisten Fällen eher nicht – und mit kleineren Abweichungen im Bereich der Ein- und Ausgabe lässt sich sicher leben. Wenn es Ihnen reicht, dass Print-Ausgaben im Direktfenster (aufzurufen über (Strg)+(G)) erscheinen und Eingaben über kleine Fenster via InputBox getätigt werden, ist die Portierung in wenigen Augenblicken erledigt. Betrachten wir folgendes einfache QBasic-Programm, das eine Zahl abfragt und darüber Auskunft gibt, ob es sich bei der Zahl um eine Primzahl handelt oder nicht. Nach dem Import des Quelltextes zeigt das Codefenster folgenden Inhalt: DECLARE FUNCTION Prim% (a&) Rem Primzahltester INPUT "Bitte Zahl eingeben: ", a& If Prim(a&) Then k$ = "keine " Print a&; "ist "; k$; "Primzahl" Function Prim%(a&) For i% = 2 To Sqr(a&) If a& Mod i% = 0 Then Prim% = i% Exit Function End If Next End Function
454
Einfache Programme
Visual Basic kann weder mit der DECLARE- noch mit der INPUT-Anweisung etwas anfangen, was der Editor durch Ausgabe der entsprechenden Zeilen in roter Farbe kundtut. Aber auch die Print-Anweisung macht Probleme. Um Code wie diesen ans Laufen zu kriegen, gehen Sie wie folgt vor:
Nach der Portierung sieht der Quelltext so aus: Rem Primzahltester Dim a&, k$ Sub Main() a& = InputBox("Bitte Zahl eingeben: ") If Prim(a&) Then k$ = "keine " Debug.Print a&; "ist "; k$; "Primzahl" End Sub Function Prim%(a&) For i% = 2 To Sqr(a&) If a& Mod i% = 0 Then Prim% = i% Exit Function End If Next End Function
Wer damit nicht zufrieden ist und die Implementation lieber in ein Formularmodul packen will, muss schon einiges mehr an Aufwand betreiben – und sollte sich bei dem einfachen Programm vielleicht sogar überlegen, ob er es nicht lieber gleich neu aufbaut. Ein generelles Problem bei der Umsetzung älterer Basic-Programme nach Visual Basic ist nämlich die Umsetzung des (synchronen) Programmablaufs, wenn Eingaben ins Spiel kommen. Da sich Visual Basic das ereignisorientierte Programmiermodell von Windows zu eigen macht, ist für Visual-Basic-Programme zunächst einmal kein fester Programmablauf vorgeschrieben: Das Programm reagiert vielmehr auf die einzelnen Benutzereingaben. Mit anderen Worten: Das, was die Flexibilität und Bedienfreundlichkeit von Windows-Programmen eigentlich ausmacht, wird einem bei der Portierung leider zum Hemmschuh. Sehen wir uns die Sache einmal genauer am Beispiel der INPUT-Anweisung an. Solange man auf InputBox ausweicht, bleibt zwar der synchrone Programmablauf gewahrt, die Eingabe in einem eigenen Dialogfeld stellt aber schon eine erhebliche Einschränkung dar. Der Versuch, solche Eingaben über ein Steuerelement, beispielsweise über ein einfaches Textfeld, zu realisieren,
455
Einfache Programme
1. Löschen Sie DECLARE-Anweisungen. Sie sind unter Visual Basic für modulinterne Funktionen/ Prozeduren nicht nötig. (Visual Basic benutzt Declare in anderer Syntax für den Import von Bibliotheksroutinen, die in DLLs beheimatet sind.) 2. Fassen Sie »losen Code«, das heißt den Code, der keiner Prozedur/Funktion zugeordnet ist, in einer Prozedur namens Main zusammen und deklarieren Sie alle Shared-Variablen aus den Funktionen/Prozeduren als globale Variablen. Lokale Variablen gleichen Namens müssen explizit deklariert werden, um Fehlern durch Namenskonflikte vorzubeugen. (Eine Option Explicit-Anweisung zu Beginn des Moduls deckt implizite Deklarationen auf.) 3. Ersetzen Sie Input-Anweisungen durch InputBox-Anweisungen, wobei Sie jeden via Input gelesenen Wert mit einer eigenen InputBox-Anweisung bedenken müssen. 4. Ersetzen Sie jede Print-Anweisung durch eine Debug.Print-Anweisung. 5. Definieren Sie die Methode Main im Fenster PROJEKTEIGENSCHAFTEN als Startobjekt. 6. Öffnen Sie das Direktfenster ((Str)+(G)) und starten Sie das Programm.
Einfache Programme
Einfache Programme
wirft sofort die Frage nach dem Programmablauf auf: Ein traditionelles Basic-Programm, wie unser Beispiel, erwartet an einer bestimmten Stelle im Programm eine Eingabe, um im weiteren Programmverlauf darauf rekurrieren zu können – ein Visual-Basic-Programm kann zwar auf Eingaben, die ein Benutzer in einem Textfeld vornimmt, reagieren, etwa wenn es das ValidateEreignis behandelt, den Benutzer aber zu zwingen, dies an einer bestimmten Stelle im Programmablauf zu tun, erfordert schon einige Kunstgriffe – zumal wenn mehrere (gegebenenfalls aufeinander aufbauende) Eingaben zu koordinieren sind. Im Sinne einer einfachen Portierung ist das sicher nicht.
Implementation einer eigenen Input- Routine Einen Ausweg stellt die folgende Implementation InputQB der Input-Anweisung dar: Wie InputBox arbeitet InputQB mit einem zweiten Formular, das jedoch nichts weiter als ein Textfeld enthält und an passender Position ohne Rahmen als modales Dialogfeld zum Aufruf kommt. InputQB gibt wie Input den Text EingabeAufforderung an der aktuellen Ausgabeposition aus und bereitet dann das zweite Formular für den Aufruf entsprechend vor: Schrift und Farben des Textfelds werden an das aktuelle Formular angeglichen, die Position des Formulars wird so berechnet, dass dieses an der richtigen Stelle zu liegen kommt, und die Abmessungen werden genau so getrimmt, dass es für eine einzeilige Eingabe bis zum Ende des aktuellen Formulars reicht. Sub InputQB(EingabeAufforderung As String, Param) Dim f As New InputForm ' Eingabeformular Dim RandOffsOben As Integer Dim RandOffsLinks As Integer Dim Params() As String Print EingabeAufforderung; ' Eingabeformular für die Eingabe an (CurrentX, CurrentY) vorbereiten f.Text1.BorderStyle = vbBSNone f.Text1.BackColor = BackColor f.Text1.ForeColor = ForeColor RandOffsOben = Height – ScaleHeight – (Width – ScaleWidth) / 2 RandOffsLinks = (Width – ScaleWidth) / 2 f.Left = CurrentX + Left + RandOffsLinks f.Top = CurrentY + Top + RandOffsOben f.Width = ScaleWidth – CurrentX f.Font = Font f.Height = f.TextHeight("Test") f.Text1.Height = f.Height f.Text1.Width = ScaleWidth – CurrentX f.Show vbModal, Me ' Formular aufrufen, gibt bei ' Hide die Kontrolle zurück Param = f.Text1 ' Wert übernehmen Print Param End Sub
Ein wenig verzwickt ist die Berechnung der Formularposition, da Visual Basic seine Position relativ zum Ursprung des Screen-Objekts (linker oberer Bildschirmpunkt) ausgedrückt haben will – und nicht relativ zum Formular des rufenden Codes (das ist nur bei MDI-Formularen so). Die Berechnung lebt übrigens von der Annahme, dass der untere Formularrand (Abstand zwischen der Unterkante des Client-Bereichs und der Unterkante des Formulars) genauso breit ist wie der rechte und linke Formularrand (genauer: die Hälfte der Summe).
456
Anspruchsvollere Programme
Die Implementation des zweiten Formulars InputForm sieht recht einfach aus. Sie setzt jedoch ein Textfeld Text1 an der Position (0, 0) voraus und baut darauf, dass die Eigenschaft BorderStyle zur Entwurfszeit auf »0 – Kein« gesetzt wurde – anders ist ein rahmenloser Aufruf des Formulars nicht zu bewerkstelligen. ' Modul: InputForm Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then Hide End Sub
PrimzahlTester im neuen Gewand Das Projekt PrimzahlTester ist eine etwas anspruchsvollere Portierung des zuvor vorgestellten QBasic-Programms in ein Formularmodul. Es demonstriert zum einen den Einsatz der Funktion InputQB und zum anderen, wie man den losen Programmcode im Formularmodul platziert. Private Sub Form_Load() AutoRedraw = True Show DoProgram ' Unload Me ' Bei Bedarf End Sub Sub DoProgram() InputQB "Bitte Zahl eingeben: ", Eingabe If Eingabe = "" Then Eingabe = "0" a& = Eingabe If Prim(a&) Then k$ = "keine " Print a&; "ist "; k$; "Primzahl" End Sub
Anspruchsvollere Programme Anspruchsvollere Programme – und diese dürften gut 90 Prozent des zu portierenden Codes ausmachen – verlangen nach einem Formular, das den Ausgabebildschirm im Textmodus oder im Grafikmodus simuliert. Seien Sie aber darauf gefasst, dass Ihnen hier ein gutes Stück Arbeit bevorsteht: Gerade was die Ausgabe betrifft, sind die Unterschiede und Ungereimtheiten zwischen Visual Basic und älteren Basic-Varianten nämlich am größten. Die erfolgreiche Portierung mit vertretbarem Aufwand setzt da mitunter eine erhebliche Kompromissbereitschaft voraus.
457
Anspruchsvollere Programme
Wie man sieht, tut das Formular nichts weiter, als sich nach erfolgter Eingabe in das Textfeld Text1 unsichtbar zu machen. Damit hat es folgende Bewandtnis: Da der Show-Aufruf des Formulars modal erfolgt, wird der rufende Code erst fortgesetzt, wenn das gerufene Formular die Kontrolle abgibt. Das passiert beim Ableben des Formulars, aber auch, wenn es auf »unsichtbar« gesetzt wird – zum Glück, denn anders könnte der rufende Code die Eingaben des Benutzers in das Textfeld nicht in Erfahrung bringen. Die »Parameterübergabe« lebt also davon, dass das InputForm-Objekt noch existiert, wenn die Kontrolle zurückkommt – es stirbt erst mit Beendigung der Routine. Natürlich ist die hier vorgestellte Implementation kein äquivalenter Ersatz für Input, zumal die traditionelle Syntax für diese Anweisung immer schon recht ausladend war. Die weitere Ausgestaltung dürfte aber keine Schwierigkeiten mehr bereiten.
Anspruchsvollere Programme
Anspruchsvollere Programme
Nachdem Visual Basic einige beispielsweise unter QBasic noch unverzichtbare Funktionen und Anweisungen schlicht nicht hat, steht man häufig vor der Wahl, passende »Prothesen« zu implementieren, die den alten Code »herüberretten«, oder den inkompatiblen Code mit Mitteln von Visual Basic neu zu schreiben. Ersteres kann sich lohnen, aber auch recht schnell in ein Dickicht führen, das sich durch einen beherzteren Eingriff in den Code vielleicht vermeiden ließe. Mit beiden Herangehensweisen lassen sich bis zu einem gewissen Grad befriedigende Ersatzlösungen finden, eine Äquivalenz jedoch in den wenigsten Fällen. Bedenkt man jedoch, dass ein älteres, noch aus DOS-Zeiten stammendes Programm heutzutage kaum wegen seiner überzeugenden Bildschirmdarstellung und grafischen Gimmicks portiert wird, sondern wegen seines algorithmischen Kerns, dürfte eine gewisse »Entstellung« der Benutzeroberfläche aufgrund vereinfachender Ersatzlösungen nicht so stark ins Gewicht fallen. Bevor es um die konkrete Implementation einiger Standardlösungen für die wichtigsten fehlenden Funktionen und Prozeduren geht, noch ein paar Regeln dafür, wie Sie dem Code generell zu Leibe rücken sollten: 1. Laden Sie den Code, wie gehabt, am besten in ein (neues) Standardmodul und kopieren Sie ihn von da aus häppchenweise in das Formularmodul des Projekts. 2. Entfernen Sie alle DECLARE-Anweisungen ersatzlos und verschaffen Sie sich einen Überblick über den Code. Zeilen, die der Editor in roter Farbe ausgibt, enthalten eine oder mehrere Anweisungen, mit denen Visual Basic nichts anfangen kann. Unternehmen Sie erst einmal noch nichts dagegen. Sie können diese Anweisungen später gegebenenfalls als selbst definierte Funktionen/Prozeduren nachliefern und müssen dann nur die Aufrufsyntax anpassen (hierzu gleich mehr). 3. Kopieren Sie den Code aus dem Hauptmodul in die Load-Routine des Formulars oder in eine von dieser aufgerufene Hilfsprozedur. 4. Kopieren Sie alle Funktionen und Prozeduren in das Formularmodul und gehen Sie jede einzelne Funktion/Prozedur daraufhin durch, ob sie Shared-Vereinbarungen enthält. (Shared-Variablen haben in QBasic so etwas ähnliches wie einen globalen Geltungsbereich, müssen aber von jeder Funktion/Prozedur, die damit arbeitet, eigens über Shared-Anweisungen importiert bzw. exportiert werden.) Deklarieren Sie die entsprechenden Variablen im Bereich Allgemein des Formulars als globale Variablen. Bevor Sie die Shared-Anweisungen für eine Variable entfernen, sollten Sie noch die Funktionen/Prozeduren ohne Shared-Vereinbarungen danach durchgehen, ob sie nicht zufällig die gleichen Variablenbezeichner mit impliziter Deklaration (und somit als lokale Variable) verwenden. Wenn ja, ergänzen Sie lokale Deklarationen. Ansonsten fangen Sie sich aufgrund von Namenskonflikten schwer aufzufindende Fehler ein. 5. Lokalisieren Sie die für die Eingabe sowie die für die Ausgabe zuständigen Routinen und analysieren Sie die Benutzerschnittstelle des Programms. Von diesen Routinen haben Sie am meisten Ärger zu erwarten. Treffen Sie eine Entscheidung, ob Sie Eingabeschleifen und Menüs des Programms im Stile von Windows neu implementieren oder ob Sie versuchen, den vorhandenen Code durch Bereitstellung einer geeigneten Infrastruktur zu emulieren. 6. Bereinigen Sie Ungereimtheiten bei der Zeichenfolgendarstellung: beim Import nach Windows entstellte Umlaute, Punkt-/Kommaproblematik bei der Wandlung von Zeichenfolgen in Zahlenwerte (und umgekehrt) sowie veränderte Tastaturcodes. 7. Implementieren Sie Funktionen/Prozeduren und Voraussetzungen, die Visual Basic nicht unterstützt, und passen Sie die betroffenen Aufrufe an die neue Syntax bzw. Semantik an. 8. Spannen Sie den Compiler für die Überprüfung der syntaktischen Kompatibilität ein und schreiben Sie nicht emulierbare, inkompatible Codesequenzen um. Geizen Sie nicht mit Kommentaren. 9. Testen Sie die semantische Äquivalenz des portierten Codes schrittweise durch geeigneten Testcode und schreiben Sie Codesequenzen, die nicht das gewünschte Ergebnis (meist Ausgabe) liefern, um.
458
Implementation von Inkey$ Natürlich wird jedes komplexere Programm seine eigenen Fallstricke enthalten, wenn es nicht absolut sauber implementiert und kommentiert wurde oder gar den einen oder anderen »Trick« benutzt. Generelle Regeln lassen sich für die Umsetzung der verschiedenen Programmiertechniken kaum aufstellen. Die folgenden Abschnitte stellen verschiedene Routinen vor, die sich bei der Portierung schon so mancher QBasic-Programme bewährt haben. Sie sind im Projekt QBEmulation als Standardmodul zusammengefasst. Das Projekt lässt sich gut als Ausgangspunkt für eigene Portierungen sowie Emulationen verwenden.
Implementation von Inkey$
Private InkeyChar As String Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = 0 Then ' Funktionstasten ignorieren InkeyChar = Chr(0) + Chr(KeyCode) ' Tastaturcode merken End If End Sub Private Sub Form_KeyPress(KeyAscii As Integer) InkeyChar = Chr(KeyAscii) ' Zeichen merken End Sub Function InKey$() DoEvents InKey$ = InkeyChar InkeyChar = "" End Function
Die Implementation ist zwar geradlinig, hat aber einen Haken: Die Tastaturcodes von Windows sind anders als die von DOS. So hat beispielsweise die Taste (Rechts) unter DOS den Code 77 und unter Windows den Code 39 (oder vbKeyRight). Es wird Ihnen also nicht erspart bleiben, Tastatursteuerungen komplett zu überarbeiten. Die Tastencodes entnehmen Sie dem Aufzählungstyp KeyCodeConstants. Aufgrund des DoEvents-Aufrufs ist die Implementation auch gegen Endlosschleifen gefeit (wäre da nicht das »Stehaufmännchen«-Problem, wie noch ausführlich im Abschnitt »Ereignisbehandlung mit DoEvents, ein komplexes Problemfeld«, S. 485 erläutert). Somit stellt die klassische INKEY$-Schleife – wie hier in der Implementation einer Schreibmaschine – keine Hürde mehr dar: a$ = InKey$ While a$ Chr$(27) Print a$; a$ = InKey$ Wend
459
Anspruchsvollere Programme
Neben Input fehlt Visual Basic auch die Funktion INKEY$. Hierfür lässt sich jedoch relativ einfach Ersatz finden, wenn man die Ereignisse KeyDown und KeyPress des Formulars behandelt und eine globale Variable einsetzt, um den jeweils letzten Tastendruck zu speichern. (Falls das Formular ein Steuerelement besitzt, das den Fokus erhalten kann, müssen Sie die Eigenschaft KeyPreview auf True setzen, sonst bekommt das Formular die Eingaben nicht zu sehen.) Bekanntlich liefert INKEY$ ASCII-Zeichen als Zeichenfolge der Länge 1 und alle anderen Zeichen als Tastaturcodes mit vorangestelltem Nullbyte. Da das KeyPress-Ereignis nur auftritt, wenn ein ASCII-Zeichen eingegeben wurde, arbeiten die beiden Routinen mit derselben globalen Variable.
Anspruchsvollere Programme
Implementation von LOCATE, POS, CSRLIN und COLOR
Anspruchsvollere Programme
Nicht wenige Basic-Programme sind auf einen Textbildschirm mit 80 Spalten und 25 Zeilen zugeschnitten und machen massiv von der Anweisung Locate Gebrauch, die es erlaubt, die Ausgabeposition für die Print-Anweisung frei zu setzen. Zur Abfrage der aktuellen Position findet man weiterhin die Funktionen POS und CSRLIN. Alle drei Routinen arbeiten mit dem jeweils aktuellen Koordinatensystem und lassen sich recht einfach nachrüsten. Zeilen- und Spaltenzählung sind Eins-basiert. Sub Locate(Optional Zeile = 0, Optional Spalte = 0) If Zeile Then CurrentX = ScaleLeft + (Zeile – 1) * TextWidth("A") If Spalte Then CurrentY = ScaleTop + (Spalte – 1) * TextHeight("A") End Sub Function Pos(dummy) As Integer Pos = CInt((CurrentX – ScaleLeft) / TextWidth("A") + 1) End Function Function CsrLin() As Integer CsrLin = (CurrentY – ScaleTop) / TextHeight("A") + 1 End Function
Damit das funktioniert, ist allerdings eine gewisse Vorbereitung notwendig: das Setzen einer nichtproportionalen Schrift sowie geeigneter Formularabmessungen. Private Sub Form_Load() AutoRedraw = True FontName = "Courier New" FontSize = 8 Width = Width – ScaleWidth + 80 * TextWidth("T") Height = Height – ScaleHeight + 25 * TextHeight("T") ' Testen der Methoden Locate 10, 10 Print CsrLin; Locate, 20 Print Csrlin; End Sub
Ein gravierendes Problem dürfte allerdings der fehlende automatische Umbruch am Zeilenende bei der Print-Ausgabe darstellen. Hiergegen scheint aufseiten von Visual Basic kein Kraut gewachsen zu sein, es sei denn, man implementiert die Print-Anweisung neu. Angesichts des zusätzlichen Aufwands, den das für die Portierung bedeutet, wird es meist besser sein, die entsprechenden Stellen »von Hand« zu bereinigen, als alle Print-Ausgaben umzuschreiben. Auch die Color-Anweisung lässt sich nicht völlig äquivalent implementieren, da sich eine Änderung der Hintergrundfarbe immer gleich auf das gesamte Fenster bezieht und nicht nur auf die Texthöhe und Textbreite der kommenden Print-Ausgaben. Für die korrekte Semantik müsste man gleichermaßen eine andere Implementation der Print-Anweisung bereitstellen. Sub Color(Vordergrund%, Optional Hintergrund% = 0) BackColor = QBColor(Hintergrund%) ForeColor = QBColor(Vordergrund%) End Sub
460
Koordinatensystem und Grafikmodus
Koordinatensystem und Grafikmodus
Sub Screen(Modus) Select Case Modus Case 10 ' 640x350 Width = Width – ScaleWidth + ScaleX(640, vbPixels, vbTwips) Height = Height – ScaleHeight + ScaleX(350, vbPixels, vbTwips) ScaleMode = vbPixels Case 11, 12 ' 640x480 Width = Width – ScaleWidth + ScaleX(640, vbPixels, vbTwips) Height = Height – ScaleHeight + ScaleX(480, vbPixels, vbTwips) ScaleMode = vbPixels Case Else Err.Raise 1000, , "Bildschirmmodus nicht implementiert" End Select End Sub
Lassen Sie sich nicht von den Eigenschaften Height und Width ärgern! Diese Eigenschaften erwarten unabhängig vom eingestellten Koordinatensystem ihre Werte immer in Twips. Eine generelle Implementation der SCREEN-Funktion ist wahrlich »kein Zuckerschlecken« und dürfte zu sehr umständlichen Lösungen führen. Am besten, Sie schreiben das zu portierende Programm nach Möglichkeit um. Einfacher haben Sie es mit der WINDOW-Anweisung. Sie lässt sich (bis auf die Geschichte mit der Orientierung) unverändert in die Scale-Methode überführen. Damit wäre der Grafikmodus »eingeschaltet« und das Koordinatensystem gesetzt, so dass man mit den Methoden Line, PSet und Circle ungestraft zu Werke gehen kann. Na, sagen wir fast ungestraft: gegebenenfalls vorhandene Farbe-Parameter bedürfen noch einer Übersetzung in den TrueColor-Farbraum, was sich am einfachsten mittels der QBColor-Methode erledigen lässt. Der folgende Code zeichnet ein rotes Rechteck im VGA-Modus 12: Screen 12 Line (10, 10)-(630, 470), QBColor(12), BF
Schön und gut. Was aber, wenn das zu portierende Programm seine Grafikausgaben mit Textausgaben kombiniert. Aufseiten von Visual Basic ist das keine triviale Angelegenheit. Immerhin, als Schrift für die VGA-Auflösung 640×480 bietet sich »Courier New« in der Größe 8 an. Sie hat eine Höhe von 16 Bildpunkten und eine Breite von 8 Bildpunkten, so dass sich genau die gewünschte 80×30 Zeichenmatrix ergibt. Problematisch ist aber, dass Visual Basic die Eigenschaften CurrentX und CurrentY sowohl für Print als auch für die Grafikmethoden PSet, Line und Circle verwendet. Um ein Programm mit gemischter Text- und Grafikausgabe portieren zu
461
Anspruchsvollere Programme
Wie Sie gesehen haben, war es für den Textmodus nicht erforderlich, ein Koordinatensystem zu setzen. Sobald aber eine Grafikausgabe ins Spiel kommt, führt kein Weg mehr daran vorbei, da ältere Basic-Versionen im Grafikmodus standardmäßig ein Koordinatensystem mit der Einheit »Bildpunkte« verwenden, dessen Ursprung in der linken oberen Ecke des Bildschirms gelegen und dessen vertikale Achse nach unten orientiert ist. Zum Umschalten in den Grafikmodus findet man in älteren Programmen die SCREEN-Anweisung. Diese Anweisung vollständig zu implementieren, ist weder möglich noch in den wenigsten Fällen wirklich erforderlich (unter Windows gibt es eben keine unterschiedlichen Grafikmodi und man kann nicht auf einer Bildschirmseite zeichnen, während man eine andere anzeigt – vom Ansatz her könnte man jedoch versuchen, mit mehreren Fenstern oder mit PictureBox-Steuerelementen zu arbeiten, zwischen denen SCREEN hin- und herschaltet). Eine einfache Implementation der Screen-Anweisung könnte etwa so aussehen:
Anspruchsvollere Programme
können, muss ein Weg gefunden werden, die Ausgabepositionen getrennt zu verwalten. Das geht beispielsweise über zwei zusätzliche Methoden TextQB und GrafikQB sowie vier globale Variablen für die jeweiligen Positionen und eine Zustandsvariable:
Anspruchsvollere Programme
Private Private Private Private
CurrentTextX As Single CurrentTextY As Single CurrentGrafikX As Single CurrentGrafikY As Single
' Positionen in Grafik' und Textmodus getrennt ' verwalten
Enum CurrentStates vbCurrentText = 0 vbCurrentGrafik = 1 End Enum Private CurrentState As CurrentStates Sub TextQB() If CurrentState = vbCurrentGrafik Then CurrentState = vbCurrentText CurrentGrafikX = CurrentX CurrentGrafikY = CurrentY CurrentX = CurrentTextX CurrentY = CurrentTextY End If End Sub Sub GrafikQB() If CurrentState = vbCurrentText Then CurrentState = vbCurrentGrafik CurrentTextX = CurrentX CurrentTextY = CurrentY CurrentX = CurrentGrafikX CurrentY = CurrentGrafikY End If End Sub
Die Implementation mag noch angehen, für die Portierung bedeutet das aber, dass Sie Printund Locate-Anweisungen mit TextQB und PSet-, Circle- und Line- mit GrafikQB flankieren müssen. (Sofern Letztere keine Step-Zusätze haben und alle Parameter angegeben sind, werden sie von Print- und Locate-Anweisungen zwar nicht durcheinander gebracht – umgekehrt aber schon.) Falls das Programm ein eigenes Koordinatensystem verwendet, ist noch dazu eine Implementation von WINDOW erforderlich, die neben dem Scale-Aufruf auch die aktuellen Positionen für den Text- und Grafikmodus umrechnet. Die Implementation ist ein wenig trickreich, da sie eines der beiden Koordinatenpaare vor Einführung des neuen Koordinatensystems in ein Referenzkoordinatensystem transformiert und danach wieder zurücktransformiert. Das andere Koordinatenpaar stimmt mit CurrentX und CurrentY überein und wird implizit von Scale umgerechnet. Außerdem definiert WINDOW ein kartesisches Koordinatensystem, bei dem die vertikale Achse nach oben orientiert ist. Sub Window(x1, y1, x2, y2) ScaleMode = vbUser If CurrentState = vbCurrentGrafik Then
462
Zusammenfassung der Emulation als Standardmodul
Zusammenfassung der Emulation als Standardmodul Im Projekt QBEmulation ist der gesamte Emulationscode in einem weitgehend eigenständigen Standardmodul zusammengefasst und ausgiebig kommentiert; einzig die Behandlungsroutinen für die beiden Tastaturereignisse sowie die Initialisierung der Emulation treten im Formular in Erscheinung. Die Aktivierung der Emulation geschieht durch einen InitQB-Aufruf unter Angabe einer Referenz auf das Formular (Me). In Abänderung zum vorgestellten Code, müssen die Routinen im Standardmodul den Zugriff auf die Eigenschaften und Methoden des Formulars über eine globale Objektvariable des Typs Form abwickeln. Etwas komplizierter als diskutiert ist die Implementation der Anweisung InputQB ausgefallen, ein Tribut an die Unabhängigkeit vom Koordinatensystem. Der Code des Formularmoduls mit ein wenig Testcode sieht so aus: '*********************************************************************** ' Formularmodul : QBEmulationTest ' Autor : 2000 Rudolf Huttary ' : testet Emulationsmodul '*********************************************************************** Option Explicit Private Sub Form_Load() InitQB Me ' Emulation initialisieren ' Testen der Methoden Show Screen 12 Window -1, -1, 1, 1 TextQB Locate 10, 10
463
Anspruchsvollere Programme
' Auf Referenzkoordinatensystem ausweichen CurrentTextX = ScaleX(CurrentTextX – ScaleLeft, vbUser, vbTwips) CurrentTextY = ScaleY(CurrentTextY – ScaleTop, vbUser, vbTwips) f.Scale (x1, IIf(y1 > y2, y1, y2))-(x2, IIf(y1 > y2, y2, y1)) ' Ins neue Koordinatensystem CurrentTextX = ScaleX(CurrentTextX, vbTwips, vbUser) + ScaleLeft CurrentTextY = ScaleY(CurrentTextY, vbTwips, vbUser) + ScaleTop ' akt. Position übernehmen CurrentGrafikX = CurrentX CurrentGrafikY = CurrentY Else ' Auf Referenzkoordinatensystem ausweichen CurrentGrafikX = ScaleX(CurrentGrafikX – ScaleLeft, vbUser, vbTwips) CurrentGrafikY = ScaleY(CurrentGrafikY – ScaleTop, vbUser, vbTwips) f.Scale (x1, IIf(y1 > y2, y1, y2))-(x2, IIf(y1 > y2, y2, y1)) ' Ins neue Koordinatensystem CurrentGrafikX = ScaleX(CurrentGrafikX, vbTwips, vbUser) + ScaleLeft CurrentGrafikY = ScaleY(CurrentGrafikY, vbTwips, vbUser) + ScaleTop ' akt. Position übernehmen CurrentTextX = CurrentX CurrentTextY = CurrentY End If End Sub
Anspruchsvollere Programme
Anspruchsvollere Programme
Print "Hinge"; ' Erstes Textstück GrafikQB ' Grafikmodus Line (-1, -1)-(0, 0) ' erste Linie TextQB ' Textmodus Window -10, -1, 40, 20 ' Koordinatensystem ändern Print "bungs"; ' zweites Textstück GrafikQB ' Grafikmodus Line -(-8, 26) ' zweite Linie direkt dransetzen TextQB ' Textmodus Print "voll"; ' drittes Textstück Locate , 20 Print Pos(0); CsrLin; ' aktuelle Position: (24, 20) Dim s InputQB "Bitte Text eingeben: ", s ' Texteingabe testen Locate 1, 1 ' Eingabe links oben ausgeben Print s End Sub ' Teil der Emulation Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = 0 Then ' Funktionstasten ignorieren InkeyChar = Chr(0) + Chr(KeyCode) ' Tastaturcode merken End If End Sub ' Teil der Emulation Private Sub Form_KeyPress(KeyAscii As Integer) InkeyChar = Chr(KeyAscii) ' Zeichen merken End Sub
Hier der Code des Standardmoduls QBEmulation: '*********************************************************************** ' Standardmodul : QBEmulation ' Autor : 2000 Rudolf Huttary ' Beschreibung : stellt einige Funktionen und Anweisungen ' für das Portieren von Code aus QBasic bereit. ' Initialisierung mit InitQB erforderlich '*********************************************************************** Option Explicit Public InkeyChar As String Private f As Form Private CurrentTextX As Single Private CurrentTextY As Single Private CurrentGrafikX As Single Private CurrentGrafikY As Single Enum CurrentStates vbCurrentText = 0 vbCurrentGrafik = 1 End Enum
464
' für Inkey$ ' akt. Position für Textausgabe ' akt. Position für Grafikausgabe
Zusammenfassung der Emulation als Standardmodul
Private CurrentState As CurrentStates ' Zustandsvariable
Anspruchsvollere Programme
Sub InitQB(Formular As Form) ' Initialisiert Formular für Ausgaben im Textmodus Set f = Formular ' Referenz auf Formular speichern f.AutoRedraw = True ' Ausgabe nicht über Paint f.FontName = "Courier New" ' nichtproportionale Schrift f.FontSize = 8 ' 16x8 Bildpunkte pro Zeichen Color ' Standardfarben setzen f.Width = f.Width – f.ScaleWidth + 80 * f.TextWidth("T") ' 80 Spalten f.Height = f.Height-f.ScaleHeight + 25 * f.TextHeight("T") ' 25 Zeilen End Sub Function InKey$() ' Letztes Zeichen von der Tastatur holen DoEvents ' Wartende Ereignisse verarbeiten InKey$ = InkeyChar ' InkeyChar wird von Formularmodul InkeyChar = "" ' gesetzt! End Function Sub Locate(Optional Zeile = 0, Optional Spalte = 0) ' Setzt (Zeile, Spalte) für nächsten Print-Aufruf (Eins-basiert) If Zeile Then f.CurrentX = f.ScaleLeft + (Zeile – 1) * f.TextWidth("A") If Spalte Then f.CurrentY = f.ScaleTop + (Spalte – 1) * f.TextHeight("A") End Sub Function Pos(dummy) As Integer ' Liefert aktuelle Spalte für Textausgabe Pos = CInt((f.CurrentX – f.ScaleLeft) / f.TextWidth("A") + 1) End Function Function CsrLin() As Integer ' Liefert aktuelle Zeile für Textausgabe CsrLin = (f.CurrentY – f.ScaleTop) / f.TextHeight("A") + 1 End Function Sub Screen(Modus) ' Schaltet auf Grafikmodus um Select Case Modus Case 10 ' 640x350 f.FontName = "Courier New" f.FontSize = 8 f.Width = f.Width – f.ScaleWidth + f.ScaleX(640, vbPixels, vbTwips) f.Height = f.Height – f.ScaleHeight + f.ScaleX(350, vbPixels, _ vbTwips) f.ScaleMode = vbPixels Case 11, 12 ' 640 * 480 f.FontName = "Courier New" f.FontSize = 8 f.Width = f.Width – f.ScaleWidth + f.ScaleX(640, vbPixels, vbTwips) f.Height = f.Height – f.ScaleHeight + f.ScaleX(480, vbPixels, _
465
Anspruchsvollere Programme
Anspruchsvollere Programme
vbTwips) f.ScaleMode = vbPixels Case Else Err.Raise 1000, , "Grafikmodus nicht emuliert" End Select End Sub Sub Color(Optional Vordergrund% = 0, Optional Hintergrund% = 15) ' Setzt Farben f.BackColor = QBColor(Hintergrund%) f.ForeColor = QBColor(Vordergrund%) End Sub Sub TextQB() ' Speichert aktuelle Position für Grafikausgabe und ' stellt aktuelle Position für Textausgabe wieder her ' (muss vor Locate, Print und Input aufgerufen werden) If CurrentState = vbCurrentGrafik Then CurrentState = vbCurrentText CurrentGrafikX = f.CurrentX CurrentGrafikY = f.CurrentY f.CurrentX = CurrentTextX f.CurrentY = CurrentTextY End If End Sub Sub GrafikQB() ' Speichert aktuelle Position für Textausgabe und ' stellt aktuelle Position für Grafikausgabe wieder her If CurrentState = vbCurrentText Then CurrentState = vbCurrentGrafik ' Zustand merken CurrentTextX = f.CurrentX ' Textausgabepos merken CurrentTextY = f.CurrentY f.CurrentX = CurrentGrafikX ' Grafikposition restaurieren f.CurrentY = CurrentGrafikY End If End Sub Sub Window(x1, y1, x2, y2) ' Stellt Koordinatensystem ein, bei dem der Punkt (x1, y1) links oben ' und der Punkt (x2, y2) links unten liegt f.ScaleMode = vbUser ' für ersten Aufruf erforderlich If CurrentState = vbCurrentGrafik Then 'Ist Grafikpos. akt. Position? ' Für Textausgabepos auf Referenzkoordinatensystem ausweichen CurrentTextX = f.ScaleX(CurrentTextX – f.ScaleLeft, vbUser, vbTwips) CurrentTextY = f.ScaleY(CurrentTextY – f.ScaleTop, vbUser, vbTwips) f.Scale (x1, y1)-(x2, y2) ' Textausgabeposition ins neue Koordinatensystem umrechnen CurrentTextX = f.ScaleX(CurrentTextX, vbTwips, vbUser) + f.ScaleLeft CurrentTextY = f.ScaleY(CurrentTextY, vbTwips, vbUser) + f.ScaleTop
466
Zusammenfassung der Emulation als Standardmodul
Anspruchsvollere Programme
' akt. Position übernehmen CurrentGrafikX = f.CurrentX CurrentGrafikY = f.CurrentY Else ' Für Grafikposition auf Referenzkoordinatensystem ausweichen CurrentGrafikX = f.ScaleX(CurrentGrafikX – f.ScaleLeft, vbUser, _ vbTwips) CurrentGrafikY = f.ScaleY(CurrentGrafikY – f.ScaleTop, vbUser, _ vbTwips) f.Scale (x1, y1)-(x2, y2) ' Grafikposition ins neue Koordinatensystem umrechnen CurrentGrafikX = f.ScaleX(CurrentGrafikX, vbTwips, vbUser) + _ f.ScaleLeft CurrentGrafikY = f.ScaleY(CurrentGrafikY, vbTwips, vbUser) + _ f.ScaleTop ' akt. Position übernehmen CurrentTextX = f.CurrentX CurrentTextY = f.CurrentY End If End Sub Sub InputQB(EingabeAufforderung As String, Param) ' emuliert die QBasic-Anweisung INPUT für einen Parameter Dim iForm As New InputForm ' Eingabeformular Dim RandOffsOben As Integer Dim RandOffsLinks As Integer Dim fscalewTwips As Integer Dim fscalehTwips As Integer Dim fCurrentXTwips As Integer Dim fCurrentYTwips As Integer f.Print EingabeAufforderung; ' Höhe und Breite des Clientbereichs, Randoffsets ' sowie aktuelle Position in Twips umrechnen f.ScaleMode = vbUser ' Falls noch nicht geschehen fscalewTwips = f.ScaleX(f.ScaleWidth, vbUser, vbTwips) fscalehTwips = f.ScaleY(f.ScaleHeight, vbUser, vbTwips) RandOffsOben = f.Height – fscalehTwips – (f.Width – fscalewTwips) / 2 RandOffsLinks = (f.Width – fscalewTwips) / 2 fCurrentXTwips = f.ScaleX(f.CurrentX – f.ScaleLeft, vbUser, vbTwips) fCurrentYTwips = f.ScaleY(f.CurrentY – f.ScaleTop, vbUser, vbTwips) ' Eingabeformular für die Eingabe an (CurrentX, CurrentY) vorbereiten iForm.Text1.BorderStyle = vbBSNone iForm.Text1.BackColor = f.BackColor iForm.Text1.ForeColor = f.ForeColor iForm.Left = fCurrentXTwips + f.Left + RandOffsLinks iForm.Top = fCurrentYTwips + f.Top + RandOffsOben iForm.Width = fscalewTwips – fCurrentXTwips iForm.Text1.Font = f.Font iForm.FontSize = f.FontSize
467
Von W ANKEL. BAS
zur W ankelAnimation
Von WANKEL.BAS zur WankelAnimation
iForm.Height = iForm.TextHeight("Test") iForm.Text1.Height = iForm.Height iForm.Text1.Width = fscalewTwips – f.CurrentX iForm.Show vbModal, f ' Formular aufrufen, gibt bei ' Hide die Kontrolle an f zurück Param = iForm.Text1 ' Wert übernehmen f.Print Param ' ausgeben End Sub '*********************************************************************** ' Formularmodul : InputForm ' Autor : 2000 Rudolf Huttary '*********************************************************************** Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then Hide End Sub
Ausgabe des Testcodes für das Emulationsmodul
Von WANKEL.BAS zur WankelAnimation Der Fundus eines jeden Programmierers, der schon einige Jahre »im Geschäft« ist, enthält so manches verwaiste Programm, das einst viel Mühe gemacht hat, inzwischen aber einem Plattformwechsel zum Opfer gefallen ist. Mir geht es da nicht anders: Die Halde enthält Hunderte kleiner Programmskizzen, aber auch eine ganze Menge liebevoll ausgestaltete Programme, die ihren Sinn schlicht deshalb verwirkt haben, weil sie mit QuickBasic oder QBasic geschrieben wurden und somit nur in einem DOS-Fenster unter Windows ausführbar sind. Eine dieser Skizzen, das Programm WANKEL.BAS, das ich vor vielen Jahren in QBasic geschrieben habe, um mir den mechanischen Ablauf des Kolbens im Wankelmotor als Animation vor Augen zu bringen, wird Ihnen dieser Abschnitt in originaler und in portierter Fassung vorstellen.
468
Von W ANKEL. BAS zur W ankelAnimation
Von WANKEL.BAS zur WankelAnimation
Animationsphase im Formular von WankelAnimation
Hier zunächst der Code des altehrwürdigen Originals: DECLARE SUB zylinder (mx!, my!) DECLARE SUB kolben (mx!, my!, w!, sicht!) DECLARE SUB zahn (mx!, my!, r!, h!, w!, anz!, sicht!) Rem Konstanten Const pi = 3.141593 Const pi3 = pi / 3 Const pi6 = pi / 6 Const pi2 = 2 * pi Const r = 10 ' Radius Kolbenzahnrad Const r2 = r * 2 / 3 ' Radius innerer Zahnrad Const b = r – r2 Const mx = 0 ' Mittelpunktsverschiebung Const my = 0 ' Mittelpunktsverschiebung Const w = 3 ' Drehkolben-Faktor Const z2 = 24 ' Anzahl der Zahnräder äußeres Rad Const z1 = z2 * r2 / r ' Anzahl der Zahnräder inneres Rad Const wi = 0 ' Winkelgeschw. inn. Rad (0 bei Radius = 2/3) Const w2off = 0 '+ pi / z1 ' Phasenverschiebung inneres Rad 'Variablen initialisieren st = -pi / 60 ' Schleifeninkrement, Animationsgeschwindigkeit x1 = 0 ' Animationswinkel x2 = 0 ' Animationswinkel Screen 12 Print "Zähne:"; z1; "/"; z2; "schneller/langsamer: Cursor, Ende: Esc" WINDOW (-32, -24)-(32, 24) PSet (mx, my) ' Mittelpunkt zylinder mx, my ' Zylinder zeichnen
469
Von W ANKEL. BAS
zur W ankelAnimation
Do ' Animationsschleife kolben mx + b * Cos(x2 * w), my + b * Sin(x2 * w), x2, 0 kolben mx + b * Cos(x1 * w), my + b * Sin(x1 * w), (x1), 15
Von WANKEL.BAS zur WankelAnimation
zahn mx + b * Cos(x2 * w), my + b * Sin(x2 * w), r, r / 10, x2, z2, 0 zahn mx + b * Cos(x1 * w), my + b * Sin(x1 * w), r, r / 10, x1, z2, 15 zahn mx, my, r – b, r / 10, wi * x1, z1, 15 a$ = InKey$ ' Tastaturinteraktion If a$ "" Then taste = Asc(Right$(a$, 1)) Select Case taste Case 77: st = st + 0.2 * Abs(st) + 0.001 ' Cursor links Case 75: st = st – 0.2 * Abs(st) – 0.001 ' Cursor rechts Case 27, 79: Exit Do ' Abbruch End Select End If x2 = x1 ' alter Winkel x1 = x1 + st ' Schleifeninkrement Loop Sub kolben(mx, my, winkel, sicht) Dim r0, r1, w1, w2, w3, ef, c1, c2, c3, a, x, y, x1, x2, x3 r0 r1 w1 w2 w3 ef c1 c2 c3
= = = = = = = = =
a = x = y = xx1 xx2 xx3
2 * r Sqr(3) * r * 1 * 0.97 winkel + pi3 w1 + pi3 * 2 w2 + pi3 * 2 0.26 * r2 / r Cos(w1): s1 = Sin(w1) Cos(w2): s2 = Sin(w2) Cos(w3): s3 = Sin(w3)
0 r1 * Sin(a) * ef + r1 * Cos(a) = x * c1 – y * s1: = x * c2 – y * s2: = x * c3 – y * s3:
For a = 0 To pi * x = r1 * Sin(a) y = r1 * Cos(a) x1 = x * c1 – y x2 = x * c2 – y x3 = x * c3 – y Line (xx1 + mx, Line (xx2 + mx, Line (xx3 + mx, xx1 = x1: xx2 =
47 0
r1 / 1.75
' ' ' ' ' ' ' '
Ellipsenradius +60° , 1. Teilellipse +120°, 2. Teilellipse +120°, 3. Teilellipse Ellipsenfaktor Winkelwerte für Drehung Winkelwerte für Drehung Winkelwerte für Drehung
' Ellipse ' Ellipse yy1 = x * s1 + y * c1 yy2 = x * s2 + y * c2 yy3 = x * s3 + y * c3
y-Anteil mit Verschiebung y-Anteil ' Start Teilellipse 1 ' Start Teilellipse 2 ' Start Teilellipse 3
1.01 Step pi / 10 ' Schleife für halbe Ellipse * ef + r1 / 1.75 ' Ellipse y-Anteil mit Verschiebung ' Ellipse y-Anteil * s1: y1 = x * s1 + y * c1 ' Drehung Teilellipse 1 * s2: y2 = x * s2 + y * c2 ' Drehung Teilellipse 2 * s3: y3 = x * s3 + y * c3 ' Drehung Teilellipse 3 yy1 + my)-(x1 + mx, y1 + my), sicht ' Teilellipse 1 yy2 + my)-(x2 + mx, y2 + my), sicht ' Teilellipse 2 yy3 + my)-(x3 + mx, y3 + my), sicht ' Teilellipse 3 x2: xx3 = x3
Von W ANKEL. BAS zur W ankelAnimation
yy1 = y1: yy2 = y2: yy3 = y3 Next a End Sub
Von WANKEL.BAS zur WankelAnimation
Sub zahn(mx, my, r, h, w, anz, sicht) dw = pi / anz rz1 = r – h / 2 rz2 = r + h / 2 Min = 1000 PSet (mx + Cos(w – dw) * rz1, my + Sin(w – dw) * rz1), sicht For y = 0 To anz x = w + 2 * dw * y zx1 = mx + Cos(x + dw) * rz1 zy1 = my + Sin(x + dw) * rz1 di = zx1 * zx1 + zy1 * zy1 If Min > di Then Min = Sqr(di): dx = zx1: dy = zy1 End If Line -(mx + Cos(x) * rz2, my + Sin(x) * rz2), sicht Line -(zx1, zy1), sicht Next End Sub Sub zylinder(mx, my) r0 = 2 * r PSet (r0 * Cos(x) + mx + b * Cos(x * w), _ r0 * Sin(x) + my + b * Sin(x * w)) For x = 0 To pi2 + pi / 40 Step pi / 40 Line -(r0 * Cos(x) + mx + b * Cos(x * w), _ r0 * Sin(x) + my + b * Sin(x * w)) Next x End Sub
Sieht man von den mathematischen Einzelheiten und den vielen Parametern ab, ist das Programm recht einfach aufgebaut. Es enthält ein Hauptmodul, das die Variableninitialisierung vornimmt, den Zylinder zeichnet und ansonsten die Animationsschleife durchläuft, bis der Benutzer die Taste (Esc) drückt. In jeder Animationsphase überzeichnet der Schleifenkörper die vorherige Phase des Kolbens und des äußeren Zahnrads mit Hintergrundfarbe und zeichnet dann den Kolben sowie beide (!) Zahnräder unter Beachtung eines Winkelinkrements neu. Der Benutzer kann die Rotationsgeschwindigkeit des Kolbens verändern, indem er die Cursortasten (Rechts) oder (Links) drückt. In der DOS-Version wird die Grundgeschwindigkeit der Animation schlicht durch die Ausführungsgeschwindigkeit des Programms bestimmt, und die Geschwindigkeitsregelung erfolgt durch Manipulation des Winkelinkrements. Die drei Funktionen des Programms kolben, zylinder und zahn zeichnen die drei unterschiedlichen Figuren, aus denen sich die Animation zusammensetzt. Da der Zylinder feststehend ist (das ist nicht bei allen Wankelmotoren so), braucht er nur ein einziges Mal vor Eintritt in die Animationsschleife gezeichnet zu werden. Das innere Zahnrad steht zwar still, würde aber von dem äußeren Zahnrad mit der Zeit ausradiert werden, so dass es kurzerhand gleichfalls in jeder Phase nachgezeichnet wird.
47 1
Von W ANKEL. BAS
zur W ankelAnimation
Von WANKEL.BAS zur WankelAnimation
Die einzelnen Funktionen geben eigentlich außer der Berechnung der Drehung nicht allzu viel Interessantes her. Eine Drehung um den Winkel w bildet einen Punkt (x, y) auf den Punkt (x', y') ab. Dabei gilt folgende Beziehung: x' =
x · cos(w)
–
y · sin(w)
y' =
x · sin(w)
+
y · cos(w)
Die Funktion zylinder zeichnet den Wankel-Zylinder um den Punkt (mx, my) als vieleckiges Polygon, wobei sich die Eckpunkte des Polygons als Summe zweier Kreisfunktionen ergeben, deren Frequenzen im ganzzahligen Verhältnis 1:3 zueinander stehen. Die zuständige Konstante hat den Bezeichner w und ist als »Drehkolbenfaktor« kommentiert. (Ändern Sie doch den Wert einmal!) Wer das Prinzip nicht kennt: Die Eckpunkte für die polygonale Annäherung an einen Kreis erhält man, indem man eine Variable zwischen 0 und 2 als Winkel laufen lässt, dann in horizontaler Richtung den Sinus sowie in vertikaler Richtung den Cosinus (oder umgekehrt) des Winkels anträgt und schließlich die Werte mit dem gewünschten Radius skaliert. Nimmt man für die beiden Richtungen unterschiedliche Radien, ergibt sich eine (horizontal/vertikal ausgerichtete) Ellipse. Die Funktion zahn zeichnet ein vereinfachtes Zahnrad in Form einer Zickzacklinie. Die Aufrufparameter definieren der Reihe nach: x- und y-Koordinaten des Mittelpunkts, Radius, Zahnhöhe, Phasenwinkel, Zähneanzahl und Linienfarbe. Die Methode kolben zeichnet schließlich den Kolben in angenäherter Form, indem sie drei Ellipsenabschnitte aus vieleckigen Polygonen passend aneinander klebt. (Im Gegensatz zum Zylinder des Wankelmotors ist die geschlossene Darstellung des Kolbens von der Mathematik her recht anspruchsvoll und die Berechnung zu aufwändig für eine Animation – die Ellipsenabschnitte ergeben eine brauchbare Annäherung. Leider lässt sich die Circle-Funktion für das Zeichnen der Ellipsen nicht einsetzen, da Basic Ellipsen nur mit horizontal/vertikal ausgerichteten Achsen zeichnet) Die Parameter der Funktion sind der Reihe nach: x- und y-Koordinaten des Mittelpunkts, Phasenwinkel, Linienfarbe.
Die portierte Fassung Die portierte Fassung WankelAnimation des Codes unterscheidet sich nicht sonderlich von der originalen Fassung, wenn man das zuvor vorgestellte Modul QBEmulation zur Verfügung hat. Änderungen und Ergänzungen erscheinen im Listing fettgedruckt. '*********************************************************************** ' Formularmodul : WankelAnimation ' Autor : 2000 Rudolf Huttary ' Beschreibung : Demonstriert Ablauf im Inneren des Wankelmotors '*********************************************************************** Rem Konstanten Const pi = 3.141593 Const pi3 = pi / 3 Const pi6 = pi / 6 Const pi2 = 2 * pi Const r = 10 ' Radius Kolbenzahnrad Const r2 = r * 2 / 3 ' Radius inneres Zahnrad Const b = r – r2 Const mx = 0 ' Mittelpunktsverschiebung Const my = 0 ' Mittelpunktsverschiebung Const w = 3 ' Drehkolben-Faktor Const z2 = 48 ' Anzahl der Zahnräder äußeres Rad Const z1 = z2 * r2 / r ' Anzahl der Zahnräder inneres Rad
47 2
Die portierte Fassung
Const wi = 0 ' Winkelgeschwindigkeit inneres Rad (0 bei Radius = 2/3) Const w2off = 0 '+ pi / z1 ' Phasenverschiebung inneres Rad Dim st, x1, x2
Von WANKEL.BAS zur WankelAnimation
' Teil der Emulation Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = 0 Then ' Funktionstasten ignorieren InkeyChar = Chr(0) + Chr(KeyCode) ' Tastaturcode merken End If End Sub ' Teil der Emulation Private Sub Form_KeyPress(KeyAscii As Integer) InkeyChar = Chr(KeyAscii) ' Zeichen merken End Sub Private Sub Form_Load() InitQB Me Timer1.Interval = 100 st = -pi / 60 ' x1 = 0 ' x2 = 0 ' Screen 12 Print "Zähne:"; z1; "/"; Window -32, -24, 32, 24 PSet (mx, my) ' zylinder mx, my ' End Sub
Schleifeninkrement, Animationsgeschwindigkeit Animationswinkel Animationswinkel z2; "schneller/langsamer: Cursor, Ende: Esc" Mittelpunkt Zylinder zeichnen
Sub kolben(mx, my, winkel, sicht) Dim r1, w1, w2, w3, ef, c1, c2, c3, r1 = Sqr(3) * r * 1 * 0.97 w1 = winkel + pi3 w2 = w1 + pi3 * 2 w3 = w2 + pi3 * 2 ef = 0.26 * r2 / r c1 = Cos(w1): s1 = Sin(w1) c2 = Cos(w2): s2 = Sin(w2) c3 = Cos(w3): s3 = Sin(w3) a = x = y = xx1 xx2 xx3
0 r1 * Sin(a) * ef + r1 * Cos(a) = x * c1 – y * s1: = x * c2 – y * s2: = x * c3 – y * s3:
r1 / 1.75
a, ' ' ' ' ' ' ' '
x, y, x1, x2, x3 Ellipsenradius +60° , 1. Teilellipse +120°, 2. Teilellipse +120°, 3. Teilellipse Ellipsenfaktor Winkelwerte für Drehung Winkelwerte für Drehung Winkelwerte für Drehung
' Ellipse ' Ellipse yy1 = x * s1 + y * c1 yy2 = x * s2 + y * c2 yy3 = x * s3 + y * c3
y-Anteil mit Verschiebung y-Anteil ' Start Teilellipse 1 ' Start Teilellipse 2 ' Start Teilellipse 3
For a = 0 To pi * 1.01 Step pi / 10 ' Schleife für halbe Ellipse x = r1 * Sin(a) * ef + r1 / 1.75 ' Ellipse y-Anteil mit Verschiebung y = r1 * Cos(a) ' Ellipse y-Anteil
47 3
Von WANKEL.BAS zur WankelAnimation
Von W ANKEL. BAS
zur W ankelAnimation
x1 = x * c1 – y * s1: y1 = x * s1 + x2 = x * c2 – y * s2: y2 = x * s2 + x3 = x * c3 – y * s3: y3 = x * s3 + Line (xx1 + mx, yy1 + my)-(x1 + mx, QBColor(sicht) Line (xx2 + mx, yy2 + my)-(x2 + mx, QBColor(sicht) Line (xx3 + mx, yy3 + my)-(x3 + mx, QBColor(sicht) xx1 = x1: xx2 = x2: xx3 = x3 yy1 = y1: yy2 = y2: yy3 = y3 Next a End Sub
y * c1 ' Drehung Teilellipse 1 y * c2 ' Drehung Teilellipse 2 y * c3 ' Drehung Teilellipse 3 y1 + my), _ ' Teilellipse 1 y2 + my), _ ' Teilellipse 2 y3 + my), _ ' Teilellipse 3
Sub zahn(mx, my, r, h, w, anz, sicht) dw = pi / anz rz1 = r – h / 2 rz2 = r + h / 2 Min = 1000 PSet (mx + Cos(w – dw) * rz1, my + Sin(w – dw) * rz1), QBColor(sicht) For y = 0 To anz x = w + 2 * dw * y zx1 = mx + Cos(x + dw) * rz1 zy1 = my + Sin(x + dw) * rz1 di = zx1 * zx1 + zy1 * zy1 If Min > di Then Min = Sqr(di): dx = zx1: dy = zy1 End If Line -(mx + Cos(x) * rz2, my + Sin(x) * rz2), QBColor(sicht) Line -(zx1, zy1), QBColor(sicht) Next End Sub Sub zylinder(mx, my) r0 = 2 * r PSet (r0 * Cos(x) + mx + b * Cos(x * w), r0 * Sin(x) + my + b * Sin(x * w)) For x = 0 To pi2 + pi / 40 Step pi / 40 Line -(r0 * Cos(x) + mx + b * Cos(x * w), r0 * Sin(x) + my + b * Sin(x * w)) Next x End Sub Private Sub Timer1_Timer() ' Do ' Animationsschleife kolben mx + b * Cos(x2 * w), my + b * Sin(x2 * w), x2, 15 kolben mx + b * Cos(x1 * w), my + b * Sin(x1 * w), (x1), 0 zahn mx + b * Cos(x2 * w), my + b * Sin(x2 * w), r, r / 10, x2, z2, 15 zahn mx + b * Cos(x1 * w), my + b * Sin(x1 * w), r, r / 10, x1, z2, 0 zahn mx, my, r – b, r / 10, wi * x1, z1, 0
47 4
Die portierte Fassung
Als einzige Abweichung von der ursprünglichen Programmlogik ist die Umsetzung der INKEY$Schleife in eine Timer-Behandlungsroutine zu bemerken. Eine Beibehaltung der ursprünglichen Logik wäre vom Prinzip her zwar möglich, jedoch mit Rücksicht auf das Multitasking alles andere als sinnvoll. Das Zeitgeber-Steuerelement hat den Vorteil, dass es eine recht stabile und systemunabhängige Zeitbasis für die Abfolge der einzelnen Animationsphasen bereitstellt.
475
Von WANKEL.BAS zur WankelAnimation
a$ = InKey$ ' Tastaturinteraktion If a$ "" Then taste = Asc(Right$(a$, 1)) Select Case taste Case vbKeyLeft: st = st + 0.2 * Abs(st) + 0.001 ' Cursor rechts Case vbKeyRight: st = st – 0.2 * Abs(st) – 0.001 ' Cursor links ' Abbruch Case 27, vbKeyEnd: Unload Me: Exit Sub End Select End If x2 = x1 ' alter Winkel x1 = x1 + st ' Schleifeninkrement ' Loop End Sub
Mathematik und Algorithmen Wer programmiert, tut gut daran, mit der Mathematik auf gutem Fuße zu stehen. Der geschickte und sichere Umgang mit den mathematischen Funktionen der Sprache bringt nicht nur Vorteile für die saubere Implementation schneller und sicherer Algorithmen, er ist zuweilen sogar Voraussetzung, wenn es um die Bewältigung kniffliger Angelegenheiten geht. Da wären zum einen die einfachen linearen Transformationen (Translation und Skalierung), wie sie für den Übergang zwischen verschiedenen Koordinatensystemen auftreten. Um die Anzahl solcher Transformationen klein zu halten, empfiehlt es sich, im Ausgabebereich (Form, Printer, PictureBox, UserControl, UserDocument) mittels Scale das Koordinatensystem so zu wählen, dass keine unübersichtlichen und zeitaufwändigen Umrechnungen erforderlich werden. Während die vordefinierten Koordinatensysteme, die man durch Setzen der Eigenschaft ScaleMode auf eine der vordefinierten Konstanten (vbPixels, vbMillimeters, ...) einstellt, ihren Ursprung links oben in der Ecke der Ausgabefläche haben und nichts weiter als unterschiedliche Skalierungsmaße für die Koordinatenachsen vorgeben, lassen sich mittels Scale Koordinatensysteme mit unterschiedlich orientierten sowie beliebig skalierten Koordinatenachsen bei freier Wahl des Ursprungs einstellen. Man übergibt Scale einfach die Koordinaten des linken oberen Punkts und des rechten unteren Punkts der Ausgabefläche in ihrer aktuellen Gestalt (vgl. Height, Width) und definiert damit den Ausschnitt, die Skalierung, die Orientierung und den Ursprung in einem Aufwasch. Was die Sprache nicht vorsieht, ist eine zusätzliche Drehung der Koordinatenachsen aus der Senkrechten bzw. Waagrechten heraus. Da hilft nur die im vorigen Abschnitt vorgestellte Drehung – nachträglich auf die Punktkoordinaten angewandt. Darüber hinaus ist das mathematische Vokabular der Sprache reichhaltig genug, um selbst komplexeste Berechnungen anstellen zu können. Ein Anwendungsgebiet ist beispielsweise die Visualisierung von Funktionsverläufen mittels zweidimensionaler Funktionsgraphen. Nimmt man die Farbinformation als »dritte« Dimension, lassen sich recht aussagekräftige Darstellungen errechnen. Vom Prinzip her führt man dazu den Graphen (gegebenenfalls durch Projektion) auf eine der folgenden Darstellungen zurück. 1. eindimensionale Abbildungen (aber auch Relationen), bei denen ein Wert aus einem Definitionsbereich einem Wert aus einem Wertebereich zugeordnet wird. Für die Darstellung werden Definitions- und Wertebereich je einer Achse zugeordnet, so dass sich ein Kurvenverlauf ergibt (Beispiele dazu finden Sie im Referenzteil in den Abschnitten »Resize-Methode« und »ScaleLeft-Eigenschaft und ScaleTop-Eigenschaft«, wo es um die Ausgabe einer Sinuskurve bzw. einer approximierten Rechteckkurve geht). Die Kurve wird entweder aus Punkten zusammengesetzt oder aus Liniensegmenten (Polygon). 2. zweidimensionale Abbildungen, bei denen ein zweidimensionaler Wertebereich auf einen eindimensionalen Wert abgebildet wird. Die Darstellung des eindimensionalen Werts erfolgt entweder als Farbwert (vgl. das Projekt Apfelmann, in diesem Abschnitt) oder als Höhenwert bei perspektivischer Projektion (Kurvenschar erscheint dann als »Landschaft«). 3. zweidimensionale Abbildungen, bei denen ein eindimensionaler Definitionsbereich in einen zweidimensionalen Wertebereich abgebildet wird. Die Darstellung zeigt häufig nur den Kurvenverlauf im Wertebereich, kann aber auch nach dem vorgenannten Prinzip erfolgen. Ein Beispiel dafür ist die Kreisfunktion, bei der ein Winkelwert in der einen Dimension auf den Sinus und in der anderen auf den Cosinus des Winkels abgebildet wird – speziell bei der Kreisfunktion lässt sich der Winkel sogar direkt im Wertebereich ablesen, das ist aber nicht die Regel (vgl. die Darstellung des Wankel-Zylinders sowie der Ellipsenabschnitte im vorherigen Abschnitt »Das Programm WANKEL.BAS«). Unter Algorithmus wird landläufig eine »Vorschrift für die Ausführung einer komplexen Operation« verstanden. Auch wenn sich im weiteren Sinne jede Prozedur/Funktion unter diesem Begriff subsumieren lässt, spricht man eigentlich nur dann von einem Algorithmus, wenn es um
477
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
die Implementation eines spezifischen Verfahrens geht, das entweder metasprachlich (etwa als mathematische Formel) oder natürlichsprachlich (als Anleitung im Sinne eines Kochrezepts) beschrieben ist. Zu den klassischen Algorithmen zählen Sortierverfahren wie Bubble-Sort (vgl. den Abschnitt »Schleifen«, S. 40) oder Quick-Sort, Iterationsverfahren etwa für die Integralberechnung oder die numerische Approximation, aber auch Berechnungen verschiedenster Art, wie die von Primzahlen (vgl. »Funktionen selbst definieren«), Determinanten, Folgengliedern oder Reihensummen. Wie viel Komplexität und auch »Anmut« hinter einer einfachen Rechenvorschrift stecken kann, demonstriert auf besonders eindrucksvolle Weise die Mandelbrotmenge, deren Graph aufgrund seiner Form als »Apfelmännchen« bezeichnet wird. (Ein wenig mehr Mathematisches findet sich im Abschnitt »Von WANKEL.BAS zur WankelAnimation », S. 468, sowie im Abschnitt »3DAnimation – Drahtgittermodelle frei im Raum gedreht«, S. 577).
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge Die von dem Mathematiker Benoit B. Mandelbrot im Zuge seiner Beschäftigung mit so genannten »Julia«-Mengen Anfang der Siebzigerjahre entdeckte Mandelbrotmenge zählt heute noch zu den augenscheinlichsten Ergebnissen der Chaosforschung und dürfte der noch jungen Wissenschaft zusehends auf die Beine geholfen haben. Mandelbrot benutzte damals einen IBM-Computer, um die Menge erstmals zu visualisieren, und war umgehend von ihrer »bizarren Schönheit« bezaubert. Der mathematische Kern der Mandelbrotmenge ist wahrlich einfach. Man untersucht eine parametrisierte Folge im komplexen Zahlenraum daraufhin, ob sie konvergiert oder divergiert. Die Folgenvorschrift lautet: f0
=
0
fn+1
=
fn² + z
wobei der Parameter z aus der komplexen Ebene gewählt wird. Für die Visualisierung der Menge untersucht man das Verhalten der Folge fn, indem man z systematisch in einem bestimmten (um die Null herum gelegenen) Bereich variiert und für jedes z bis zu cMaxIterat (also endlich viele) Folgenglieder berechnet. Übersteigt der Betrag eines Folgenglieds einen hinreichend groß gewählten Grenzwert cGrenze, bricht man die Iteration ab und wertet die zu c gehörige Folge als divergent – z gehört dann nicht zur Mandelbrotmenge. Die Anzahl der Iterationen, die bis zum Abbruch nötig waren, trägt man als Farbwert für den Punkt z in der komplexen Ebene an. Sind dagegen für ein z alle Folgenglieder vom Betrag her kleiner gleich dem Grenzwert, wertet man die zu z gehörige Folge als konvergent und z als Element der Mandelbrotmenge. Das Ergebnis dieser Vorschrift gehört zu den »Bildern, die um die Welt gingen«. Das Projekt ApfelmannZoom, mit dem die abgebildeten Bildschirme erzeugt wurden, hat – wie der Titel bereits verrät – neben dem reinen Algorithmus für die Berechnung der Mandelbrotmenge noch eine recht komfortable Zoomfunktion zu bieten. Um sich in das Bild hineinzuzoomen, markiert man den gewünschten Ausschnitt mit der Maus unter Verwendung der linken Maustaste. Das geht auch wiederholt, bis die Rechengenauigkeit des Datentyps Double erschöpft ist und das Bild streifig wird. Ein Klick mit der linken Maustaste bringt dagegen das jeweils zuvor berechnete Bild wieder zum Vorschein. Einer Fahrt durch die Mandelbrotmenge steht also nichts mehr im Wege – nun ja, allzu rasant dürfte sie nicht werden, denn unter Basic ist das Laufzeitverhalten des Programms nicht gerade als überzeugend zu bezeichnen. Je nach Größe des Formulars müssen Sie auf einem halbwegs vernünftigen System schon zwischen 10 und mehreren hundert Sekunden je Bild veranschlagen.
478
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge 479
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
Ausgabe des Programms Apfelmann
Ein Kompilieren des Programms mit allen Beschleunigungsoptionen halbiert zwar die Ausführungszeit in etwa, so richtig Beine macht es dem Programm aber auch nicht. Vor einer eingehenderen Diskussion der Implementation zunächst das Listing im Überblick: '*********************************************************************** ' Formularmodul : ApfelmannZoom ' Autor : 2000 Rudolf Huttary ' Beschreibung : Zeichnet Mandelbrotmenge ' : Zoomfähig, Bereichsauswahl mit der Maus '*********************************************************************** ' Konstanten für Startbereich Const cx1 As Single = -2.1 Const cy1 As Single = -1.4 Const cx2 As Single = 0.7 Const cy2 As Single = 1.4 ' Konstanten für Algorithmus Const cMaxIterat As Double = 200 Const cGrenze As Double = 10000 Const cZoom = "Apfelmann – Zoomstufe " ' Gobale Variablen für Bildschirmpunkte Private PixelsX, PixelsY ' Globale Variablen für Gummiband Private MouseStartX As Single, MouseEndX As Single Private MouseStartY As Single, MouseEndY As Single Private Tracking As Boolean Private Break As Boolean
480
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
' Undo-Info für Zoomfunktion Dim Stack()
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
Private Sub Form_Load() ' Verhältnis Höhe/Breite richtig stellen Height = ScaleWidth * (cy2 – cy1) / (cx2 – cx1) + _ (Height – ScaleHeight) ReDim Preserve Stack(4, 0) ' Stack anlegen Caption = cZoom & 0 ' Zoomstufe ausgeben ScaleMode = vbPixels ' Anzahl der Bildpunkte merken PixelsX = ScaleWidth PixelsY = ScaleHeight AutoRedraw = True Scale (cx1, cy1)-(cx2, cy2) ' Startbereich einstellen Show ' Damit man das Zeichnen sieht Apfel End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) Dim Index As Integer If Button = vbLeftButton Then ' Hineinzoomen? Tracking = True ' Gummiband einschalten MouseStartX = X ' Start- und Endkoordinaten ' vorgeben MouseStartY = Y MouseEndX = X MouseEndY = Y Else ' Herauszoomen! PopFromStack End If End Sub Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _ X As Single, Y As Single) Dim dm If Tracking Then ' Verhältnis Höhe/Breite für Aussschnitt erzwingen Y = (MouseStartY + Sgn(Y – MouseStartY) * Abs(X – MouseStartX) * _ (ScaleHeight / ScaleWidth)) ' altes Gummiband löschen und dann neu zeichnen dm = DrawMode ' alten Zeichenmodus merken DrawMode = vbInvert ' XOR-Zeichenmodus einschalten Line (MouseStartX, MouseStartY)-(MouseEndX, MouseEndY), , B Line (MouseStartX, MouseStartY)-(X, Y), , B DrawMode = dm ' alten Zeichenmodus restaurieren MouseEndX = X: MouseEndY = Y ' vorläufige Endkoordinaten merken End If End Sub
481
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If Tracking Then Tracking = False ' Gummiband ausschalten dm = DrawMode ' alten Zeichenmodus merken DrawMode = vbInvert ' XOR-Zeichenmodus einschalten
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
' Gummiband löschen Line (MouseStartX, MouseStartY)-(MouseEndX, MouseEndY), , B DrawMode = dm ' alten Zeichenmodus restaurieren ' x-Koordinaten ggf. vertauschen If MouseStartX = X Or MouseStartY = Y Then Exit Sub If MouseStartX > MouseEndX Then MouseEndX = MouseStartX MouseStartX = X Else MouseEndX = X End If ' y-Koordinaten ggf. vertauschen If MouseStartY > MouseEndY Then MouseEndY = MouseStartY MouseStartY = Y Else MouseEndY = Y End If ' Zeichnen des gezoomten Bereichs vorbereiten PushOnStack Cls Scale (MouseStartX, MouseStartY)-(MouseEndX, MouseEndY) Apfel End If End Sub ' Prozedur zeichnet Mandelbrotmenge für geltendes Koordinatensystem Private Sub Apfel() Dim m_x1 As Double, m_x2 As Double, m_y1 As Double, m_y2 As Double Dim step_x As Double, step_y As Double Dim r1 As Double, re As Double, im As Double Dim zr As Double, zi As Double Dim it As Long Static Zoomstufe As Integer Zoomstufe = Zoomstufe + 1 ' Bereichsgrenzen und Schrittweiten ermitteln m_x1 = ScaleLeft m_x2 = ScaleLeft + ScaleWidth m_y1 = ScaleTop m_y2 = ScaleTop + ScaleHeight
482
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
step_x = (m_x2 – m_x1) / PixelsX step_y = (m_y2 – m_y1) / PixelsY
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
For zr = m_x1 To m_x2 Step step_x ' alle Spalten in x-Richtung For zi = m_y1 To m_y2 Step step_y ' alle Punkte in Spalte zr re = 0 ' Realteil initialisieren im = 0 ' Imaginärteil initialisieren For it = 0 To cMaxIterat ' Iteration für Punkt r1 = re * re – im * im + zr im = 2 * re * im + zi re = r1 If re * re + im * im > cGrenze Then ' divergent? PSet (zr, zi), it * 16 ' Ja: Punkt ausgeben Exit For End If Next it ' Iteration beendet Next zi ' Spalte beendet? ' Ereignisse verarbeiten. Abbruch, falls Formular geschlossen wurde ' oder Zoomstufe inzwischen zu klein ist If DoEvents = 0 Or Zoomstufe > UBound(Stack, 2) + 1 Then Zoomstufe = Zoomstufe – 1 Exit Sub Else ' Warten bis Zoomstufe erreicht While Zoomstufe < UBound(Stack, 2) + 1 If DoEvents = 0 Then Exit Sub ' Formular geschlossen? Wend End If Next zr ' Bild fertig? Zoomstufe = Zoomstufe – 1 End Sub Private Sub PushOnStack() Dim Index As Integer Index = UBound(Stack, 2) + 1 ReDim Preserve Stack(4, Index) ' Koordinatensystem merken Stack(0, Index) = ScaleLeft Stack(1, Index) = ScaleTop Stack(2, Index) = ScaleWidth Stack(3, Index) = ScaleHeight Set Stack(4, Index) = Image Caption = cZoom & Index End Sub
' Push-Operation
' Bild merken
Private Sub PopFromStack() Dim Index As Integer Index = UBound(Stack, 2) If Index > 0 Then ' Stack leer? ' Nein: Koordinatensystem wiederherstellen
483
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
ScaleLeft = Stack(0, Index) ScaleTop = Stack(1, Index) ScaleWidth = Stack(2, Index) ScaleHeight = Stack(3, Index) ' Gespeichertes Bild zeichnen PaintPicture Stack(4, Index), ScaleLeft, ScaleTop ReDim Preserve Stack(4, Index – 1) ' Pop-Operation Caption = cZoom & Index – 1 End If End Sub
Einstiegspunkt in das Programm ist, wie sollte es anders sein, die Load-Routine. Sie initialisiert das Formular so, dass der Client-Bereich den über Konstanten definierten Startbereich für die Berechnung der Mandelbrotmenge verzerrungsfrei und vollständig abbilden kann. Dies beinhaltet eine Anpassung der Formularhöhe an die zur Entwurfszeit gewählte Formularbreite sowie eine entsprechende Wahl des Koordinatensystems. Darüber hinaus werden noch zwei globale Variablen mit der Anzahl der Bildpunkte in horizontaler und vertikaler Richtung initialisiert, was der Routine Apfel die Berechnung der Schrittweite für die komplexe Ebene erleichtert, sowie ein dynamisches Array Stack, das im Zusammenhang mit dem Speichern der für die Zoomfunktion erforderlichen Informationen seinen Namen alle Ehre macht. Die Ausgabe der jeweils aktuellen Zoomstufe erfolgt über die Caption-Eigenschaft in der Titelzeile des Formulars.
Implementation des Apfelmännchen- Algorithmus An der Routine Apfel ist eigentlich nur die Kernroutine für die Berechnung der einzelnen Elemente der Mandelbrotmenge interessant. Die beiden äußeren Schleifen samt Initialisierung sind obligatorischer Überbau ohne Besonderheiten. Der Iterationsalgorithmus für einen einzelnen Parameter z = zr + i zi ist eine exakte Umsetzung der Visualisierungsvorschrift in die Sprache Basic. re = 0 im = 0 For it = 0 To cMaxIterat r1 = re * re – im * im + zr im = 2 * re * im + zi re = r1 If re * re + im * im > cGrenze Then PSet (zr, zi), it * 16 Exit For End If Next it
' Realteil initialisieren ' Imaginärteil initialisieren ' Iteration für Punkt
' divergent? ' Ja: Punkt ausgeben
' Iteration beendet
Da Basic für komplexe Zahlen keinen passenden Datentyp unterstützt, findet die Berechnung komponentenweise unter Verwendung von Double-Variablen statt. Die Addition ist komponentenweise definiert und macht keine Probleme, einzig die Quadratur (bzw. Multiplikation) einer komplexen Zahl mag ein wenig seltsam anmuten, wenn man das hinter den komplexen Zahlen steckende Prinzip nicht kennt. Die Formel dafür lautet z² = zr² – zi² + i 2zizr. Der Betrag einer komplexen Zahl erhält man dagegen über das gewöhnliche Maß der euklidischen Ebene: |z| = (zr² + zi²)½. Da es sich bei dieser Iteration um die innerste Schleife einer mehrfach verschachtelten Schleife handelt, sollte man natürlich alles dafür tun, das Laufzeitverhalten so günstig wie möglich zu gestalten. Viel Zeit (ca. 50 Prozent) geht allerdings in der PSet-Anweisung verloren, die jeden Punkt einzeln zum Bildschirm »befördert«. PSet erwartet als Farbe
484
Optimierung
einen Long-Wert, bei dem die unteren drei Byte die Sättigung für die Farbkomponenten Rot, Grün und Blau enthalten. Grundlegende Information für die Farbgestaltung ist die Zählvariable it. Sie gibt an, wie schnell die Folge divergiert. Wie die Farbabbildung dann im Einzelnen aussieht, fällt in die Kategorie künstlerische Freiheit. Die Multiplikation mit 16 ist nur eine Variante, wer es bunt liebt, könnte die Anweisung auch so gestalten: PSet (zr, zi), QBColor(it Mod 16)
Oder, wie wäre es mit einer geheimnisvollen grünen Korona? PSet (zr, zi), RGB((it Mod 16) * 16, it * 4, it)
Der Code zeigt verschiedene Optimierungen, die für einen guten Programmierer selbstverständlich sein sollten. So ist beispielsweise die einfache Multiplikation um einiges schneller als die Quadratur mit dem Operator ^, und Zählvariablen vom Typ Long sind schneller als Zählvariablen aller anderen Typen. Auch macht es wenig Sinn, die Wurzel bei der Berechnung des Betrags mittels Sqr zu ziehen, da sich der Vergleichswert ja auch auf das Quadrat des Werts trimmen lässt. Das Zwischenspeichern des zuerst errechneten Realteils in der Variable r1 ist notwendig, da der ursprüngliche Wert noch für die Berechnung des Imaginärteils zi benötigt wird. Analysiert man den Code auf weitere Möglichkeiten für die Optimierung, zeigt sich, dass sich noch einige Multiplikationen durch einfaches Zwischenspeichern einsparen lassen. Das bringt zwar nicht gerade viel, dafür dass es zwei weitere Variablen zzr und zzi erfordert und den Code doch einigermaßen entstellt, aber warum sollte man das Prozent an Laufzeitgewinn verschenken? re = 0 im = 0 zzr = 0 zzi = 0 For it = 0 To cMaxIterat im = 2 * re * im + zi re = zzr – zzi + zr zzr = re * re zzi = im * im If zzr + zzi > cGrenze Then PSet (zr, zi), it * 16 Exit For End If Next it
' Realteil initialisieren ' Imaginärteil initialisieren
' Iteration für Punkt
' divergent? ' Ja: Punkt ausgeben
' Iteration beendet
Ereignisbehandlung mit DoEvents, ein komplexes Problemfeld Ein wichtiger Punkt im Zusammenhang mit zeitaufwändigen Algorithmen ist die Aufrechterhaltung der Reaktivität des Programms gegenüber Benutzeraktionen. Damit der Benutzer nicht das Gefühl bekommt, das Programm sei abgestürzt oder reagiere nur schleppend auf seine Aktionen, empfiehlt es sich, beim Programmentwurf auf die so genannte Zehntelsekundenregel zu achten. Sie besagt, dass ein Ereignis nicht viel länger als eine Zehntelsekunde auf seine Behandlung warten sollte. Da Visual Basic die Behandlungsroutine für ein Ereignis standardmäßig erst dann aufruft, wenn die Behandlung des vorherigen Ereignisses abgeschlossen ist, sollte demnach jede Behandlungsroutine dafür sorgen, dass sie mit 100 Millisekunden an Laufzeit auskommt. Das ist leichter gesagt als getan: Insbesondere eine Routine wie Apfel, egal von welcher Behandlungsroutine sie aufgerufen wird, dürfte mit ihrer mehrsekündigen bis mehrminütigen Laufzeit einen doch recht erheblichen Verstoß gegen diese Regel darstellen. Was also tun, wenn
485
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
Optimierung
ApfelmannZoom – eine Fahrt durch die Mandelbrotmenge
ApfelmannZoom eine Fahrt durch die Mandelbrotmenge
der Zeitbedarf einer Routine die Grenze der Zumutung übersteigt? Als Lösung bietet sich der Einsatz der Anweisung DoEvents an. Sie kann als Prozedur oder als Funktion aufgerufen werden und übergibt die Kontrolle temporär an den Ereignisbehandlungsmechanismus des Laufzeitsystems, um die Behandlung des nächsten eventuell anstehenden Ereignisses einzuschieben. Falls kein Ereignis ansteht, geht die Kontrolle umgehend, ansonsten nach Behandlung des nächsten anstehenden Ereignisses an die unterbrochene Routine zurück. Beachtet man die Zehntelsekundenregel, ist der beste Platz für DoEvents nicht nach der innersten Schleife (das wäre Laufzeitverschwendung), sondern nach der zweitinnersten, also jeweils nach Beendigung einer Spalte. So weit, so gut. Bei näherer Betrachtung stellt sich aber gleich die Frage, was passiert, wenn der Benutzer das Formular schließt, bevor die auf diese Weise unterbrochene Routine mit ihrer Arbeit fertig ist und (wie im vorliegenden Fall) das Formular weiterhin benötigt? Nun, Visual Basic lädt das entladene Formular beim nächsten Zugriff auf eine seiner Eigenschaften oder Methoden implizit erneut, mit dem Effekt, dass als Nächstes ein Load-Ereignis zur Behandlung ansteht. Im vorliegenden Programm würde das Load-Ereignis dummerweise erneut die Routine Apfel ausführen, noch ehe der alte Aufruf derselben Routine fertig ist. Da sowohl Apfel als auch DoEvents einen rekursiven Aufruf nicht übelnehmen, wäre das vom Prinzip her kein Problem, wenn nicht die »Befehlsverweigerung« dabei herauskommen würde. Abhilfe schafft der Aufruf in der folgenden Form: If DoEvents = 0 Then Exit Sub
Als Funktion aufgerufen liefert DoEvents nämlich genau dann den Wert 0 zurück, wenn kein Formular der Anwendung mehr offen oder sichtbar ist, das eine Nachrichtenbehandlung vornimmt. Damit die Sache auch funktioniert, muss man jedoch beim Codedesign entweder darauf achten, dass auch in der rufenden Routine – im vorliegenden Fall also in Form_Load bzw. in Form_MouseUp – keine Zugriffe auf Eigenschaften oder Methoden des Formulars mehr erfolgen, denn das hätte natürlich gleichsam den »Stehaufmänncheneffekt«, oder man führt die den DoEvents-Aufruf enthaltende Routine als Funktion aus und lässt sie beispielsweise False zurückgeben, wenn das Formular nicht mehr existiert. (Ein Beispiel für Letzteres findet sich im Projekt DiaProjektor.) Wer das beherzigt, bekommt immerhin schon einmal einen sicheren Programmabbruch hin, gegen einen rekursiven Aufruf der unterbrochenen Routine ist er aber noch nicht gefeit – warum auch, wenn dieser vom Prinzip her kein Problem bereitet. Natürlich kann der rekursive Aufruf, wie im Beispielprogramm, auch zum Problem werden. Dazu folgendes Szenario: Starten Sie das nur mit dieser einfachen DoEvents-Logik ausgestattete Beispielprogramm Apfelma