AW: Combox Druckerauswal-zellbereich
27.06.2022 23:39:56
Wolfgang
Combox Druckerauswal-zellbereich
Liebe(r) Fragesteller(in)
Ich habe für Dich eine ergonomisch viel schönere Lösung.
Mit einem UserForm und Event-Handlern, das ist Supreme-Programmierung,
da Du Deine Excel und VBA Kenntnisse mit kaum bei Deiner interessanten Frage eingeschätz hast,
solltest Du Dich nicht überfordert fühlen, wenn ich Dir hier eine Hard-Core-Lösung vorstelle,
Zunächst lass mich Dich psychisch aufbauen:
Man kann alles, wenn man nur will!
Was ist ein UserForm, na ja, darüber bist Du gestolpert,
in der Entwicklungs-Umgebung ganz links wird der Application(genannt Projekt)-Baum angezeigt da drin hast Du schon herumgeklickt um VBS-Code einzugeben, vielleicht auf der Microsoft-Root,
Weder da, noch auf den Arbeitsblättern hat Dein Code was zu suchen, der richtiger Ort ist gleich unterhalb den Arbeitsblättern im Ordner "Module" oberhalb dieses Ordner ist der Ordner "Formulare"
mit einem Element "UserForm1", wenn Du darauf links klickst, dann hast Du im Eigenschaften-Fenster ganz oben den Namen dieses UserForm zu ändern und das würde ich tun, gib dem Ding einen Sprechenden Bezeichner,
den wirst Du später in Deinem VBA-Code verwenden, im rechten Fenster, da wo Du früher Deinen Code eingegeben hast, siehst Du ein ganz kleines Windows-Fenster, am rechten Rand hängt ein Fenster mit lauter kleinen Symbolen,
das Zeug nennt sich Controlls (bei Microsoft), das ist aber ein unscharfer Begriff; denn Text- und Editierfelder und ComboBox gehören zu den Elementen, die auch "Widgets" genannt werden.
das Windows-Fenster mit den "Widgets" nennt sich "Masken-Editor", findest in vielen Programmieroberflächen, z.B. Visual-Basic oder -C, oder Borland C++, damit baut man ein Dialog-Fenster,
das geht so, Du klickst aus der Widget-Tafel ein Element an und klickst im Windows-Fensterlein die Position an der die linkeobere Ecke des Widgets sein soll, neu eingefügte Widgets haben einen
weißen Rahmen, daran kannst Du die Größe ändern, klickst Du mitten hinein, so ändert sich der Curso zum Kreuz, nun kannst Du die Position des Widgets ändern,
klickst Du auf eine leere Stelle im Fenster so hat das ganze Fenster einen weißen Rahmen und Du kannst die größe des Fensters ändern, links ist das Eigenschafts-Fenster,
da ist der wichtigsten Eintrag "Caption" das ist die Beschriftung des Widgets und der Titel des Fensters, wenn ich einige Widgets sauber in einer Reihe haben will,
trage ich die unterste Eigenschaft "Top" ein, sehr hilfreich sind die Eigenschaft "Höhe" und "Breite".
Und nun komme ich auf den Hard-Core-Teil der Lösung, befreie Dich von der Vorstellung ein Programm fängt bei einem ersten Statemen (Code-Zeile A) und endet bei einem letzten Statement
(Code-Zeile Z) und es durchläuf alle Programmzeilen dazwischen, dies tut nicht einmal das, womit Du Dir das hier durchliest, alle Windows-Programme sind objekt-orientiert geschrieben, das ist ein Geschenk der Programmiersprache C,
damit der Programmierer einen Überblick in seinem Code hat ist dieser aufgeteilt in Funktionsgruppen, Objekte genannt, so eine Gruppe (Window, Button, und unserer ComboBox),
so ein Objekt ist eine Kapsel in die Du nur 'reinkommst, wenn Du ihren Namen kennst und ihren innere Aufbau,
das kennst Du auch, ein "Workbook" ist in Excel ein Objekt des Excel-Application-Objekt, diese Hierarchie wird uns in der Folge Probleme bereiten,
man kann nur durch die Tür des übergeordneten Objekt in die Kapsel hinein, über den Zaun kann man nicht springen
Ein Objekt besteht per definitionem aus "Eigenschaften" (Properies) und "Methoden", das kennst Du auch, "Sub", "Funktion" sind so eine "methode"
Jetzt zu Windows, das ist in C und objektorientiert geschrieben, damit aber nicht genug, Windows und Office sind interaktiv, das wird realisiert mit einer "message-queue",
und einem "Event-Handler", an den die "message-queue" alle messages, die für das jeweilige Window (dazu zählt auch die "Widgets")
Ein Window, das keine "Event-Handler" hat ist blind und taub.
Du brauchst den Kopf der "Event-Handler" nicht selbst zu schreiben, doppel-klicke im "masken-editor" ins leere Fenster, dann geht ein VBA-Eingabefenster" auf,
in dem Du in einem DropDown links oben den Namen Deines UserForm, das Ereignis auf das Du reagieren willst kannst Du in einem DropDown rechts oben,
default ist Click", das brauchst Du nicht, lösche es. Du befindest Dich in einem Bereich, in dem der Anwender darauf wartet, daß Dein UserForm aufgeht
und "Event-Handler" verlangsamen Dein Programm. Beachte bitte meine Kommentare in den nachfolgenden Codes.
Das mußt Du mit meinem Code nicht machen, es sei denn, Du willst weitere "Widgets"
Verwende meine Codes, wie folgt:
Kopiere sie mit einem Text-Editor,
z.B. Edit oder Textpad in zwei Dateien und speichere diese als text, wie Du die Datei mit den "Even-Handler" nennst ist egal,
Die Datei mit dem Hauptprogramm, solltest Du so nennen, wie Dein Modul heißen soll.
Dann speicher sie mit der "Extention", also Dateityp "bas". Nun gehe in Deine Entwicklungsumgebung und links klicke in Deinem Projektbaum "Module" und
wähle aus dem lokalen Menu "Datei importieren" und wähle Dein Hauptprogramm aus,
falls es nötig ist, ändere in der letzten Zeile die "Show"-Anweisung auf den Namen Deiner UserForm
Nun rechts-klicke im Baum "Formulare" und im lokalen Menu "Einfügen"->"UserForm"
Nenne die Form beliebig, dazu links-klickst Du Deine neue UserForm, dann öffnete sich ein Eigenschaftenfenster da kannst Du ganz oben den Namen eintragen.
Nun rechts-klicke Dein UserForm, im lokalen Menu wähle aus "Code anzeigen", lösche alles weg, was nach VB aussieht, und kopiere stattdessen mein Code hinein.
Wenn Du jetzt links-klickst Dein Modul und in das Sub reinklickst und mit dem Pfeilsymbol in der Symbol-Menu-Line das makro laufen lässt,
müsste Dein UserForm aufgehen, sonst hast Du Fehler drin.
arbeite das UserForm ab. Denk dran, Deinen Drucker einzuschalten.
WSP = Worksheets.Add
WSP.Name = "Drucker"
WSP.Range(1, 1).Val = "Device"
WSP.Range(1, 2).Val = "Driver"
WSP.Range(1, 3).Val = "Port"
'Jetzt müssen wir gaaanz weit herum durch das Microsoft Zeug, um an das aktives Application-Objekt
Set AB = ActiveWorkbook
AP = AB.Application 'Nur so kommen wir an das Application-Objekt
'Nun greifen wir die Druckerliste aus dem System ab
PrntLst = AP.Printers
'Wieviele sind installiert?
PrntCnt = PrntLst.Count
If PrntCnt > 0 Then
i = 2 'Zeilenzahl in WorkSheet Drucker
For Each Prnt In PrntLst
With PrntLst
WSP.Range(i, 1).Value = .DeviceName
WSP.Range(i, 2).Value = .DriverName
WSP.Range(i, 3).Value = .Port
End With
i = i + 1
Next
End If
'Nun können wir das UserForm anzeigen, um dieses Arbeitsblatt auazudrucken
UserForm_Print.Show
End Sub
Dim SlctFrom As Integer
Dim SlctTo As Integer
Dim SlctCpy As Integ
Dim SlctPrntr As String
Dim SlctPrvw As Boolean
Dim MaxRows As Integer
Dim Ereignis As Integer
Dim resText As String
Private Sub ActivateButtonPrint
If Ereignis = 5 Then
CommandButtonPrint.Enabled = True
End If
End Sub
Private Sub CB_Drucker_Change()
SlctPrntr = ListIndex.Text
Ereignis = Ereignis + 1
ActivateButton
End Sub
Private Sub CB_From_Change()
SlctFrom = ListIndex
IF SlctFrom = 21 Then
SlctFrom = MaxRows
End IF
End Sub
Private Sub CB_To_Change()
SlctTo = ListIndex
IF SlctTo = 21 Then
SlctTo = MaxRows
End IF
End Sub
Private Sub CommandButtonPrint_Click()
Dim res As Integer
res = Worksheets("Drucker").PrintOut(SlctFrom, SlctTo, SlctCpy, SlctPrvw, SlctPrntr)
Select Case res
Case -1
resText = "Keine Nachrich"
Case 0
resText = "Kein Fehler aufgetreten"
Case 1
resText = "1"
Case 2
resText = "2"
End Select
End Sub
Private Sub UserForm_Print_Initialize()
Dim ArAnz(5) As Integer
Dim ArPrv(2) As String
Dim ArFrom(21) As Integer
Dim UsrFrm As Object
Dim PrntCnt As Integer
Dim PrntLst As Object
Dim Prnt As Object
Dim AP As Object
Dim AB As Workbook
Dim i As Integer
Dim WSP As Worksheet
Dim UsrFrm As Object
Dim CBPrntr As Object
Set UsrFrm = UserForm_Print
ArAnz = Array(1, 2, 3, 4, 5)
ArPrv = Array("Ja", "Nein")
ArFrom = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1048576)
'Füllen CB_Printer
'aus System
UsrFrm = UserForm_Print
CBPrntr = UsrFrm.CB_Drucker
'Jetzt müssen wir gaaanz weit herum durch das Microsoft Zeug, um an das aktives Application-Objekt
Set AB = ActiveWorkbook
AP = AB.Application 'Nur so kommen wir an das Application-Objekt
'Nun greifen wir die Druckerliste aus dem System ab
PrntLst = AP.Printers
'Wieviele sind installiert?
PrntCnt = PrntLst.Count
If PrntCnt > 0 The
For Each Prnt In PrntLst
With PrntLst
CB_Drucker.AddItem .DeviceName
End With
Next
End If
'Setze die ComboBox auf Listenanfang
CB_Drucker.ListIndex = 0
With UsrFrm
.CB_Anz.List = ArAnz
.CB_Preview.List = ArPrv
.CB_From.List = ArFrom
.CB_To = ArFrom
End With
MaxRows = 1048576
Ereignis = 0
CommandButtonPrint.Enabled = False
End Sub
Ich deaktiviere den "Drucken"-Knopf in der Initialisierung und prüfe nach jeder "Widget"-Änderung
in der Sub "ActivateButtonPrint" ob die UserForm vollständig ausgefüllt ist, dann aktiviere ich den Button
Nette Grüße
(UserForm-)Wolfgang