Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Probleme mit Public Declare PtrSafe

Forumthread: Probleme mit Public Declare PtrSafe

Probleme mit Public Declare PtrSafe
10.07.2022 13:20:48
Micha
Hallo zusammen,
ich versuche schon seit einigen Tagen, ein Excel-Makro zu erstellen, das "Public Declare PtrSafe ..." nutzt. Aber aus irgendeinem Grund kommt immer einen bzw. mehrere Fehlermeldungen, wenn ich die Datei speichern möchte, wenn ich z.B. nutze (Win 10, Office 2019, 64bit):
(...)
Public Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
(...)
Die Fehlermeldungen lauten:
"Excel konnte 'Mappe1.xlsm' nicht speichern, da die Datei von einem anderen Benutzer zum Bearbeiten gesperrt ist. Versuchen Sie die Speicherung unter einem anderen Dateinamen." (Ich bin der einzige Benutzer und das Speichern unter anderen Namen funktioniert auch nicht.)
Dann kommt:
"Excel kann auf die Daten in '9FED...' nicht zugreifen. Die Datei ist inter Umständen schreibgeschützt oder verschlüsselt." (Eigentlich weder noch... zumindest nicht von mir ...)
Dann:
"Auf '9FED...' konnte nicht zugegriffen werden. Unter Umständen ist die Datei beschädigt, befindet sich auf einem Server, der nicht mehr reagiert, oder die ist schreibgeschützt." (Nein, eigentlichs nichts davon... zumindest nicht von mir ...)
Dann:
"Datei wurde unter dem Namen '9FED...' gespeichert. Kann nicht in 'Mappe1.xlsm" umbenannt werden. Sie müssen diese Datei schließen."
Diese Meldeungen kommen direkt nacheinander. Wenn ich die Datei versuche wieder zu öffnen, kommen die Meldung, dass die Datei defekt sei...
Das komische für mich ist, dass "Public Declare PtrSafe Function ShellExecute..." in Outlook bei mir problemlos läuft. Word und Excel geht nicht...
Hat jemand einen Tip für mich, was da bei mir falsch läuft und wie ich das beheben kann?
Vielen Dank bereits vorab und noch einen schönen Sonntag!!
Anzeige

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Probleme mit Public Declare PtrSafe
10.07.2022 13:51:58
ralf_b
Zeig mal den bösen Code. Da er sich unserer Kenntnis entzieht ,kann man dir schlecht sagen warum du die offene/aktive Datei nicht so manipulieren kannst, wie es der Code möchte.
Die Api-Funktionsdeklaration, kann nicht die Ursache sein. Eher das was du damit machst.
AW: Probleme mit Public Declare PtrSafe
10.07.2022 14:17:07
Micha
Das hier ist der Code, den ich umgebaut habe:
Option Explicit
#If VBA7 And Win64 Then
Public Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As LongPtr, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As LongPtr
Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr
Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As LongPtr, _
ByVal hWnd2 As LongPtr, _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr
Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
lParam As Any) As LongPtr
Public Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As Long
#Else
Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Public Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
#End If
Public Const SW_HIDE As Long = 0
Public Const SW_SHOWNORMAL As Long = 1
Public Const SW_SHOWMAXIMIZED As Long = 3
Public Const SW_SHOWMINIMIZED As Long = 2
Public Const WM_SETTEXT = &HC
Public Const VK_RETURN = &HD
Public Const WM_KEYDOWN = &H100

Public Sub OpenLockedPdf()
#If VBA7 And Win64 Then
Dim parentWindow            As LongPtr
Dim firstChildWindow        As LongPtr
#Else
Dim parentWindow            As Long
Dim firstChildWindow        As Long
#End If
Dim timeCount                   As Date
timeCount = Now()
Do Until Now() > timeCount + TimeValue("00:00:05")
parentWindow = 0
DoEvents
parentWindow = FindWindow("#32770", "PDF-Datei speichern unter")
If parentWindow  0 Then Exit Do
Loop
If parentWindow  0 Then
'Child Window
timeCount = Now()
Do Until Now() > timeCount + TimeValue("00:00:05")
firstChildWindow = 0
DoEvents
firstChildWindow = FindWindowEx(parentWindow, ByVal 0&, "DUIViewWndClassName", vbNullString)
If firstChildWindow  0 Then Exit Do
Loop
If fifthChildfourthWindow  0 Then
'OK button (default)
PostMessage firstChildWindow, WM_KEYDOWN, VK_RETURN, 0
End If
End If
End Sub

