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

Forumthread: VBA-Code anpassen für 64-bit

VBA-Code anpassen für 64-bit
10.07.2023 10:53:49
Kisska

Hallo zusammen,

ich möchte einen älteren Code verwenden, der mal in diesem Beitrag gepostet wurde:
https://www.herber.de/forum/cgi-bin/callthread.pl?index=1686150#1686256

Es erscheint ein Fehler bei diesem Teil des Codes:


Option Explicit

Private Declare Function FindExecutableA Lib "shell32.dll" ( _
    ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByVal lpResult As String) As Long
Private Declare Function LockWindowUpdate Lib "user32.dll" ( _
    ByVal hwndLock As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long


Fehlermeldung:
"Fehler beim Kompilieren:
Der Code in diesem Projekt muss für die Verwendung auf 64-Bit-Systemen aktualisiert werden. Überarbeiten und aktualisieren Sie Declare-Anweisungen, und markieren Sie sie mit dem PtrSafe-Attribut."

Ich habe den o.a. Code dann wie folgt ergänzt:

#If VBA7 Then 
Private Declare PtrSafe Function FindExecutableA Lib "shell32.dll" ( _
    ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByVal lpResult As String) As Long
Private Declare PtrSafe Function LockWindowUpdate Lib "user32.dll" ( _
    ByVal hwndLock As Long) As Long
Private Declare PtrSafe Function GetDesktopWindow Lib "user32.dll" () As Long
#Else 
Private Declare Function FindExecutableA Lib "shell32.dll" ( _
    ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByVal lpResult As String) As Long
Private Declare Function LockWindowUpdate Lib "user32.dll" ( _
    ByVal hwndLock As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
#End If 


Aber dann kommt wieder eine Fehlermeldung, dass das Objekt nicht eingefügt werden kann.
Debuggen führt mich zu diesem Teil des Codes:
Set objOLEObject = ActiveSheet.OLEObjects.Add(Filename:=strPath, _
                    Link:=False, DisplayAsIcon:=True, IconIndex:=lngIconIndex, _
                    IconFileName:=strExecutable, IconLabel:=strDisplayName)


Mein Gesamtcode:

Option Explicit

#If VBA7 Then
Private Declare PtrSafe Function FindExecutableA Lib "shell32.dll" ( _
    ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByVal lpResult As String) As Long
Private Declare PtrSafe Function LockWindowUpdate Lib "user32.dll" ( _
    ByVal hwndLock As Long) As Long
Private Declare PtrSafe Function GetDesktopWindow Lib "user32.dll" () As Long
#Else
Private Declare Function FindExecutableA Lib "shell32.dll" ( _
    ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByVal lpResult As String) As Long
Private Declare Function LockWindowUpdate Lib "user32.dll" ( _
    ByVal hwndLock As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
#End If

Private Const MAX_PATH As Long = 260&

Public Sub InsertFileObject()
    
    Dim objOLEObject As OLEObject
    Dim lngReturn As Long, lngIconIndex As Long
    Dim strPath As String, strFilename As String, strDisplayName As String
    Dim strTemp As String * MAX_PATH
    Dim strExtension As String, strExecutable As String
    
    With Application.FileDialog(msoFileDialogFilePicker)
        
        .Filters.Clear
        .Title = "Add General Document"
        .AllowMultiSelect = False
        
        If .Show Then
            
            strPath = .SelectedItems(1)
            strExtension = Mid$(strPath, InStrRev(strPath, ".") + 1)
            strFilename = Mid$(strPath, InStrRev(strPath, "\") + 1)
            strFilename = Left$(strFilename, InStrRev(strFilename, ".") - 1)
            
            lngReturn = FindExecutableA(strPath, vbNullString, strTemp)
            
            If lngReturn > 32 Then
                strExecutable = Left$(strTemp, InStr(strTemp & vbNullChar, vbNullChar) - 1)
            Else
                Call MsgBox("Kein Programm zum Öffnen gefunden.", vbCritical, "Programmabbruch")
                Exit Sub
            End If
            
            strDisplayName = InputBox("Bitte Anzeigetext eingeben.", "Einagbe", strFilename)
            If StrPtr(strDisplayName) > 0 Then
                
                If LCase$(strExtension) = "pdf" Then
                    lngIconIndex = 1
                Else
                    lngIconIndex = 0
                End If
                
                Call LockWindowUpdate(GetDesktopWindow)
                
                Set objOLEObject = ActiveSheet.OLEObjects.Add(Filename:=strPath, _
                    Link:=False, DisplayAsIcon:=True, IconIndex:=lngIconIndex, _
                    IconFileName:=strExecutable, IconLabel:=strDisplayName)
                objOLEObject.ShapeRange.AlternativeText = strFilename
                
                Call LockWindowUpdate(0&)
                
                Set objOLEObject = Nothing
                
            End If
        End If
    End With
End Sub


Kann jemand helfen, den Code wieder ans Laufen zu bringen?

VG, Kisska


Anzeige

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA-Code anpassen für 64-bit
10.07.2023 11:26:11
Nepumuk
Hallo Kisska,

nur PtrSafe einfügen genügt nicht. Du musst auch die Parameter und deine Variablen anpassen. Teste mal:

Option Explicit

#If Win64 Then
    Private Declare PtrSafe Function FindExecutableA Lib "shell32.dll" ( _
        ByVal lpFile As String, _
        ByVal lpDirectory As String, _
        ByVal lpResult As String) As LongPtr
    Private Declare PtrSafe Function LockWindowUpdate Lib "user32.dll" ( _
        ByVal hwndLock As LongPtr) As Long
    Private Declare PtrSafe Function GetDesktopWindow Lib "user32.dll" () As LongPtr
#Else
    Private Declare Function FindExecutableA Lib "shell32.dll" ( _
        ByVal lpFile As String, _
        ByVal lpDirectory As String, _
        ByVal lpResult As String) As Long
    Private Declare Function LockWindowUpdate Lib "user32.dll" ( _
        ByVal hwndLock As Long) As Long
    Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
#End If

Private Const MAX_PATH As Long = 260&

Public Sub InsertFileObject()

    #If Win64 Then
        Dim lngReturn As LongPtr
    #Else
        Dim lngReturn As Long
    #End If

    Dim objOLEObject As OLEObject
    Dim lngIconIndex As Long
    Dim strPath As String, strFilename As String, strDisplayName As String
    Dim strTemp As String * MAX_PATH
    Dim strExtension As String, strExecutable As String

    With Application.FileDialog(msoFileDialogFilePicker)

        .Filters.Clear
        .Title = "Add General Document"
        .AllowMultiSelect = False

        If .Show Then

            strPath = .SelectedItems(1)
            strExtension = Mid$(strPath, InStrRev(strPath, ".") + 1)
            strFilename = Mid$(strPath, InStrRev(strPath, "\") + 1)
            strFilename = Left$(strFilename, InStrRev(strFilename, ".") - 1)

            lngReturn = FindExecutableA(strPath, vbNullString, strTemp)

            If lngReturn > 32 Then
                strExecutable = Left$(strTemp, InStr(strTemp & vbNullChar, vbNullChar) - 1)
            Else
                Call MsgBox("Kein Programm zum Öffnen gefunden.", vbCritical, "Programmabbruch")
                Exit Sub
            End If

            strDisplayName = InputBox("Bitte Anzeigetext eingeben.", "Einagbe", strFilename)
            If StrPtr(strDisplayName) > 0 Then

                If LCase$(strExtension) = "pdf" Then
                    lngIconIndex = 1
                Else
                    lngIconIndex = 0
                End If

                Call LockWindowUpdate(GetDesktopWindow)

                Set objOLEObject = ActiveSheet.OLEObjects.Add(Filename:=strPath, _
                    Link:=False, DisplayAsIcon:=True, IconIndex:=lngIconIndex, _
                    IconFileName:=strExecutable, IconLabel:=strDisplayName)
                objOLEObject.ShapeRange.AlternativeText = strFilename

                Call LockWindowUpdate(0)

                Set objOLEObject = Nothing

            End If
        End If
    End With
End Sub
Gruß
Nepumuk


Anzeige
AW: VBA-Code anpassen für 64-bit
10.07.2023 12:03:47
Pappawinni
Muss da
    Private Declare PtrSafe Function LockWindowUpdate Lib "user32.dll" ( _
        ByVal hwndLock As LongPtr) As LongPtr
nicht auch ein LongPtr hin ?


AW: VBA-Code anpassen für 64-bit
10.07.2023 12:10:47
Nepumuk
Hallo,

NEIN.

Gruß
Nepumuk


AW: VBA-Code anpassen für 64-bit
10.07.2023 12:31:44
Pappawinni
Ist das deine Meinung, oder hast du dafür auch eine Begründung ?


Anzeige
AW: VBA-Code anpassen für 64-bit
10.07.2023 13:20:06
Pappawinni
Hm... ok, aber so richtig definitiv ist das auch nicht, was da steht.
Wonach der Rückgabewert verlangt, naja was heißt das, ich verwende ja auch long, selbst wenn es eine integer täte.


Anzeige
AW: VBA-Code anpassen für 64-bit
10.07.2023 14:12:18
Ulf
Hi,
Hab nur WIN64/Office 32Bit zur Verfügung, da läuft es so:

Option Explicit

Private Declare PtrSafe Function FindExecutable64 Lib "shell32.dll" Alias "FindExecutableA" ( _
ByVal lpFile As String, _
ByVal lpDirectory As String, _
ByVal lpResult As String) As LongPtr
Private Declare PtrSafe Function LockWindowUpdate64 Lib "user32.dll" Alias "LockWindowUpdate" ( _
ByVal hwndLock As LongPtr) As Long
Private Declare PtrSafe Function GetDesktopWindow64 Lib "user32.dll" Alias "GetDesktopWindow" () As LongPtr

Private Declare Function FindExecutable86 Lib "shell32.dll" _
  Alias "FindExecutableA" ( _
  ByVal lpFile As String, _
  ByVal lpDirectory As String, _
  ByVal lpResult As String) As Long
Private Declare Function LockWindowUpdate86 Lib "user32.dll" Alias "LockWindowUpdate" ( _
ByVal hwndLock As Long) As Long
Private Declare Function GetDesktopWindow86 Lib "user32.dll" Alias "GetDesktopWindow" () As Long
    
Private Declare Function lstrlen Lib "kernel32.dll" _
  Alias "lstrlenA" ( _
  ByVal lpString As Any) As Long
     
Private Const MAX_PATH As Long = 256
     
Public Function FindExecutableA(ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByRef lpResult As String)
   If InStr(Application.Path, "x86") Then
       FindExecutableA = FindExecutable86(lpFile, lpDirectory, lpResult)
   Else
       FindExecutableA = FindExecutable64(lpFile, lpDirectory, lpResult)
   End If
End Function

Public Function LockWindowUpdate(ByVal hwndLock As Long)
    If InStr(Application.Path, "x86") Then
        LockWindowUpdate = LockWindowUpdate86(hwndLock)
    Else
        Dim hwndLockPtr As LongPtr
        hwndLockPtr = hwndLock
        LockWindowUpdate = LockWindowUpdate86(hwndLockPtr)
    End If
End Function

Public Function GetDesktopWindow()
    If InStr(Application.Path, "x86") Then
        GetDesktopWindow = GetDesktopWindow86()
    Else
        GetDesktopWindow = GetDesktopWindow64()
    End If
End Function

Public Sub InsertFileObject()
    Dim objOLEObject As OLEObject
    Dim lngReturn As Long, lngIconIndex As Long
    Dim strPath As String, strFilename As String, strDisplayName As String
    Dim strTemp As String '
    Dim strExtension As String, strExecutable As String
    strTemp = Space(MAX_PATH)
    With Application.FileDialog(msoFileDialogFilePicker)
        .Filters.Clear
        .Title = "Add General Document"
        .AllowMultiSelect = False
        If .Show Then
            strPath = .SelectedItems(1)
            strExtension = Mid$(strPath, InStrRev(strPath, ".") + 1)
            strFilename = Mid$(strPath, InStrRev(strPath, "\") + 1)
            strFilename = Left$(strFilename, InStrRev(strFilename, ".") - 1)
            lngReturn = FindExecutableA(strPath, "", strTemp)
            If lngReturn > 32 Then
                strExecutable = Left$(strTemp, lstrlen(strTemp))
            Else
                Call MsgBox("Kein Programm zum Öffnen gefunden.", vbCritical, "Programmabbruch")
                Exit Sub
            End If
            strDisplayName = InputBox("Bitte Anzeigetext eingeben.", "Einagbe", strFilename)
            If StrPtr(strDisplayName) > 0 Then
                If LCase$(strExtension) = "pdf" Then
                    lngIconIndex = 1
                Else
                    lngIconIndex = 0
                End If
                Call LockWindowUpdate(GetDesktopWindow)
                Set objOLEObject = ActiveSheet.OLEObjects.Add(Filename:=strPath, _
                Link:=False, DisplayAsIcon:=True, IconIndex:=lngIconIndex, _
                IconFileName:=strExecutable, IconLabel:=strDisplayName)
                objOLEObject.ShapeRange.AlternativeText = strFilename
                Call LockWindowUpdate(0&)
                Set objOLEObject = Nothing
            End If
        End If
    End With
End Sub
hth
Ulf

Anzeige
;

Forumthreads zu verwandten Themen

Anzeige
Anzeige
Anzeige
Entdecke relevante Threads

Schau dir verwandte Threads basierend auf dem aktuellen Thema an

Alle relevanten Threads mit Inhaltsvorschau entdecken
Anzeige
Anzeige

Infobox / Tutorial

VBA-Code anpassen für 64-bit Systeme


Schritt-für-Schritt-Anleitung

  1. Code überprüfen: Stelle sicher, dass dein Code die PtrSafe-Attribute verwendet. Füge das Attribut zu allen Declare-Anweisungen hinzu, die auf 64-bit Systeme abzielen.

    Beispiel:

    #If VBA7 Then
       Private Declare PtrSafe Function FindExecutableA Lib "shell32.dll" ( _
           ByVal lpFile As String, _
           ByVal lpDirectory As String, _
           ByVal lpResult As String) As LongPtr
    #End If
  2. Variablen anpassen: Verwende LongPtr anstelle von Long, um sicherzustellen, dass dein Code kompatibel mit 64-bit ist.

    Beispiel:

    Private Declare PtrSafe Function LockWindowUpdate Lib "user32.dll" ( _
       ByVal hwndLock As LongPtr) As Long
  3. Testen: Führe den aktualisierten Code aus, um sicherzustellen, dass keine Fehler mehr auftreten. Achte auf Fehlermeldungen wie "Fehler beim kompilieren: Der Code in diesem Projekt muss für die Verwendung auf 64-Bit-Systemen aktualisiert werden".


Häufige Fehler und Lösungen

  • Fehler beim Kompilieren: Wenn du die Meldung erhältst, dass "der Code in diesem Projekt muss für die Verwendung auf 64-Bit-Systemen aktualisiert werden", stelle sicher, dass alle Declare-Anweisungen das PtrSafe-Attribut enthalten.

  • Falscher Datentyp: Achte darauf, dass du LongPtr für Zeiger und Handles verwendest. Wenn du Long verwendest, kann es zu Problemen kommen.


Alternative Methoden

Falls du den Code nicht anpassen möchtest, kannst du einen Wrapper verwenden, der automatisch zwischen 32-bit und 64-bit unterscheidet. Eine Möglichkeit ist die Verwendung von Funktionen wie FindExecutableA, die je nach Architektur unterschiedliche Deklarationen nutzen.

Public Function FindExecutable(ByVal lpFile As String, ByVal lpDirectory As String, ByRef lpResult As String) As Long
    If InStr(Application.Path, "x86") Then
        ' 32-bit Code
    Else
        ' 64-bit Code
    End If
End Function

Praktische Beispiele

Hier ist ein Beispiel, wie du einen OLE-Objekt in ein Excel-Arbeitsblatt einfügen kannst. Achte darauf, dass alle Declare-Anweisungen korrekt angepasst sind:

Public Sub InsertFileObject()
    Dim objOLEObject As OLEObject
    ' ...
    Set objOLEObject = ActiveSheet.OLEObjects.Add(Filename:=strPath, _
        Link:=False, DisplayAsIcon:=True, IconIndex:=lngIconIndex, _
        IconFileName:=strExecutable, IconLabel:=strDisplayName)
    ' ...
End Sub

Nutze PtrSafe und LongPtr, um sicherzustellen, dass dein Code auf 64-bit Systemen läuft.


Tipps für Profis

  • Verwende #If Win64: Nutze diese Bedingung, um spezifischen Code für 64-bit Systeme zu schreiben.

  • Überprüfe die Rückgabewerte: Achte darauf, die Rückgabewerte der API-Funktionen korrekt zu verarbeiten, um unerwartete Fehler zu vermeiden.

  • Dokumentation lesen: Informiere dich über die spezifischen API-Dokumentationen, um die richtigen Datentypen und -formate zu verwenden. Ein Beispiel findest du hier.


FAQ: Häufige Fragen

1. Warum muss ich PtrSafe verwenden?
PtrSafe ist notwendig, um sicherzustellen, dass dein Code auf 64-bit Versionen von Excel funktioniert. Andernfalls erhältst du Kompilierungsfehler.

2. Was ist der Unterschied zwischen Long und LongPtr?
LongPtr ist ein Datentyp, der für Zeiger und Handles auf 64-bit Systemen verwendet wird. Long ist für 32-bit Systeme. Verwende LongPtr, um sicherzustellen, dass dein Code plattformunabhängig ist.

3. Wie kann ich meinen Code testen?
Du kannst den Code in einem 64-bit Excel-Umfeld testen. Achte auf Fehlermeldungen und debugge den Code, um sicherzustellen, dass alles korrekt funktioniert.

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