Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Druckerwechsel per VBA

Begonnen von Gerdi, August 02, 2025, 15:59:49

⏪ vorheriges - nächstes ⏩

Gerdi

Hallo zusammen, ich bekomme eine Meldung die ich nicht verstehe, warum diese erscheint??

Ich möchte per VBA auf einen Etikettendrucker zugreifen per

    DoCmd.OpenReport "MeinBericht", acViewNormal, , , acHidden
    Reports!MeinBericht.Printer = Application.Printers("Etikettendrucker")

Der Ausdruck funktioniert, dann kommt aber die Meldung

Der Berichtsname 'MeinBericht', den Sie eingegeben haben, ist entweder falsch geschrieben oder verweist auf einen Bericht, der nicht geöffnet oder nicht vorhanden ist.

Der Bericht beruht auf eine Abfrage auch diese funktioniert. sonst wäre der Ausdruck nicht OK.
Der Berichtsname ist, auch nach 10maliger Prüfung korrekt.

We hat eine Idee wo das Problem ist??



Knobbi38

#1
Hallo Gerdi,

deine Programmierung kann so nicht funktionieren, weil du erst den Bericht druckst und wenn das beendet ist, versuchst du, dem jetzt schon wieder geschlossenen Bericht einen Drucker zuzuweisen.

Im Übrigen mußt du für die Zuweisung eines Objekts, in diesem Fall das Printer-Objekt, an eine Eigenschaft immer SET verwenden!

Hier mal ein kleines Beispiel, wie man so etwas machen könnte:
Option Compare Database
Option Explicit

Sub PrintTest()
 
  Dim objPrinter As Access.Printer
 
  Const PRT_NAME As String = "Etikettendrucker"
  Const RPT_NAME As String = "MeinBericht"
 
  Set objPrinter = Application.Printers(PRT_NAME)
 
  ' Bericht im Hintergrund öffnen
  DoCmd.OpenReport Reportname:=RPT_NAME, _
      View:=acViewReport, WindowMode:=acHidden
   
  If IsReportLoaded(RPT_NAME) Then
    ' Drucker zuweisen
    Set Reports(RPT_NAME).Printer = objPrinter
   
    ' Ausdruck starten
    DoCmd.SelectObject acReport, RPT_NAME
    DoCmd.PrintOut
   
    ' Bericht wieder schließen
    DoCmd.Close acReport, RPT_NAME
  Else
    ' TODO: Fehlermeldung Bericht unerwartet nicht geladen!
  End If
 
  ' Auf Standarddrucker zurücksetzen
  Set Application.Printer = Nothing
 
  ' Bereinigen
  Set objPrinter = Nothing
End Sub

Fehlt nur noch eine kleine Hilfsfunktion in einem Modul, mit der überprüft werden kann, ob ein Bericht geöffnet ist und dieser sich nicht gerade im Entwurfsmodus befindet:
Public Function IsReportLoaded(ByVal Reportname As String) As Boolean

  On Error GoTo IsReportLoaded_End

  If Len(Reportname) = 0 Then Exit Function

  If SysCmd(acSysCmdGetObjectState, acReport, Reportname) <> 0 Then
    If Reports(Reportname).CurrentView <> 0 Then
      IsReportLoaded = True
    End If
  End If

IsReportLoaded_End:
  Exit Function

IsReportLoaded_Err:
  Debug.Print "IsReportLoaded() Error: " _
      & Err.Number & " - " & Err.Description
  Resume IsReportLoaded_End
End Function



Gerdi

Hallo Knobbi38,

ich Danke dir für deine ausführliche Antwort. Ich habe das Prozedere eingegeben und die Const angepasst. Jetzt bekomme ich eine Fehlermeldung bei If IsRepordLoaded..... die Fehlermeldung lautet: Fehler beim Kompilieren Sub oder Funktion nicht definiert!

Ich Starte das Prozedere über einen Button mit Beim Klicken.


Gerdi

Hallo Knobbi38,
Entwarnung scheinbar funktionierte es jetzt!!!

Danke Danke

Gruß Gerdi

Gerdi

Hallo Knobbi38,

jetzt muss ich leider nochmals stören. Ich habe 7 verschiedene Etiketten, ich bekomme wieder die Fehlermeldung bei IsReportLoaded die const sind korrekt (siehe vorletzten Post von mir)!! Fällt dir hierzu etwas ein??

Gruß Gerdi

Knobbi38

#5
Hallo Gerdi,

den Code der Funktion IsReportLoaded() kopierst du komplett aus diesem Forum und packst ihn in ein neues Modul. Da die Funktion selber als Public deklariert ist, sollte sie damit im gesamten Projekt zur Verfügung stehen und erreichbar sein. Ich gehe jetzt mal davon aus, daß du automatisch in allen Klassen und Module die zwei Zeilen
Option Compare Database
Option Explicit
stehen hast.

Du kannst zur Probe die Funktion auch im Direktfenster aufrufen:
? IsReportLoaded("MyReportName")
Die Ausgabe sollte dann False/True ergeben.

Was deine sieben Etiketten betrifft, kannst du die Prozedur "PrintLabels()", am einfachsten mit in das gleiche Modul wie IsReportLoaded() speichern, um einem Parameter erweitern, dem du dann den Reportnamen zum Ausdrucken als Argument mit übergibst. Da der Druckernamen eigentlich in der gesamten Anwendung konstant bleibt, verschiebst du diese Konstante dann in ein Modul für alle deine Einstellung, z.B. modSettings.

Public Sub PrintLabels(ByVal Reportname As String)

  Dim objPrinter As Access.Printer

  ' Const PRT_NAME As String = "Etikettendrucker"
  ' Const RPT_NAME As String = "MeinBericht"

  Set objPrinter = Application.Printers(PRT_NAME)

  ' Bericht im Hintergrund öffnen
  DoCmd.OpenReport Reportname:=Reportname, _
      View:=acViewReport, WindowMode:=acHidden

  If IsReportLoaded(Reportname) Then
    ' Drucker zuweisen
    Set Reports(Reportname).Printer = objPrinter

    ' Ausdruck starten
    DoCmd.SelectObject acReport, Reportname
    DoCmd.PrintOut

    ' Bericht wieder schließen
    DoCmd.Close acReport, Reportname
  Else
    ' TODO: Fehlermeldung Bericht unerwartet nicht geladen!
  End If

  ' Auf Standarddrucker zurücksetzen
  Set Application.Printer = Nothing

  ' Bereinigen
  Set objPrinter = Nothing
End Sub

Gruß Knobbi38

PhilS

Zitat von: Knobbi38 am August 04, 2025, 13:59:59' Auf Standarddrucker zurücksetzen
Set Application.Printer = Nothing
Das kommt mir in dem Codebeispiel etwas seltsam vor.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Knobbi38

#7
@phil:

mit der Zuweisung wird tatsächlich von Access der Application.Printer wieder auf den Standarddrucker zurückgesetzt. So muß man diesen vorher nicht sichern und man braucht auch nicht abzufragen, was gerade als Standarddrucker bei Windows eingestellt ist - mach Access alles automatisch.  :)

Gruß Knobbi38

Gerdi

Hallo Miteinander,

ich bedanke mich bei euch für die Unterstützung. Es ist doch gut das es Menschen gibt die Ahnung von der Materie haben, nur so können Amateure bzw. unfähige wie ich sich weiter entwickeln.
Ich werde meine Problem mit den weiteren Infos hinbekommen.

Nochmals Besten Dank

Gruß Gerdi

PhilS

Zitat von: Knobbi38 am August 04, 2025, 18:46:50mit der Zuweisung wird tatsächlich von Access der Application.Printer wieder auf den Standarddrucker zurückgesetzt.
Mich hat daran so irritiert, dass dein Code den Standarddrucker ja nie ändert. Deshalb erschien mir das Zurücksetzten dann irgendwie fehl am Platze.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Knobbi38

So gesehen hast du natürlich recht.

Die Zeile stammt wohl noch aus der Variante, wo vor dem Öffnen des Reports der spezifische Drucker als Standarddrucker zugewiesen wird und nicht dem Bericht selber. Wenn ich mich recht erinnere, wird beim Zuweisen eines Druckers an einen geöffneten Bericht dieser nämlich nochmal gerendert, was dadurch vermieden werden sollt. In diesem Beispiel kann die Zeile tatsächlich ersatzlos entfallen.

Grüße Knobbi38