Das Gleiche passiert aber z.B. auch, wenn ich den nachstehenden Code für einen Timer nutzen möchte:
Attribute VB_Name = "Timer"
#If VBA7 Then
Private Declare PtrSafe Function SetTimer Lib "user32" ( _
ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, _
ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
Private Declare PtrSafe Function KillTimer Lib "user32" ( _
ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
Private lngStart As LongPtr
#Else
Private Declare Function SetTimer Lib "user32" ( _
ByVal hWnd As Long, ByVal nIDEvent As Long, _
ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" ( _
ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
Private lngStart As Long
#End If

Public Sub TimerAn() '(ByVal strName As String)    '(ByVal msInterval As Long)
Dim msInterval As Long
Dim Sekunden As Long
Sekunden = 1
msInterval = Sekunden * 1000
Debug.Print "Start1: " & Time
lngStart = 0
SetTimer 0, 0, msInterval, AddressOf Uhr10s
End Sub

Public Sub Uhr10s(ByVal hWnd As LongPtr, ByVal uMsg As LongPtr, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr)
Dim StartZeit As String
StartZeit = Format(Now, "hh:mm:ss;@")
Dim LaufzeitSekunden As Long
Dim Laufzeit As Long
LaufzeitSekunden = 1
Laufzeit = LaufzeitSekunden * 1000
Select Case lngStart
Case 0                      '''Startzeitpunkt merken
lngStart = lParam
Debug.Print "Start2: " & Time
Case Is 

Anzeige
AW: Probleme mit Public Declare PtrSafe
10.07.2022 14:20:06
Micha
Vielen Dank für die Hilfe!!
AW: Probleme mit Public Declare PtrSafe
11.07.2022 12:24:37
Herbert_Grom
Hallo Micha,
muss diese Zeile

#If VBA7 And Win64 Then
nicht eigentlich so lauten:

#If VBA7 Or Win64 Then
Servus
AW: Probleme mit Public Declare PtrSafe
11.07.2022 15:51:46
Micha
Ich habe sowohl "and" als auch "or" probiert - oder auch "And Win64" einfach wegzulassen - bringt leider keinen Besserung...
Public / Private macht auch keinen Unterschied ...
Was mich vor allem wundert: Wenn ich das Makro in Outlook einfüge, kommt keinen Fehlermeldung und es funktioniert einwandfrei. In Excel läuft das Makro auch, wenn ich es einfüge - nur beim Speichern der Datei ist halt schluss ...
Anzeige
AW: Probleme mit Public Declare PtrSafe
11.07.2022 16:41:13
volti
Hallo Micha,
beim einfachen Drüberschauen ist mir jetzt nichts aufgefallen.
Ohne das "Phänomen" direkt bei sich vor Ort zu sehen kann Dir da wahrscheinlich niemand helfen.
Gruß
#KH
AW: Probleme mit Public Declare PtrSafe
11.07.2022 16:26:26
volti
Hallo Herbert,
meine Meinung dazu:
Die Variante "#If VBA7 And Win64 Then" ist m.E. doppelt "gemoppelt", da unter 64 Bit wohl auch nur das neue Excel mit VBA7 laufen kann.
Da würde dann auch "#If Win64 Then" reichen.
Die Variante ist aber auch nicht schädlich.
Ich würde aber auch die Or-Variante einsetzen, muss man aber nicht.
Die Variante "#If VBA7 And Win64 Then" deckt im Else-Teil das alte VBA6 (ohne PtrSafe) ab und auch VBA7 32-Bit (ohne PtrSafe) ab.
Das funktioniert.
Bei Excel 64-Bit werden die API-Funktionen mit "VBA7 And Win64"-Teil mit PtrSafe abgedeckt.
Die Variante "#If VBA7 Or Win64 Then" deckt im Else-Teil nur das alte VBA6 (ohne PtrSafe) ab.
Im "VBA7 Or Win64"-Teil werden dagegen alle Funktionen über VBA7 (32- und 64-Bit Excel) bearbeitet, auch die reinen 64-Bit-API-Funktionen.
Es gibt nur wenige reine 64-Bit-API-Funktionen, die z.B. mit Variablen-Typ LongLong arbeiten und deshalb über den Compiler-Schalter "IF Win64" deklariert werden müssen.
Setzt man nur "#IF VBA7 Then" kann es bei den reinen 64-Bit-API-Funktionen unter Excel 32-Bit zum Fehler oder falschen Ergebnissen kommen, da sie nicht unterstützt werden oder zwar laufen aber z.B. Handle abschneiden usw..
Gruß
Karl-Heinz
Anzeige
AW: Probleme mit Public Declare PtrSafe
12.07.2022 10:29:41
Herbert_Grom
Hallo Karl-Heinz,
danke für deine Infos.
Servus
;

Forumthreads zu verwandten Themen

Anzeige
Entdecke relevante Threads

Schau dir verwandte Threads basierend auf dem aktuellen Thema an

Alle relevanten Threads mit Inhaltsvorschau entdecken
Anzeige

Infobox / Tutorial

Probleme mit Public Declare PtrSafe in Excel VBA


Schritt-für-Schritt-Anleitung

Um das Public Declare PtrSafe korrekt in Excel VBA zu verwenden, folge diesen Schritten:

  1. Öffne den VBA-Editor:

    • Drücke ALT + F11, um den VBA-Editor zu öffnen.
  2. Erstelle ein neues Modul:

    • Rechtsklicke im Projektfenster auf VBAProject (DeineDatei.xlsm) und wähle Einfügen > Modul.
  3. Füge den Code ein:

    • Nutze die folgende Struktur, um sicherzustellen, dass dein Code sowohl für 32-Bit- als auch für 64-Bit-Versionen von Excel funktioniert:
    #If VBA7 And Win64 Then
       Public Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
    #Else
       Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    #End If
  4. Verwende das PtrSafe Attribut:

    • Achte darauf, dass alle Declare-Anweisungen das PtrSafe Attribut enthalten, wenn Du in einer 64-Bit-Umgebung arbeitest.
  5. Teste den Code:

    • Führe den Code aus, um sicherzustellen, dass er wie gewünscht funktioniert.

Häufige Fehler und Lösungen

Hier sind einige häufige Fehler, die beim Arbeiten mit dem Public Declare PtrSafe auftreten können, und deren Lösungen:

  • Fehlermeldung: "Excel konnte 'Mappe1.xlsm' nicht speichern"

    • Lösung: Stelle sicher, dass kein anderer Prozess die Datei sperrt. Überprüfe auch, ob die Datei schreibgeschützt oder verschlüsselt ist.
  • Fehler beim Zugriff auf Funktionen:

    • Lösung: Achte darauf, dass alle verwendeten Funktionen die richtige Deklaration haben, insbesondere bei den Datentypen wie LongPtr für 64-Bit.
  • "Datei ist beschädigt" beim Öffnen:

    • Lösung: Überprüfe den Code auf Syntaxfehler und stelle sicher, dass alle API-Aufrufe korrekt sind.

Alternative Methoden

Falls das Arbeiten mit Public Declare PtrSafe problematisch ist, kannst Du alternative Ansätze in Betracht ziehen:

  • Verwendung von Shell anstelle von ShellExecute:

    Shell "notepad.exe", vbNormalFocus
  • Verwende VBA-Funktionen, die keine API-Deklarationen erfordern:

    • Wenn möglich, nutze native VBA-Funktionen, um die Funktionalität zu erreichen, die Du benötigst.

Praktische Beispiele

Hier sind einige praktische Beispiele zur Verwendung von Public Declare PtrSafe in Excel VBA:

  1. Öffnen einer PDF-Datei mit ShellExecute:

    Public Sub OpenPDF()
       ShellExecute 0, "open", "C:\Pfad\zu\deiner\Datei.pdf", vbNullString, vbNullString, 1
    End Sub
  2. Timer verwenden:

    #If VBA7 Then
       Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
    #Else
       Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    #End If

Tipps für Profis

  • Verwende LongPtr für Zeiger: In 64-Bit-Umgebungen ist es wichtig, LongPtr anstelle von Long zu verwenden, um sicherzustellen, dass der Code korrekt funktioniert.

  • Prüfe die Version von Excel: Nutze #If VBA7 Then um sicherzustellen, dass dein Code sowohl in 32-Bit als auch in 64-Bit funktioniert.

  • Debugging: Nutze Debug.Print zur Anzeige von Werten während der Ausführung, um Fehler schneller zu identifizieren.


FAQ: Häufige Fragen

1. Was ist der Unterschied zwischen Public Declare und Private Declare?
Public Declare macht die Funktion für alle Module verfügbar, während Private Declare die Funktion nur im aktuellen Modul verfügbar macht.

2. Warum funktioniert Public Declare PtrSafe in Outlook, aber nicht in Excel?
Die Umgebung und spezifische API-Zugriffe können in Outlook und Excel unterschiedlich behandelt werden. Überprüfe die verwendeten Funktionen und deren Kompatibilität mit Excel.

3. Muss ich PtrSafe immer verwenden?
Ja, wenn Du in einer 64-Bit-Umgebung arbeitest, ist das PtrSafe Attribut erforderlich, um die Kompatibilität sicherzustellen.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige