MS-Office 2010 Programmierung - created by Daniel Deckensattl in

Transcription

MS-Office 2010 Programmierung - created by Daniel Deckensattl in
W14Makroprogrammierung.dotm
VBA-Bibliothek und Schulung
MS-Office 2010 Word-VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
MS-Office 2010 Programmierung
Office-Applikationen von Microsoft lassen sich mit Visual Basic for Application, kurz VBA, gelungen
automatisieren. In diesem Dokument wird genauer beschrieben, wie Makros anzulegen und wo die Grenzen sind.
Anhand von mehreren VBA-Projekten wird illustriert, wie man effizient in Visual Basic programmiert und welche
Werkzeuge dazu verwendet werden.
Wer einmal in Winword und Excel Makros erstellt hat und ein Flair für die VBA-Programmierung entwickelt hat,
kann dies dann auch sehr schnell zB. in Outlook, CorelDraw und anderen VBA-unterstützten Programmen
einsetzen und die tollsten Dinge realisieren.
Erste Schritte mit VBA
Um den Einstieg zu erleichtern, beginnen wir mit einer Makro-Aufzeichnung um zB. einen Titel automatisch zu
formatieren. Hierzu wird in Word im Menüregister [Ansicht] der Menüpunkt [Makros] aktiviert, wo wir ein
Untermenüpunkt [Makro aufzeichnen] starten.
Es erscheint ein Aufzeichnungsdialog der beschreibt,
welcher Makroname das System verwendet, unter welchem
der VBA-Code abgelegt wird.
Hier geben wir einen kurzen Beschreibungstext hinzu, der
erklärt, was der Makro zu leisten vermag.
Nun wird der Schreibcursor in diese Titelzeile gesetzt, dann
drücken wir die HOME-Taste (Cursor fährt dann zum Beginn
der Zeile). Weiter halten wir die Umschalttaste gedrückt und
aktivieren die END-Taste (gesamte Zeile wird nun selektiert).
Jetzt wechseln wir in Word zu Menüregister [Start] und fetten diesen markierten Text ein und vergeben die
Schriftgrösse 11. Als letzten Schritt drücken wir die Pfeiltaste rechts sodass die Markierung wieder aufgelöst wird.
Das war es schon, nun kann die Makroaufzeichnung beendet werden, was wieder ein Registerwechsel zur
[Ansicht] bedeutet, wo wir unter Makros die Aufzeichnung beenden können.
Im Hintergrund hat nun Word folgenden VBA-Code
generiert (siehe Kasten rechts):
Von nun an können Sie Titelzeilen per Makroaufruf
einfetten und vergrössern. Bevor wir jedoch auf den
VBA-Code näher eingehen, möchte ich an diesem
Beispiel noch aufzeigen, wie wir diesen Makro in
unser Wordmenü aufnehmen, sodass wir diesen per
Mausklick auf eine gewünschte Makroschaltfläche
starten können.
Sub Makro1()
'
' Makro1 Makro
' Fettet eine Zeile ein und stattet diese mit der
Schriftgrösse 11 aus.
'
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtEnd
Selection.Font.Bold = wdToggle
Selection.Font.Size = 11
Selection.MoveRight Unit:=wdCharacter, Count:=1
End Sub
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 1 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
In sechs Schritten binden wir unser erstelltes Makro in unsere Menüliste ein. Mit einem Rechtsklick auf das
Menüband erscheint das Kontextmenü [Menüband anpassen] welches den Optionen-Dialog von Word aktiviert.
Beim ersten Einfügen einer neuen Makroschaltfläche muss eine
neue Menügruppe erstellt werden (Schritt 2), was wir hier im Menü
[Ansicht] vornehmen. Im Schritt drei benennen wir die neuerstellte
Gruppe um, zB. in Tools.
Jetzt wählen wir im Listenfenster Befehle auswählen (Schritt 5) den
Listenpunkt Makros aus und sogleich wird unser Makro unterhalb
dargestellt. Diesen nun selektieren und über die HinzufügenSchaltfläche der neuen Gruppe Tools zuschieben (Schritt 6).
Das hinzugefügte Makro kann nun umbenennt werden, hier im
Beispiel mit „Titel einfetten“ und mit einem
aussagekräftigem Bildchen versehen werden.
Als Ergebnis erhalten wir eine neue
Schaltfläche in unserem Menüband über
welches unser Makro jederzeit gestartet werden kann.
VBA-Editor aktivieren
Am schnellsten geht die Aktivierung der Makro-Programmierumgebung
(IDE) über die Tastenkombination Alt/F11.
Sie könne jedoch auch über das Makromenü den Makro anzeigen lassen.
Ûber die Schaltfläche Bearbeiten gelangen Sie auch in die VBAEntwicklerumgebung, die wir an dieser Stelle etwas genauer unter die Lupe
nehmen wollen
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 2 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Die VBA-Entwicklerumgebung, kurz IDE genannt, hat standartmässig drei Unterfenster, über welche Makros
strukturiert sind. Im Projektfenster sehen wir das Makromodul NewMacros, welches beim Erstellen von Makros
eingerichtet wird und unsere Makros aufnimmt. Unterhalb dieses Projektfensters wird das Eigenschaftsfenster
angezeigt, wo wir den Namen zB. umbenennen können.
Im rechten Hauptfenster befindet sich der Makrocode, den wir aufgezeichnet haben und natürlich auch jederzeit
erweitern können. Über den Punktoperator wird ein Submenü angezeigt, welches alle verfügbaren VBA-Befehle
eines Objektes (hier im Bild das Selection-Objekt) zur Auswahl anzeigt.
Man muss nicht alle Befehle auswendig lernen,
sondern diese können aus dieser Liste ausgewählt
werden, was die Arbeit mit Visual Basic enorm
erleichtert.
Wer mehr Informationen über ein VBA-Objekt benötigt,
der kann in der IDE-Umgebung über das Menü
[Ansicht/Objektkatalog] den Objektkatalog anzeigen
lassen, wo jeder Befehl mit Parameter aufgeführt ist.
Mit der F1-Taste wird die Wordhilfe aufgerufen, welche
dann diverse Beispiele bereit hält, wie ein selektierter
Befehl (hier zB. MoveRight) in Makro eingesetzt
werden kann.
Innerhalb der Wordhilfe kann weiter gesucht werden,
was über die Suchen-Schaltfläche vonstatten geht.
Wer noch nicht so mit VBA vertraut ist soll sich etwas
Zeit nehmen die Beispiele zu studieren oder sogar
einfach zu kopieren und ausprobieren.
Einstiegsmakros
Z o o m mo d u s an p a s se n
Per
Knopfdruck
zur
gewünschten
Zoomansicht
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 3 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
wechseln ist hier das Motto. Wer viel mit Word arbeitet stellt die Ansicht gerne in die gewünschte Grösse ein. Hier
das Beispielmakro dazu.
'/-----------------------------------------------------------------------------------------------------------'/ Diese Beispiel-Makroprozedur wechselt die Fensteransichtsgrösse auf einen gewünschten Wert.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub AutoZoom()
Dim intZoomWert As Integer
intZoomWert = 180
ActiveWindow.ActivePane.View.Zoom.Percentage = intZoomWert
Application.StatusBar = "Aktuelles Fenster wurde auf " & Format(intZoomWert, "0") & "% Ansichtsgrösse eingestellt"
End Sub
In der unteren Dokumentfenster-Leiste wird die Umstellung angezeigt.
Su ch en / E r s et z e n - M akro
Nehmen wir an Sie haben ein längeres Dokument in welchem Sie zB. den Firmennamen MUSTER in MUSTER
AG umtauschen möchten und wollen dies einem Makro überlassen. Folgende Befehle werden vom
Makrogenerator aufgezeichnet was sich aber auch kürzen lässt wie dieses Beispiel zeigt. Im Beispieltext sollen 3
Wert getauscht werden, der Firmenname MUSTER, die Telefonnummer und die Ansprechsperson.
Die Firma MUSTER stellt hochwertige Geräte her die für den Umbau von Küchen spezialisiert sind. Die
Mitarbeiter der Firma MUSTER sind sehr kompetent und erfüllen Ihre Wünsche im Handumdrehen. Unter
der Telefonnummer 041 555 26 30 können Kunden jederzeit anrufen. Herr Meier nimmt sich Ihrem Anliegen
an und kümmert sich um eine prompte Erledigung.
Der aufgezeichnete Makro Makro2 produziert eine Menge VBA-Code was sich mit Hilfe einer neuen Funktion
SuchenTausch(..) stark reduzieren lässt. Diese Prozedur kann nun in anderen VBA-Projekten eingesetzt werden,
wo wir Suchbegriffe in einem ganzen Dokument tauschen möchten.
Dieses Beispiel verdeutlicht, das wir viele Schritte in Word aufzeichnen können, um den produzierten Code dann
in eigenen Makros einsetzen zu können.
Sub Makro2()
'
' Makro2 Makro
'
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "MUSTER"
.Replacement.Text = "MUSTER AG"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute replace:=wdReplaceAll
With Selection.Find
.Text = "041 555 26 30"
.Replacement.Text = "052 222 16 88"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute replace:=wdReplaceAll
With Selection.Find
.Text = "Meier"
.Replacement.Text = "Koller"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute replace:=wdReplaceAll
End Sub
Sub WörterErstzen()
SuchenTausch "MUSTER", "MUSTER AG"
SuchenTausch "041 555 26 30", "052 222 16 88"
SuchenTausch "Meier", "Koller"
End Sub
'-- Suchfunktion die des öfteren in Gebrauch ist
Private Function Suchen(ByVal Suchbegriff As String, _
Optional ByVal Ersetzen As String = "", _
Optional ByVal bolNachUntenSuchen As Boolean = True, _
Optional ByVal bolWeitersuchen As Boolean = True) As
Boolean
Selection.Find.ClearFormatting
With Selection.Find
.Text = Suchbegriff
.Replacement.Text = Ersetzen
.Forward = bolNachUntenSuchen
If bolWeitersuchen = True Then
.Wrap = wdFindContinue
Else
.Wrap = wdFindStop
End If
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Suchen = Selection.Find.Execute
End Function
Beim nächsten Beispiel wird dies noch deutlicher, wieviel Code wir
einsparen können, wenn ein aufgezeichneter Makro entschlankt
wird.
M akro s en t s ch l an k en
Um folgende leere zweizeilige Tabelle per Makro zu erzeugen,
wird folgender VBA-Code produziert, was wir aber mit drei
Makrocodezeilen realisieren können:
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 4 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Sub Makro8()
'
' Makro8 Makro
'
'
ActiveDocument.Tables.Add Range:=Selection.Range, _
NumRows:=4, NumColumns:= 4, _
DefaultTableBehavior:=wdWord9TableBehavior,
AutoFitBehavior:= _
wdAutoFitFixed
With Selection.Tables(1)
If .Style <> "Tabellenraster" Then
.Style = "Tabellenraster"
End If
.ApplyStyleHeadingRows = True
.ApplyStyleLastRow = False
.ApplyStyleFirstColumn = True
.ApplyStyleLastColumn = False
.ApplyStyleRowBands = True
.ApplyStyleColumnBands = False
End With
End Sub
Deckensattl Daniel
[08.01.2015]
Sub NeueTabelle()
Dim myTable As Table
Set myTable =
ActiveDocument.Tables.Add(Range:=Selection.Range, _
NumRows:=2, NumColumns:=4)
myTable.Style = "Tabellenraster"
End Sub
Das Makro Aufzeichnungstool zeichnet deutlich mehr VBACode auf als nötig ist, um denselben Effekt zu erreichen. Das
mit Set myTable erstellte Objekt kann mit dem Punktoperator
weiter gesteuert werden um zB. die Gesamtbreite der Tabelle
zu beeinflussen, mit:
myTable.PreferredWidth = 200
' (Pixel)
Dat u m st a b e ll e e in f ü g en l as s en
Beim nächsten Makro wird illustriert, wie wir das gelernte in Praxisbeispiele umsetzen können folgende Tabelle
soll automatisch erzeugt werden mithilfe eines Auswahldialoges. Der Monatskalender-Dialog soll so aussehen:
Dezember 2014
Mo Di
Mi
01
02
03
08
09
10
15
16
17
22
23
24
29
30
31
Do
04
11
18
25
Fr
05
12
19
26
Sa
06
13
20
27
So
07
14
21
28
Um eine neue leeren Dialogform zu erstellen, klicken Sie im Projekt-Explorer der IDE mit einem Rechtsklick auf
den Ordner Module und fügen dann eine leere UserForm ein.
Im Menü Ansicht gibt es einen Untermenüpunkt
Werkzeugsammlung, dieser wird aufgerufen um die
nötigen Labels, ComboBoxen und Schaltflächen auf die
noch leere UserForm zu ziehen.
Unterhalb des Projektexplorers befindet sich das Eigenschaftsfenster über welches jedem neu eingefügten
Control ein aussagekräftiger Name (wie oben angedeutet) vergeben wird, so auch der Form selber
(frmMonatskalender).
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 5 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Nachdem Sie die Beschriftung (Einmalklick auf die neuen Buttonelemente) OK und Abbrechen eingegeben
haben, doppelklicken Sie auf eine der neuen Schaltflächen (zB. OK) und landen dann im VBA-Formmodul wo wir
folgenden Code eingeben:
'/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 03.12.2014
Update: 03.12.2014
Ver.: 1.00 ¦
'/
¦
'/ Zweck: Erstellt eine kleine Datumstabelle von einem per Dialog ausgewähltem Datum
¦
'/-----------------------------------------------------------------------------------------------------------Dim vntMonthArray As Variant
Private Sub UserForm_Initialize()
Dim intI As Integer
vntMonthArray = Array("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember")
For intI = 1 To 12
cmbMonat.AddItem vntMonthArray(intI - 1)
Next
cmbMonat.ListIndex = Month(Now) - 1
For intI = 1900 To 2100
cmbJahr.AddItem Format(intI, "####")
Next
cmbJahr.ListIndex = Year(Now) - 1900
End Sub
Private
Dim
Dim
Dim
Dim
Dim
Dim
Dim
Sub cmdOK_Click()
intYear As Integer
intMonth As Integer
vntDayArray As Variant
objTable As Table
intI As Integer
intFirstDay As Integer
intDayCount As Integer
intYear = cmbJahr.value
intMonth = cmbMonat.ListIndex + 1
vntDayArray = Array("Mo", "Di", "Mi", "Do", "Fr", "Sa", "So")
Set objTable = ActiveDocument.Tables.Add(Range:=Selection.Range, NumRows:=8, NumColumns:=7)
With Selection
.MoveRight Unit:=wdCharacter, Count:=7, Extend:=wdExtEnd
.Cells.Merge
.TypeText Text:=vntMonthArray(intMonth - 1) & " " & Format(intYear, "####")
.MoveRight Unit:=wdCell
For intI = 1 To 7
.TypeText vntDayArray(intI - 1)
.MoveRight Unit:=wdCell
Next
intFirstDay = WeekDay(Date:=DateSerial(Year:=intYear, Month:=intMonth, Day:=1), FirstDayOfWeek:=vbMonday)
For intI = 1 To intFirstDay - 1
.MoveRight Unit:=wdCell
Next
intDayCount = Day(Date:=DateSerial(Year:=intYear, Month:=intMonth + 1, Day:=0))
For intI = 1 To intDayCount
.TypeText Format(intI, "00")
.MoveRight Unit:=wdCell
Next
End With
With objTable
.AutoFormat Format:=wdTableFormatSimple1
.Rows(2).Select
With Selection
.Font.ColorIndex = wdBlue
While .Information(wdWithInTable) = True
.MoveDown Unit:=wdLine
Wend
End With
.PreferredWidthType = wdPreferredWidthPoints
.PreferredWidth = 200
.Style = "Tabellenraster"
End With
In das VBA-Modul NewMacros geben Sie
folgende Dialoform-Aufruf-Prozedur ein:
Public Sub Monatskalender()
frmMonatskalender.Show 0
End Sub
Unload Me
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Sehen wir uns nun den VBA-Code etwas genauer an. Über den Makro-Ausführen-Dialog starten Sie nun den
Aufrufmakro Monatskalender, der die Form zur Anzeige bewegt. In der Initialisierungs-Prozedur auf der neuen
UserForm frmMonatskalender, welche beim Aufruf der Form automatisch ausgeführt wird, werden die Monate
und Jahre aufbereitet und den ComboBoxen übergeben, sodass Sie diese bei dem angezeigten Dialog
auswählen können.
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 6 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Wird nun die Schaltfläche cmdOK angeklickt, wird im Formmodul die Prozedur cmdOK_Click() ausgeführt, die die
Datumstabelle erzeugt. Das aktuell gewählte Jahr wird nun der ComboBox (mit cmbJahr.value) entnommen,
wie auch der gewünschte Monat.
Der Variant-Variable wird ein Array der Wochentage zugewiesen, die wir dann weiter unten benötigen. Nun wird
die Tabelle mit Set objTable …. erzeugt, mit 8 Zeilen und 7 Spalten. Die erste Zeile (die das Datum enthält) wird
nun mit Cells.Merge so verbunden, das nur eine Zeile ohne Spalten erstellt wird.
Dann werden in einer For-Schlaufe alle Wochentage in die Spalten der zweiten Zeile abgefüllt (aus Array
extrahiert).
In einer nächsten Schlaufe werden dann die Tage in die Zellen abgefüllt und am Ende die tabelle noch formatiert.
! Eine Besonderheit in der Enwicklungsumgebung ist die Möglichkeit ein Code zu debuggen, sprich ihn
zeilenweise abarbeiten zu lassen um mitverfolgen zu können, was der laufende VBA-Code gerade anstellt. Mit
der Taste F9 setzen sie an einem beliebigen Punkt einen Haltepunkt worauf die Codeausführung dort gestoppt
wird. Mit der Taste F8 können Sie nun Schrittweise durch den Code fahren und beobachten was dieser im
Dokument anstellt.
Man kann auch mit der Maus über Variablen fahren und sieht gleich welchen Wert zB. eine Stringvariable oder
ein Integer-Wert inne hat. Im untenstehenden Beispiel sehen wir den Wert der Integer-Variable intMonth= 12!
Wer dieses Werkzeug versteht, hat mit der Zeit so richtig Spass daran, Makros zu schreiben, da diese
Programmiersprache Visual basic for Application eine Menge an Kompfor zu bieten hat.
Makroroutinen, welche immer wieder benötigt werden, wie zB. unsere Suchen/Ersetzen-Funktion die wir oben
beschrieben haben, lassen sich in portierbare VBA-Module unterbringen, sodass wir diese Prozeduren in allen
VBA-Projekten wieder einsetzen können.
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 7 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Ko n t ex t m en u - E in b in d u n g
Leider lassen sich in Office 2010 die Kontextmenüs nicht mehr mit VBA allein anpassen. Hierzu ist eine
integrierte XML-Datei notwendig, die mit Hilfe eines Gratis-Tool CustomUIEditor (unter dem Weblink:
http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2009/08/06/7293.aspx
downloadbar
>
OfficeCustomUIEditorSetup.zip!) erstellt und implementiert werden kann.
Die XML-Datei darf nur bearbeitet werden, wenn die Quell-Dotm-Word-Datei geschlossen ist, da diese XML-Datei
beim Speichern in die hier im CustomUIEditor geöffnete Dotm-Datei integriert wird.
Die hier vorliegende Makrovorlage W14Makroprogrammierung.dotm-Datei enthält den oben abgebildeten XMLCode, der insgesamt 7 Contextmenüs abdeckt, sodass wir auch wenn wir auf eine Grafik mit einem Rechtsklick
das Kontextmenü öffnen der Inhaltsverzeichnis-Makro aufgerufen werden kann.
Der Einstiegsmakro befindet sich im Hauptmodul mdlmakros und sieht folgendermassen aus:
Sub InhaltsverzeichnisAnzeigen(control As IRibbonControl)
InhaltAnzeigen
End Sub
' Kontextmenü-Aufruf (integrierte XML-Datei)
S ca n n e rb il d ei n f ü g en
Im AddIn von W14DlgOpen.Dotm wurde ein Makroaufruf mit einer Schaltfläche im Register [Einfügen]
hinzugefügt, über welches man Direkt auf den Scanner zugreifen und Bilder einfügen kann.
Hierzu wurde in der XML-Datei folgender Code hinzugefügt:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab idMso="TabInsert">
<group id="Scannen" label="Scannen" insertAfterMso="GroupInsertIllustrations">
<button id="btnScannen" label="Bild von Scanner holen" onAction="InsertFromScanner" imageMso="OmsCustomizeLayout" size="large"
supertip="Bild von Scanner holen" screentip="Scannen" />
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 8 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Der Makro hierzu sieht folgendermassen aus:
In Excel sieht der Makro etwas anders aus:
' Scanner-Bild-Einfügen In Register [Einfügen] anzeigen
Public Sub InsertFromScanner(control As IRibbonControl)
On Error Resume Next
WordBasic.InsertImagerScan
End Sub
' Scanner-Bild-Einfügen In Register [Einfügen] anzeigen
Public Sub InsertFromScanner(control As IRibbonControl)
SendKeys "%EGS"
End Sub
Habe Sie einen Scanner installiert, wird beim Aufruf dieses Makros die Twain-Schnittstelle aktiviert und der
eingerichtete Scanner wird angezeigt. Über [Einfügen anpassen] kann der Scannbereich definiert werden.
Wiederverw endbarer Code
In diesem Abschnitt widme ich mich verschiedenen Makroprozeduren, die immer wieder in VBA-Projekten
benötigt werden. Im nächsten Beispiel zeige ich die Möglichkeit einer Sortierroutine, welche auch in anderen
Office-Applikationen, wie zB. in Excel oder Powerpoint verwendet werden kann.
So rt ie r- F u n k t io n f ü r VB A
Leider gibt es in der VBA-Entwicklungsumgebung keine Sortierfunktion, man muss diese selber implementieren.
Es gibt einen Haufen von Lösungen, die wir im Internet finden, mit Vor und Nachteilen. Da ich schon länger mit
VBA programmiere habe ich schon vor über 10 Jahren eine Funktion geschrieben, welche eine Sortierung eines
Arrays vornimmt und dieses als Resultat zurückgibt.
Es gibt immer wieder Projekte, in welchem Listenfelder-Werte sortiert angezeigt werden sollen. Mit der
untenstehenden Funktion ist dies kein Problem mehr. Kopieren Sie diese Funktion in ein VBA-Modul und schon
lassen sich Arrays sortieren und über diese Funktion gleich auf einem Listencontrol (Comboboxen oder
Listenfenster) ausgeben.
Wer den Code genauer analysiert, wird feststellen, das ich das ADODB-Objekt virtuell instanziere um Werte zu
sortieren. Dies funktioniert auch mit tausenden von Datensätzen sehr schnell und zuverlässig. Details, wie diese
Funktion zu gebrauchen ist kann dem nachfolgendem Beschreib entnommen werden.
'/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 16.03.03
Update: 19.06.03
Version 1.00
¦
'/
¦
'/ Zweck: Sortiert ein als Argument übergebenes eindim. Datenarray mit ADODB! Wird die maximale Grösse der ¦
'/
zu sortierenden Records nicht angegeben (lohnt sich bei tausenden von Records), ermittelt diese
¦
'/
Sortierroutine selbständig den grössten Wert und verwendet dies dann bei der ADODB-Sortierung!
¦
'/
Mit dieser dynamischen Grössenanpassung können somit auch sehr lange Zeichenketten noch akzep¦
'/
tabel umsortiert werden.
¦
'/
¦
'/ Ausg.: Standardmässig gibt diese Funktion ein sortiertes Array der als Parameter angebenen Arraydaten
¦
'/
zurück. Durch die optionale Angabe eines Listencontrols (ComboBox, ListBox etc) oder sogar eines ¦
'/
Textfeld-Controlelementes (TextBox, RTFText etc.) kann eine ausgeführte Sortierung gleich in das ¦
'/
angegebene Control ausgegeben werden (spart Zeit und zusätzlichen Ausgabecode!).
¦
'/
¦
'/ Arg.1: Ein eindim. zu sortierendes Variant-Array wird als ByVal übergeben (Tastet Urarray nicht an!)
¦
'/
Das Array wird sortiert und als Funktionsrückgabe erhalten wir eine sortierte Kopie der Daten.
¦
'/
¦
'/ Arg.2: Mit Hilfe dieses optionalen Argumentes können wir das sortierte Ergebnis gleich in ein Listen¦
'/
Box-Control einfügen lassen (DropDown, CommandBarComboBox etc.)!
¦
'/
¦
'/ Arg.3: Dieses Argument zeigt nur Wirkung, wenn ein Listencontrol angegeben wurde und kann entweder ein
¦
'/
Integer-Wert sein oder eine Strinzeichenkette. Hier können wir einen Index vorgeben, nachdem
¦
'/
die sortierten Daten im Listencontrol vorhanden sind.
¦
'/
¦
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 9 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/ Arg.4: Mit einem True-Wert kann hier anstatt aufsteigend (Standard) absteigend sortiert werden.
¦
'/
¦
'/ Arg.5: Ab einigen tausend Datensätzen bringt die Angabe der längste Stringzeichenkette enorm viel
¦
'/
Geschwindigkeitsvorteile, da die Längen- (automat.) -Berechnung nicht durchgeführt werden muss.
¦
'/-----------------------------------------------------------------------------------------------------------Public Function ArraySortAusgabe(SortArrayObjekt As Variant, Optional
Optional
Optional
Optional
lstObjListe, _
VorgabeIndex As Variant, _
bolAbsteigendSortieren As Boolean = False, _
MaxZeichenlaenge As Variant)
Dim objRecordSet
As Object
' ADODB.Recordset ' Object
Dim SortArray
As Variant
' Sortierarray-Kopie
Dim strTextBox
As String
' Textfeld-Ausgabezeichenkette
Dim lngMaxLen
As Long
' Anzahl der längsten Strings im Array
Dim lngLen
As Long
' Hilfsvariable für Längenscan
'/---------------------------------- ADODB VIRTUELLE SORTIERUNG ---------------------------------------------On Error GoTo SortAbbruch
intLstExist = -1
intTypAusgabe = 0
intIndex = -1
If IsMissing(VorgabeIndex) = False Then
varVorgabe = VorgabeIndex
Else
varVorgabe = ""
End If
' Bei Fehler unsortierte
' Funktionsrückgabe!
' Keine Ausgabe in Liste oder Textfeld
SortArray = SortArrayObjekt
If UBound(SortArray) > 0 Then
' Sortierarray abfüllen
lngMaxLen = -1
' Grösse der Sortierelemente initial.
If IsMissing(MaxZeichenlaenge) = False Then
' Bei X-Tausenden von Datensätzen
lngMaxLen = MaxZeichenlaenge
' kann mit Angaben der höchsten ZeichenElse
' anzahl in einem der Records Speed
For intV = 0 To UBound(SortArray)
' herausgeholt werden, da dann diese
lngLen = Len(SortArray(intV)): If lngLen > lngMaxLen Then lngMaxLen = lngLen
Next
' nicht noch zuerst durchlaufen werden
lngMaxLen = Iif(lngMaxLen = -1, 512, lngMaxLen)
' müssen (für automatischen Betrieb)
End If
Set objRecordSet = Nothing
Set objRecordSet = CreateObject("ADODB.RecordSet")
' ADODB-Zugriffsobjekt
With objRecordSet
' wird instanziert und
.Fields.Append "rstSort", 200, lngMaxLen
' eine Feld "rstSort"
.Open
' adVarChar = 200
' wird virtuell erzeugt!
For intV = 0 To UBound(SortArray)
' Sortierdaten aufnehmen
.AddNew
objRecordSet!rstSort = SortArray(intV)
.Update
' und in Feld speichern
Next
.Sort = "[rstSort]"
' Nun wird RecordSet sort.
intZ = 0
If IsMissing(lstObjListe) = False Then lstObjListe.Clear: intLstExist = 1
intP = IsMissing(lstObjListe)
If intP = False Then
If lstObjListe.ListCount > 0 Then lstObjListe.Clear
End If
If bolAbsteigendSortieren = False Then
' Anhand des optionalen Sortier-Arg.
.MoveFirst
' Record-Cursor an den Beginn setzen
Else
.MoveLast
' Record-Cursor ans Ende setzen
End If
Do While Not Iif(bolAbsteigendSortieren = False, .EOF, .BOF) ' Je nach Sortierrichtung
SortArray(intZ) = .Fields("rstSort").value
' diese in Ergebnis-Array zuweisen
If IsMissing(lstObjListe) = False Then
If SortArray(intZ) <> "" Then
strControlTyp = TypeName(lstObjListe)
' Bei Textboxen Ausgabe mit Enter!
Select Case strControlTyp
Case "ComboBox", "ListBox", "CommandBarComboBox", "CommandBarPopUp"
lstObjListe.AddItem SortArray(intZ) ' Sort. Werte in Liste abfüllen
intTypAusgabe = 1
Case "TextBox", "RTFControl", "CommandBarButton"
strTrenner = Iif(intZ = .Counts, "", vbCrLf)
strTextBox = strTextBox & SortArray(intZ) & strTrenner
intTypAusgabe = 2
End Select
If varVorgabe <> "" Then
' das angegebene Listenfeld-Control!
If TypeName(varVorgabe) = "String" Then
If UCase(varVorgabe) = UCase(SortArray(intZ)) Then intIndex = lstObjListe.ListCount - 1
Else
If Val(varVorgabe) = intZ Then intIndex = intZ
End If
End If
End If
End If
intZ = intZ + 1
If bolAbsteigendSortieren = False Then
' Bei auf/absteigender Aufbereitung
.MoveNext
' Nächster Datensatz
Else
.MovePrevious
' Vorheriger Datensatz
End If
Loop
.Close
' RecordSet-Objekt schliessen
If intTypAusgabe = 1 Then
If intLstExist = 1 And intIndex <> -1 And varVorgabe <> "" Then _
lstObjListe.ListIndex = intIndex
Else
If intTypAusgabe = 2 Then lstObjListe = strTextBox ' Standardeigenschaft des Textfeldes
End If
End With
Set objRecordSet = Nothing
' RecordSet-Objekt zerstören
Else
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 10 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
If IsEmpty(SortArray) = False Then
If IsMissing(lstObjListe) = False Then lstObjListe.Clear
If SortArray(0) <> "" And IsMissing(lstObjListe) = False Then lstObjListe.AddItem SortArray(0)
If IsMissing(VorgabeIndex) = False Then
If UCase(SortArray(0)) = UCase(VorgabeIndex) Then lstObjListe.ListIndex = 0
End If
End If
End If
ArraySortAusgabe = SortArray
' und Sortarray zurückgeben!
Exit Function
' Bei Fehler virtuelles ReSortAbbruch:
Set objRecordSet = Nothing
' cordset wieder entfernen!
' Bei Fehler unsortierte Daten!
ArraySortAusgabe = SortArray
Application.StatusBar = "Fehler in ADODB-Sortiertroutine: " & Err.Description
On Error GoTo 0
' Errormeldung ignorieren
End Function
So rt ie ru n g mit d em C o ll e ct io n - O b je kt
Public Function Sortierung(arrSort As Variant) As Variant
Dim intZ As Long
Dim mySortArray As Object
Dim myZielSort As Variant
Set mySortArray = CreateObject("System.Collections.ArrayList")
For intZ = 0 To UBound(arrSort)
mySortArray.Add arrSort(intZ)
Next
' Werte In Collection aufnehmen
mySortArray.Sort
' Collection Sortieren
ReDim myZielSort(UBound(arrSort))
For intZ = 0 To UBound(arrSort)
myZielSort(intZ) = mySortArray(intZ)
Next
' Ergebnis-Array abfüllen
Sortierung = myZielSort
' Sortiertes Array zurückgeben
mySortArray.Clear
' Collection leeren
Set mySortArray = Nothing
End Function
' und löschen
E rmö g l ic h t Au t o v erv o ll st än d ig u n g b e i Co mb o B o x
'/-----------------------------------------------------------------------------------------------------------'/ Autor: daniel Deckensattl
Email: [email protected]
Erstellt: 30.12.2014
Update: 30.12.2014 Ver. 1.00 ¦
'/
¦
'/ Zweck: Dieser KeyUp-Routine ermöglicht eine Autovervollständigung bei einer ComboBox.
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Static NoSelectText As String
Dim i As Long
With
If
If
If
If
ComboBox1
KeyCode =
KeyCode =
KeyCode =
KeyCode =
vbKeyUp Then Exit Sub
vbKeyDown Then Exit Sub
vbKeyLeft Then Exit Sub
vbKeyRight Then Exit Sub
If KeyCode <> vbKeyBack Then
NoSelectText = Mid(.Text, 1, Len(.Text) - .SelLength)
Else
If NoSelectText <> "" Then
NoSelectText = Mid(NoSelectText, 1, Len(NoSelectText) - 1)
End If
End If
For i = 0 To .ListCount - 1
If Ucase(NoSelectText) = _
Ucase(Mid(.List(i), 1, Len(NoSelectText))) Then
.ListIndex = i
Exit For
End If
Next
.SelStart = Len(NoSelectText)
.SelLength = Len(.Text)
If .ListIndex = -1 Then
.Text = ""
.BackColor = vbWhite
Else
.BackColor = vbWindowBackground
End If
End With
End Sub
W in w o rd Do ku me n t v ar i ab l e s et z en / l es en
Dokumentvariablen sind eine feine Sache, da wir hier Informationen mit einer maximalen Länge von 255 Zeichen
unsichtbar in ein beliebiges Worddokument schreiben und wieder lesen können. Mit der hier beschriebenen
Funktion ein Kinderspiel.
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 11 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 01.04.03
Update: 07.05.03
Version 1.00
¦
'/
¦
'/ Zweck: Setzt oder liest einen Dokumentvariableninhalt eines gewünschten Zieldokumentes
¦
'/
¦
'/
Mit DocVariable "Geschlecht", "männlich" schreiben wir in die Dokumentvariable
¦
'/
Mit strWertVonVariable = DocVariable("Geschlecht") lesen wir die Variable wieder aus
¦
'/-----------------------------------------------------------------------------------------------------------Private Function DocVariable(strDocname, Optional strDocInhalt, Optional strZielDokument)
Dim int_OK As Integer
Dim ZielDoku As Document
Set ZielDoku = ActiveDocument
' Vorgängig auf aktuelles Dokument setzen
If IsMissing(strZielDokument) = False Then
' Wurde ein Zieldoku. angegeben dann ....
For intZ = 1 To Application.Documents.Count
' Dokument suchen und wenn gefunden setzen
If UCase(Application.Documents(intZ).Name) = UCase(strZielDokument) Then Set ZielDoku = Application.Documents(intZ): Exit For
Next
End If
With ZielDoku.Variables
int_OK = -1
For intZ = 1 To .Count
If UCase(.Item(intZ).Name) = UCase(strDocname) Then
int_OK = intZ: Exit For
End If
Next
If IsMissing(strDocInhalt) = False Then
If int_OK >= 0 Then
.Item(int_OK).Value = strDocInhalt
Else
.Add strDocname, strDocInhalt
End If
Else
If int_OK >= 0 Then
DocVariable = .Item(int_OK).Value
End If
End If
End With
End Function
T ext m a rk en l e sen / s ch re ib en
Wer Informationen in einen Textmarkenbereich schreiben möchte, und ihn wieder auslesen ist mit dieser
Funktion bestens bedient. Der Textmarkenname bleibt nach dem Schreiben erhalten!
'/---------------------------------------------------------------------------------------------'/ Autor: Daniel Deckensattl
Erstellt: 31.10.2014
Update: 31.10.2014 ¦
'/
¦
'/ Zweck: Setzt oder liest einen Textmarken-Inhalt. Mit nur einem Parameter wird gelesen,
¦
'/
und mit zwei Parameter In die Textmarke geschrieben. Der dritte Parameter erstellt
¦
'/
eine neue Textmarke und füllt den Inhalt dort hinein.
¦
'/
¦
'/
Beispiel Lesen:
TextBox1.Text = Bookmark("Titelinfo1")
¦
'/
Beispiel Schreiben: Bookmark "Titelinfo1", TextBox1.Text
¦
'/
Beispiel Schreiben: Bookmark "TitelInfo1", "Textmarkeninhalt", True
(Neuerstellen) ¦
'/
Beispiel Schreiben: Bookmark "TitelInfo1", Selection.Range
¦
'/
Beispiel Schreiben: Bookmark "TitelInfo1", Selection.Range, True
(Neuerstellen) ¦
'/---------------------------------------------------------------------------------------------Private Function Bookmark(strBookmarkName As String, Optional strNewValue As Variant = "XXXNurLesenXXX", _
Optional bolNewBookmark As Boolean = False)
Dim myRange As Range
ActiveDocument.Application.ScreenUpdating = False
On Error Resume Next
With ActiveDocument.Bookmarks
If strNewValue = "XXXNurLesenXXX" Then
strText = ""
If .Exists(strBookmarkName) = True Then
strText = .Item(strBookmarkName).Range
End If
Bookmark = strText
Else
If bolNewBookmark = True Then
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:=strBookmarkName
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
End If
If .Exists(strBookmarkName) = True Then
Application.DisplayAutoCompleteTips = True
strZ = strNewValue.ComputeStatistics(Statistic:=wdStatisticCharacters)
If IsEmpty(strZ) = False Then
Selection.Copy
Set myRange = .Item(strBookmarkName).Range
myRange.Select
myRange.Paste
Else
Set myRange = .Item(strBookmarkName).Range
myRange = strNewValue
End If
myRange.Select
.Add Range:=Selection.Range, Name:=strBookmarkName
End If
End If
End With
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 12 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
ActiveDocument.Application.ScreenUpdating = True
ActiveDocument.Application.ScreenRefresh
End Function
W ö rt e rb u ch u m B eg ri f f e e rw eit e rn
'/-------------------------------------------------------------------------------------------------'/ Einfache Wörterbucherweiterung. Nimmt selektierten Text und schreibt diesen In Custom.Dic!
¦
'/-------------------------------------------------------------------------------------------------Sub WoerterbuchErweitern()
Dim nDoc As Document
Dim oRange As Range
benutzer = Environ("USERNAME")
Wort = Selection.Text
If len(Wort) > 1 Then
oPfad = "C:\Users\" & benutzer & "\AppData\Roaming\Microsoft\UProof\"
'anpassen
Set nDoc = Documents.Open(oPfad & "Custom.Dic") 'ggf. Namen des Wörterbuchs anpassen
nDoc.Activate
Set oRange = nDoc.Range
oRange.Paragraphs.Add
oRange.Paragraphs.Last.Range.InsertBefore Wort
nDoc.Close wdSaveChanges
End if
End Sub
Sprache rudimentär ermittlen
'/-----------------------------------------------------------------------------------------------------------'/ Anhand der im aktiven Worddokument befindlichen Spracheinstellung (Selection.LanguageID) könnte die
¦
'/ Dialogbeschriftungssprache dokumentenbezogen ermittelt werden (kann erwünscht sein). Anhand des einge¦
'/ stellte Systemdatums wird mit einem Monatsnamen-Vergleich die Sprache hier festgelegt!
¦
'/ (LanguageID = [Englisch (US) 1033] [Deutschweiz(1031) Deutschland(2055)] [Franz 3082] [Spanisch (US) 4108]¦
'/ [Italien(Schweiz 2064) & (Italien 1040)] könnte mit einer Case-Anweisung ermittelt werden!
¦
'/-----------------------------------------------------------------------------------------------------------Public Function DokumentSprache()
Dim strMt As Variant, datMt As Variant
datMt = "01.01." & Format(Now, "yyyy")
strMt = Format(datMt, "mmmm")
Select Case strMt
Case "January"
DokumentSprache = 3
Case "Januar"
DokumentSprache = 4
Case "Gennaio"
DokumentSprache = 5
Case "Janiver"
DokumentSprache = 6
Case "Gennaia"
DokumentSprache = 7
Case Else
DokumentSprache = 3
End Select
End Function
' Englisch (US)
' Deutsch
' Italienisch
' Franz
' Spanisch
' sonst Englisch
Al l e F eld e r a kt u al is ie re n
'/-----------------------------------------------------------------------------------------------------------'/ Aktualisiert alle Felder im aktuellen Dokument (Kopfzeile, Hauptbereich, Fusszeile und Textfelder!)
¦
'/-----------------------------------------------------------------------------------------------------------Sub AlleFelderMitTextfeldernAktualisieren()
Dim rngDoc As Range
Dim oDoc As Document
Dim docSec As Section
Dim oHF As HeaderFooter
Dim shp As Shape
Set oDoc = ActiveDocument
For Each docSec In oDoc.Sections
For Each oHF In docSec.Headers
For Each shp In oHF.Shapes
With shp.TextFrame
If .HasText Then
.TextRange.Fields.Update
End If
End With
Next shp
Next oHF
For Each oHF In docSec.Footers
For Each shp In oHF.Shapes
With shp.TextFrame
If .HasText Then
.TextRange.Fields.Update
End If
End With
Next shp
Next oHF
For Each rngDoc In oDoc.StoryRanges
rngDoc.Fields.Update
While Not (rngDoc.NextStoryRange Is Nothing)
Set rngDoc = rngDoc.NextStoryRange
rngDoc.Fields.Update
Wend
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 13 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Next rngDoc
Next docSec
Set rngDoc = Nothing
Set oDoc = Nothing
End Sub
In h alt sv e rz ei ch n i s ak t u a li si e re n m it T ab u l at o re rh a lt
'/-----------------------------------------------------------------------------------------------------------'/ Prozedur: InhaltsverzeichnisAktualisieren()
Erstellt: 09.12.14
Uppdate: 09.12.14
Version: 1.00 ¦
'/
¦
'/ Zweck:
Diese Makroroutine sucht im aktiven Dokument nach einem Inhaltsverzeichnis und aktualisiert
¦
'/
dieses mit Beibehaltung der Tabulatoreinstellung und kehrt zum Ausgangspunkt zurück!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub InhaltsverzeichnisAktualisieren()
If ActiveDocument.TablesOfContents.Count = 0 Then Exit Sub
Application.ScreenUpdating = False
ActiveDocument.Bookmarks.Add Range:=Selection.Range, Name:="TempInhaltsverzeichnisAktual"
For intZ = 1 To ActiveDocument.TablesOfContents.Count
ActiveDocument.TablesOfContents(intZ).Range.Select
Selection.MoveLeft Unit:=wdCharacter, Count:=1
intTabPos = PointsToCentimeters(Selection.ParagraphFormat.TabStops(2).Position)
ActiveDocument.TablesOfContents(intZ).Update
arrInhalt = Split(ActiveDocument.TablesOfContents(intZ).Range.Text, vbCr, -1, vbTextCompare)
intInhaltCount = UBound(arrInhalt)
For intD = 1 To intInhaltCount
Selection.ParagraphFormat.TabStops(CentimetersToPoints(intTabPos)).Position = CentimetersToPoints(intTabPos)
Selection.MoveDown Unit:=wdLine, Count:=1
Next
Next
With ActiveDocument
If .Bookmarks.Exists("TempInhaltsverzeichnisAktual") = True Then
.Bookmarks("TempInhaltsverzeichnisAktual").Select
.Bookmarks("TempInhaltsverzeichnisAktual").Delete
End If
End With
Application.ScreenUpdating = True
End Sub
Au t o t e xt - Ein t r äg e an z eig en / h in z u f ü g e n
Dieser Makro benötigt die unten beschriebene TastenStatus(..) – Funktion. Bei Aufruf wird AutotextAuswahldialog von Word angezeigt. Mit gedrückter Shifttaste wird der Autotext-Hinzufügen-Dialog angezeigt!
'/---------------------------------------------------------------------------------------------------------------------'/ Zeigt den Autotext-Einfüg-Dialog von Word. Bei gedrückter Shifttaste wird Neuer Autotext - Dialog angezeigt
¦
'/ Benötigt die Funktion TastenStatus(..)!
¦
'/---------------------------------------------------------------------------------------------------------------------Public Sub AutotextAnzeigenNeu()
If TastenStatus(vbKeyShift) = False Then
Application.Dialogs(wdDialogBuildingBlockOrganizer).Show
Else
Application.Dialogs(wdDialogCreateAutoText).Show
End If
End Sub
M arki e rt ab C u r so rp o sit io n b i s u n d m it g e su ch t em W o rt
'/---------------------------------------------------------------------------------------------------------------------'/ Markiert ab Cursorposition bis und mit gesuchtem Wort
¦
'/---------------------------------------------------------------------------------------------------------------------Private Function MarkierenBisZuEinemWort(strBisZumWort As String)
Dim strZielwort As String
Dim lngStart As Long
Dim lngEnd As Long
lngStart = Selection.Start
lngEnd = Selection.End
With Selection.Find
.Forward = True
.ClearFormatting
.MatchWholeWord = True
.MatchCase = False
.Wrap = wdFindContinue
.Execute FindText:=strBisZumWort
End With
If lngEnd >= Selection.End Then
MsgBox "nach der selectierten Stelle das Suchwort:
ActiveDocument.Range(lngStart, lngEnd).Select
Exit Function
End If
" & strZielwort & "
nicht gefunden!"
ActiveDocument.Range(lngStart, Selection.End).Select
End Function
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 14 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
H yp e rl in ks i m Do ku m en t en t f e rn en
'/---------------------------------------------------------------------------------------------------------'/ Hyperlinks im aktuellen Dokument entfernen
¦
'/---------------------------------------------------------------------------------------------------------Sub NoHyperlinks()
Dim x As Variant
For Each x In ActiveDocument.Hyperlinks
Selection.WholeStory
Selection.Range.Hyperlinks(1).Delete
Next x
End Sub
Dr u c k e ak t u e ll e W o rd se it e
'/---------------------------------------------------------------------------------------------------------'/ Drucken aktuelle Word-Seite
¦
'/---------------------------------------------------------------------------------------------------------Sub DruckenAktuelleSeite()
On Error Resume Next
Application.PrintOut FileName:="", Range:=wdPrintCurrentPage, _
Item:=wdPrintDocumentContent, Copies:=1, Pages:="", _
PageType:=wdPrintAllPages, Collate:=True, _
Background:=True, PrintToFile:=False
End Sub
Dr u c k e ak t u e ll e M ark ie ru n g ei n e s W o r d d o ku m en t e s
'/---------------------------------------------------------------------------------------------------------'/ Drucken aktuelle Markierung eines Word-Dokumentes
¦
'/---------------------------------------------------------------------------------------------------------Sub DruckenMarkierung()
On Error Resume Next
Options.PrintReverse = True
Application.PrintOut FileName:="", Range:=wdPrintSelection, _
Item:=wdPrintDocumentContent, Copies:=1, Pages:="", _
PageType:=wdPrintAllPages, Collate:=True, _
Background:=True, PrintToFile:=False
End Sub
Dr u c k en v o n 2 S eit en p r o Bl at t
'/---------------------------------------------------------------------------------------------------------'/ Drucken 2 Seiten pro Blatt
¦
'/---------------------------------------------------------------------------------------------------------Sub Drucken_2_Seiten_pro_Blatt()
On Error Resume Next
Options.PrintReverse = False
Application.PrintOut FileName:="", _
Range:=wdPrintAllDocument, _
Item:=wdPrintDocumentContent, Copies:=1, Pages:="", _
PageType:=wdPrintAllPages, Collate:=True, _
Background:=True, PrintToFile:=False, _
PrintZoomColumn:=2, PrintZoomRow:=1, _
PrintZoomPaperWidth:=0, _
PrintZoomPaperHeight:=0
End Sub
Dr u c k en v o n 4 S eit en p r o Bl at t
'/---------------------------------------------------------------------------------------------------------'/ Drucken 4 Seiten pro Blatt
¦
'/---------------------------------------------------------------------------------------------------------Sub Drucken_4_Seiten_pro_Blatt()
On Error Resume Next
With Options
.UpdateFieldsAtPrint = True
.UpdateLinksAtPrint = False
.DefaultTray = "Druckereinstellungen verwenden"
.PrintBackground = True
.PrintProperties = False
.PrintFieldCodes = False
.PrintComments = False
.PrintHiddenText = False
.PrintDrawingObjects = True
.PrintDraft = False
.PrintReverse = False
.MapPaperSize = False
End With
With ActiveDocument
.PrintPostScriptOverText = False
.PrintFormsData = False
End With
Application.PrintOut FileName:="", _
Range:=wdPrintAllDocument, _
Item:=wdPrintDocumentContent, Copies:=1, Pages:="", _
PageType:=wdPrintAllPages, Collate:=True, _
Background:=True, PrintToFile:=False, _
PrintZoomColumn:=2, PrintZoomRow:=2, _
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 15 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
PrintZoomPaperWidth:=11907, _
PrintZoomPaperHeight:=16839
End Sub
Je d e W o rd se it e in e i n n eu es D o ku m en t st el le n
'/---------------------------------------------------------------------------------------------------------'/ Dieses Beispiel speichert jede einzelne Seite des aktiven WORD-Dokumentes in ein neues WORD-Dokument ab ¦
'/---------------------------------------------------------------------------------------------------------Public Sub
Dim
Dim
Dim
JedeSeiteInNeuesDokument()
wdDoc As Document
wdDocNeu As Document
wdBereich As Range
' Aktives Dokument
' Neues Dokument
' Dokument-Bereich
Dim sPfad As String
Dim optAnsicht As Long
' Pfadangabe für neue Dokumente
' Dokumentansicht
Dim iSeitenAnz As Integer
Dim i As Integer
Dim iDocNum As Integer
' Anzahl der Seiten im Dokument
' Zähler
' Zähler für Dateiname
Set wdDoc = ActiveDocument
' Verweis auf Dokument setzen:
'Speicher-Pfad für neue Dokumente:
'Es wird vorausgesetzt, dass das aktive Dokument gespeichert ist
sPfad = wdDoc.Path & "\" & "Test_"
'Bildschirmaktualisierung deaktivieren (Flackern wird zumindest vermindert)
Application.ScreenUpdating = False
'Einstellung Seiten-Ansicht sichern:
'optAnsicht = wdDoc.ActiveWindow.View.Type
optAnsicht = Windows(wdDoc).View.Type
Windows(wdDoc).View.Type = wdPageView
' Seiten-Ansicht SeitenLayout einstellen:
wdDoc.Range(0, 0).Select
' Cursor zum Anfang des Dokuments:
'Browser-Eigenschaft einstellen, hier: "Nach Seite durchsuchen"
'Gibt ein Browser-Objekt zurück, das die Schaltfläche "Objekt für
'Durchsuchen markieren" auf der vertikalen Bildlaufleiste darstellt
Application.Browser.Target = wdBrowsePage
iDocNum = 0
' Dokument-Nr. zum Speichern - Startwert setzen
'Anzahl Seiten im Dokument ermitteln
iSeitenAnz = wdDoc.ComputeStatistics(wdStatisticPages)
For i = 1 To iSeitenAnz
'Verweis auf den zu kopierenden Bereich setzen
Set wdBereich = wdDoc.Bookmarks("\Page").Range
'Den zu kopierenden Bereich überprüfen, ob Seitenwechsel dabei ist;
'ggf. den Bereich verkleinern
If Right(wdBereich.Text, 1) = Chr(12) Then
wdBereich.SetRange Start:=wdBereich.Start, End:=wdBereich.End - 1
End If
'Neues Dokument öffnen, auf Basis derselben Dokumentvorlage
'wie das Original-Dokument
Set wdDocNeu = Documents.Add(Template:=wdDoc.AttachedTemplate.FullName)
'oder auf Basis der Normal.dot:
'Set wdDocNeu = Documents.Add
'Formatierten Text -> neue Datei
wdDocNeu.Content.FormattedText = wdBereich.FormattedText
'Dokument-Nr. zum Speichern erhöhen
iDocNum = iDocNum + 1
'Neues Dokument speichern:
wdDocNeu.SaveAs FileName:=sPfad & Format(iDocNum, "000")
'Neues Dokument schließen
wdDocNeu.Close
'Dokument aktivieren
wdDoc.Activate
'Zur nächsten Seite im Original-Dokument wechseln
Application.Browser.Next
Next i
'Ursprüngliche Seiten-Ansicht wieder einstellen
Windows(wdDoc).View.Type = optAnsicht
'Cursor zum Anfang des Dokuments
wdDoc.Range(0, 0).Select
'Bildschirmaktualisierung aktivieren
Application.ScreenUpdating = True
'Verweise freigeben
Set wdBereich = Nothing
Set wdDocNeu = Nothing
Set wdDoc = Nothing
End Sub
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 16 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
S ch rif t en li st e e rst e ll en
'/-----------------------------------------------------------------------------------------------------------'/ Erstellt in Word eine Liste aller Schriften
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub SchriftenlisteErstellen()
Selection.InsertAfter "Ausdruck der verfügbaren Schriftarten" + String$(2, 13)
Selection.Paragraphs.Alignment = wdAlignParagraphCenter
With Selection.Font
.Size = 18
.Bold = True
.Italic = True
End With
Selection.Collapse direction:=wdCollapseEnd
Set Tabelle = ActiveDocument.Tables.Add(Selection.Range, 1, 2)
Tabelle.Cell(1, 1).SetWidth ColumnWidth:=InchesToPoints(2), RulerStyle:=wdAdjustNone
Selection.InsertAfter "Schriftart"
Tabelle.Cell(1, 2).SetWidth ColumnWidth:=InchesToPoints(4), RulerStyle:=wdAdjustNone
Tabelle.Cell(1, 2).Range.InsertAfter "Beispiel in Schriftgröße 12"
Beispiel = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz € ÄäÖöÜüߧ0123456789" _
+ Chr$(34) + Chr$(132) + Chr$(147) + "@#$%&?!*"
Anzahl = FontNames.Count - 1
Redim Schrift(Anzahl)
For z = 0 To Anzahl
Schrift(z) = FontNames(z + 1)
Next
For x = 0 To Anzahl
Selection.Tables(1).Rows.Add
Tabelle.Cell(x + 2, 1).Range.InsertAfter Schrift(x)
Tabelle.Cell(x + 2, 2).Range.InsertAfter Beispiel
With Tabelle.Cell(x + 2, 2).Range.Font
.Name = Schrift(x)
.Size = 12
End With
Next x
FontCounter = "Anzahl der installierten Schriften: " + CStr(Anzahl)
Selection.EndKey Unit:=wdStory
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.TypeParagraph
Selection.TypeText Text:=FontCounter
End Sub
W o rd - W o rt li st e in E x ce l e rs t e ll en
'/-----------------------------------------------------------------------------------------------------------'/ Erstellt eine sortierte Word-Häufigkeitswortliste in einer neuen Excel-Arbeitsmappe
¦
'/-----------------------------------------------------------------------------------------------------------Sub XLWortListeGenerieren()
Dim objActDoc As Document
Dim objWort As Range
Dim strWort As String
Dim intI As Integer
Dim blnVorhanden As Boolean
Dim colWörter As New Collection
Dim colHäufigkeiten As New Collection
Dim vntWert As Integer
Dim objXL As Object
If Documents.Count = 0 Then
MsgBox Prompt:="Es ist kein Dokument geöffnet.", Title:="Wortliste generieren"
End
End If
System.Cursor = wdCursorWait
Set objActDoc = ActiveDocument
For Each objWort In objActDoc.Words
strWort = Trim(objWort.Text)
If Len(strWort) > 1 Then
If Asc(strWort) > 31 Then
If Val(strWort) = 0 Then
For intI = 1 To colWörter.Count
blnVorhanden = False
If LCase(colWörter(intI)) = LCase(strWort) Then
blnVorhanden = True
vntWert = colHäufigkeiten(intI)
colHäufigkeiten.Add Item:=vntWert + 1, _
Before:=intI
colHäufigkeiten.Remove intI + 1
Exit For
End If
Next
If blnVorhanden = False Then
colWörter.Add Item:=strWort
colHäufigkeiten.Add Item:="1"
End If
End If
End If
End If
Next
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 17 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
System.Cursor = wdCursorNormal
If colWörter.Count > 0 Then
Set objXL = CreateObject("Excel.Application")
If objXL Is Nothing Then
MsgBox "Excel kann nicht gestartet werden."
End
End If
With objXL
.Visible = True
.Workbooks.Add
With .ActiveSheet
.Columns("A:A").NumberFormat = "@"
.Columns("B:B").NumberFormat = "General"
With .Cells(1, 1)
.value = "Wortliste: " & objActDoc.Name
.Font.Size = 12
.Font.Bold = True
End With
For intI = 1 To colWörter.Count
.Cells(intI + 1, 1) = colWörter(intI)
.Cells(intI + 1, 2) = colHäufigkeiten(intI)
Next
.UsedRange.Select
End With
.Selection.Sort Key1:=.Range("A2"), Order1:=1, Header:=1
End With
MsgBox Prompt:="Wortliste mit " & CStr(colWörter.Count) & _
" Einträgen in neuer Excel-Arbeitsmappe gespeichert.", _
Buttons:=vbInformation, Title:="Wortliste generieren"
Set objXL = Nothing
End If
End Sub
De- Ak t iv i e rt H yp e r lin k- Ak t iv ie ru n g
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
'/---------------------------------------------------------------------------------------------------------------------'/ Deaktiviert die Hyperlink-Aktivierung beim Eingeben einer Emailadresse oder URL. Mit gedrückter Shifttaste wird
¦
'/ Option wieder aktiviert >> Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
¦
'/---------------------------------------------------------------------------------------------------------------------Sub HyperlinkAktivierungOnOff()
With Options
.AutoFormatAsYouTypeReplaceHyperlinks = TastenStatus(vbKeyShift)
.AutoFormatReplaceHyperlinks = TastenStatus(vbKeyShift)
End With
End Sub
'/---------------------------------------------------------------------------------------------------------------------'/ Funktion: TastenStatus
Erstellt: 1.7.01
Update: 26.10.01
Version: 1.10
¦
'/ Argument: APITastenKonstante
Typ: Long
' vbKey.... - Konstante, wie vbKeyShift, vbKeyControl
¦
'/ Rückgabe: Boolean-Wert
' Wahr wenn Taste gedrückt ist, False wenn nicht!
¦
'/
¦
'/ Über diese Funktion erhalten wir von einer gewünschten Keyboard-Taste dess Zustand (gedückt) wenn wir die
¦
'/ gewünschte Taste als VB-Konstanten-Argument dieser Funktion übergeben (häufig sind vbKeyControl/.KeyMenu)!
¦
'/
¦
'/ erfordert: Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
¦
'/---------------------------------------------------------------------------------------------------------------------Public Function TastenStatus(API_VB_TastenKonstante As Long) As Boolean
TastenStatus = Cbool(GetAsyncKeyState(API_VB_TastenKonstante) And &H8000)
End Function
' ermittelt Tastenstatus
' oder Maustastenstatus!
G en au Ru n d e n , a u ch au f 5 R ap p en
'/-------------------------------------------------------------------------------------------------'/ Rundet einen angegenen Double-Wert auf eine bestimmte Anzahl Nachkomma-Stellen und auf den
¦
'/ nächsten Rundungsfaktor. Dies ist vor allem hilfreich beim Rechnen mit Franken-Beträgen
¦
'/
¦
'/
Beispiele:
¦
'/
¦
'/
Runden(+1.22556 , 2 , 5 )
>>> 1.25
¦
'/
Runden(+1.22556 , 2 , 1 )
>>> 1.23
¦
'/
Runden(+1.22556 , 3 , 10)
>>> 1.230
¦
'/
Runden(-1.32712 , 2 , 5 )
>>> 1.35
¦
'/
¦
'/-------------------------------------------------------------------------------------------------Public Function Runden(pdblValue As Double, Optional plngStellen As Long = 2, Optional plngRunden As Long = 1) As String
Dim dblReturn
As Long
Dim lngDifferenz As Long
Dim intVorzeichen As Long
'/*--- Vorzeichen ermitteln und anschliessen alles mit Absolutwert berechnen
intVorzeichen = Sgn(pdblValue)
'/*--- Wert so umwandeln, dass keine Kommastelle mehr vorhanden ist
dblReturn = Abs(CLng(pdblValue * 10 ^ plngStellen))
'/*--- Differenz zum nächsten Rundungsschritt ermitteln
lngDifferenz = (dblReturn Mod plngRunden)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 18 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/*--- Wenn Differenz kleiner als die Hälfte des Rundungsschrittes, dann abrunden, sonst aufrunden
dblReturn = dblReturn + Iif(lngDifferenz < (plngRunden / 2), -lngDifferenz, plngRunden - lngDifferenz)
'/*--- Wert richtig gerundet und formatiert zurück geben (Vorzeichen wieder hinzufügen)
Runden = Format(intVorzeichen * dblReturn / 10 ^ plngStellen, "0." & String(plngStellen, "0"))
End Function
VB ( A) - Co d e in HT M L 4. 0 u mw an d e ln
'/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 08.09.03
Update: 08.11.04
Version 1.00 ¦
'/
¦
'/ SubFnc: Dieser Makro benutzt die Subroutine [SuchTausch(..)] um Suchbegriffe im Text auszutauschen
¦
'/
¦
'/ Zweck: Dieser Wordmakro konvertiert einen farbigen VB.NET-Sourcecode In ein HTML-4.0-Textformat. Das
¦
'/
Ergebnis wird In <pre>...</pre> - Tags eingebettet um im Dreamweaver dann einfügen zu können.
¦
'/
¦
'/
Ein VB.ET-Source In einem aktiven Worddokument wird hier so umgewandelt, dass VB.NET-Anweisungen ¦
'/
In hellblauer Farbe, Remarkzeilen mit hellgrüner Farbe und die Grundschrift-Farbe In weiss einge- ¦
'/
stellt wird. Alle Wordoptionen die hier umgestellt werden, werden am Ende wieder zurüchgestellt¨ ¦
'/
wie der autom. Leerzeichen-Ausgleich beim Ersetzen, die Apostroph-Autokorrektur, usw.!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub VBNETCode2HTML40()
Dim myAdata As Variant, myBdata As Variant, myCdata As Variant, myDdata As Variant, bolFound As Boolean
Dim strAdat As String, strBdat As String, strDocName As String, strGrundfarbe As String
Dim intZ As Integer, strZ As String, strAusgabe As String, myWordCFg(2) As Variant
Dim intRemarks As Integer, strFarbeTag01 As String, strFarbeTag02 As String, bolAllSelect As Boolean
'-- Bildschirmaktualisierung während dem Austausch abschalten
Application.ScreenUpdating = False
If Selection.Paragraphs.Count = 1 Then
' Kein Text selektiert
Selection.WholeStory
' dann alles selektieren
End If
intP = Selection.Paragraphs.Count
' Zähle anzahl Absätze
Selection.MoveLeft Unit:=wdCharacter, Count:=1
' Gehe Ein Zeichen nach Links
For intZ = 1 To intP
' Alle Absätze durchsuchen
Selection.Find.ClearFormatting
With Selection.Find
.Text = "^p"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = True
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
' Such auslösen
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
intP = Selection.Characters.Count
If intP = 1 And Selection.Text = vbCr Then
Selection.Text = " "
End If
Selection.EndKey Unit:=wdLine
Selection.MoveRight Unit:=wdCharacter, Count:=1
Next
Selection.MoveLeft Unit:=wdCharacter, Count:=1
strSE = Chr(34): bolAllSelect = False
'-- Grundschriftfarbe, Aweisungsfarbe und Remarkfarbe gleich zu Beginn festlegen
strFarbeStart = "<pre style=" + strSE + "FONT-SIZE: 9pt; FONT-FAMILY: Fixedsys,Courier,monospace" + strSE + _
"><FONT COLOR=" + strSE + "#FFFFFF" + strSE + " FACE=" + strSE + "Courier New" + strSE + _
" SIZE=" + strSE + "2" + strSE + "></font><br>"
' Einleitungsformat
strFarbeTag01 = "<FONT COLOR=" + strSE + "#00FFFF" + strSE + ">"
' Aweisungs-Farbe
strFarbeTag02 = "<FONT COLOR=" + strSE + "#00FF00" + strSE + ">"
' Remark-Farbe
strGrundfarbe = "<FONT COLOR=" + strSE + "#FFFFFF" + strSE + ">"
' Grundschriftfarbe
'-- Änderunge die dieser Makro an den Wordoptionen vornimmt sichern und am Ende wiederherstellen
'-- Leerzeichenausgleich abschalten, auch Apostroph-Ersetzung und Bindestrich-Ersetzung
myWordCFg(0) = Options.PasteAdjustWordSpacing
myWordCFg(1) = Options.AutoFormatAsYouTypeReplaceQuotes
myWordCFg(2) = Options.AutoFormatAsYouTypeReplaceSymbols
Options.PasteAdjustWordSpacing = False
Options.AutoFormatAsYouTypeReplaceQuotes = False
Options.AutoFormatAsYouTypeReplaceSymbols = False
'-- Alle VisualBasic-Befehle die im folgenden Array sind werden blau eingefärbt
'-- Erst werden alle blau einzufärbenden Befehle gesucht und mit HTML-1.0-Farbtags ausgestattet
strAdat = "For,Next, If,Then,Else,True,False,UBound,LBound,While,Wend,Boolean,Variant,Long,Byte,Integer,"
strAdat = strAdat + "String, Trim, Asc,Finaly,Select Case,End Select, Nothing, Each, vbCr,vbCrLf, & ,Step"
strAdat = strAdat + "End Class, End Enum,End Function,End Sub,End With,End Try,End Select,End If,Enum ,ByVal"
strAdat = strAdat + "Nothing,Optional ,Return , And, Or , New,Try,Catch,On Error Resume,Property,Declare"
strAdat = strAdat + "Array,Dim,Public,Private,Exit,Imports ,Namespace ,Class,Inherits , As ,Friend , Instr"
strAdat = strAdat + "Len, Mid,If,Class,End,With,Case,Function,Sub,On Error GoTo,Split,Cbool,Option Explicit"
strAdat = strAdat + "Range,Set ,Exit Sub,Exit Function,Do ,Loop,End Select,Ucase,LCase,Replace,Replace, To "
strAdat = strAdat + "Property,End Property,Const,Exit Do,Exit For,Exit Sub, End Sub,Object,Collection"
strAdat = strAdat + "Option Explicit,Not,Is"
'-- alle auszutauschenden Begriffe erst sammeln und dann In Array spitzen und Ersetzen starten
myAdata = Split(strAdat, ",", -1, vbBinaryCompare)
'-- Ausgags-Selektion als Bookmark merken, wenn nichts markiert wurde vorgängig alles Selektieren
If Len(Selection.Text) < 2 Then Selection.WholeStory: bolAllSelect = True
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 19 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Selection.Font.Name = "Courier New"
Selection.Font.Size = 6
If bolAllSelect = True Then Selection.HomeKey Unit:=wdStory: Selection.WholeStory
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:="ASCII2FlashHTML10SelBeginn"
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
'-- Zuerst beim Original-Text die Sonderzeichen alle ersetzen
SuchTausch "<", "<", True, True, True, True
SuchTausch ">", ">", True, True, True, True
'-- Änderungen In alle Remark-Zeilen suchen und nach Begrifftausch wieder zurückstellen
If Len(Selection.Text) > 1 Then
myCdata = Split(Selection.Text, vbCr, -1, vbBinaryCompare)
Else
myCdata = Split(ActiveDocument.Range.Text, vbCr, -1, vbBinaryCompare)
End If
'-- Jetzt werde alle VB-Befehle (VBA,VB und VB.NET) blau eingefärbt
For intZ = 0 To UBound(myAdata)
SuchTausch myAdata(intZ), "</font>" + strFarbeTag01 + myAdata(intZ) + "</font>" + _
strGrundfarbe, True, True, True, True
Next
Selection.GoTo What:=wdGoToBookmark, Name:="ASCII2FlashHTML10SelBeginn"
'-- Änderungen In alle Remark-Zeilen suchen und nach Begrifftausch wieder zurückstellen
If Len(Selection.Text) > 1 Then
myDdata = Split(Selection.Text, vbCr, -1, vbBinaryCompare)
Else
myDdata = Split(ActiveDocument.Range.Text, vbCr, -1, vbBinaryCompare)
End If
'-- Bei auftretenden Remarkzeilen wird nur immer bei der ersten Zeile grün zugewiesen
strAusgabe = ""
intRemarks = 0
For intZ = 0 To UBound(myCdata) - 1
strZ = Trim(myDdata(intZ))
If Len(strZ) > 1 Then
'-intApoPos = Instr(2, strZ, "'", vbBinaryCompare)
'-- Eine nur Remarkzeile hat ach einem Trim Einleitungszeichen als 1. Zeichen
If Mid(strZ, 1, 1) = Chr(39) Then
If myDdata(intZ) <> myCdata(intZ) Then myDdata(intZ) = myCdata(intZ)
'-- Remark-Farbtag vor Remarkzeile setzen
If intRemarks = 0 Then myDdata(intZ) = "</font>" + strFarbeTag02 + myDdata(intZ)
intRemarks = intRemarks + 1
Else
'-- Bei Remarkzeilen steht grüer Farbtag vor Zeile, bei Änderungen zurückstelle
If intApoPos > 0 Then
intApoPos = Instr(Len(myDdata(intZ)) - Len(strZ) + 1, myDdata(intZ), "'", vbBinaryCompare)
myDdata(intZ) = Left(myDdata(intZ), intApoPos - 1) + "</font>" + strFarbeTag02 + _
Right(myDdata(intZ), Len(myDdata(intZ)) - (intApoPos - 1)) + "</font>" + strGrundfarbe
Else
If intRemarks > 0 Then
myDdata(intZ) = "</font>" + strGrundfarbe + myDdata(intZ)
End If
End If
intRemarks = 0
End If
End If
' -- jetzt noch alle Enters ersetzen entweder durch <br> oder <P ALIGN="Left">
strAusgabe = strAusgabe + myDdata(intZ) + "<br>"
' vbCr dann lesbarer
Next
'-- Ergebnis nun im Dokument ausgeben (alter Bookmark wird autom. gelöscht, daher Neusetzen)
Selection.GoTo What:=wdGoToBookmark, Name:="ASCII2FlashHTML10SelBeginn"
Selection.Text = vbCrLf + vbCrLf + vbCrLf
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:="ASCII2FlashHTML10SelBeginn"
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
'-- Drei Leere Enters wurden eingefügt und Cursor wird nun In die Mitte positioniert
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.Text = strFarbeStart + strAusgabe + "</pre>"
'-- Nachdem der konvertierte Text ausgegeben wurde, Doppelspurige Farb-Tags entfernen
Selection.GoTo What:=wdGoToBookmark, Name:="ASCII2FlashHTML10SelBeginn"
strDoppelte = "<FONT COLOR=" + strSE + "#FFFFFF" + strSE + "></font><FONT COLOR=" + _
strSE + "#00FFFF" + strSE + ">"
SuchTausch strDoppelte, strFarbeTag01, True, True, True, True
'-- Erster und letzter unnötiger Absatz wieder entfernen
Selection.Characters(1).Delete
Selection.GoTo What:=wdGoToBookmark, Name:="ASCII2FlashHTML10SelBeginn"
Selection.Characters(Len(Selection)).Delete
'-- Leerzeichen-Ausgleich wieder zurückstellen
Options.PasteAdjustWordSpacing = myWordCFg(0)
Options.AutoFormatAsYouTypeReplaceQuotes = myWordCFg(1)
Options.AutoFormatAsYouTypeReplaceSymbols = myWordCFg(2)
Application.ScreenUpdating = True
ActiveWindow.ActivePane.VerticalPercentScrolled = 0
End Sub
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 20 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 08.11.02
Update: 08.11.04
Version 1.00 ¦
'/
¦
'/ Zweck: Tauscht einen Suchbegriff durch einen anderen aus und per optionalen Arg. bedienbar. Diese sehr
¦
'/
universal gehaltene Arbeitsroutine wird von diversen Wordmakros verwendet.
¦
'/-----------------------------------------------------------------------------------------------------------Private Function SuchTausch(ByVal Suchbegriff As String, Optional ByVal Ersetzen As String = "_DefaultValueNoSettig_ThisArg", _
Optional ByVal bolNachUntenSuchen As Boolean = True, Optional ByVal bolWeitersuchen As Boolean = True, _
Optional ByVal bolWortSuche As Boolean = True, Optional ByVal bolGrossKleinBuchstabe As Boolean = False) As
Boolean
Selection.Find.ClearFormatting
With Selection.Find
.Text = Suchbegriff
.Replacement.Text = Ersetzen
.Forward = bolNachUntenSuchen
If bolWeitersuchen = True Then
.Wrap = wdFindContinue
Else
.Wrap = wdFindStop
End If
.Format = False
.MatchCase = bolGrossKleinBuchstabe
.MatchWholeWord = bolWortSuche
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
If Ersetzen <> "_DefaultValueNoSettig_ThisArg" Then
SuchTausch = Selection.Find.Execute(Replace:=wdReplaceAll)
Else
SuchTausch = Selection.Find.Execute
End If
End Function
Ak t u a li si e rt n u r Ref - F el d e r
Manchmal ist es nur nötig, wenn die REF-Felder aktualisert werden müssen
'/-----------------------------------------------------------------------------------------------------------'/ Aktualisiert auf Wunsch nur REF-Felder
¦
'/-----------------------------------------------------------------------------------------------------------Sub REFAktualisierung()
On Error Resume Next
Dim f As Field
For Each f In ActiveDocument.Fields
If f.Type = 3 Then f.Update
Next f
End Sub
'
3=wdFieldRef
S ca n n e r- E in b in d u n g au ch mit W i n w o rd 2 0 13
'/---------------------------------------------------------------------------------------------------------------------'/ Scannt ein Bild und speichert temporär im Profilverzeichnis des Anwenders und fügt dies In das aktuelle Dokument
¦
'/---------------------------------------------------------------------------------------------------------------------Public Sub Scanner(control As IRibbonControl)
Scannen
End Sub
' Makroaufruf für Ribbon-XML-Datei (AddIn)
Public Sub Scannen()
Dim objWiaImg As Object
Dim strDateiname
On Error GoTo Abbruch
Set objWiaDlg = CreateObject("WIA.CommonDialog")
strDateiname = Environ("USERPROFILE") & "\Test.jpg"
Set objWiaImg = objWiaDlg.ShowAcquireImage
On Error Resume Next
If Not objWiaImg Is Nothing Then
If Dir(strDateiname) <> "" Then Kill strDateiname
objWiaImg.SaveFile strDateiname
Set MyDocument = ActivePresentation.Slides(1)
Selection.InlineShapes.AddPicture FileName:=strDateiname, LinkToFile:=False, SaveWithDocument:=True
Set MyDocument = Nothing
End If
Set objWiaDlg = Nothing
Exit Sub
Abbruch:
MsgBox "Kein Scanner erreichbar", vbCritical, "Scanner fehlt"
End Sub
S er i en d ru ck i n ei n z e l n e Do ku men t e s p e ic h er n
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 21 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/-----------------------------------------------------------------------------------------------------------'/ Zweck: Diese Prozedur speichert Seriendruckdokumente einzel ab und schliesst sie.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub Seriendruck_in_getrennte_Dateien()
Dim iBrief As Integer, sBrief As String
On Error GoTo Fehler
Application.Visible = False
With ActiveDocument.MailMerge
.DataSource.ActiveRecord = 1
Do
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
.FirstRecord = .ActiveRecord
.LastRecord = .ActiveRecord
sBrief = "C:\DeinPfad\" & .DataFields("Nachname").Value & "_" & .DataFields("Vorname").Value & ".docx"
End With
.Execute Pause:=False
ActiveDocument.SaveAs FileName:=sBrief
ActiveDocument.Close False
If .DataSource.ActiveRecord < .DataSource.RecordCount Then
.DataSource.ActiveRecord = wdNextRecord
Else
Exit Do
End If
Loop
End With
Fehler:
Application.Visible = True
End Sub
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 22 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Window s-Funktionen nutzen
Windows besitzt eine Unmenge von API-Funktionen, über welche Dialoge von Windows aufgerufen werden
können, Programme gestartet und beendet werden, Kopierfunktionen, Löschfunktionen, welche auch in VBA
genutz werden können, usw.! Sehen wir uns nun ein paar wertvolle Routinen an, die es in sich haben.
T ast e n st at u s ab f r ag e n
Eine besonders hilfreiche Funktion die ich immer wieder in VBA-Projekten
einsetze ist die Tastenstatus-Abfragefunktion TastenStatus(..) die es mir
ermöglicht, festzustellen ob ein Anwender während einer Makroausführung
die Umschaltaste (vbKeyShift) oder die Alt-Taste (vbKeyMenu) gedrückt hält.
So sind Doppel-und Dreifachbelegungen möglich.
Am Beginn, also im Kopfbereich eines VBA-Modules wird die API-Funktion deklariert, welche dann in der
Funktion TastenStatus abgefragt wird und feststellt welche Taste gedrückt wurde. Wie die obige Abbildung zeigt
können fast alle Tasten abgefragt werden, ob diese gedrückt werden.
Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Im VBA-Modul wird TastenStatus und ein Leerzeichen angegeben und über die Ctrl/Leertaste-Kombination kann
dann eine vbKey….-Konstante ausgewählt werden. Im mittleren Teil dieser Gesamtdokumntation werde ich
AddIn-Projekte vorstellen, in denen diese hier beschriebenen Funktionen zum Einsatz kommen.
'/--------------------------------------------------------------------------------------------------------------'/ Funktion: TastenStatus
Erstellt: 1.7.01
Update: 26.10.01
Version: 1.20 ¦
'/ Argument: APITastenKonstante
Typ: Long
' vbKey.... - Konstante, wie vbKeyShift, vbKeyControl
¦
'/ Rückgabe: Boolean-Wert
' Wahr wenn Taste gedrückt ist, False wenn nicht!
¦
'/
¦
'/ Dies ist die erste nach Aussen offene Hilfsfunktion, die in allen VBA-Projekten bequem über einen Klassenver-¦
'/ weis und Aufruf abgerufen werden kann. In diesem Beispiel kann der aktuelle Tastenabfragestatus einer als vb-¦
'/ Konstante übergebenen Taste (zb vbKeyShift) ermittelt werden. Es wird ein Wahrheitswert zurückgegeben!
¦
'/
¦
'/ erfordert: Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
¦
'/--------------------------------------------------------------------------------------------------------------Public Function TastenStatus(APITastenKonstante As Long) As Boolean ' ermittelt Tastenstatus
TastenStatus = CBool(GetAsyncKeyState(APITastenKonstante) And &H8000)
' oder Maustastenstatus!
End Function
P au sen ein b in d en
In manchen VBA-Projekten sind Pausen notwendig, also der Code eine Weile warten muss bis es weiter geht.
Hierzu existiert eine hilfreiche Funktion die ohne API-Deklaration auskommt, wie folgt beschrieben. Optional kann
ein Wahrheitswert (True oder False, also Wahr oder Falsch) angegeben werden, ob Windows im Hintergrund
weiter aktiv sein soll.
'/--------------------------------------------------------------------------------------------------------------'/ Eine Wartepause (in Sekunden) um die Einfach/Doppelklick-Unterscheidung ermittelbar zu machen, etc.!
¦
'/--------------------------------------------------------------------------------------------------------------Private Function Timing(Zeit As Variant, Optional bolDoEvent As Variant)
Dim intDoEvent As Integer, Start As Variant
' Lokale Variablen definieren
intDoEvent = Iif(IsMissing(bolDoEvent) = False, 0, 1)
Start = Timer
' Startzeit speichern
Do
If intDoEvent = 0 Then DoEvents
If Timer < Start Then Zeit = Zeit - 86400
' Mitternachtskorrektur
Loop Until (Timer - Start > Zeit)
End Function
T emp o rä r e r Pf ad e rm it t e ln
Es gibt Situationen, wo wir eine Datei im temporären Pfad ablegen müssen um dann wieder eingelesen werden
zu können. So lassen sich auch grössere Dateien von Winword zu Excel verschieben oder zu anderen
Programmen. Das System liefert uns den Temporärpfad den wir immer mit Schreibrechten nutzen können.
Public Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
'/---------------------------------------------------------------------------------------------------------------------'/ Die Funktion ermittelt den Temp-Pfad des Systems (per API-Funkt. GetTempPath(..))
¦
'/----------------------------------------------------------------------------------------------------------------------
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 23 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Public Function GetTempPfad() As String
Dim strPath As String * 255
Dim lTempPathLength As Long
lTempPathLength = GetTempPath(255, strPath)
GetTempPfad = Left(strPath, lTempPathLength - 1)
End Function
Und auch hier gilt es die API-Deklaration zuoberst im VBA-Modul (Formmodul, Klassenmodul oder VB-Modul) zu
deklarieren, hingegen die GetTempPfad-Routine kann beliebig stehen.
Ben u t z e r- N am e
Anhand des Benutzernamens können Entscheidungen in einem Makro getroffen werden, die äusserst wichtig
sind. Daher hier diese Hilfsfunktion
Public Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
'/--------------------------------------------------------------------------------------------------------------'/ Diese Funktion ermittelt den am System angemeldeten Benutzer-Login-Name
¦
'/--------------------------------------------------------------------------------------------------------------Public Function BenutzerLogin()
Dim strBuffer As String * 25, lngResultat As Long
lngResultat = GetUserName(strBuffer, 25)
BenutzerLogin = Left$(strBuffer, InStr(strBuffer, Chr(0)) - 1)
End Function
P ro f ilv e rz ei ch n i s v o n an g e me ld et en B en u t z er
'/---------------------------------------------------------------------------------------------------------'/ Liefert das Profil-Verzeichnis des angemeldeten Benutzer:
¦
'/---------------------------------------------------------------------------------------------------------Public Function GetUserProfilDirectory()
GetUserProfilDirectory = Environ("USERPROFILE")
End Function
Co mp u t e r- N am e
Der Name des Computers kann auch hilfreich sein, wenn im Makro diese Informationen benötigt werden.
Public Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
'/--------------------------------------------------------------------------------------------------------------'/ Die Funktion ermittelt den Computer-Namen
¦
'/--------------------------------------------------------------------------------------------------------------Public Function GetComputerInfo() As String
Dim lngResult As Long
Dim strInfo As String
strInfo = Space$(256)
lngResult = GetComputerName(strInfo, Len(strInfo))
If InStr(strInfo, Chr$(0)) > 0 Then _
strInfo = Left$(strInfo, InStr(strInfo, Chr$(0)) - 1)
GetComputerInfo = strInfo
End Function
Dr u c k er n a me n e rmi t t eln
'/---------------------------------------------------------------------------------------------'/ Autor: Daniel Deckensattl
Erstellt: 20.01.2010
Update: 20.01.2010 ¦
'/
¦
'/ Zweck: List alle am System vorhandenen Druckernamen aus, als Ergebnis erhalten wir zB.:
¦
'/
Name: Microsoft XPS Document Writer
¦
'/
Name: FreePDF
¦
'/
Name: FAX
¦
'/
Name: Brother PC-FAX v.3.2
¦
'/
Name: Brother MFC-J870DW Printer
¦
'/
Name: An OneNote 2010 senden
¦
'/---------------------------------------------------------------------------------------------Sub DruckerModelle()
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Printer", , 48)
For Each objItem In colItems
Debug.Print "Name: " & objItem.Name
Next
End Sub
PC - Um g e b u n g sv a r ia b len er mit t e ln
'/-----------------------------------------------------------------------------------------------------------'/ Diese Funktion liest den Umgebungsvariablen-Speicher des Betriebsystems aus und sucht nach einer MSDOS¦
'/ Set-Variable zum Beispiel COMPUTERNAME=Disi_PC und gibt diesen Wert als Zeichenkette der Funktion zurück. ¦
'/
¦
'/ Beispiele
¦
'/ ALLUSERSPROFILE=C:\ProgramData
¦
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 24 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/ APPDATA=C:\Users\Disi\AppData\Roaming
¦
'/ CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip
¦
'/ CommonProgramFiles=C:\Program Files (x86)\Common Files
¦
'/ CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
¦
'/ CommonProgramW6432=C:\Program Files\Common Files
¦
'/ COMPUTERNAME = Disi_PC
¦
'/ ComSpec=C:\Windows\system32\cmd.exe
¦
'/ FP_NO_HOST_CHECK = NO
¦
'/ HOMEDRIVE = c:
¦
'/ HOMEPATH=\Users\Disi
¦
'/ INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio .NET 2003\SDK\v1.1\include\
¦
'/ LIB=C:\Program Files (x86)\Microsoft Visual Studio .NET 2003\SDK\v1.1\Lib\
¦
'/ LOCALAPPDATA=C:\Users\Disi\AppData\Local
¦
'/ LOGONSERVER=\\DISI_PC
¦
'/ NUMBER_OF_PROCESSORS = 4
¦
'/ OS = Windows_NT
¦
'/ Path=C:\Program Files (x86)\Microsoft Office\Office14\;C:\Program Files (x86)\PC Connectivity Solution\; ¦
'/ PROCESSOR_ARCHITEW6432 = AMD64
¦
'/ PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 42 Stepping 7, GenuineIntel
¦
'/ PROCESSOR_LEVEL = 6
¦
'/ PROCESSOR_REVISION=2a07
¦
'/ ProgramData=C:\ProgramData
¦
'/ ProgramFiles=C:\Program Files (x86)
¦
'/ ProgramFiles(x86)=C:\Program Files (x86)
¦
'/ ProgramW6432=C:\Program Files
¦
'/ PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
¦
'/ PUBLIC=C:\Users\Public
¦
'/ QTJAVA=C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip
¦
'/ SESSIONNAME = Console
¦
'/ SystemDrive = c:
¦
'/ SystemRoot=C:\Windows
¦
'/ TEMP=C:\Users\Disi\AppData\Local\Temp
¦
'/ TMP=C:\Users\Disi\AppData\Local\Temp
¦
'/ USERDOMAIN = Disi_PC
¦
'/ UserName = Disi
¦
'/ USERPROFILE=C:\Users\Disi
¦
'/ VBOX_INSTALL_PATH=C:\Program Files\Oracle\VirtualBox\
¦
'/ VS71COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio .NET 2003\Common7\Tools\
¦
'/ WecVersionForRosebud 0.1598 = 4
¦
'/ windir=C:\Windows
¦
'/ windows_tracing_flags = 3
¦
'/ windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub ErmittleMSDOSVariablen()
MsgBox ErmittleUmgebungsVariable("OS")
End Sub
Public Function ErmittleUmgebungsVariable(VariabelName)
Dim UmgZF, Indx, Mldg, PfadLänge, SetName
Indx = 1: GetName = "": SetName = VariabelName & "="
LenVarName = Len(VariabelName) + 1
Do
UmgZF = Environ(Indx)
If Len(UmgZF) >= Len(UmgZF) Then
If Left(UmgZF, LenVarName) = SetName Then
w = Len(UmgZF)
U = InStr(1, UmgZF, "=", 1)
GetName = Right(UmgZF, w - U)
Exit Do
Else
Indx = Indx + 1
End If
Else
Indx = Indx + 1
End If
Loop Until UmgZF = ""
ErmittleUmgebungsVariable = Trim(GetName)
End Function
' Kommt ohne API aus!
' Variablen deklarieren.
' Variablen-Initialisierung
' Umgebungsvariable
' Eintrag prüfen.
' Länge bestimmen.
' Kein PATH-Eintrag,
' also hochzählen.
' Kein PATH-Eintrag,
' Gefundener Wert zurüchgeben
W in d o w s- V e rs io n e r mit t el n
'/--------------------------------------------------------------------------------------------------------------'/ Diese Funktion liefert auf rudimentärste Weise die aktuelle Windows-Familienversion 98/NT/W2000/W7!
¦
'/ Testen mit: MsgBox WindowsVersion
¦
'/--------------------------------------------------------------------------------------------------------------Public Function WindowsVersion() As String
Select Case True
Case Len(Environ$("OS")) = 0
WindowsVersion = "Win9x"
Case Len(Environ$("PROGRAMFILES")) = 0
WindowsVersion = "WinNT"
Case Else
sText = Environ$("OS")
pText = Environ$("PROGRAMFILES")
If sText = "Windows_NT" And pText = "C:\Program Files (x86)" Then
WindowsVersion = "Windows 7"
Else
WindowsVersion = "Win2000"
End If
End Select
End Function
Bil d s ch i rm au f lö s u n g er mit t e ln
'/---------------------------------------------------------------------------------------------------------'/ Private Declare Function GetSystemMetrics Lib "user32.dll" (ByVal nIndex As Long) As Long
¦
'/
¦
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 25 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/ Liefert die aktuelle Bildschirmgrösse des Rechners
¦
'/---------------------------------------------------------------------------------------------------------Public Sub BildschirmaufloesungErmitteln()
Dim DisplayResolutionY As Long
Dim DisplayResolutionX As Long
DisplayResolutionY = GetSystemMetrics(1)
DisplayResolutionX = GetSystemMetrics(0)
'// 1 = Y Resolution
'// 0 = X Resolution
Debug.Print DisplayResolutionY & " x " & DisplayResolutionX
End Sub
In t er n et - E xp lo re r m it U RL an z ei g e n
'/---------------------------------------------------------------------------------------------------------'/ Öffnet eine neue Internet-Instanz und lädt gewünschte URL
¦
'/---------------------------------------------------------------------------------------------------------Public Sub InternetExplorerAnzeigen()
Dim objApp As Object
' Kreiert eine Explorer-Instanz und macht diese sichtbar
On Error GoTo ErrHandler
Set objApp = CreateObject("InternetExplorer.Application")
With objApp
.Visible = True
.Navigate URL:="https://www.google.ch"
End With
ErrHandler:
'Bei Abbruch VBA-Instanz löschen
Set objApp = Nothing
On Error GoTo 0
End Sub
Z w isch en ab l ag e v e rw en d en
'/---------------------------------------------------------------------------------------------------------'/ Mit Hilfe dieser Routinen können wir einen beliebigen, als Parameter übergebenen Text in die
¦
'/ Zwischenablage befördern [EinTextZurAblage(Textkopie)] oder zurückermitteln [EinTextVonAblage]
¦
'/---------------------------------------------------------------------------------------------------------Public Function EinTextZurAblage(ObjektInAblage)
If TypeName(ObjektInAblage) = "String" Then
Clipboard.SetText ObjektInAblage
Else
Clipboard.SetData ObjektInAblage, 2
End If
End Function
'
Kopiert Text in Zwischenablage
Public Function EinTextVonAblage()
If Clipboard.GetFormat(1) = True Then
EinTextVonAblage = Clipboard.GetText(1)
Else
EinTextVonAblage = ""
End If
End Function
'
Liest Text von Zwischenablage
S ch alt ja h r e r mit t el n
'/---------------------------------------------------------------------------------------------------------'/ Liefert nach übergebenen Jahr True oder False zurück, ob es ein Schaltjahr ist oder nicht!
¦
'/---------------------------------------------------------------------------------------------------------Function Schaltjahr(Jahreszahl)
Schaltjahr = Iif((Jahreszahl Mod 4) = 0 And (Jahreszahl Mod 100) <> 0 Or (Jahreszahl Mod 400) = 0, True, False)
End Function
Ka le n d erw o c h e e in e s D at u m s e r mit t el n
'/-----------------------------------------------------------------------------------------------------------'/ Gibt die Kalenderwoche nach DIN 1355 zurück (zB. strZ = KWoche("04.12.2014"))
¦
'/-----------------------------------------------------------------------------------------------------------Function KWoche(d As Date) As Integer
Dim t&
t = DateSerial(Year(d + (8 - Weekday(d)) Mod 7 - 3), 1, 1)
KWoche = (d - t - 3 + (Weekday(t) + 1) Mod 7) \ 7 + 1
End Function
M o n at sl et z t er
'/---------------------------------------------------------------------------------------------------------'/ Liefert vom aktuellen Datum den Monatsletzten
¦
'/---------------------------------------------------------------------------------------------------------Function MonatsLetzter()
Jahr = Format(Now, "yyyy")
Monat = Format(Now, "mm")
f = "dd.mm.yyyy"
MonatsLetzter = Format(DateSerial(Jahr, Monat + 1, 0), f)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 26 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
End Function
O st er n b e re ch n e n
'/---------------------------------------------------------------------------------------------------------'/ Ausgehend vom Ostersonntag kann man die Feiertage berechnen:
Weitere Feiertage:
¦
'/
¦
'/ Neujahr = DateSerial(Year(Now), 1, 1)
¦
'/ Maifeiertag = DateSerial(Year(Now), 5, 1)
¦
'/ Karfreitag = Ostern(Year(Now)) - 2
¦
'/ Ostermontag = Ostern(Year(Now)) + 1
¦
'/ Himmelfahrt = Ostern(Year(Now)) + 39
¦
'/ Pfingstsonntag = Ostern(Year(Now)) + 49
¦
'/ Pfingstmontag = Ostern(Year(Now)) + 50
¦
'/ Fronleichnam = Ostern(Year(Now)) + 60
¦
'/ TagDeutscheEinheit = DateSerial(Year(Now), 10, 3)
¦
'/---------------------------------------------------------------------------------------------------------Function Ostern(Yr As Integer) As Date
Dim d As Integer
d = (((255 - 11 * (Yr Mod 19)) - 21) Mod 30) + 21
Ostern = DateSerial(Yr, 3, 1) + d + (d > 48) + 6 - ((Yr + Yr \ 4 + d + (d > 48) + 1) Mod 7)
End Function
Ei n f a ch e r Da t u m s ka l en d e r
Dieser Kalender kann auch in anderen VBA-Projekten eingesetzt werden, wie zum Beispiel in Excel in einem
Spesenformular.
'/-----------------------------------------------------------------------------------------------------------'/ Autor: Daniel Deckensattl
Erstellt: 08.02.13
Update: 08.02.13
Version 1.00 ¦
'/
¦
'/ Zweck: Datumauswahl mit einem einfachen Kalender der das ausgewählte Datum im Format 05.02.2013 zurück- ¦
'/
gibt. Die getätigte Datumsauswahl wird im aktuellen Dokument ausgegeben.
¦
'/
Wird ein Doppelklick auf eine Tages-Auswahl getroffen, dann dieses Datum übernehmen, einfügen
¦
'/
und Dialog schliessen.
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub UserForm_Initialize()
Dim intI As Integer
Dim arrMonthArray As Variant
arrMonthArray = Array("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", _
"August", "September", "Oktober", "November", "Dezember")
'-- Alle Monate In DropDown-Box abfüllen und aktueller Monat selektieren
For intI = 1 To 12
cmdList02.AddItem arrMonthArray(intI - 1)
Next
cmdList02.ListIndex = Month(Now) - 1
'-- Alle 200 Jahre In DropDown-Box abfüllen und aktuelles Jahr selektieren
For intI = 1900 To 2100
cmdList01.AddItem Format(intI, "####")
Next
cmdList01.ListIndex = Year(Now) - 1900
'-- Aktueller Tag In entsprechendes Textfeld ausgeben
txt01.Text = Format(Day(Now), "00")
frmKalender.Caption = "Datumauswahl - [" & Format(Now, "dd.mm.yyyy") & "]"
DatumAnzeigen
End Sub
Private Function DatumAnzeigen()
If cmdList01.ListIndex = -1 Then Exit Function
' Datum nun abfüllen
intYear = cmdList01.List(cmdList01.ListIndex)
intMonth = cmdList02.ListIndex + 1
'vntDayArray = Array("Mo", "Di", "Mi", "Do", "Fr", "Sa", "So")
intFirstDay = Weekday(Date:=DateSerial(Year:=intYear, Month:=intMonth, Day:=1),
FirstDayOfWeek:=vbMonday)
intDayCount = Day(Date:=DateSerial(Year:=intYear, Month:=intMonth + 1, Day:=0))
intY = 1
For intI = 1 To 42
sLabCtrl = "Lab" & Format(intI, "00")
If intI >= intFirstDay And intI < (intDayCount + intFirstDay) Then
Me.Controls(sLabCtrl) = Format(intY, "00")
intY = intY + 1
Else
Me.Controls(sLabCtrl) = ""
End If
Next
End Function
'/-- Die Taste Abbrechen wurde ausgewählt und fügt kein Datum ein
Private Sub cmdBut01_Click()
Unload Me
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 27 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
End Sub
'/-- Die Jahres-Liste wurde ausgewählt und aktualisiert Datumanzeige
Private Sub cmdList01_Change()
DatumAnzeigen
End Sub
'/-- Die Monats-Liste wurde ausgewählt und aktualisiert Datumanzeige
Private Sub cmdList02_Change()
DatumAnzeigen
End Sub
'/-- Die Taste einfügen wurde ausgewählt und fügt das Datum In die Parent-Form
Private Sub cmdBut02_Click()
strDatum = Format(txt01.Text, "00") & "." & Format(cmdList02.ListIndex + 1, "00") & "." & Format(cmdList01.Value, "####")
Selection.Text = strDatum
End Sub
'/-- Nach einem Doppelklick wird ausgewähltes Datum eingefügt, der Fokus weitergereicht und die Sub-Form entladen
Private Function Unloader(objEntladen As Object, objTextControl As Object)
If objTextControl.Caption <> "" Then
txt01.Text = objTextControl.Caption
cmdBut02_Click
' frmSpesen.TextBox1.SetFocus
Unload objEntladen
End If
End Function
'/-- Klickt ein Anwender auf ein Tag-Text-Control dann diese Nummer In Tagauswahl-Textbox anzeigen
Private Sub Lab01_Click()
If Lab01.Caption <> "" Then txt01.Text = Lab01.Caption
End Sub
'/-- Bei einem Doppelklick wird ausgewählter Tag übernommen und
'/--dann die Entlade-Routine aufgerufen
Private Sub Lab01_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab01
End Sub
Private Sub Lab02_Click()
If Lab02.Caption <> "" Then txt01.Text = Lab02.Caption
End Sub
Private Sub Lab02_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab02
End Sub
Private Sub Lab03_Click()
If Lab03.Caption <> "" Then txt01.Text = Lab03.Caption
End Sub
Private Sub Lab03_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab03
End Sub
Private Sub Lab04_Click()
If Lab04.Caption <> "" Then txt01.Text = Lab04.Caption
End Sub
Private Sub Lab04_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab04
End Sub
Private Sub Lab05_Click()
If Lab05.Caption <> "" Then txt01.Text = Lab05.Caption
End Sub
Private Sub Lab05_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab05
End Sub
Private Sub Lab06_Click()
If Lab06.Caption <> "" Then txt01.Text = Lab06.Caption
End Sub
Private Sub Lab06_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab06
End Sub
Private Sub Lab07_Click()
If Lab07.Caption <> "" Then txt01.Text = Lab07.Caption
End Sub
Private Sub Lab07_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab07
End Sub
Private Sub Lab08_Click()
If Lab08.Caption <> "" Then txt01.Text = Lab08.Caption
End Sub
Private Sub Lab08_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab08
End Sub
Private Sub Lab09_Click()
If Lab09.Caption <> "" Then txt01.Text = Lab09.Caption
End Sub
Private Sub Lab09_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab09
End Sub
Private Sub Lab10_Click()
If Lab10.Caption <> "" Then txt01.Text = Lab10.Caption
End Sub
Private Sub Lab10_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab10
End Sub
Private Sub Lab11_Click()
If Lab11.Caption <> "" Then txt01.Text = Lab11.Caption
End Sub
Private Sub Lab11_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab11
End Sub
Private Sub Lab12_Click()
If Lab12.Caption <> "" Then txt01.Text = Lab12.Caption
End Sub
Private Sub Lab12_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab12
End Sub
Private Sub Lab13_Click()
If Lab13.Caption <> "" Then txt01.Text = Lab13.Caption
End Sub
Private Sub Lab13_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab13
End Sub
Private Sub Lab14_Click()
If Lab14.Caption <> "" Then txt01.Text = Lab14.Caption
End Sub
Private Sub Lab14_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab14
End Sub
Private Sub Lab15_Click()
If Lab15.Caption <> "" Then txt01.Text = Lab15.Caption
End Sub
Private Sub Lab15_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab15
End Sub
Private Sub Lab16_Click()
If Lab16.Caption <> "" Then txt01.Text = Lab16.Caption
End Sub
Private Sub Lab16_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab16
End Sub
Private Sub Lab17_Click()
If Lab17.Caption <> "" Then txt01.Text = Lab17.Caption
End Sub
Private Sub Lab17_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab17
End Sub
Private Sub Lab18_Click()
If Lab18.Caption <> "" Then txt01.Text = Lab18.Caption
End Sub
Private Sub Lab18_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 28 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Unloader Me, Lab18
End Sub
Private Sub Lab19_Click()
If Lab19.Caption <> "" Then txt01.Text = Lab19.Caption
End Sub
Private Sub Lab19_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab19
End Sub
Private Sub Lab20_Click()
If Lab20.Caption <> "" Then txt01.Text = Lab20.Caption
End Sub
Private Sub Lab20_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab20
End Sub
Private Sub Lab21_Click()
If Lab21.Caption <> "" Then txt01.Text = Lab21.Caption
End Sub
Private Sub Lab21_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab21
End Sub
Private Sub Lab22_Click()
If Lab22.Caption <> "" Then txt01.Text = Lab22.Caption
End Sub
Private Sub Lab22_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab22
End Sub
Private Sub Lab23_Click()
If Lab23.Caption <> "" Then txt01.Text = Lab23.Caption
End Sub
Private Sub Lab23_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab23
End Sub
Private Sub Lab24_Click()
If Lab24.Caption <> "" Then txt01.Text = Lab24.Caption
End Sub
Private Sub Lab24_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab24
End Sub
Private Sub Lab25_Click()
If Lab25.Caption <> "" Then txt01.Text = Lab25.Caption
End Sub
Private Sub Lab25_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab25
End Sub
Private Sub Lab26_Click()
If Lab26.Caption <> "" Then txt01.Text = Lab26.Caption
End Sub
Private Sub Lab26_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab26
End Sub
Private Sub Lab27_Click()
If Lab27.Caption <> "" Then txt01.Text = Lab27.Caption
End Sub
Private Sub Lab27_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab27
End Sub
Private Sub Lab28_Click()
If Lab28.Caption <> "" Then txt01.Text = Lab28.Caption
End Sub
Private Sub Lab28_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab28
End Sub
Private Sub Lab29_Click()
If Lab29.Caption <> "" Then txt01.Text = Lab29.Caption
End Sub
Private Sub Lab29_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab29
End Sub
Private Sub Lab30_Click()
If Lab30.Caption <> "" Then txt01.Text = Lab30.Caption
End Sub
Private Sub Lab30_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab30
End Sub
Deckensattl Daniel
[08.01.2015]
Private Sub Lab31_Click()
If Lab31.Caption <> "" Then txt01.Text = Lab31.Caption
End Sub
Private Sub Lab31_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab31
End Sub
Private Sub Lab32_Click()
If Lab32.Caption <> "" Then txt01.Text = Lab32.Caption
End Sub
Private Sub Lab32_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab32
End Sub
Private Sub Lab33_Click()
If Lab33.Caption <> "" Then txt01.Text = Lab33.Caption
End Sub
Private Sub Lab33_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab33
End Sub
Private Sub Lab34_Click()
If Lab34.Caption <> "" Then txt01.Text = Lab34.Caption
End Sub
Private Sub Lab34_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab34
End Sub
Private Sub Lab35_Click()
If Lab35.Caption <> "" Then txt01.Text = Lab35.Caption
End Sub
Private Sub Lab35_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab35
End Sub
Private Sub Lab36_Click()
If Lab36.Caption <> "" Then txt01.Text = Lab36.Caption
End Sub
Private Sub Lab36_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab36
End Sub
Private Sub Lab37_Click()
If Lab37.Caption <> "" Then txt01.Text = Lab37.Caption
End Sub
Private Sub Lab37_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab37
End Sub
Private Sub Lab38_Click()
If Lab38.Caption <> "" Then txt01.Text = Lab38.Caption
End Sub
Private Sub Lab38_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab38
End Sub
Private Sub Lab39_Click()
If Lab39.Caption <> "" Then txt01.Text = Lab39.Caption
End Sub
Private Sub Lab39_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab39
End Sub
Private Sub Lab40_Click()
If Lab40.Caption <> "" Then txt01.Text = Lab40.Caption
End Sub
Private Sub Lab40_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab40
End Sub
Private Sub Lab41_Click()
If Lab41.Caption <> "" Then txt01.Text = Lab41.Caption
End Sub
Private Sub Lab41_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab41
End Sub
Private Sub Lab42_Click()
If Lab42.Caption <> "" Then txt01.Text = Lab42.Caption
End Sub
Private Sub Lab42_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unloader Me, Lab42
End Sub
Au s R eg i st r y l es en o d e r in d i es e s ch r eib e n
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 29 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/-----------------------------------------------------------------------------------------------------------'/ Mit Hilfe dieser Funktion werden Einstellungen des Anwenders aus Registry gelesen, bzw. gesetzt!
¦
'/-----------------------------------------------------------------------------------------------------------Public Function RegistryWerte(strRegZweigName, Optional strRegSectionName, Optional strRegKeyName, _
Optional strRegKeyInhalt) As Variant
Dim strAntwort As String
If IsMissing(strRegKeyInhalt) = True Then
' Nur lesen wenn Parameter fehlt!
strAntwort = GetSetting(APPNAME:=strRegZweigName, Section:=strRegSectionName, Key:=strRegKeyName)
RegistryWerte = Iif(strAntwort = "", "FALSCH", strAntwort)
Else
SaveSetting APPNAME:=strRegZweigName, Section:=strRegSectionName, Key:=strRegKeyName, Setting:=strRegKeyInhalt
End If
End Function
L ie f e rt D at e in am e o d er Pf ad
'/-----------------------------------------------------------------------------------------------------------'/ Liefert nur den Dateiname (intAktion = 1) oder nur den Pfad, ohne Dateinamen. strPfad=ganzer Dateipfad!
¦
'/-----------------------------------------------------------------------------------------------------------Public Function NurDateiName(strPfad, intAktion)
Dim varSplit As Variant
If Len(strPfad) < 3 Then NurDateiName = strPfad: Exit Function
varSplit = Split(strPfad, "\", -1, vbTextCompare)
If intAktion = 0 Then
NurDateiName = Left(strPfad, Len(strPfad) - Len(varSplit(UBound(varSplit))))
Else
NurDateiName = varSplit(UBound(varSplit))
End If
End Function
O u t lo o kn a ch ri ch t v e r se n d en
'/---------------------------------------------------------------------------------------------------------'/ Dieses Beispiel sendet eine e-Mail über Outlook:
¦
'/---------------------------------------------------------------------------------------------------------Sub Mail_senden()
Dim olApp As Object
Set olApp = CreateObject("Outlook.Application")
With olApp.CreateItem(0)
.Recipients.Add "[email protected]"
' Empfänger
.subject = "Test-Mail"
' Betreff
' Nachricht
.body = "Das ist eine e-Mail" & Chr(13) & "Viele Grüße..." & Chr(13) & Chr(13)
.ReadReceiptRequested = False
.Attachments.Add "c:\Dok1.doc"
.Send
End With
Set olApp = Nothing
End Sub
' Lesebestätigung aus
' Dateianhang
V erz e ich n i s au sw äh l en
Oftmals benötigen wir eine Verzeichnisauswahl, wo wir bestimmte Dateien ablegen oder öffnen wollen. Zuerst die
API-Funktionen und Konstanten die im Header (Kopfbereich eines Moduls) hinterlegt werden müssen:
Private Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (ByRef lpbi As BROWSEINFO) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" _
Alias "SHGetPathFromIDListA" (ByVal pidl As Long, _
ByVal pszPath As String) As Long
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private Type BROWSEINFO
hwndOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpFn As Long
lParam As String
iImage As Long
End Type
Private
Private
Private
Private
Private
Const
Const
Const
Const
Const
MAX_PATH = 259
WM_USER As Long = &H400
BIF_RETURNONLYFSDIRS As Long = 1
BFFM_INITIALIZED As Long = 1
BFFM_SETSELECTION As Long = (WM_USER + 102)
Dann die Aufruf-Prozedur:
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 30 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'------------------------------------- Ordnerauswahl ---------------------------------------------Public Function GetFolderInternal(ByVal Caption As String, ByVal Default As String) As String
Dim BI As BROWSEINFO
Dim ListIdx As Long
Dim Path As String
With BI
.lpszTitle = Caption
.ulFlags = BIF_RETURNONLYFSDIRS
.lpFn = MakeFktnPtr(AddressOf BrowseCallbackProc)
.lParam = Default
End With
Path = String$(MAX_PATH + 1, vbNullChar)
ListIdx = SHBrowseForFolder(BI)
If SHGetPathFromIDList(ListIdx, Path) Then
GetFolderInternal = Left$(Path, InStr(Path, vbNullChar) - 1)
End If
CoTaskMemFree ListIdx
End Function
Public Function BrowseCallbackProc(ByVal hwnd As Long, ByVal Msg As Long, _
ByVal lParam As Long, ByVal lpData As Long) As Long
On Error Resume Next
If Msg = BFFM_INITIALIZED Then
SendMessage hwnd, BFFM_SETSELECTION, 1&, lpData
End If
End Function
Private Function MakeFktnPtr(ByVal FktnPtr As Long) As Long
MakeFktnPtr = FktnPtr
End Function
Aufgerufen wird der hier beschriebene Auswahldialog mit den Zeilen:
strExportOrdner = GetFolderInternal("Ordner auswählen", „C:\“)
Dat ei su ch e in O rd n e r u n d d es s en Un t e ro r d n e r
'/---------------------------------------------------------------------------------------------------------'/ Sucht eine gewünschte Datei In einem Ordner plus dessen Unterordner!
¦
'/ Erfordert API-Funktion: Private Declare Function SearchTreeForFile Lib "imagehlp.dll" ( _
¦
'/
ByVal RootPath As String, _
¦
'/
ByVal InputPathName As String, _
¦
'/
ByVal OutputPathBuffer As String) As Long ¦
'/---------------------------------------------------------------------------------------------------------Private Sub DateiSuche()
Dim Retval As Long, TmpStr As String * 256
' Suche beginnen
Retval = SearchTreeForFile("c:\windows", "Chord.wav", TmpStr)
If Retval = 0 Then
MsgBox "Es wurde keine Datei mit diesem Namen gefunden"
Else
MsgBox Left$(TmpStr, Instr(1, TmpStr, vbNullChar) - 1), , "Gefundene Datei"
End If
End Sub
An d er e VB A- Ap p l ik at io n en au f ru f en
Oft kommt es vor, das wir zum Beispiel aus Winword einen Outlook-Kontakt beziehen wollen, oder von Winword
auf eine Excel-tabelle zugreifen möchten. Die hier vorgestellte Routine ermöglicht diesen Applications-Zugriff
untereinander
Zuerst die Header-konstanten-Deklarationen:
Public enuOfficeAppName
Public ClientAufrufen
As Long
As Integer
Enum enuOfficeAppName
Winword = 1
Excel = 2
Powerpoint = 3
Outlook = 4
Access = 5
Frontpage = 6
Visio = 7
CorelDraw = 8
End Enum
Enum enuAppStatus
appStatus = 1
appSichtbarStarten
appSichtbarMitDoku
appUnsichtbStarten
appUnsichtbMitDoku
appTaskSchliessen
End Enum
'
'
'
'
'
'
'
'
'
=
=
=
=
=
Funktion: ..()
Winword
Excel
Powerpoint
Outlook
Access
Frontpage
Vision
Corel
2
3
4
5
6
Dann die eigentliche Zugriffs-Prozedur:
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 31 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
'
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
/-----------------------------------------------------------------------------------------------/ Mit Hilfe dieser Funktion können wir eine globalen Programm-Objektvariabel für eine Office¦
/ Komponenten-Instanz mit einem Applicationsverwes einrichten. Als Rückgabecode wird ein
¦
/ Application-Objekt der jeweiligen Zugriffsapplikation geliefert.
¦
/
¦
/ In die globale Variable appClientPreStatus wird angegeben ob die Instanz noch nicht gelaufen ¦
/ ist 1 Der Rückgabewert 0 bedeutet, dass die Appl. schon am Laufen ist, und dieser Task am Ende¦
/ nicht beendet werden darf (nur der Verweis wird zerstört). Beim Rückgabewert 1 deutet dass auf¦
/ eine neu erstellte Applikationsinstanz hin, auf die über die globale Objekt-Modulvariable
¦
/ appClient zugegriffen werden kann.
¦
/-----------------------------------------------------------------------------------------------Enum enuAppStatus
appStatus = 1
appSichtbarStarten
appSichtbarMitDoku
appUnsichtbStarten
appUnsichtbMitDoku
appTaskSchliessen
End Enum
As Long
=
=
=
=
=
2
3
4
5
6
Enum enuOfficeAppName
scWinword
= 1
scExcel
= 2
scPowerpoint = 3
scOutlook
= 4
scAccess
= 5
scFrontpage = 6
scVisio
= 7
scCorelDraw = 8
End Enum
'
'
'
'
'
'
'
'
‘
Funktion: ..()
Winword
Excel
Powerpoint
Outlook
Access
Frontpage
Vision
CorelDraw
'/--------------------------------------------------------------------------------------------------------------'/ Diese Funktion stellt bei Gebrauch einen Zeiger zu der gewünschten Windows-Applikation her, welche für eine ¦
'/ Datenmanipulation genutzt werden möchte (auch nur temporär nutzen!) > siehe Applications-Objekt der Anwendung¦
'/--------------------------------------------------------------------------------------------------------------Private Function ClientInstanz(strApplName As OffAppNamen, bolInstanzAnzeigen As Boolean) As Object
Dim obj_appClient As Object
On Error Resume Next
' aktiviert. [Berichtauswahl] mit einem zugewiesenen Wert
Select Case strApplName
Case 1
ClientObjekt = "Word.Application"
Case 2
ClientObjekt = "Excel.Application"
Case 3
ClientObjekt = "Powerpoint.Application"
Case 4
ClientObjekt = "Outlook.Application"
Case 5
ClientObjekt = "Access.Application"
Case 6
ClientObjekt = "Visio.Application"
Case 7
ClientObjekt = "Frontpage.Application"
Case 8
ClientObjekt = "CorelDRAW.Application.10"
Case Else
ClientObjekt = ""
Set ClientInstanz = obj_appClient
' Leeres Objekt zurückgeben und aussteigen
Exit Function
End Select
appClientPreStatus = 0
Set obj_appClient = GetObject(, ClientObjekt)
If obj_appClient Is Nothing Then
On Error GoTo ClientFehler
appClientPreStatus = 1
Set obj_appClient = CreateObject(ClientObjekt)
If bolInstanzAnzeigen = True Then obj_appClient.Visible = True
End If
Set ClientInstanz = obj_appClient
Exit Function
ClientFehler:
On Error GoTo 0
'
MsgBox "Word konnte nicht gestartet werden!", vbCritical, "Programmfehler"
appClientPreStatus = -1
Set ClientInstanz = obj_appClient
End Function
Sp e rrt au g en b li c kl ic h d e n Re ch n e r mit An me ld es ch ir m
'/---------------------------------------------------------------------------------------------------------'/ Sperrt sofort den Rechner und es erscheint der Anmeldeschirm des PC's
¦
'/ Erfordert API-Funktion: Private Declare Function LockWorkStation Lib "user32.dll" () As Long
¦
'/---------------------------------------------------------------------------------------------------------Private Sub WindowsSperren()
Dim Retval As Long
Retval = LockWorkStation
End Sub
Di es e F u n kt io n li ef e r t d en In h alt ein e r e xt er n e n Dat e i
'/------------------------------------------------------------------------------------------------'/ Funktion liefert kommpletten Inhalt einer externen TXT-Datei
¦
'/------------------------------------------------------------------------------------------------Function getFileValues(location As String)
Dim txt As String
Open location For Input As #1
getFileValues = ""
Do Until EOF(1)
Line Input #1, txt
If (getFileValues = "") Then
getFileValues = txt
Else
getFileValues = getFileValues & vbCrLf & txt
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 32 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
End If
Loop
Close
End Function
Hi er w ir d z ei le n w ei se in e in e e xt e rn e D at ei g e s ch ri eb en :
'/------------------------------------------------------------------------------------------------'/ Schreibt zeilenweise in eine externen TXT-Datei (anhängen)
¦
'/------------------------------------------------------------------------------------------------Public Sub setNewLineInFile(sNameFile, sNewLineText)
Dim txt
As String
Dim fn
As Long
fn = FreeFile()
Open sNameFile For Append As #fn
Print #fn, sNewLineText
Close #fn
End Sub
E xt e rn e D at ei st a rt e n ü b er D at ei an g ab e
(zB. PDF-Dateipfad öffnet autom. Acrobat Reader)
' ermöglicht das Starten
Private Declare Function
ByVal lpOperation
ByVal lpDirectory
der PDF-Datei von der Dialogform heraus
ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, _
As String, ByVal lpFile As String, ByVal lpParameters As String, _
As String, ByVal nShowCmd As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
'/---------------------------------------------------------------------------------------------------------'/ Startet die angegebene Programmdatei wie wenn ein Doppelklick über Explorer auf Datei ausgeführt wird! ¦
'/---------------------------------------------------------------------------------------------------------Public Function DateiEndungStarten(PrgArg)
' Installationsassistent beenden. Falls
If PrgArg = "" Then Exit Function
varSplit = Split(PrgArg, "\", -1, vbTextCompare)
' Dateiname von Pfad trennen und für
strFilename = UCase(varSplit(UBound(varSplit)))
' DIR-Prüfung verwenden.
If UCase(Dir(PrgArg)) = strFilename Then
' PrgArg einen Wert aufweist, wird hier
If Trim(PrgArg) <> "" Then
' Die API-Doppelklickfunktiuon ShellExecute
ProcessId = ShellExecute(0&, vbNullString, PrgArg, vbNullString, vbNullString, vbNormalFocus)
SetForegroundWindow ProcessId
' Beenden wieder ermöglichen
DateiEndungStarten = ProcessId
End If
' Gestartete Applikation nach vorne holen.
Else
DateiEndungStarten = -1
' -1 anstatt neue Prozess-ID zurückgeben
End If
' PrgSav auf Null gesetzt.
End Function
Aufruf wie folgt: DateiEndungStarten "D:\Temp\MeineDoku.Pdf"
O p t io n en - Di a lo g m it W S cr ip t - S en d K e ys st eu er n
'/--------------------------------------------------------------------------------------------------------------'/ SendKeys über WScript abspielen (in VBA funktioniert SendKey nicht beim Optionen-Dialog!)
¦
'/--------------------------------------------------------------------------------------------------------------Public Sub WSSendkeys()
Dim objWS
Set objWS = CreateObject("WScript.Shell")
objWS.SendKeys "%doe%y{ENTER}"
End Sub
' In den Optionen [Popupsymbolleise anzeigen] ausschalten
W o rd d at ei en l ad en ü b e r let z t en Vo rg ab ep f ad
Ganz praktisch ist dieser Makro, der Worddateien (zB.*.DOTM) aus einem Verzeichnis lädt und dabei den
Ladepfad für einen nächsten Ladevorgang speichert.
'/-----------------------------------------------------------------------------------------------------------'/ Autor: daniel Deckensattl
Email: [email protected]
Erstellt: 08.12.2014
Update: 08.12.2014 Ver. 1.00 ¦
'/
¦
'/ Zweck: Die Funktion GetOpenFileArray startet den Öffnendialog zur Auswahl von Worddateien. Aufgerufen
¦
'/
wird diese Funktion mit der Prozedur WorddokumenteLaden die den Pfad vorgibt!
¦
'/-----------------------------------------------------------------------------------------------------------Option Explicit
Private Declare Function GetOpenFileName Lib "comdlg32.dll" _
Alias "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 33 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
Flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
pTemplateName As String
End Type
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
Const
OFN_ALLOWMULTISELECT = &H200
OFN_CREATEPROMPT = &H2000
OFN_ENABLEHOOK = &H20
OFN_ENABLETEMPLATE = &H40
OFN_ENABLETEMPLATEHANDLE = &H80
OFN_EXPLORER = &H80000
OFN_EXTENSIONDIFFERENT = &H400
OFN_FILEMUSTEXIST = &H1000
OFN_HIDEREADONLY = &H4
OFN_LONGNAMES = &H200000
OFN_NOCHANGEDIR = &H8
OFN_NODEREFERENCELINKS = &H100000
OFN_NOLONGNAMES = &H40000
OFN_NONETWORKBUTTON = &H20000
OFN_NOREADONLYRETURN = &H8000
OFN_NOTESTFILECREATE = &H10000
OFN_NOVALIDATE = &H100
OFN_OVERWRITEPROMPT = &H2
OFN_PATHMUSTEXIST = &H800
OFN_READONLY = &H1
OFN_SHAREAWARE = &H4000
OFN_SHAREFALLTHROUGH = 2
OFN_SHARENOWARN = 1
OFN_SHAREWARN = 0
OFN_SHOWHELP = &H10
Public Function GetOpenFileArray(strFilter As String, lngFlags As Long, strDir As String) As Variant
'Function gibt ein Array zurück das alle gewählten File enthält
Dim strText As String
Dim vntPathAndFileNamen As Variant
Dim strBuffer As String
Dim lngResult As Long
Dim lngI As Long
Dim ComDlgOpenFileName As OPENFILENAME
'strBuffer = String$(256, 0)
strBuffer = String$(256& * 256, 0)
With ComDlgOpenFileName
.lStructSize = Len(ComDlgOpenFileName)
.Flags = lngFlags
.nFilterIndex = 1
.nMaxFile = Len(strBuffer)
.lpstrFile = strBuffer
.lpstrFilter = strFilter
.lpstrTitle = "Mit gedrückter Shift oder Strg Taste alle gewünschten Dateien markieren!"
.lpstrInitialDir = strDir
End With
lngResult = GetOpenFileName(ComDlgOpenFileName)
If lngResult <> 0 Then
vntPathAndFileNamen = Split(Left$(ComDlgOpenFileName.lpstrFile, _
Instr(ComDlgOpenFileName.lpstrFile, Chr$(0) & Chr(0)) - 1), Chr(0), -1, 0)
If UBound(vntPathAndFileNamen) = 0 Then
strText = Chr(0) & Left$(ComDlgOpenFileName.lpstrFile, _
Instr(ComDlgOpenFileName.lpstrFile, Chr$(0) & Chr(0)) - 1) 'XX
Else
For lngI = 1 To UBound(vntPathAndFileNamen)
strText = strText & Chr(0) & vntPathAndFileNamen(0) & "\" & vntPathAndFileNamen(lngI)
Next
End If
GetOpenFileArray = Split(Mid$(strText, 2), Chr(0), -1, 0)
Else
GetOpenFileArray = ""
End If
End Function
Public Sub WorddokumenteLaden()
Dim lngI
As Long
Dim strDir
As String
Dim strFilter
As String
Dim strDirPath
As String
Dim lngFlags
As Long
Dim vntFileNamen As Variant
Dim wdDoc
As Word.Document
lngFlags = OFN_FILEMUSTEXIST Or OFN_HIDEREADONLY Or OFN_PATHMUSTEXIST Or OFN_ALLOWMULTISELECT Or OFN_EXPLORER
lngFlags = OFN_ALLOWMULTISELECT Or OFN_EXPLORER
strFilter = "Documente (*.doc)" & Chr$(0) & "*.Do*" & Chr$(0) & Chr$(0) ' *.doc Anpassen!!!!
strDirPath = GetSetting("DDTOOL", "AppCFG", "LastPath")
If strDirPath <> "" Then
strDir = strDirPath
Else
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 34 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
strDir = "C:\"
End If
vntFileNamen = GetOpenFileArray(strFilter, lngFlags, strDir)
If VarType(vntFileNamen) = 8200 Then
For lngI = LBound(vntFileNamen) To UBound(vntFileNamen)
Set wdDoc = Application.Documents.Open(vntFileNamen(lngI))
If lngI = 0 Then
SaveSetting "DDTOOL", "AppCFG", "LastPath", wdDoc.Path
End If
DoEvents
Next
Else
Application.StatusBar = "Es wurde keine Datei ausgewählt"
End If
End Sub
Dat ei en i n P ap i e r ko r b lö s ch en
'/--------------------------------------------------------------------------------------------------------------'/ Funktion:
Kill
Erstellt: 20.4.02
Update: 20.04.02
Version: 1.00 ¦
'/
¦
'/ Papierkorb-Löschung mit Nutzung von Wildcards und Datei/Folder-Arrays-Auflistungen (systemnah)
¦
'/
¦
'/ Argument1: True
Name: AllowUndo
Typ: Boolean
¦
'/ Argument2: True
Name: ShowProgress
Typ: Boolean
¦
'/ Argument3: True
Name: Confirmation
Typ: Boolean
¦
'/ Argument4: True
Name: Simple
Typ: Boolean
¦
'/ Argument5: True
Name: SysErrors
Typ: Boolean
¦
'/ Argument6: 167889000001
Name: hWnd
Typ: Long
¦
'/ Argument5: True
Name: UserAborts
Typ: Variant
¦
'/
¦
'/ Rückgabe: Variant-Typ
¦
'/
¦
'/ Die hier vorgestellte Ersatzfunktion Kill verhält sich wie das VB-Original, wenn man ihr (Standard) ledig¦
'/ lich den gewünschten Dateinamen übergibt. Es können aber auch mehrere Dateien (dimensioniertes oder aktuell ¦
'/ mit der Array-Funktion zusammengestelltes) in einem Array oder eine Collection welche aus einzelnen Datei¦
'/ und Ordnerpfaden übergeben. Und sie können Wildcards (etwa "*.*" oder "*.bas") verwenden.
¦
'/
¦
'/ Die gewünschte Funktionalität legen Sie in den einzelnen optionalen Parametern fest. Sollen die Dateien in
¦
'/ den Papierkorb verschoben werden, setzen Sie AllowUndo gleich True. Soll der Windows-übliche Fortschritts¦
'/ dialog mit Möglichkeit zum Abbrechen des Vorgangs angezeigt werden, setzen Sie ShowProgress gleich True. Die ¦
'/ Rückfrage, ob wirklich gelöscht werden soll, legen Sie mit Confirmation gleich True fest. Eine etwas verein ¦
'/ fachte Fortschrittsanzeige, bei der die Anzeige der gerade bearbeiteten Dateinamen unterbleibt, wählen Sie
¦
'/ mit Simple gleich True. Wenn Sie im Falle eines Fehlers die Windows-Anzeige dieses Fehlers beibehalten
¦
'/ wollen, setzen Sie SysErrors gleich True.
¦
'/
¦
'/ In hWnd übergeben Sie die hWnd-Eigenschaft eines Forms, damit Windows den Löschvorgang Ihrer Anwendung zuzu- ¦
'/ ordnen weiss. Ist die Leerung fehlgeschlagen, gibt die Funktion den Wert True zurück.
¦
'/
¦
'/ Unabhängig davon, wie Sie den letztgenannten Parameter setzen, gibt die Funktion Kill den Wert True zurück, ¦
'/ wenn ein Fehler aufgetreten ist. Allerdings lässt sich der Fehler nicht näher spezifizieren - Sie müssen auf ¦
'/ andere Weise prüfen, was schief gegangen sein könnte (Datei nicht vorhanden, gesperrt u.a.). Hat der Anwender¦
'/ bei den gelegentlichen Rückfragen des Systems (Löschen einer Systemdatei o.ä.) beispielsweise einzelne
¦
'/ Dateien übersprungen, können Sie diese Information über den Parameter UserAborts erhalten, in der Sie dazu
¦
'/ eine Variable übergeben müssen. Allerdings müssen Sie auch hierbei wieder selbst herausfinden, welche Dateien¦
'/ übersprungen worden sind.
¦
'/--------------------------------------------------------------------------------------------------------------Public Function
Optional
Optional
Optional
Optional
Optional
Optional
Optional
Kill(Files As Variant, _
ByVal AllowUndo As Boolean, _
ByVal ShowProgress As Boolean, _
ByVal Confirmation As Boolean, _
ByVal Simple As Boolean, _
ByVal SysErrors As Boolean, _
ByVal hwnd As Long, _
UserAborts As Variant _
) As Boolean
Dim l As Long
Dim nFileOperations As SHFILEOPSTRUCT
Const
Const
Const
Const
Const
Const
FO_DELETE = &H3
FOF_ALLOWUNDO = &H40
FOF_SILENT = &H4
FOF_NOCONFIRMATION = &H10
FOF_SIMPLEPROGRESS = &H100
FOF_NOERRORUI = &H400
With nFileOperations
If IsArray(Files) Then
For l = LBound(Files) To UBound(Files)
.pFrom = .pFrom & Files(l) & vbNullChar
Next 'l
.pFrom = .pFrom & vbNullChar
ElseIf VarType(Files) = vbObject Then
If TypeOf Files Is Collection Then
For l = 1 To Files.Count
.pFrom = .pFrom & Files(l) & vbNullChar
Next 'l
.pFrom = .pFrom & vbNullChar
End If
ElseIf VarType(Files) = vbString Then
.pFrom = Files
If Right$(.pFrom, 1) <> vbNullChar Then
.pFrom = .pFrom & vbNullChar
End If
If Mid$(.pFrom, Len(.pFrom) - 1, 1) <> vbNullChar Then
.pFrom = .pFrom & vbNullChar
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 35 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
End If
End If
If AllowUndo Then
.fFlags = FOF_ALLOWUNDO
End If
If Not ShowProgress Then
.fFlags = .fFlags Or FOF_SILENT
End If
If Not Confirmation Then
.fFlags = .fFlags Or FOF_NOCONFIRMATION
End If
If Simple Then
.fFlags = .fFlags Or FOF_SIMPLEPROGRESS
End If
If Not SysErrors Then
.fFlags = .fFlags Or FOF_NOERRORUI
End If
.wFunc = FO_DELETE
.hwnd = hwnd
Kill = Not CBool(SHFileOperation(nFileOperations))
If Not IsMissing(UserAborts) Then
UserAborts = CBool(.fAnyOperationsAborted)
End If
End With
End Function
T ime r- F u n kt io n
Eine etwas spezielle API-Funktion ist der Timer, welcher periodisch aufgerufen wird. Hierzu benötigen wir zwei
API-Funktionen, sehen wir uns zuerst die Deklarationen an:
Public Declare Function SetTimer Lib "user32.dll" (ByVal hwnd As Long, ByVal nIDEvent As Long, _
ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32.dll" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Public Const WM_TIMER = &H113
' Timer-Ereignis trifft ein
Nachdem diese beiden API-Funktionen deklariert sind, kann die SetTimer-Funktion aufgerufen werden. Hier im
Beispiel in der Sub-Routine TimerManagen(Aktivieren/Deaktivieren) wo sie im Sekundentakt (1000
Millisekunden) die Prozedur TimerWordaction aufruft.
'/-----------------------------------------------------------------------------------------------------------'/ Der Timer für die Dokumentenwechselüberwachung kann hier per Funktionsaufruf gestartet oder mit Angaben
¦
'/ eines opt. False-Parameters entladen werden. Dies war nötig um bei Textbaustein-Kopieraktionen keine Pro- ¦
'/ bleme zu bekommen, indem vor einer Aktion der Timer entladen und erst nach ausgeführter Aktion wieder ge- ¦
'/ laden wird!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub TimerManagen(Optional bolStarten As Boolean = True)
If bolStarten = True Then
If lngActionEvent = 0 Then
lngActionEvent = VBA_Bibliothek.SetTimer(0&, 0&, 1000, AddressOf mdlAutotexte.TimerWordaction)
End If
Else
If lngActionEvent > 0 Then
VBA_Bibliothek.KillTimer 0&, lngActionEvent
lngActionEvent = 0
End If
End If
End Sub
Die TimerWordAction – Routine illustriert, wie die CallBack-Funktion aufgebaut sein muss, - in roter Farbe dann
der VBA-Code der unterschiedlich sein kann.
'/-----------------------------------------------------------------------------------------------------------'/ Lädt der Anwender ein neues Dokument oder eine Vorlage in den Speicher, dann prüft diese API-Timer-Ereig- ¦
'/ nisfunktion alle 1000 ms, ob neue Autotexteinträge hinzugekommen sind, oder gar wegfallen sollen.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub TimerWordaction(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
Dim intCounter
As Integer
On Error Resume Next
If uMsg = WM_TIMER Then
intCounter = Application.Documents.Count
If intCounter = 0 Then TimerManagen False
If intAnzahlDokumente <> intCounter Then
TimerManagen False
frmAutotexte.DokumentWechsel
TimerManagen True
End If
End If
End Sub
Die obigen Timer-Funktionen sind sehr heikel, es darf kein Fehler (im roten Bereich) auftreten, da sonst
Schutzverletzungen
vorkommen.
Ich
habe
diese
Routine
zB.
in
meiner
AddIn-Vorlage
W14ProjektManagement.dotm eingebaut, die laufend kontrolliert, ob eine Worddatei hinzugeladen oder entfernt
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 36 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
Deckensattl Daniel
[08.01.2015]
MS-Office 2010 VBA-Programmierung
wurde um die betroffenen Listenfenster autom. zu aktualisieren, was
W14ProjektManagement.XLSM) – VBA-mittel allein nicht zu bewerkstelligen ist.
mit
Word
(oder
Excel-
Im weiter unten beschriebenen PopUp-Menü für VBA habe ich diesen Timer auch implementiert (darf kein Fehler
darin vorkommen!) der während der PopUp-Menüanzeige prüft, ob der Kontextmenübreich mit der Maus noch
überfahren wird, sonst ausblenden).
Während der Programmierung an einem VBA-Projekt sollte diese API-Timerfunktion deaktiviert werden, man
vermeidet so Schutzverletzungen und erst wenn das Projekt einwandfrei läuft, sollte der Timer wieder aktiviert
werden!
M au sp o sit io n l es en / set z en
Public Declare Function GetMessagePos Lib "user32" () As Long
' Mauskoordinaten
Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
!
'/--------------------------------------------------------------------------------------------------------------'/ Diese Funktion gibt die aktuellen Mauskoordinaten (in Pixel) getrennt durch einen Doppelpunkt zurück!
¦
'/ werden die Pixel-Longwert-Argumente lngLinkePos & lngObenPos optional angegeben, kann der Mauszeiger
¦
'/ an dieser gewünschten Screen-Position gesetzt werden (in Pixel angeben oder manuell umrechnen!).
¦
'/--------------------------------------------------------------------------------------------------------------Public Function MauspositionSteuern(Optional longLinkePos As Variant, Optional longObenPos As Variant) As Variant
Dim lngResultat As Long, PosLSetzen As Long, PosOSetzen As Long, varCtrl(2) As Variant
On Error GoTo Abbruch
PosLSetzen = -1: PosOSetzen = -1
If IsMissing(longLinkePos) = False Then
' Wurde ein Linker Positionierungswert angegeben
PosLSetzen = Iif(longLinkePos < 0, 0, longLinkePos) ' dann Wert auf Minus prüfen & ev. korrigieren !
End If
If IsMissing(longObenPos) = False Then
PosOSetzen = Iif(longObenPos < 0, 0, longObenPos)
End If
' Wurde ein Top Positionierungswert angegeben
' dann Wert auf Minus prüfen & ev. korrigieren !
lngResultat = GetMessagePos()
lngPosLSetzen = Val(LoWord(lngResultat))
lngPosOSetzen = Val(HiWord(lngResultat))
' Aktuelle Mauspositionswerte festhalten
' Linke Bildschirmposition der Maus
' Obere Bildschirmposition der Maus
If PosLSetzen < 0 And PosOSetzen < 0 Then
' Bei keiner Argumentübergabe wird nur Resultat
MauspositionSteuern = Array(lngPosLSetzen, lngPosOSetzen) ' zurückgegeben (Array(0)=Links/(1)=Top)
Else
If PosLSetzen >= 0 And PosOSetzen >= 0 Then
' Bei zwei vorhandenen Argumenten Mausposition neu
SetCursorPos PosLSetzen, PosOSetzen
' den übergebenen Koordinaten zuweisen
MauspositionSteuern = Array(PosLSetzen, PosOSetzen) ' Die optionalen TOP/LEFT-Werten zuweisen!
Else
If PosLSetzen >= 0 And PosOSetzen < 0 Then
' Im Falle nur eines angegebenen Argumentes, in
SetCursorPos PosLSetzen, lngPosOSetzen
' diesem Fall die linke Mausposition-Verschiebung
MauspositionSteuern = Array(PosLSetzen, lngPosOSetzen) ' mit bestehendem TOP-Wert zuweisen!
Else
SetCursorPos lngPosLSetzen, PosOSetzen
' Im Falle nur eines angegebenen Argumentes, in
MauspositionSteuern = Array(lngPosLSetzen, PosOSetzen) ' diesem Fall die obere Mausposition
End If
' Verschiebung mit bestehendem LEFT-Wert arbeiten!
End If
End If
Exit Function
Abbruch:
MauspositionSteuern = Array(-1, -1)
' Array mit Minuswerten im Fehlerfall zurückgeben!
End Function
Public Function LoWord(dWert As Long) As Integer
If (dWert And &H8000&) = 0 Then
LoWord = dWert And &H7FFF&
Else
LoWord = &H8000 Or (dWert And &H7FFF&)
End If
End Function
' API-Rückgabewerte ermitteln
Public Function HiWord(dWert As Long) As Integer
If (dWert And &H8000&) = 0 Then
HiWord = dWert / &H10000
Else
HiWord = (dWert And &H7FFF&) / &H10000
End If
End Function
Bin ä r- D ez i m al- Ko n v e rt er
'/---------------------------------------------------------------------------------------------------------------------'/ Wandelt einen übegebenen Dezimalwert In eine binäre Zahl um und umgekehrt!
¦
'/---------------------------------------------------------------------------------------------------------------------Public Function DezimalBinaerKonverter(ByVal Dec As Long, ByVal NumDigitsMin As Long, Optional bolInDezimal = True) As String
Dim lngI As Long, lngLen As Long, lngRes As Long
On Error GoTo DecBinError
' Bei Fehler In Zahl abbrechen
If bolInDezimal = True Then
' Binärstring zerlegen
lngLen = Len(Bin)
For lngI = lngLen To 1 Step -1
' Wir gehen von rechts nach links vor (LSB -> MSB)
lngRes = lngRes + Iif(Mid$(Bin, i, 1) = "1", 2 ^ (lngLen - lngI), 0)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 37 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
Next lngI
DezimalBinaerKonverter = lngRes
Else
Do
If (Dec And 2 ^ lngI) > 0 Then
lngRes = "1" & lngRes
Dec = Dec - 2 ^ lngI
Else
lngRes = "0" & lngRes
End If
lngI = lngI + 1
Loop Until Dec = 0
MS-Office 2010 VBA-Programmierung
'
'
'
'
Deckensattl Daniel
[08.01.2015]
Binären String zusammensetzen
Bit ist zu setzen
"1" setzen
Subtrahieren für Abbruchbedingung
' "0" setzen
' Nächste Position
' Abbruchbedingung prüfen
' Falls minimale Länge unterschritten, mit "0" auffüllen
DezimalBinaerKonverter = Format$(lngRes, String(NumDigitsMin, "0"))
End If
DecBinExit:
Exit Function
DecBinError:
With Err
.Raise .Number, .Source, .Description, .HelpFile, .HelpContext
End With
Resume DecBinExit
End Function
F r ei e r Sp ei ch e rp lat z er mit t e ln
'/---------------------------------------------------------------------------------------------------------------------'/ Ermittelt freien Platz auf einem angegbenen Laufwerk. ZB.: MsgBox GetNewFreespace("D:\"). Erforder API-Funktionen: ¦
'/
¦
'/ Private Declare Function GetDiskFreeSpaceEx Lib "kernel32" Alias _
¦
'/
"GetDiskFreeSpaceExA" (ByVal lpRootPathName As String, _
¦
'/
lpFreeBytesAvailableToCaller As LARGE_INTEGER, lpTotalNumberOfBytes _
¦
'/
As LARGE_INTEGER, lpTotalNumberOfFreeBytes As LARGE_INTEGER) As Long
¦
'/
¦
'/ Private Type LARGE_INTEGER
¦
'/
lowpart As Long
¦
'/
highpart As Long
¦
'/ End Type
¦
'/---------------------------------------------------------------------------------------------------------------------Private
Dim
Dim
Dim
Dim
Dim
Dim
Dim
Function GetNewFreespace(sLW As String)
lResult As Long
liAvailable As LARGE_INTEGER
liTotal As LARGE_INTEGER
liFree As LARGE_INTEGER
dblAvailable As Double
dblTotal As Double
dblFree As Double
'Determine the Available Space, Total Size And Free Space of a drive
lResult = GetDiskFreeSpaceEx(sLW, liAvailable, liTotal, liFree)
'Convert the return values from LARGE_INTEGER To doubles
dblAvailable = CLargeInt(liAvailable.lowpart, liAvailable.highpart)
dblTotal = CLargeInt(liTotal.lowpart, liTotal.highpart)
dblFree = CLargeInt(liFree.lowpart, liFree.highpart)
'Display the results
Debug.Print "Available Space: " & dblAvailable & " bytes (" & _
Format(dblAvailable / 1024 ^ 3, "0.00") & " G) " & vbCr & _
"Total Space:
" & dblTotal & " bytes (" & _
Format(dblTotal / 1024 ^ 3, "0.00") & " G) " & vbCr & _
"Free Space:
" & dblFree & " bytes (" & _
Format(dblFree / 1024 ^ 3, "0.00") & " G) "
GetNewFreespace = dblFree & " bytes (" & Format(dblFree / 1024 ^ 3, "0.00") & " G)"
End Function
Private Function CLargeInt(Lo As Long, Hi As Long) As Double
'This Function converts the LARGE_INTEGER data type To a double
Dim dblLo As Double, dblHi As Double
If Lo < 0 Then
dblLo = 2 ^ 32 + Lo
Else
dblLo = Lo
End If
If Hi < 0 Then
dblHi = 2 ^ 32 + Hi
Else
dblHi = Hi
End If
CLargeInt = dblLo + dblHi * 2 ^ 32
End Function
M it Ex p lo r e r O rd n e r Ö f f n en
Mit diesen Makro wird ein Explorer am gewünschten Pfad geöffnet
'/---------------------------------------------------------------------------------------------------------------------' Mit Explorer Ordner öffnen
¦
'/----------------------------------------------------------------------------------------------------------------------
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 38 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Public Sub STARTUPOrdneropen()
Dim Pfad As String
Pfad = "C:\Users\" & Environ("USERNAME") & "\AppData\Roaming\Microsoft\Word\STARTUP"
Shell "Explorer.exe " & Pfad, vbNormalFocus
End Sub
Public Sub VORLAGENOrdneropen()
Dim Pfad As String
Pfad = Application.Options.DefaultFilePath(wdUserTemplatesPath)
Shell "Explorer.exe " & Pfad, vbNormalFocus
End Sub
' anpassen
S ch l i es st a ll e o f f e n e n In t e rn et E xp l o r e r
'/---------------------------------------------------------------------------------------------------------------------'/ Schliesst alle offenen Internetexporer
¦
'/---------------------------------------------------------------------------------------------------------------------Sub AlleIntenetexplorerSchliessen()
Dim objWMI As Object, objProcessList As Object, objProcess As Object
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set objProcessList = objWMI.ExecQuery("Select * from Win32_Process " & _
"Where Name = 'iexplore.exe'")
For Each objProcess In objProcessList
Call objProcess.Terminate(0)
Next
Set objProcessList = Nothing
Set objWMI = Nothing
End Sub
URL - V al id ie ru n g
'Für 64 Bit Systeme muss übrigens wie folgt deklariert werden (URLs validieren):
#If VBA7 Then
Private Declare PtrSafe Function InternetCheckConnection Lib "wininet.dll" _
Alias "InternetCheckConnectionA" (ByVal url As String, _
ByVal dwFlags As Long, ByVal dwReserved As Long) As Long
#Else
Private Declare Function InternetCheckConnection Lib "wininet.dll" _
Alias "InternetCheckConnectionA" (ByVal url As String, _
ByVal dwFlags As Long, ByVal dwReserved As Long) As Long
#End If
' URLs validieren
Public Sub UrlTesten()
' liefert 1 = existiert , 0 = nicht erreichbar
Debug.Print InternetCheckConnection("http://deckensattl.goip.de/", 1, 0)
Debug.Print InternetCheckConnection("http://www.google.ch/", 1, 0)
End Sub
F a rb au sw ah l- Di al o g v o n W in d o w s n u t z e n
'/---------------------------------------------------------------------------------------------------------------------'/ Farbauswahl-Dialog von Windows In Word-UserForm anzeigen und auswählen. Folgende API-Deklarationen sind nötig:
¦
'/
¦
'/ Private Declare Function ChooseColor_Dlg Lib "comdlg32.dll" _
¦
'/
Alias "ChooseColorA" (lpcc As CHOOSECOLOR_TYPE) As Long
¦
'/
¦
'/ Private Type CHOOSECOLOR_TYPE
¦
'/
lStructSize As Long
¦
'/
hwndOwner As Long
¦
'/
hInstance As Long
¦
'/
rgbResult As Long
¦
'/
lpCustColors As Long
¦
'/
flags As Long
¦
'/
lCustData As Long
¦
'/
lpfnHook As Long
¦
'/
lpTemplateName As String
¦
'/
End Type
¦
'/
¦
'/ ' Anwender kann alle Farben wählenPrivate Const CC_ANYCOLOR = &H100
¦
'/ ' Nachrichten können "abgefangen" werdenPrivate Const CC_ENABLEHOOK = &H10
¦
'/ ' Dialogbox TemplatePrivate Const CC_ENABLETEMPLATE = &H20
¦
'/ ' Benutzt Template, ignoriert aber den Template-Namen
¦
'/ Private Const CC_ENABLETEMPLATEHANDLE = &H40 ' Vollauswahl aller Farben anzeigen
¦
'/ Private Const CC_FULLOPEN = &H2
¦
'/ ' Deaktiviert den Button zum Öffnen der Dialogbox-Erweiterung
¦
'/ Private Const CC_PREVENTFULLOPEN = &H4 ' Vorgabe einer Standard-Farbe
¦
'/ Private Const CC_RGBINIT = &H1 ' Hilfe-Button anzeigen
¦
'/ Private Const CC_SHOWHELP = &H8 ' nur Grundfarben auswählbar
¦
'/ Private Const CC_SOLIDCOLOR = &H80
¦
'/---------------------------------------------------------------------------------------------------------------------Private Sub CommandButton1_Click()
Dim CC_T As CHOOSECOLOR_TYPE, Retval As Long
Static BDF(16) As Long
' Einige
BDF(0) =
BDF(1) =
BDF(2) =
Farben vordefinieren (Benutzerdefinierte Farben)
RGB(255, 0, 255)
RGB(125, 125, 125)
RGB(90, 90, 90)
' Handle von Word-Form ermitteln
If Val(Application.Version) >= 9 Then
hWndForm = FindWindow("ThunderDFrame", Me.Caption)
Else
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 39 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
hWndForm = FindWindow("ThunderXFrame", Me.Caption)
End If
With CC_T
.lStructSize = Len(CC_T)
' Strukturgröße
'.hInstance = App.hInstance
' Anwendungs-Instanz
.hwndOwner = hWndForm
' Fenster-Handle
' Flags
.flags = CC_RGBINIT Or CC_ANYCOLOR Or CC_FULLOPEN Or CC_PREVENTFULLOPEN
.rgbResult = RGB(0, 255, 0)
' Farbe voreinstellen
.lpCustColors = VarPtr(BDF(0))
' Benutzerdefinierte Farben zuweisen
End With
Retval = ChooseColor_Dlg(CC_T)
' Dialog anzeigen
If Retval <> 0 Then
' gewählte Farbe als Hintergrund setzen
Me.BackColor = CC_T.rgbResult
Else
MsgBox "Das Auswählen einer Farbe ist fehlgeschlagen," & _
"oder Sie haben Abbrechen gedrückt", vbCritical, "Fehler"
End If
End Sub
W o rd r eg i st e r ak t iv i e r en
Private Declare Function AccessibleChildren Lib "oleacc.dll" ( _
ByVal paccContainer As Object, _
ByVal iChildStart As Long, _
ByVal cChildren As Long, _
ByRef rgvarChildren As Variant, _
ByRef pcObtained As Long) As Long
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" ( _
ByRef psa() As Any) As Long
Private
Private
Private
Private
Const
Const
Const
Const
CHILDID_SELF As Long = &H0&
STATE_SYSTEM_UNAVAILABLE As Long = &H1&
STATE_SYSTEM_INVISIBLE As Long = &H8000&
STATE_SYSTEM_SELECTED As Long = &H2&
Private Enum RoleNumber
ROLE_SYSTEM_CLIENT = &HA&
ROLE_SYSTEM_PANE = &H10&
ROLE_SYSTEM_GROUPING = &H14&
ROLE_SYSTEM_TOOLBAR = &H16&
ROLE_SYSTEM_PAGETAB = &H25&
ROLE_SYSTEM_PROPERTYPAGE = &H26&
ROLE_SYSTEM_GRAPHIC = &H28&
ROLE_SYSTEM_STATICTEXT = &H29&
ROLE_SYSTEM_TEXT = &H2A&
ROLE_SYSTEM_BUTTONDROPDOWNGRID = &H3A&
ROLE_SYSTEM_PAGETABLIST = &H3C&
End Enum
Private Enum NavigationDirection
NAVDIR_FIRSTCHILD = &H7&
End Enum
Public Sub SwitchTabMain()
' Registername aktivieren
If Not SwitchTab("Verweise") Then _
Call MsgBox("Kein Tab ''Verweise'' gefunden.", vbCritical, "Fehler")
End Sub
Private Function SwitchTab(ByVal pvstrTabName As String) As Boolean
Dim objRibbonTab As IAccessible
Set objRibbonTab = GetAccessible(CommandBars("Ribbon"), _
ROLE_SYSTEM_PAGETAB, pvstrTabName)
If Not objRibbonTab Is Nothing Then
If ((objRibbonTab.accState(CHILDID_SELF) And (STATE_SYSTEM_UNAVAILABLE _
Or STATE_SYSTEM_INVISIBLE)) = 0) Then
Call objRibbonTab.accDoDefaultAction(CHILDID_SELF)
SwitchTab = True
End If
End If
End Function
Private Function GetAccessible( _
ByRef probjElement As IAccessible, _
ByVal pvenmRoleWanted As RoleNumber, _
ByVal pvstrNameWanted As String, _
Optional ByVal opvblnGetClient As Boolean) As IAccessible
Dim
Dim
Dim
Dim
avntChildrenArray() As Variant
objChild As IAccessible, objReturnElement As IAccessible
ialngChild As Long
strNameComparand As String, strName As String, strValue As String
On Error Resume Next
strValue = probjElement.accValue(CHILDID_SELF)
On Error GoTo 0
strName = probjElement.accName(CHILDID_SELF)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 40 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Select Case strValue
Case "Ribbon", "Quick Access Toolbar", _
"Ribbon Tabs List", "Lower Ribbon", "Status Bar"
strNameComparand = strValue
Case vbNullString, "Ribbon Tab", "Group"
strNameComparand = strName
Case Else
strNameComparand = strName
End Select
If probjElement.accRole(CHILDID_SELF) = pvenmRoleWanted And _
strNameComparand = pvstrNameWanted Then
Set objReturnElement = probjElement
Else
avntChildrenArray = GetChildren(probjElement)
If Cbool(SafeArrayGetDim(avntChildrenArray)) Then
For ialngChild = LBound(avntChildrenArray) To UBound(avntChildrenArray)
If TypeOf avntChildrenArray(ialngChild) Is IAccessible Then
Set objChild = avntChildrenArray(ialngChild)
Set objReturnElement = GetAccessible(objChild, _
pvenmRoleWanted, pvstrNameWanted)
If Not objReturnElement Is Nothing Then Exit For
End If
Next
End If
End If
If opvblnGetClient Then Set objReturnElement = objReturnElement.accNavigate( _
NAVDIR_FIRSTCHILD, CHILDID_SELF)
Set GetAccessible = objReturnElement
Set objReturnElement = Nothing
Set objChild = Nothing
End Function
Private Function GetChildren(ByRef probjElement As IAccessible) As Variant()
Const FIRST_CHILD As Long = 0&
Dim lngChildCount As Long, lngReturn As Long
Dim avntChildrenArray() As Variant
lngChildCount = probjElement.accChildCount
If lngChildCount > 0 Then
ReDim avntChildrenArray(lngChildCount - 1)
Call AccessibleChildren(probjElement, FIRST_CHILD, _
lngChildCount, avntChildrenArray(0), lngReturn)
End If
GetChildren = avntChildrenArray
End Function
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 41 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Po p Up - Ko n t e xt m en i n VB A
Leider unterstützt Winword auf Benutzerdialogformen keine Kontextmenüs, welche den gewohnten
windowskonformen Umgang mit den Kopieren/Ausschneiden/Einfügen-Aktionen bietet. Mit wenigen
API-Funktionen wurde eine eigen Lösung eingebaut mit demselben Effekt, wie ein normales
Kontextmenü. Es ist sogar erlaubt, die Kontextfläche während der Anzeige zu
verschieben, falls sie einem gerade die Sicht nimmt. Alle Editierfelder, welche
mit Werten gefüllt werden können so wie gewohnt kopiert oder
ausgeschnitten werden.
Ich habe die ganze PopUp-Funktionalität in zwei portierbare Module
(frmPopUp und mdlPopUp) gepackt um sie so jederzeit auch in anderen
Projekten einsetzen zu können. Einzig individuelle Menüpunkte müssen mit eigenen Makroprozeduren
verknüpft werden (MenuKontext()-Prozedur!) und natürlich die MouseUp-Verbindungen der
auszustattenden PopUp-Controls müssen mit der global verfügbaren PopUp-Aufruffunktion
KontextMenü() verknüpft werden.
Kurzbeschreib
Durch den fehlenden Menüeditor ist es wie schon angedeutet nicht möglich in einem TextBoxControlelement ein PopUp-Menü anzuzeigen. Aus diesem Grund habe ich eine leere Form genommen,
ihr
die
'/----- Kontextmenü-Ereignisse ------------------------------------------------------------------Titelleiste
'/-----------------------------------------------------------------------------------------------------------'/ Hier wird rechter Mausklick für PopUp-Menu-Anzeige abgefangen
¦
per
API'/-----------------------------------------------------------------------------------------------------------Funktion
Private Sub KontextMenu(QeullControl, Optional lngMenuFontColor As enuColor, Optional lngMenuBackColor As enuColor)
DokuStart.StandardPopUp QeullControl, lngMenuFontColor, lngMenuBackColor
abgeschnit
End Sub
ten
und
Private Sub DTB01_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If Button = 2 Then KontextMenu DTB01, scViolett, scGelb ' Farbwechsel im PopUp als demonstration
soviele
End Sub
neue leere
Label-Controls erzeugt, wie Menüpunkte übergeben worden sind. Im Anschluss daran wird dann über
die ganze Kontextform ein Klicklabel gesetzt, über welches wir die darunterliegenden Menüpunkte
“errechnen“,
wenn
varMenuNamen = Array("Kopieren", "Ausschneiden", "Einfügen", "Alles Markieren", "Rückgängig")
varMenuMakro = Array("Doku_Makro1", "Doku_Makro2", "Doku_Makro3", "Doku_Makro4", "Doku_Makro5")
der Anwender auf
eines der Kontextmenüs klickt. Was passiert '/-------- PopUp Hilfsvariablen ---------------------------------------varMenuNamen
As Variant
' enthält ein Array voller Menunamen
nun wenn im MouseUp-Ereignis des Public
Public varMenuMakro
As Variant
' enthält ein Array voller Makronamen
hWndForm
As Long
' Handle für Titelbeschneidung
gewünschten Controls, auf welchem das Public
Public bCaption
As Boolean
' alter Zustand
Public
intPopXAchse
As
Integer
PopUp erscheinen soll, die rechte Maustaste Public intPopYAchse As Integer '' X-Achsen-Koordinaten
Y-Achsen-Koordinaten
gedrückt wird (Button=2)? In unserem '/-------- PopUp-Konstanten -------------------------------------------Projekt wird die KontextMenu(..)-Hilfsfunktion
Public enuColor
As Long
Public Enum enuColor
' Function StandardPopUp
aufgerufen, die dann die PopUp-AnzeigescSchwarz = &H0&
scWeiss = &HFFFFFF
Prozedur anstösst. Dieser Prozedur wird im
scHellgrau = &HE0E0E0
scDunkelgrau = &HFF8080
einfachsten Fall das Control als Object beim
scBlau = &HFF0000
scDunkelblau = &H800000
ersten Argument angegeben. Mit dem
scHellblau = &HFF8080
scCyan = &HFFFF00
zweiten und dritten optionalen Parameter
scGruen = &HC000&
scDunkelgruen = &H8000&
können wir die Menühintergrundfarbe und
scHellgruen = &HFF00&
scRot = &HFF&
die selektierte Menüschriftfarbe direkt
scDunkelrot = &H80&
scHellrot = &H8080FF
beeinflussen. Fehlen diese Farbangaben
scGelb = &HFFFF&
scDunkelgelb = &H8080&
scViolett = &HC000C0
wird die klassische blaue Farbe als
scDunkelviolett = &H800080
scHellviolett = &HFF00FF
Balkenmarkierung eingesetzt mit gelber
scOrange = &H80FF&
scHellorange = &H80C0FF
Schriftfarbe (beim Überfahren der Maus).
scDunkelorange = &H40C0&
End Enum
Die nächstseitig abgebildete PopUp-AufrufD:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 42 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
Deckensattl Daniel
[08.01.2015]
MS-Office 2010 VBA-Programmierung
Funktion nimmt das Quellcontrol entgegen und bildet gleich zu Beginn der prozedur zwei MakronamenArrays in welchen die Menübezeichner und im anderen Array die auszuführenden Makronamen
abgelegt werden, die mit den einzelnen Menüs verknüpft werden. Anhand dieser Arrayelemente
werden dann in der PopUp-Dialogform die Menüpunkte dynamisch aufgebaut und mit den eigenen, als
Public definierten (eindeutige Namensbezeichner verwenden!) Makroprozeduren verknüpft.
In einem weiteren Schritt werden die Balkenfarben, also die Labelhintergrundfarben und die
Schriftfarbe (bei der Balkenanzeige) angegeben, welche beim Überfahren des Menüpunktes angezeigt
'/---------------------------------------------------------------------------------------------------------'/ Diese in der formTBSEdit-Dialogform instanzierte API-Timerfunktion wird alle 250 ms aufgerufen und kon- ¦
'/ trolliert die aktuellen Maus-Bewegungskoordinaten des RTF-Kontextmenu (formPopUp) um es auszublenden,
¦
'/ wenn der Anwender mit der Maus die Kontextfläche mit der Maus verlässt.
¦
'/---------------------------------------------------------------------------------------------------------Public Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
Dim CP As POINTAPI
Dim intGefunden As Integer
If uMsg = WM_TIMER Then
GetCursorPos CP
intGefunden = -1
If CP.X < (1.3338 * frmPopUp.Left) Or CP.X > ((1.3338 * frmPopUp.Left) + (1.3338 * frmPopUp.Width)) Then intGefunden = 1
If CP.Y < (1.3338 * frmPopUp.Top) Or CP.Y > ((1.3338 * frmPopUp.Top) + (1.3338 * frmPopUp.Height)) Then intGefunden = 1
If intGefunden < 0 Then Exit Sub
KillTimer 0&, frmPopUp.hEvent
Unload frmPopUp
End If
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 25.04.2001
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Ein Standard-Kontextmenü für einzeilige Textfeld-Controls > Kopieren, Ausschneiden, Einfügen, markieren! ¦
'/ In dieser Routine sind keine Anpassungen nötig, die vorgeschaltete KontextMenu()-Funktion liefert die be- ¦
'/ nötigten Parameter selber. Hier wird die PopUp-Dialogform vorbereitet und angezeigt.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub StandardPopUp(InitialObjekt As Object, lngX, lngY, Optional lngSelMenuBackColor As enuColor, _
Optional lngSelMenuFontColor As enuColor, _
Optional lngSelMenuFontBackColor As enuColor, _
Optional lngMenuBackColor As enuColor, _
Optional intMenubreiteInPixel)
Dim CP As POINTAPI
Dim lngFocus
As Long
On Error Resume Next
GetCursorPos CP
'/-------- automatische Breiteneinstellung wenn keine erzwungene Formbreite angegeben wurde -----------------If IsMissing(intMenubreiteInPixel) = True Then
intLenX = -1
For intZ = 0 To UBound(varMenuNamen)
intR = Len(varMenuNamen(intZ))
If intR > intLenX Then intLenX = intR
Next
lngMenuPtBreite = Iif(intLenX < 0, 100, intLenX * 6)
Else
lngMenuPtBreite = Iif(intMenubreiteInPixel > 0, intMenubreiteInPixel, 100)
End If
lngMenuSelColor
lngMenuFntColor
lngMenuFntBkCol
lngMenuBackColo
=
=
=
=
Iif(lngSelMenuBackColor <> 0, lngSelMenuBackColor, &H800000)
Iif(lngSelMenuFontColor <> 0, lngSelMenuFontColor, &HFFFFFF)
Iif(lngSelMenuFontBackColor <> 0, lngSelMenuFontBackColor, &H12&)
Iif(lngMenuBackColor <> 0, lngMenuBackColor, &H8000000A)
Load frmPopUp
Set frmPopUp.frmParentForm = InitialObjekt.Parent
strAktivesControl = InitialObjekt.Name
frmPopUp.Left = (CP.X / 1.44)
frmPopUp.Top = (CP.Y / 1.44) + Iif(CP.Y > 200, -10, -10)
frmPopUp.Show
InitialObjekt.Enabled = False
InitialObjekt.Enabled = True
InitialObjekt.SetFocus
'
'
'
'
Standardfarbe
Standardfarbe
Standardfarbe
Standardfarbe
Blau = &H800000
Weiss = &HFFFFFF
Schwarz = &H12&
Grau = &H8000000A
' Fokus wieder reichen
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Diese öffentlichen Makronamen müssen eindeutig vergeben werden, um Konflikte mit anderen gleichzeitig
¦
'/ genutzten Dokumentvorlagen zu vermeiden (diese arbeiten mit den dynamischen PopUp-Elementen)!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub Doku_Makro1()
SendKeys "^c", False
End Sub
' Auswahl in Zwischenablage kopieren
werden sollen. Auch die Breite des Kontextmenüs kann in Pixel als viertes optionales Argument
angegeben werden, - ohne Angaben wird die Breite automatisch berechnet, anhand des längsten
Menütextes, der im Array gefunden wird! Im Allgemeinteil des VBA-Modules auf welchem die
StandardPopUp- abgelegt wurde müssen auch die nebenan abgebildeten globalen Variablen mitsamt
der Farb-Enumerationskonstante vorhanden sein. Per GetCursorPos()-API-Funktion und der TypenVariabel POINTAPI wird die aktuelle Mausposition ermittelt und diese Angaben der geladenen, aber
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 43 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
noch nicht angezeigten Dialogform übergeben. Die Show-Anweisung bringt dann den schon im
Hintergrund initialisierten Dialog zur Anzeige.
Hier die beiden vollständigen VBA-Module (Formmodul frmPopUp und VBA-Modul mdlPopUp):
[VBA-Modul]: mdlPopUp
'/-----------------------------------------------------------------------------------------------------------'/ Funktion: PopUp-Menü für Winword
Erstellt: 25.04.2001
Ver.: 1.50 ¦
'/ Autor:
[email protected]
Update:
12.05.2003
¦
'/
¦
'/ Zweck:
Mit einem VB-Modul [mdlPopUp] und einer titelleistenlosen Dialogform [frmPopUp] habe ich einen ¦
'/
PopUp-Menü-Ersatz entwickelt, der in jedes beliebige Projekt integriert werden kann!
¦
'/
In einem ersten Schritt werden die genannten beiden Module in das gewünschte VBA-Projekt im¦
'/
portiert. In einem zweiten Schritt müssen dann die mit einem PopUp-Menü auszustatteten Controls ¦
'/
über die jeweiligen MousUp-Ereignisse mit der globalen Funktion [KontextMenu(..)] verbinden,
¦
'/
was wir wie das untenstehende Beispiel mit folgendem Code erreichen:
¦
'/
¦
'/
Private Sub cmbOLc01_MouseUp(ByVal Button As Integer, _
¦
'/
ByVal Shift As Integer, _
¦
'/
ByVal X As Single, _
¦
'/
ByVal Y As Single)
¦
'/
If Button = 2 Then mdlPopUp.KontextMenu cmbOLc01, X, Y, Blau, Gelb, Schwarz, Grau
¦
'/
End Sub
¦
'/
¦
'/
Das 1. Arg. enthält das Controlobjekt, welches mit einem dynamischen PopUpmenü ausgestattet
¦
'/
werden soll. Das 2. und 3. Arg. sind die X und Y - Koordinaten die hier von der MouseUp¦
'/
Funktion geliefert und einfach durchgeschlauft werden.
¦
'/
Die Farbwert-Parameter 4 - 7 enthalten Long-Werte von den einzelnen PopUp-Menü-Hintergrund /
¦
'/
Vordergrund- und Schriftfarben die individuell gesetzt werden können.
¦
'/
Das letzte optionale Argument [intMenubreiteInPixel] ermöglicht eine gezielte Menübreiten¦
'/
Anpassung wenn erwünscht. Im Normalfall wird diese Breite anhand des breitesten Menüeintrages
¦
'/
der Menübezeichner automatisch eingestellt.
¦
'/
¦
'/
Der dritte und letzte Schritt besteht darin eigene Makrofunktionen mit Leben zu füllen, die
¦
'/
dann vom PopUp-Menu aufgerufen werden sollen. In der Function [KontextMenu(..)] müssen dann
¦
'/
die Namen der Makroprozeduren und die PopUp-Menübezeichner in den PopUp-Arrays mit den eigenen ¦
'/
gewünschten Prozeduren korrespondieren.
¦
'/
¦
'/
Unsere frmPopUp-Form ohne Titelleiste (per API entfernt) sieht wie ein Kontextmenü aus. Die
¦
'/
Menüpunkte selber bestehen aus dynamisch erstellten Label-Controls, dessen Hintergrundfarben¦
'/
und die Schriftfarben von Aussen parameterisiert pro PopUp-Aufruf angepasst werden kann.
¦
'/
¦
'/
Um nicht für jedes Menü eine eigene Ereignis-Funktion einbauen zu müssen, habe ich über die
¦
'/
dyn. erstellten Menü-Labels (über die ganze Form) ein transparentes Label [PopUpAuswahl] pla- ¦
'/
ziert, und stelle dann rechnerisch so sicher (im MouseMove-Ereignis werden die Mauskoordinaten ¦
'/
laufend (alle 500 ms) aktualisiert) welche Label vom Anwender ausgewählt wurde.
¦
'/
Andererseits werden die Mauspositionen (Left und Top) auch dazu verwendet, festzustellen, ob
¦
'/
sich die Maus überhaupt noch über der Pseudo-Kontext befindet, wenn nicht, dann wird sie aus¦
'/
geblendet und der API-Timer mit KillTimer(..) wieder deaktiviert.
¦
'/
¦
'/ Hinweis: Vorsicht beim Debuggen innerhalb eines PopUp-Aufrufes, da zu dieser Zeit ein sensibler API¦
'/
Timer (TimerProc(..)) läuft, der ein Abbruch im Debug-Modus mit einer Schutzverletzung dankt.
¦
'/
Innerhalb dieser periodisch aufgerufenen Timerfunktion muss alles fehlerfrei laufen, ansonsten ¦
'/
muss der API-Timer inaktiviert werden und der Ausblendmechanismus erfolgt dann zB. im Doppel¦
'/
klickereignis des transparenten-Klicklaber [PopUpAuswahl].
¦
'/-----------------------------------------------------------------------------------------------------------'/-------- PopUp Hilfsvariablen -----------------------------------------------------------------------------Public varMenuNamen
Public varMenuMakro
Public lngMenuBackColo
As Variant
As Variant
As Long
' enthält ein Array voller Menunamen
' enthält ein Array voller Makronamen
' Kontext-Hintergrundfarbe
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
Public
As
As
As
As
As
As
As
As
As
As
As
'
'
'
'
'
'
'
'
'
'
'
lngMenuPtBreite
lngMenuSelColor
lngMenuFntColor
lngMenuFntBkCol
strAktivesControl
hEvent
hWndForm
bCaption
intPopXAchse
intPopYAchse
varPasteBug
Long
Long
Long
Long
String
Long
Long
Boolean
Integer
Integer
Variant
Menübreite für Std.Menü festlegen
Selektionfarbe für Menuhintergrund
Selektionfarbe für Menuschriftfarbe
Unselektierte Fontfarbe
Name des gerade aktiven Controls
Enthält SetTimer-Prozessnummer für diese Form
Handle für Titelbeschneidung
alter Zustand
X-Achsen-Koordinaten
Y-Achsen-Koordinaten
Sicher Absatzwerte und zurück (Bug)
'/-------- PopUp-Konstanten ---------------------------------------------------------------------------------Public enuColor
Public Enum enuColor
Schwarz = &H12&
Weiss = &HFFFFFF
Hellgrau = &HE0E0E0
Dunkelgrau = &HFF8080
Blau = &HFF0000
Dunkelblau = &H800000
Hellblau = &HFF8080
Cyan = &HFFFF00
Gruen = &HC000&
Grau = &H8000000A
Dunkelgruen = &H8000&
Hellgruen = &HFF00&
Rot = &HFF&
Dunkelrot = &H80&
Hellrot = &H8080FF
Gelb = &HFFFF&
Dunkelgelb = &H8080&
As Long
' Function StandardPopUp
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 44 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Violett = &HC000C0
Dunkelviolett = &H800080
Hellviolett = &HFF00FF
Orange = &H80FF&
Hellorange = &H80C0FF
Dunkelorange = &H40C0&
End Enum
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 25.04.2001
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Unsere PopUp-Funktionalität wurde mit zwei Modulen [mdlPopUp] [frmPopUp] realisiert. Die globale Funktion ¦
'/ [KontextMenu(..)], die nachfolgend aufgeführt ist, ist die eigentliche PopUp-Startroutine, in welcher
¦
'/ die einzelnen individuellen PopUp-Menüelemente bis auf einzelne Formcontrols herab, zentral definiert
¦
'/ sind und auch hier angepasst werden müssen, falls weitere Menüs (mit einem weiteren Makroaufruf) hinzu¦
'/ gefügt werden.
¦
'/
¦
'/ Wichtig ist die eindeutige Namensvergabe bei den PopUp-Makroprozeduren die der Anwender durch Klick aus- ¦
'/ führt (müssen pro Projekt anders lauten) sodass auch mehrere Projekte geladen sein können, ohne sich ge- ¦
'/ genseitig störend zu beeinflussen.
¦
'/
¦
'/ Die Funktionsargumente sind einfach gehalten, zwingend sind nur die ersten drei Parameter. Das 1. Arg.
¦
'/ enthält das Qeullcontrol auf welchem das PopUp-Menü erscheinen soll. Die X und Y - Mauskoordinaten ent¦
'/ nehmen wir der MouseUp-Ereignisprozedur (Weiterreichen) und sind notwendig für die Anzeige des Dialoges! ¦
'/
¦
'/ Die Farb-Argumente 4 - 7 können per Enumerationskonstanten-Vorgaben per Punktoperator ausgewählt, oder
¦
'/ aber individuell mit einem (Hex) beliebigen Farbwert belegt werden. Das letzte Argument ist auch nicht
¦
'/ zwingend erforderlich, da die Menübreite anhand des längsten Menütextes automatisch eingestellt wird.
¦
'/ Dies kann mit Hilfe dieses achten Parameters durch eine Pixelangabe überschrieben werden.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub KontextMenu(InitialObjekt As Object, lngX, lngY, Optional lngSelMenuBackColor As enuColor, _
Optional lngSelMenuFontColor As enuColor, _
Optional lngSelMenuFontBackColor As enuColor, _
Optional lngMenuBackColor As enuColor, _
Optional intMenubreiteInPixel)
Dim myForm As Object
'/---------Standard-Kontextmenu-Einträge inkl. damit verknüpfter Makro definieren ----------------Select Case InitialObjekt.Name
Case "rtfTBSInfos"
' Anhand eines bestimmten Controls anderes Menü zuweisen
varMenuNamen = Array("Kopieren", "Ausschneiden", "Einfügen", "Alles markieren", _
"Text in Word einfügen")
varMenuMakro = Array("W14Autotexte_Makro1", "W14Autotexte_Makro2", "W14Autotexte_Makro3", _
"W14Autotexte_Makro4", "W14Autotexte_Makro5")
Case Else
varMenuNamen = Array("Kopieren", "Ausschneiden", "Einfügen", "Alles markieren")
varMenuMakro = Array("W14Autotexte_Makro1", "W14Autotexte_Makro2", "W14Autotexte_Makro3", _
"W14Autotexte_Makro4")
End Select
StandardPopUp InitialObjekt, lngX, lngY, lngSelMenuBackColor, lngSelMenuFontColor, _
lngSelMenuFontBackColor, lngMenuBackColor, intMenubreiteInPixel
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 25.04.2001
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Sind die beiden Module [mdlPopUp] [frmPopUp] vorhanden und ist die MouseUp-Ereignisroutine eines PopUp¦
'/ Controls mit der PopUp-Aufruffunktion KontextMenu() verbunden, werden die in dieser Aufrufroutine auf¦
'/ geführten Makronamen und Menübezeichner in den jeweiligen Arrays (den eigen Wünschen anpassen) bei einem ¦
'/ Klick auf dieses Kontextmenü verwendet. Die dazugehörigen Makroprozeduren (hier mit OLKontakte_ beginnend)¦
'/ folgen ab hier und werden auch individuell bestimmt. In diesem Projekt sind die klassischen Kopieren,
¦
'/ Ausschneiden, Einfügen und Alles markieren-Funktionalitäten erwünscht.
¦
'/
¦
'/ Diese öffentlichen Makronamen müssen eindeutig vergeben werden, um Konflikte mit anderen gleichzeitig
¦
'/ genutzten Dokumentvorlagen zu vermeiden (welche auch mit diesen dynamischen PopUp-Elementen arbeiten)!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub W14Autotexte_Makro1()
SendKeys "^c", False
End Sub
' Auswahl in Zwischenablage kopieren
Public Sub W14Autotexte_Makro2()
SendKeys "^x", False
End Sub
' In Zwischenablage auschneiden
Public Sub W14Autotexte_Makro3()
SendKeys "^v", False
End Sub
' Aus Zwischenablage einfügen
Public Sub W14Autotexte_Makro4()
SendKeys "^a", False
End Sub
' Alles Markieren
Public Sub W14Autotexte_Makro5()
SendKeys "^c", False
Application.Selection.Paste
End Sub
' Text in Word einfügen
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 25.04.2001
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Ein Standard-Kontextmenü für einzeilige Textfeld-Controls > Kopieren, Ausschneiden, Einfügen, markieren! ¦
'/ In dieser Routine sind keine Anpassungen nötig, die vorgeschaltete KontextMenu()-Funktion liefert die be- ¦
'/ nötigten Parameter selber. Hier wird die PopUp-Dialogform vorbereitet und angezeigt.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub StandardPopUp(InitialObjekt As Object, lngX, lngY, Optional lngSelMenuBackColor As enuColor, _
Optional lngSelMenuFontColor As enuColor, _
Optional lngSelMenuFontBackColor As enuColor, _
Optional lngMenuBackColor As enuColor, _
Optional intMenubreiteInPixel)
On Error Resume Next
Dim CP As POINTAPI
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 45 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Dim lngFocus
As Long
GetCursorPos CP
'/-------- automatische Breiteneinstellung wenn keine erzwungene Formbreite angegeben wurde -----------------If IsMissing(intMenubreiteInPixel) = True Then
intLenX = -1
For intZ = 0 To UBound(varMenuNamen)
intR = Len(varMenuNamen(intZ))
If intR > intLenX Then intLenX = intR
Next
lngMenuPtBreite = Iif(intLenX < 0, 100, intLenX * 5)
Else
lngMenuPtBreite = Iif(intMenubreiteInPixel > 0, intMenubreiteInPixel, 100)
End If
lngMenuSelColor
lngMenuFntColor
lngMenuFntBkCol
lngMenuBackColo
=
=
=
=
Iif(lngSelMenuBackColor <> 0, lngSelMenuBackColor, &H800000)
Iif(lngSelMenuFontColor <> 0, lngSelMenuFontColor, &HFFFFFF)
Iif(lngSelMenuFontBackColor <> 0, lngSelMenuFontBackColor, &H12&)
Iif(lngMenuBackColor <> 0, lngMenuBackColor, &H8000000A)
InitialObjekt.Enabled = False
Load frmPopUp
Set frmPopUp.frmParentForm = InitialObjekt.Parent
strAktivesControl = InitialObjekt.Name
frmPopUp.Left = (CP.X / 1.44) - 10
frmPopUp.Top = (CP.y / 1.44) + ((CP.y / 16) - 10)
InitialObjekt.Enabled = True
frmPopUp.Show
InitialObjekt.Enabled = False
InitialObjekt.Enabled = True
If IsNull(InitialObjekt) = False Then InitialObjekt.SetFocus
'
'
'
'
Blau = &H800000
Weiss = &HFFFFFF
Schwarz = &H12&
Grau = &H8000000A
' Fokus zuweisen
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 12.01.1999
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Eine Wartepause (in Sekunden) um die Einfach/Doppelklick-Unterscheidung ermittelbar zu machen!
¦
'/-----------------------------------------------------------------------------------------------------------Public Function Timing(Zeit!, Optional bolDoEvent As Variant)
Dim intDoEvent As Integer, Start As Variant
intDoEvent = Iif(IsMissing(bolDoEvent) = False, 0, 1)
Start = Timer
Do
If intDoEvent = 0 Then DoEvents
If Timer < Start Then Zeit = Zeit - 86400
Loop Until (Timer - Start > Zeit)
End Function
' Lokale Variablen definieren
' Startzeit speichern
' Mitternachtskorrektur
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 25.04.2001
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Diese in der frmOLKOntakt-Dialogform instanzierte API-Timerfunktion wird alle 250 ms aufgerufen und kon- ¦
'/ trolliert die aktuellen Maus-Bewegungskoordinaten des Kontextmenu (frmPopUp) um es auszublenden,
¦
'/ wenn der Anwender mit der Maus die Kontextfläche mit der Maus verlässt.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As
Dim intG As Integer, lngStartTop As Long, lngStartLeft As Long, lngEndeTop
If uMsg = &H113 Then
GetCursorPos CP
intG = -1
lngStartTop = 1.3338 * frmPopUp.Top
lngStartLeft = 1.3338 * frmPopUp.Left
lngEndeTop = lngStartTop + (1.3338 * frmPopUp.Height)
lngEndeLeft = lngStartLeft + (1.3338 * frmPopUp.Width)
If CP.y < lngStartTop Or CP.y > lngEndeTop Then intG = 1
If CP.X < lngStartLeft Or CP.X > lngEndeLeft Then intG = 1
If intG < 0 Then Exit Sub
VBA_Bibliothek.KillTimer 0&, hEvent
Unload frmPopUp
hEvent = 0
End If
End Sub
Long, ByVal lParam As Long)
As Long, lngEndeLeft As Long, CP As POINTAPI
'
'
'
'
'
'
Ermittle Mauskoordinaten
Resultat in CP.X + CP.Y
Obere Form-Startposition
Linke Form-Startposition
Top-Endposition nach Form
Left-Endposition nach Form
' Arbeitsbereich vergleichen
' innerhalb dann Exit Sub
' Sonst Timer deaktivieren
'/-----------------------------------------------------------------------------------------------------------'/ Autor:
[email protected]
Erstellt: 25.04.2001
Update: 01.04.2002
Ver.: 1.50 ¦
'/
¦
'/ Mit Hilfe dieser Prozedur wird die Titelleiste einer gewünschten Form (Fensterhandler) ausgebendet!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub SetUserFormStyle()
Dim frmStyle As Long
If hWndForm = 0 Then Exit Sub
frmStyle = GetWindowLong(hWndForm, GWL_STYLE)
If bCaption Then
frmStyle = frmStyle Or WS_CAPTION
Else
frmStyle = frmStyle And Not WS_CAPTION
End If
SetWindowLong hWndForm, GWL_STYLE, frmStyle
DrawMenuBar hWndForm
End Sub
[VBA-Formmodul]: frmPopUp
/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 29.04.2003
Update:
12.05.2003 Ver.: 2.00 ¦
'/
¦
'/ Zweck:
PopUp-Menü für Winword
¦
'/
¦
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 46 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
'/ Ablauf:
Um in unserem Editor mit dem gewohnten Kopieren/Ausschneiden/Einfügen-Dialog im Editierfeld
¦
'/
arbeiten zu können, bedarfte es etwas Nachhilfe, da VBA keine PopUp-Menüs von Haus aus unter¦
'/
stützt (kein Menüeditor bei den UserForms!). Unsere formPopUp-Form ohne Titelleiste (per API
¦
'/
entfernt) sieht wie ein Kontextmenü aus. Die Menüpunkte selber bestehen aus dynamisch erstell- ¦
'/
ten Label-Controls, dessen Hintergrundfarben- und die Schriftfarbe von Aussen parameterisiert
¦
'/
pro PopUp-Aufruf angepasst werden kann.
¦
'/
Um nicht für jedes Menü eine eigene Ereignis-Funktion einbauen zu müssen, habe ich über die
¦
'/
dyn. erstellten Menü-Labels (über die ganze Form) ein transparentes Label [PopUpAuswahl] pla- ¦
'/
ziert, und stelle dann rechnerisch so sicher (im MouseMove-Ereignis werden die Mauskoordinaten ¦
'/
laufend (alle 500 ms) aktualisiert) welche Label vom Anwender ausgewählt wurde.
¦
'/
Andererseits werden die Mauspositionen (Left und Top) auch dazu verwendet, festzustellen, ob
¦
'/
sich die Maus überhaupt noch über der Pseudo-Kontext befindet, wenn nicht, dann wird sie aus¦
'/
geblendet und der API-Timer mit KillTimer(..) wieder deaktiviert.
¦
'/
¦
'/ Hinweis: Vorsicht beim Debuggen innerhalb eines PopUp-Aufrufes, da zu dieser Zeit ein sensibler API¦
'/
Timer (TimerProc(..)) läuft, der ein Abbruch im Debug-Modus mit einer Schutzverletzung dankt.
¦
'/
Innerhalb dieser periodisch aufgerufenen Timerfunktion muss alles fehlerfrei laufen, ansonsten ¦
'/
muss der API-Timer inaktiviert werden und der Ausblendmechanismus erfolgt dann zB. im Doppel¦
'/
klickereignis des transparenten-Klicklaber [PopUpAuswahl].
¦
'/-----------------------------------------------------------------------------------------------------------Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Option Explicit
Public strAktivesCtrl
Public frmParentForm
Dim Mycmd
As String
As Object
As control
' Gemeinsam verwendete Temporär-Stringvariabel
' Unter dem PopUp-Dailog vorhandene Dialogform!
' Modulspezifisches Label-Instanzen-Objekt
'/-----------------------------------------------------------------------------------------------------------'/ Bei der Forminitialisierung wird die Fenster-Handlenr. der Form ermittelt und dann die Titelleiste ent¦
'/ fernt. Dann wird die entstandene Leerfläche eliminiert und der API-Timer (Mausbereich) eingerichtet.
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub UserForm_Initialize()
On Error GoTo Abbruch
If Val(Application.Version) >= 9 Then
mdlPopUp.hWndForm = VBA_Bibliothek.FindWindow("ThunderDFrame", Me.Caption)
Else
mdlPopUp.hWndForm = VBA_Bibliothek.FindWindow("ThunderXFrame", Me.Caption)
End If
mdlPopUp.bCaption = False
PopUpAufbau
VBA_Bibliothek.SetUserFormStyle
frmPopUp.Height = frmPopUp.Height - 10
If mdlPopUp.hEvent <> 0 Then
VBA_Bibliothek.KillTimer 0&, mdlPopUp.hEvent
mdlPopUp.hEvent = 0
End If
mdlPopUp.hEvent = VBA_Bibliothek.SetTimer(0&, 0&, 500, AddressOf mdlPopUp.TimerProc)
Exit Sub
Abbruch:
MsgBox Err.Description
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Diese Funktion baut dynamisch ein Kontextmenu auf unserer frmPopUp-Form auf. Die Menüs werden als Array
¦
'/ vor Aufruf des Dialoges zuerst zusammengestellt (varMenuNamen). In einem zweiten Array mit gleich viel
¦
'/ Elementen wie das erste Array (varMenuMakro) folgen die Makronamen, welche mit den Menus verknüpft sind. ¦
'/ Zudem kann die Selektionsfarbe des Kontextmenu-Hintergrund & der Balkenschriftfarbe angegeben werden (Lng)¦
'/ Wichtig sind die eindeutigen Makronamen, welche mit den Labels verknüpft werden, da diese als Public de- ¦
'/ finiert sein müssen (wird per Application.Run gestartet!) und auch funktionieren müssen, wenn z.B. in
¦
'/ einem zweiten offenen Wordprojekt auch dieselbe PopUp-Funktion implementiert ist.
¦
'/-----------------------------------------------------------------------------------------------------------Private Function PopUpAufbau()
Dim strControlName As String, intStartPosTop As Integer
Dim intZ As Integer, TmpLab As Object, intG As Integer
On Error GoTo Abbruch
intG = ((UBound(varMenuNamen) + 1) * 12) + 20
frmPopUp.Width = lngMenuPtBreite
PopUpAuswahl.Caption = ""
frmPopUp.Height = intG
PopUpAuswahl.Height = intG
frmPopUp.BackColor = lngMenuBackColo
intStartPosTop = 1
For intZ = 0 To UBound(varMenuNamen)
strControlName = "labADynMenu" & Format(intZ + 1, "00")
Set Mycmd = frmPopUp.Controls.Add("Forms.Label.1", strControlName, True)
Mycmd.Left = 1
Mycmd.Top = intStartPosTop
Mycmd.Width = Iif(lngMenuPtBreite > 0, lngMenuPtBreite, 100)
Mycmd.Height = 12
Mycmd.Caption = " " & varMenuNamen(intZ)
Mycmd.ForeColor = lngMenuFntBkCol
intStartPosTop = intStartPosTop + 12
Next
frmPopUp.PopUpAuswahl.ZOrder msoBringToFront
Exit Function
Abbruch:
MsgBox Err.Description
End Function
'/-----------------------------------------------------------------------------------------------------------'/ Klickt der Anwender einmal kurz auf die Kontextform, wird die Auswahl (Aktion) im TBS übernommen. Bleibt ¦
'/ der Anwender jedoch mit der linken Maustaste fortwährend auf der Form, kann er diese beliebig auf dem
¦
'/ Desktop verschieben, bis er mit der Maus loslässt. Fährt er dann mit der Maus ausserhalb des per API¦
'/ Timer-Funktion überwachten Kontextmenübereiches, wird die Form (mit Arbeitsvertrag.TimerProc) entladen!
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub PopUpAuswahl_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal y As Single)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 47 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
On Error GoTo Abbruch
If hWndForm = 0 Then Exit Sub
If Button = 1 Then
mdlPopUp.Timing 0.25
If VBA_Bibliothek.TastenStatus(VK_LBUTTON) = True Then
VBA_Bibliothek.ReleaseCapture
VBA_Bibliothek.SendMessage hWndForm, WM_NCLBUTTONDOWN, HTCAPTION, 0
Else
PopUpAuswahl_Click
End If
End If
Exit Sub
Abbruch:
MsgBox Err.Description
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Bei einer getroffenen Kontext-Aktionsauswahl wird diese Klickroutine ausgeführt > Weitergabe & Unload
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub PopUpAuswahl_Click()
Dim intPopWahl As Integer
intPopWahl = Int((mdlPopUp.intPopXAchse) / 12) + 1
frmPopUp.Hide
PopKlick intPopWahl
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ ... eine getroffenen Kontextmenü-Aktionsauswahl führt die gewünschte Aktion am RTF-Text aus!
¦
'/-----------------------------------------------------------------------------------------------------------Private Function PopKlick(KlickNr)
On Error Resume Next
' On Error GoTo Abbruch deaktiviert > wegen SetTimer !!
frmParentForm.SetFocus
frmParentForm.Controls(mdlPopUp.strAktivesControl).SetFocus
Unload frmPopUp
Application.Run MacroName:=varMenuMakro(KlickNr - 1)
Exit Function
Abbruch:
MsgBox Err.Description
End Function
'/-----------------------------------------------------------------------------------------------------------'/ Wird mit der Maus über das Kontextmenü gefahren, werden alle darunterliegenden Labels auf ihre Standard- ¦
'/ Werte (BackColor & ForeColor) zurückgesetzt und nur das farbig untermalen, welches unter der Maus liegt! ¦
'/-----------------------------------------------------------------------------------------------------------Private Sub PopUpAuswahl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal y As Single)
Dim ControlObjekt As Object
Dim intPopWahl
As Integer
On Error GoTo Abbruch
mdlPopUp.intPopXAchse = X
mdlPopUp.intPopXAchse = y
AlleControlsDeaktivieren
intPopWahl = Int((mdlPopUp.intPopXAchse - 1) / 12) + 1
strAktivesCtrl = "labADynMenu" & Format(intPopWahl, "00")
If intPopWahl > (UBound(varMenuNamen) + 1) Or intPopWahl = 0 Then
' Ausserhalb des Klickraums, Kontextmenu wird nun ausgeblendet
frmPopUp.Hide
Else
Set ControlObjekt = frmPopUp.Controls(strAktivesCtrl)
ControlObjekt.BackStyle = 1
' fehlt Farbe wird blaue Hintergrundfarbe gesetzt, Fontfarbe sonst weiss
ControlObjekt.BackColor = Iif(Val(mdlPopUp.lngMenuSelColor) = 0, &H800000, mdlPopUp.lngMenuSelColor)
ControlObjekt.ForeColor = Iif(Val(mdlPopUp.lngMenuFntColor) = 0, &H80000005, mdlPopUp.lngMenuFntColor)
End If
Exit Sub
Abbruch:
' MsgBox Err.Description
Unload Me
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Bei angezeigter PopUp-Form werden beim Überfahren mit der Maus alle Farben zurückgesetzt
¦
'/-----------------------------------------------------------------------------------------------------------Private Function AlleControlsDeaktivieren()
Dim intP As Integer
Dim ControlObjekt As Object
For intP = 0 To UBound(varMenuNamen)
strAktivesCtrl = "labADynMenu" & Format(intP + 1, "00")
Set ControlObjekt = frmPopUp.Controls(strAktivesCtrl)
ControlObjekt.BackStyle = 0
' Transparenter Hintergrund
ControlObjekt.ForeColor = lngMenuFntBkCol
' Schwarze Schriftfarbe
ControlObjekt.BackColor = &H8000000F
' Grauer Hintergrund vorgeben
Next
End Function
'/-----------------------------------------------------------------------------------------------------------'/ Wird das Kontextmenü geschlossen wird per Terminate-Ereignis die API-Timer-Funktion deaktiviert!!!
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub UserForm_Terminate()
If mdlPopUp.hEvent <> 0 Then
VBA_Bibliothek.KillTimer 0&, mdlPopUp.hEvent
mdlPopUp.hEvent = 0
End If
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Wird während der Kontextmenüanzeige die ESC-Taste gedrückt wird Form sofort ausgeblendet.
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 27 Then Unload Me
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 48 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Wird auf die Form ein Doppelklick getätigt, dann wird dieser sogleich ausgeblendet
¦
'/-----------------------------------------------------------------------------------------------------------Private Sub UserForm_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Unload Me
End Sub
'/---------- PopUp-Ende -----------------------------------------------------------------------------------'/---------------------------------------------------------------------------------------------------------------------'/ Funktion: TastenStatus
Erstellt: 1.7.01
Update: 26.10.01
Version: 1.10
¦
'/ Argument: APITastenKonstante
Typ: Long
' vbKey.... - Konstante, wie vbKeyShift, vbKeyControl
¦
'/ Rückgabe: Boolean-Wert
' Wahr wenn Taste gedrückt ist, False wenn nicht!
¦
'/
¦
'/ Über diese Funktion erhalten wir von einer gewünschten Keyboard-Taste dess Zustand (gedückt) wenn wir die
¦
'/ gewünschte Taste als VB-Konstanten-Argument dieser Funktion übergeben (häufig sind vbKeyControl/.KeyMenu)!
¦
'/---------------------------------------------------------------------------------------------------------------------Private Function TastenStatus(API_VB_TastenKonstante As Long) As Boolean
TastenStatus = CBool(GetAsyncKeyState(API_VB_TastenKonstante) And &H8000)
End Function
' ermittelt Tastenstatus
' oder Maustastenstatus!
In h alt sv e rz ei ch n i s an z eig en
Um in einem grösseren Dokument schnell navigieren zu können
eignet sich ein VBA-Dialog bestens, über welcher alle Überschriften
angezeigt werden können um dann per Doppelklick angesprungen
zu werden.
Dieser
Makro ist
in diesem
Dokument
(W14Makroprogrammierung.dotm) enthalten und kann auch
erweitert werden.
Eine Besonderheit ist die Grössenanpassung des Dialoges, welches
man zu Laufzeit an den Dialogform-Ränder vornehmen kann. Sehen
wir uns diesen Wordmakro etwas genauer an.
Im Haupt-VBA-Modul befinden sich zwei API-Funktionen, welche für
die Grössenanpassung (Resize) der Dialogform zuständig sind.
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long,
ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Const HWND_TOPMOST = -1
Weiter gehört zur Grössenanpassung auch die Klasse clsUserForm, die mehrere API-Funktionen
beherbergt um eben diese Vergrösserung zu ermöglichen. In dem Formmodul hat es folgende
Variablen die ebenfalls zur Grössenanpassung gehören:
Private m_objUserForm
Private m_blnFormInit
As clsUserForm
As Boolean
Private Sub UserForm_Activate()
Set m_objUserForm = New clsUserForm
Set m_objUserForm.Form = Me
End Sub
' ermöglicht Dialog-Grössenanpassung
' Grössenanpassungs-Klasse instanzieren
Private Sub UserForm_Terminate()
' Deinitialisierungsroutine beim Ende
If bolSetTimerFunktionDeaktiviren = False Then TimerManagen False
Set m_objUserForm = Nothing
End Sub
Private Sub UserForm_Resize()
'
' Bei Grössenänderungen, Positionen
Code für die Formcontrols – Anpassung der Position und Grösse
End Sub
Hier der ganze Makrocode im Überblick:
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 49 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
[VBA-Modul]: mdlMakros
'/-----------------------------------------------------------------------------------------------------------'/ Autor: daniel Deckensattl
Email: [email protected]
Erstellt: 03.12.2014
Update: 05.12.2014 Ver. 1.00 ¦
'/
¦
'/ Zweck: Dieser Autostart-Makro ermöglicht das Navigieren im aktuellen Worddokument.
¦
'/-----------------------------------------------------------------------------------------------------------Public Declare Function SetTimer Lib "user32.dll" (ByVal hwnd As Long, ByVal nIDEvent As Long, _
ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32.dll" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long,
ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public
Public
Public
Public
Const HWND_TOPMOST = -1
Const WM_TIMER = &H113
lngProgActionEvent As Long
sBookmarkShortName As String
' Timer-Ereignis trifft ein
Public Sub AutoOpen()
' Beim Öffnen des Dokumentes aufgerufen
strDlgVisible = GetSetting("VBAProggen", "AppCFG", "DialogVisible")
If strDlgVisible = "" Or strDlgVisible = "Wahr" Then InhaltAnzeigen
End Sub
Public Sub InhaltAnzeigen()
frmBookmarksViewer.Show 0
End Sub
Sub InhaltsverzeichnisAnzeigen(control As IRibbonControl)
InhaltAnzeigen
End Sub
' Zeigt Makro im Nicht-Modalen Modus an
' Kontextmenü-Aufruf (integrierte XML-Datei)
'/-----------------------------------------------------------------------------------------------------------'/ Lädt der Anwender ein neues Dokument oder eine Vorlage in den Speicher, dann prüft diese API-Timer-Ereig- ¦
'/ nisfunktion alle 1000 ms, ob neue Textmarken hinzugekommen sind, oder gar wegfallen sollen.
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub TimerWordaction(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
Dim intCounter
As Integer
On Error Resume Next
If uMsg = WM_TIMER Then
If Selection.BookmarkID > 0 Then
If ActiveDocument.Bookmarks.Count >= 1 Then
For Each aBookmark In ActiveDocument.Bookmarks
strName = aBookmark.Name
If Selection.Range.BookmarkID = aBookmark.Range.BookmarkID Then
Application.StatusBar = "BookmarkID: " & Selection.Range.BookmarkID & " Name: " & strName
If sBookmarkShortName <> strName Then
sBookmarkShortName = strName
frmBookmarksViewer.getBookmarkInList strName
End If
End If
Next aBookmark
End If
End If
End If
End Sub
'/-----------------------------------------------------------------------------------------------------------'/ Der Timer für die Dokumentenwechselüberwachung kann hier per Funktionsaufruf gestartet oder mit Angaben
¦
'/ eines opt. False-Parameters entladen werden. Dies war nötig um bei Textbaustein-Kopieraktionen keine Pro- ¦
'/ bleme zu bekommen, indem vor einer Aktion der Timer entladen und erst nach ausgeführter Aktion wieder ge- ¦
'/ laden wird!
¦
'/-----------------------------------------------------------------------------------------------------------Public Sub TimerManagen(Optional bolStarten As Boolean = True)
If bolStarten = True Then
If lngProgActionEvent = 0 Then
lngProgActionEvent = SetTimer(0&, 0&, 1000, AddressOf TimerWordaction)
End If
Else
If lngProgActionEvent > 0 Then
KillTimer 0&, lngProgActionEvent
lngProgActionEvent = 0
End If
End If
End Sub
[VBA-Formmodul]: frmBookmarksViewer
'/-----------------------------------------------------------------------------------------------------------'/ Autor: daniel Deckensattl
Email: [email protected]
Erstellt: 03.12.2014
Update: 05.12.2014 Ver. 1.00 ¦
'/
¦
'/ Zweck: Dieses Formmodul enthält alle Dialogelemente die für die Anzeige nötig sind. Kommen neue Über¦
'/
schriften im Dokument hinzu, wird dies beim Dialog angezeigt
¦
'/-----------------------------------------------------------------------------------------------------------Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
'/------------------------------------------------------------------- Schliessen deaktivieren ---------------Private Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String, ByVal _
lpWindowName As String) As Long
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 50 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Private Declare Function GetSystemMenu Lib "user32" (ByVal _
hwnd As Long, ByVal bRevert As Long) As Long
Private Declare Function DeleteMenu Lib "user32" (ByVal _
hMenu As Long, ByVal nPosition As Long, ByVal wFlags _
As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal _
hwnd As Long) As Long
Private Const SC_CLOSE As Long = &HF060
Private hWndForm As Long
Private bCloseBtn As Boolean
' Per API das Icon Schliessen deaktivieren
' da sonst die SeTimer-Funktion nicht sauber
' entfernt wird!
'/-------------------------------------------------------------------------------------------------------------Public varAllBookmarks
Public varAllBookmarksText
As Variant
As Variant
' sammelt
' sammelt
alle Bookmark-Namen
alle Bookmark-Inhalte
Public bolSetTimerFunktionDeaktiviren
As Boolean
' unterbindung der SetTimer-Funktion
Private m_objUserForm
Private m_blnFormInit
As clsUserForm
As Boolean
' ermöglicht Dialog-Grössenanpassung
Private Sub UserForm_Activate()
Set m_objUserForm = New clsUserForm
Set m_objUserForm.Form = Me
End Sub
' Grössenanpassungs-Klasse instanzieren
Private Sub UserForm_Initialize()
bolSetTimerFunktionDeaktiviren = False
' Initialisierungsroutine beim Start
'/---------------- Schliessen deaktivieren --------------If Val(Application.Version) >= 9 Then
hWndForm = FindWindow("ThunderDFrame", Me.Caption)
Else
hWndForm = FindWindow("ThunderXFrame", Me.Caption)
End If
bCloseBtn = False
SetUserFormStyle
'/-------------------------------------------------------strDlgVisible = GetSetting("VBAProggen", "AppCFG", "DialogVisible")
ckbDlgShow.Value = Iif(strDlgVisible = "" Or strDlgVisible = "Wahr", True, False)
setNewBookmark "TempAusgangsOrt"
AlleUeberschriftenSammeln
' Überschriften mit Textmarken austatten
ActiveDocument.Bookmarks("TempAusgangsOrt").Select
ActiveDocument.Bookmarks("TempAusgangsOrt").Delete
Application.StatusBar = "BookmarkID: " & Selection.Range.BookmarkID
If bolSetTimerFunktionDeaktiviren = False Then TimerManagen True
End Sub
Private Sub UserForm_Terminate()
' Deinitialisierungsroutine beim Ende
If bolSetTimerFunktionDeaktiviren = False Then TimerManagen False
Set m_objUserForm = Nothing
End Sub
Private Function AlleUeberschriftenSammeln()
Dim strUeberschriftSammeln
As String
On Error GoTo Abbruch
ActiveDocument.Application.ScreenUpdating = False
lstInhalt.Clear
Redim varAllBookmarks(1000)
Redim varAllBookmarksText(1000)
' Listenfeld komplett löschen
Selection.HomeKey Unit:=wdStory
' Am Dokumentenbeginn starten
Selection.GoTo What:=wdGoToHeading
' Erste Überschrift selektieren
Selection.EndKey Unit:=wdLine, Extend:=wdExtEnd
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtEnd
strUeberschrift = Selection
intZ = 0
While Len(strUeberschrift) > 1
' Nur Absatz dann 1 Zeichen
If lstInhalt.ListCount = 0 Then
Selection.HomeKey Unit:=wdStory
End If
Selection.GoTo What:=wdGoToHeading
' Gehe zur nächsten Überschrift
Selection.EndKey Unit:=wdLine, Extend:=wdExtEnd
' und selektiert bis Absatzende
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtEnd
strUeberschrift = Selection
If Len(Selection) < 2 Then
' Wird nichts mehr gefunden, dann
strUeberschrift = ""
' Schlaufe beenden und zu Textbeginn
Selection.HomeKey Unit:=wdStory
' fahren
Else
' Überschrift gefunden nun Textmarke vergeben und in Listenfeld einfügen
strUeberschriftSammeln = strUeberschrift
strTextmarkenname = getCleanBookmarkName(strUeberschrift) ' Textmarkenname bilden (max. 32 Zeichen)
setNewBookmark strTextmarkenname
lstInhalt.AddItem strUeberschrift
' Textmarke setzten
' in Listenfenster darstellen
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 51 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
varAllBookmarks(intZ) = strTextmarkenname
varAllBookmarksText(intZ) = strUeberschrift
intZ = intZ + 1
Selection.MoveRight Unit:=wdCharacter, Count:=2
End If
Deckensattl Daniel
[08.01.2015]
' Name der Textmarke speichern
' Inhalt der Textmarke (für Sortierung) speichern
' Zwei Zeichen nach rechts fahren
Wend
Redim Preserve varAllBookmarks(intZ - 1)
Redim Preserve varAllBookmarksText(intZ - 1)
Selection.HomeKey Unit:=wdStory
' zum Dokumentenbeginn fahren
ActiveDocument.Application.ScreenUpdating = True
' zum Dokumentenbeginn fahren
Selection.HomeKey Unit:=wdStory
Exit Function
Abbruch:
Application.StatusBar = Err.Description & " : " & strTextmarkenname ' möglichen Fehler in Statusbar anzeigen
End Function
'/-- Störenden Enter am Ende des Strings entfernen
Private Function OhneEnter(Wert)
sRes = Wert
If InStr(1, Wert, vbCr, vbTextCompare) > 0 Then
sRes = Left(sRes, Len(sRes) - 1)
End If
OhneEnter = sRes
End Function
'/-- Erstellt eine neue Textmarke
Private Function setNewBookmark(strBookmarkname)
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:=strBookmarkname
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
End Function
'/-- Die Listenanzeige beenden
Private Sub btnCancel_Click()
Unload frmBookmarksViewer
End Sub
'/-- Dialogstart beim Öffnen des Dokumentes verhindern/zulassen
Private Sub ckbDlgShow_Click()
SaveSetting "VBAProggen", "AppCFG", "DialogVisible", ckbDlgShow.Value
End Sub
'/-- Sortierung auf Wunsch einleiten
Private Sub ckbSort_Click()
If ckbSort.Value = True Then
ArraySortAusgabe varAllBookmarksText, lstInhalt
varAllBookmarks = ArraySortAusgabe(varAllBookmarks)
Else
AlleUeberschriftenSammeln
End If
End Sub
'/-- Wird die Schaltfläche [Gehe zur selektierten Textmarke...] doppelgeklickt, dann zur Textmarke springen
Private Sub btnGoTo_Click()
If TastenStatus(vbKeyShift) = True Then
For Each aBookmark In ActiveDocument.Bookmarks
aBookmark.Delete
Next aBookmark
lstInhalt.Clear
Application.StatusBar = "Alle Textmarken gelöscht"
Else
If lstInhalt.ListIndex = -1 Then Exit Sub
ActiveDocument.Bookmarks(varAllBookmarks(lstInhalt.ListIndex)).Select
Application.StatusBar = "BookmarkID: " & Selection.Range.BookmarkID & " Name: " & getBookmarkName(Selection.Range.BookmarkID)
End If
End Sub
'/-- Wird das Listenfenster doppelgeklickt, dann zur Textmarke springen
Private Sub lstInhalt_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
btnGoTo_Click
End Sub
'/-- löscht alle störenden Sonderzeichen aus Textmarkenname der verwendet werden soll
Private Function getCleanBookmarkName(strNewTitel)
sRes = strNewTitel
If InStr(1, sRes, " ", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, " ")
If InStr(1, sRes, "-", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "-")
If InStr(1, sRes, "_", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "_")
If InStr(1, sRes, ".", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, ".")
If InStr(1, sRes, ":", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, ":")
If InStr(1, sRes, ";", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, ";")
If InStr(1, sRes, "+", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "+")
If InStr(1, sRes, "<", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "<")
If InStr(1, sRes, ">", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, ">")
If InStr(1, sRes, "&", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "&")
If InStr(1, sRes, "*", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "*")
If InStr(1, sRes, "=", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "=")
If InStr(1, sRes, "?", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "?")
If InStr(1, sRes, "%", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "%")
If InStr(1, sRes, ",", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, ",")
If InStr(1, sRes, "/", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "/")
If InStr(1, sRes, "\", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "\")
If InStr(1, sRes, "(", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "(")
If InStr(1, sRes, ")", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, ")")
If InStr(1, sRes, "¦", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "¦")
If InStr(1, sRes, "'", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, "'")
If InStr(1, sRes, """", vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, """")
If InStr(1, sRes, vbCr, vbTextCompare) > 0 Then sRes = delSearchCharacter(sRes, vbCr)
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 52 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
getCleanBookmarkName = sRes
End Function
'/-- löscht gewünschtes Sonderzeichen aus Textmarkenname der verwendet werden soll
Private Function delSearchCharacter(strTitel, strCharacter)
sRes = strTitel
If InStr(1, strTitel, strCharacter, vbTextCompare) > 0 Then
aRes = Split(strTitel, strCharacter, -1, vbTextCompare)
sRes = ""
For intZ = 0 To UBound(aRes)
sRes = sRes & aRes(intZ)
Next
Else
sRes = strTitel
End If
delSearchCharacter = sRes
End Function
'/-- Wird von der SetTimer-Funktion aufgerufen und selektiert Listeneintrag wenn nötig
Public Function getBookmarkInList(strBookmarkShortName)
For intZ = 0 To UBound(varAllBookmarks)
If strBookmarkShortName = varAllBookmarks(intZ) Then
lstInhalt.ListIndex = intZ
Exit For
End If
Next
If ActiveDocument.Bookmarks.Count <> lstInhalt.ListCount Then
TimerManagen False
AlleUeberschriftenSammeln
If ckbSort.Value = True Then ckbSort_Click
TimerManagen True
End If
End Function
'/-- liefert anhand der übergebenen BookmarID den Bookmark-Namen
Private Function getBookmarkName(intBookmarkID As Integer)
Dim aBookmark As Bookmark
sRes = ""
For Each aBookmark In ActiveDocument.Bookmarks
strName = aBookmark.Name
If intBookmarkID = aBookmark.Range.BookmarkID Then
sRes = strName
End If
Next aBookmark
getBookmarkName = sRes
End Function
'/---------------------------------------------------------------------------------------------'/ Autor: Daniel Deckensattl
Erstellt: 31.10.2014
Update: 31.10.2014 ¦
'/
¦
'/ Zweck: Setzt oder liest einen Textmarken-Inhalt. Mit nur einem Parameter wird gelesen,
¦
'/
und mit zwei Parameter in die Textmarke geschrieben
¦
'/
Beispiel Lesen:
TextBox1.Text = Bookmark("Titelinfo1")
¦
'/
Beispiel Schreiben: Bookmark "Titelinfo1", TextBox1.Text
¦
'/---------------------------------------------------------------------------------------------Private Function Bookmark(strBookmarkname As String, Optional strNewValue As String = "XXXNurLesenXXX")
With ActiveDocument.Bookmarks
If strNewValue = "XXXNurLesenXXX" Then
strText = ""
If .Exists(strBookmarkname) = True Then
strText = .Item(strBookmarkname).Range
End If
Bookmark = strText
Else
If .Exists(strBookmarkname) = True Then
Application.DisplayAutoCompleteTips = True
Set MyRange = .Item(strBookmarkname).Range
MyRange.Text = strNewValue
MyRange.Select
.Add Range:=Selection.Range, Name:=strBookmarkname
End If
End If
End With
End Function
Private Sub UserForm_Resize()
If m_objUserForm.gIsIconic = True Then Exit Sub
' Bei Grössenänderungen, Positionen
' und Grösse der Controls anpassen!
Const cMinHght As Single = 100
Const cMinWdth As Single = 258
Const cGap
As Single = 6
Dim sngTxtBoxHght As Single
Dim sngTxtBoxWdth As Single
If Me.Height < cMinHght Then Me.Height = cMinHght
If Me.Width < cMinWdth Then Me.Width = cMinWdth
Me.lstInhalt.Height = Me.InsideHeight - 60
Me.lstInhalt.Width = Me.InsideWidth - 15
Me.btnGoto.Move 8, Me.InsideHeight - (Me.btnGoto.Height + 10)
Me.btnCancel.Move Me.InsideWidth - Me.btnCancel.Width - cGap, Me.InsideHeight - (Me.btnCancel.Height + 10)
Me.ckbDlgShow.Move 10, Me.InsideHeight - (Me.ckbDlgShow.Height + 30)
Me.ckbSort.Move Me.InsideWidth - (Me.ckbSort.Width + 5), Me.InsideHeight - (Me.ckbSort.Height + 30)
End Sub
'/-------------------------------------- Schliessen deaktivieren -----------------------------------------------
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 53 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Private Sub SetUserFormStyle()
Dim frmStyle As Long
Dim hSysMenu As Long
If hWndForm = 0 Then Exit Sub
If bCloseBtn
hSysMenu =
Else
hSysMenu =
DeleteMenu
End If
Then
GetSystemMenu(hWndForm, 1)
GetSystemMenu(hWndForm, 0)
hSysMenu, SC_CLOSE, 0&
DrawMenuBar hWndForm
End Sub
'/--------------------------------------------------------------------------------------------------------------'/ Funktion: TastenStatus
Erstellt: 1.7.01
Update: 26.10.01
Version: 1.20 ¦
'/ Argument: APITastenKonstante
Typ: Long
' vbKey.... - Konstante, wie vbKeyShift, vbKeyControl
¦
'/ Rückgabe: Boolean-Wert
' Wahr wenn Taste gedrückt ist, False wenn nicht!
¦
'/
¦
'/ Dies ist die erste nach Aussen offene Hilfsfunktion, die in allen VBA-Projekten bequem über einen Klassenver-¦
'/ weis und Aufruf abgerufen werden kann. In diesem Beispiel kann der aktuelle Tastenabfragestatus einer als vb-¦
'/ Konstante übergebenen Taste (zb vbKeyShift) ermittelt werden. Es wird ein Wahrheitswert zurückgegeben!
¦
'/--------------------------------------------------------------------------------------------------------------Public Function TastenStatus(APITastenKonstante As Long) As Boolean ' ermittelt Tastenstatus
TastenStatus = CBool(GetAsyncKeyState(APITastenKonstante) And &H8000)
' oder Maustastenstatus!
End Function
'/-----------------------------------------------------------------------------------------------------------'/ Autor: [email protected]
Erstellt: 16.03.03
Update: 19.06.03
Version 1.00
¦
'/
¦
'/ Zweck: Sortiert ein als Argument übergebenes eindim. Datenarray mit ADODB! Wird die maximale Grösse der ¦
'/
zu sortierenden Records nicht angegeben (lohnt sich bei tausenden von Records), ermittelt diese
¦
'/
Sortierroutine selbständig den grössten Wert und verwendet dies dann bei der ADODB-Sortierung!
¦
'/
Mit dieser dynamischen Grössenanpassung können somit auch sehr lange Zeichenketten noch akzep¦
'/
tabel umsortiert werden.
¦
'/
¦
'/ Ausg.: Standardmässig gibt diese Funktion ein sortiertes Array der als Parameter angebenen Arraydaten
¦
'/
zurück. Durch die optionale Angabe eines Listencontrols (ComboBox, ListBox etc) oder sogar eines ¦
'/
Textfeld-Controlelementes (TextBox, RTFText etc.) kann eine ausgeführte Sortierung gleich in das ¦
'/
angegebene Control ausgegeben werden (spart Zeit und zusätzlichen Ausgabecode!).
¦
'/
¦
'/ Arg.1: Ein eindim. zu sortierendes Variant-Array wird als ByVal übergeben (Tastet Urarray nicht an!)
¦
'/
Das Array wird sortiert und als Funktionsrückgabe erhalten wir eine sortierte Kopie der Daten.
¦
'/
¦
'/ Arg.2: Mit Hilfe dieses optionalen Argumentes können wir das sortierte Ergebnis gleich in ein Listen¦
'/
Box-Control einfügen lassen (DropDown, CommandBarComboBox etc.)!
¦
'/
¦
'/ Arg.3: Dieses Argument zeigt nur Wirkung, wenn ein Listencontrol angegeben wurde und kann entweder ein
¦
'/
Integer-Wert sein oder eine Strinzeichenkette. Hier können wir einen Index vorgeben, nachdem
¦
'/
die sortierten Daten im Listencontrol vorhanden sind.
¦
'/
¦
'/ Arg.4: Mit einem True-Wert kann hier anstatt aufsteigend (Standard) absteigend sortiert werden.
¦
'/
¦
'/ Arg.5: Ab einigen tausend Datensätzen bringt die Angabe der längste Stringzeichenkette enorm viel
¦
'/
Geschwindigkeitsvorteile, da die Längen- (automat.) -Berechnung nicht durchgeführt werden muss.
¦
'/-----------------------------------------------------------------------------------------------------------Public Function ArraySortAusgabe(SortArrayObjekt As Variant, Optional
Optional
Optional
Optional
lstObjListe, _
VorgabeIndex As Variant, _
bolAbsteigendSortieren As Boolean = False, _
MaxZeichenlaenge As Variant)
Dim objRecordSet
As Object
' ADODB.Recordset ' Object
Dim SortArray
As Variant
' Sortierarray-Kopie
Dim strTextBox
As String
' Textfeld-Ausgabezeichenkette
Dim lngMaxLen
As Long
' Anzahl der längsten Strings im Array
Dim lngLen
As Long
' Hilfsvariable für Längenscan
'/---------------------------------- ADODB VIRTUELLE SORTIERUNG ---------------------------------------------On Error GoTo SortAbbruch
intLstExist = -1
intTypAusgabe = 0
intIndex = -1
If IsMissing(VorgabeIndex) = False Then
varVorgabe = VorgabeIndex
Else
varVorgabe = ""
End If
' Bei Fehler unsortierte
' Funktionsrückgabe!
' Keine Ausgabe in Liste oder Textfeld
SortArray = SortArrayObjekt
If UBound(SortArray) > 0 Then
' Sortierarray abfüllen
' Grösse der Sortierelemente initial.
lngMaxLen = -1
If IsMissing(MaxZeichenlaenge) = False Then
' Bei X-Tausenden von Datensätzen
lngMaxLen = MaxZeichenlaenge
' kann mit Angaben der höchsten ZeichenElse
' anzahl in einem der Records Speed
For intV = 0 To UBound(SortArray)
' herausgeholt werden, da dann diese
lngLen = Len(SortArray(intV)): If lngLen > lngMaxLen Then lngMaxLen = lngLen
Next
' nicht noch zuerst durchlaufen werden
lngMaxLen = Iif(lngMaxLen = -1, 512, lngMaxLen)
' müssen (für automatischen Betrieb)
End If
Set objRecordSet = Nothing
Set objRecordSet = CreateObject("ADODB.RecordSet")
With objRecordSet
.Fields.Append "rstSort", 200, lngMaxLen
.Open
' adVarChar = 200
For intV = 0 To UBound(SortArray)
.AddNew
objRecordSet!rstSort = SortArray(intV)
'
'
'
'
ADODB-Zugriffsobjekt
wird instanziert und
eine Feld "rstSort"
wird virtuell erzeugt!
' Sortierdaten aufnehmen
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 54 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
.Update
' und in Feld speichern
Next
.Sort = "[rstSort]"
' Nun wird RecordSet sort.
intZ = 0
If IsMissing(lstObjListe) = False Then lstObjListe.Clear: intLstExist = 1
intP = IsMissing(lstObjListe)
If intP = False Then
If lstObjListe.ListCount > 0 Then lstObjListe.Clear
End If
If bolAbsteigendSortieren = False Then
' Anhand des optionalen Sortier-Arg.
' Record-Cursor an den Beginn setzen
.MoveFirst
Else
' Record-Cursor ans Ende setzen
.MoveLast
End If
Do While Not Iif(bolAbsteigendSortieren = False, .EOF, .BOF) ' Je nach Sortierrichtung
' diese in Ergebnis-Array zuweisen
SortArray(intZ) = .Fields("rstSort").Value
If IsMissing(lstObjListe) = False Then
If SortArray(intZ) <> "" Then
' Bei Textboxen Ausgabe mit Enter!
strControlTyp = TypeName(lstObjListe)
Select Case strControlTyp
Case "ComboBox", "ListBox", "CommandBarComboBox", "CommandBarPopUp"
lstObjListe.AddItem SortArray(intZ) ' Sort. Werte in Liste abfüllen
intTypAusgabe = 1
Case "TextBox", "RTFControl", "CommandBarButton"
strTrenner = Iif(intZ = .Counts, "", vbCrLf)
strTextBox = strTextBox & SortArray(intZ) & strTrenner
intTypAusgabe = 2
End Select
If varVorgabe <> "" Then
' das angegebene Listenfeld-Control!
If TypeName(varVorgabe) = "String" Then
If UCase(varVorgabe) = UCase(SortArray(intZ)) Then intIndex = lstObjListe.ListCount - 1
Else
If Val(varVorgabe) = intZ Then intIndex = intZ
End If
End If
End If
End If
intZ = intZ + 1
If bolAbsteigendSortieren = False Then
' Bei auf/absteigender Aufbereitung
.MoveNext
' Nächster Datensatz
Else
.MovePrevious
' Vorheriger Datensatz
End If
Loop
.Close
' RecordSet-Objekt schliessen
If intTypAusgabe = 1 Then
If intLstExist = 1 And intIndex <> -1 And varVorgabe <> "" Then _
lstObjListe.ListIndex = intIndex
Else
If intTypAusgabe = 2 Then lstObjListe = strTextBox ' Standardeigenschaft des Textfeldes
End If
End With
Set objRecordSet = Nothing
' RecordSet-Objekt zerstören
Else
If IsEmpty(SortArray) = False Then
If IsMissing(lstObjListe) = False Then lstObjListe.Clear
If SortArray(0) <> "" And IsMissing(lstObjListe) = False Then lstObjListe.AddItem SortArray(0)
If IsMissing(VorgabeIndex) = False Then
If UCase(SortArray(0)) = UCase(VorgabeIndex) Then lstObjListe.ListIndex = 0
End If
End If
End If
ArraySortAusgabe = SortArray
' und Sortarray zurückgeben!
Exit Function
SortAbbruch:
' Bei Fehler virtuelles ReSet objRecordSet = Nothing
' cordset wieder entfernen!
' Bei Fehler unsortierte Daten!
ArraySortAusgabe = SortArray
Application.StatusBar = "Fehler in ADODB-Sortiertroutine: " & Err.Description
On Error GoTo 0
' Errormeldung ignorieren
End Function
[VBA-Klassenmodul]: clsUserForm
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal _
lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex _
As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex _
As Long, ByVal dwNewLong As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function IsIconic Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function IsZoomed Lib "user32" (ByVal hwnd As Long) As Long
Private Const GWL_STYLE As Long = (-16)
Private Const WS_THICKFRAME As Long = &H40000
Private Const WS_SYSMENU As Long = &H80000
Private Const WS_MINIMIZEBOX As Long = &H20000
Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const SW_SHOW As Long = 5
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 55 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
Private m_objUserForm
Private m_hWndForm
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
As Object
As Long
Private Sub Class_Terminate()
Set m_objUserForm = Nothing
End Sub
Public Property Set Form(ByVal objForm As Object)
Dim nStyle As Long
Set m_objUserForm = objForm
m_hWndForm = FindWindow(vbNullString, m_objUserForm.Caption)
If m_hWndForm <> 0 Then
nStyle = GetWindowLong(m_hWndForm, GWL_STYLE)
nStyle = nStyle Or WS_THICKFRAME Or WS_SYSMENU Or _
WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
SetWindowLong m_hWndForm, GWL_STYLE, nStyle
ShowWindow m_hWndForm, SW_SHOW
DrawMenuBar m_hWndForm
SetFocus m_hWndForm
End If
End Property
Public Property Get gIsIconic() As Boolean
If m_hWndForm <> 0 Then
gIsIconic = CBool(IsIconic(m_hWndForm))
End If
End Property
Public Property Get gIsZoomed() As Boolean
If m_hWndForm <> 0 Then
gIsZoomed = CBool(IsZoomed(m_hWndForm))
End If
End Property
[VBA-Klassenmodul]: ThisDocument
Private Sub Document_New()
strDlgVisible = GetSetting("VBAProggen", "AppCFG", "DialogVisible")
If strDlgVisible = "" Or strDlgVisible = "Wahr" Then mdlMakros.InhaltAnzeigen
End Sub
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 56 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Inhaltsverzeichnis
Inhalt
MS-Office 2010 Programmierung
1
Erste Schritte mit VBA
1
VBA-Editor aktivieren
2
Einstiegsmakros
3
Zoommodus anpassen
3
Suchen / Ersetzen - Makro
4
Makros entschlanken
4
Datumstabelle einfügen lassen
5
Kontextmenu-Einbindung
8
Scannerbild einfügen
8
Wiederverwendbarer Code
9
Sortier-Funktion für VBA
9
Sortierung mit dem Collection-Objekt
11
Ermöglicht Autovervollständigung bei ComboBox
11
Winword Dokumentvariable setzen/lesen
11
Textmarken lesen / schreiben
12
Wörterbuch um Begriffe erweitern
13
Alle Felder aktualisieren
13
Inhaltsverzeichnis aktualisieren mit Tabulatorerhalt
14
Autotext-Einträge anzeigen / hinzufügen
14
Markiert ab Cursorposition bis und mit gesuchtem Wort
14
Hyperlinks im Dokument entfernen
15
Drucke aktuelle Wordseite
15
Drucke aktuelle Markierung eines Worddokumentes
15
Drucken von 2 Seiten pro Blatt
15
Drucken von 4 Seiten pro Blatt
15
Jede Wordseite in ein neues Dokument stellen
16
Schriftenliste erstellen
17
Word-Wortliste in Excel erstellen
17
De-Aktiviert Hyperlink-Aktivierung
18
Genau Runden, auch auf 5 Rappen
18
VB(A)-Code in HTML 4.0 umwandeln
19
Aktualisiert nur Ref-Felder
21
Scanner-Einbindung auch mit Winword 2013
21
Seriendruck in einzelne Dokumente speichern
21
Windows-Funktionen nutzen
23
Tastenstatus abfragen
23
Pausen einbinden
23
Temporärer Pfad ermitteln
23
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 57 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Benutzer-Name
24
Profilverzeichnis von angemeldeten Benutzer
24
Computer-Name
24
Druckernamen ermitteln
24
PC-Umgebungsvariablen ermitteln
24
Windows-Version ermitteln
25
Bildschirmauflösung ermitteln
25
Internet-Explorer mit URL anzeigen
26
Zwischenablage verwenden
26
Schaltjahr ermitteln
26
Monatsletzter
26
Ostern berechnen
27
Einfacher Datumskalender
27
Aus Registry lesen oder in diese schreiben
29
Liefert Dateiname oder Pfad
30
Outlooknachricht versenden
30
Verzeichnis auswählen
30
Dateisuche in Ordner und dessen Unterordner
31
Andere VBA-Applikationen aufrufen
31
Sperrt augenblicklich den Rechner mit Anmeldeschirm
32
Diese Funktion liefert den Inhalt einer externen Datei
32
Hier wird zeilenweise in eine externe Datei geschrieben:
33
Externe Datei starten über Dateiangabe
33
Optionen-Dialog mit WScript-SendKeys steuern
33
Worddateien laden über letzten Vorgabepfad
33
Dateien in Papierkorb löschen
35
Timer-Funktion
36
Mausposition lesen / setzen
37
Binär-Dezimal-Konverter
37
Freier Speicherplatz ermitteln
38
Mit Explorer Ordner Öffnen
38
Schliesst alle offenen InternetExplorer
39
URL-Validierung
39
Farbauswahl-Dialog von Windows nutzen
39
Wordregister aktivieren
40
PopUp-Kontextmen in VBA
42
Inhaltsverzeichnis anzeigen
49
Inhaltsverzeichnis
Updateinformationen
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
57
59
Seite 58 von 59
W14Makroprogrammierung
VBA-Bibliothek und Schulung
MS-Office 2010 VBA-Programmierung
Deckensattl Daniel
[08.01.2015]
Up d at e in f o r mat io n en
Beschreibung der Anpassungen
Updatedatum
Weitere Funktionen dokumentiert
08.01.2015
Kontextmenü eingebaut (XML-Dateiintegration)
05.12.2014
Inhaltverzeichnis-VBA-Manager erstellt
05.12.2014
Inhaltsverzeichnis erstellt
04.12.2014
Diverse Prozeduren eingefügt
04.12.2014
Grunddokumentation erstellt
03.12.2014
D:\Daten\Office\DDDot\VBA-Vorlagen\W14Makroprogrammierung\W14Makroprogrammierung.dotm
Seite 59 von 59