Visual Basic 6 Referenz . Sprachkonzepte und Grundlagen
 9783827255884, 3827255880 [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

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