Live-Forum - Die aktuellen Beiträge
Datum
Titel
17.10.2025 10:28:49
16.10.2025 17:40:39
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: Aktualisierung auf 64 bit

Aktualisierung auf 64 bit
10.10.2022 14:12:37
Hans-Jürgen
Hallo Wissende,
ich wollte für einen erkrankten Kollegen heute ein monatlich auszuführendes Makro starten und bekomme die Fehlermeldung. "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 programmiere selbst ein bisschen, aber habe lange nicht so viel Wissen wie er. Er hat mir das Passwort gegeben, aber ich kann das leider nicht allein beheben. Einige Zeilen "Private Declare Function" sind rot markiert. Als Beispiel lege ich euch den Anfang vom Code bei, rote Zeilen gibts noch mehrere, aber ich hoffe, anhand dieses Beispiels kann mir jemand erklären, was ich tun muss, um den Code zu reparieren.
Das Ärgerliche ist: Er selbst sagte mir mal über meinen Code, ich müsse ihn 64-Bit-ready machen und erläuterte mir als Beispiel, nicht mehr Long zu verwenden, sondern LongPtr. Dies hilt mir hier aber nicht weiter.
Kann mir jemand erläutern, was ich an den Declare-Anweisungen (und ggf. noch woanders) ändern muss?
Vielen Dank und viele Grüße
Hans-Jürgen

        Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, _
lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32" _
(lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Anzeige

4
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
https://www.herber.de/forum/messages/1901890.html
10.10.2022 14:32:47
NoNet
Hallo Hans Jürgen,
einmal nach "64 Bit" hier im Forum suchen, zeigt Dir evtl. bereits den richtigen Lösungsansatz :
https://www.herber.de/forum/messages/1901890.html
Salut, NoNet
AW: Aktualisierung auf 64 bit
10.10.2022 14:40:53
Nepumuk
Hallo Hans-Jürgen,
der komplette Code:

Option Explicit
Option Compare Text
#If Win64 Then
Private Declare PtrSafe Function FindFirstFileA Lib "kernel32.dll" ( _
ByVal lpFileName As String, _
ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
Private Declare PtrSafe Function FindNextFileA Lib "kernel32.dll" ( _
ByVal hFindFile As LongPtr, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare PtrSafe Function FindClose Lib "kernel32.dll" ( _
ByVal hFindFile As LongPtr) As Long
Private Declare PtrSafe Function FileTimeToLocalFileTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpLocalFileTime As FILETIME) As Long
Private Declare PtrSafe Function FileTimeToSystemTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpSystemTime As SYSTEMTIME) As Long
#Else
Private Declare Function FileTimeToLocalFileTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpLocalFileTime As FILETIME) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpSystemTime As SYSTEMTIME) As Long
Private Declare Function FindClose Lib "kernel32.dll" ( _
ByVal hFindFile As Long) As Long
Private Declare Function FindFirstFileA Lib "kernel32.dll" ( _
ByVal lpFileName As String, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFileA Lib "kernel32.dll" ( _
ByVal hFindFile As Long, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
#End If
Private Enum FILE_ATTRIBUTE
FILE_ATTRIBUTE_READONLY = &H1
FILE_ATTRIBUTE_HIDDEN = &H2
FILE_ATTRIBUTE_SYSTEM = &H4
FILE_ATTRIBUTE_DIRECTORY = &H10
FILE_ATTRIBUTE_ARCHIVE = &H20
FILE_ATTRIBUTE_NORMAL = &H80
FILE_ATTRIBUTE_TEMPORARY = &H100
End Enum
Private Const MAX_PATH As Long = 260&
#If Win64 Then
Private Const INVALID_HANDLE_VALUE As LongPtr = -1
#Else
Private Const INVALID_HANDLE_VALUE As Long = -1&
#End If
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
Private maudtFiles() As FILEINFO
Private mlngFileCount As Long
Private mstrFolderPath As String
Private mstrExtension As String
Private mstrSearchLike As String
Private mblnSubFolders As Boolean
Private mblnCaseSenstiv As Boolean
Private mblnNewSearch As Boolean
Friend Property Get Files(ByVal pvlngIndex As Long) As FILEINFO
Files = maudtFiles(pvlngIndex)
End Property
Friend Property Let Files(ByVal pvlngIndex As Long, ByRef prudtFileInfo As FILEINFO)
maudtFiles(pvlngIndex) = prudtFileInfo
End Property
Friend Property Get FileCount() As Long
FileCount = mlngFileCount
End Property
Friend Property Let FileCount(ByVal pvlngFileCount As Long)
mlngFileCount = pvlngFileCount
End Property
Friend Property Get FolderPath() As String
FolderPath = mstrFolderPath
End Property
Friend Property Let FolderPath(ByVal pvstrFolderPath As String)
mstrFolderPath = pvstrFolderPath
End Property
Friend Property Get Extension() As String
Extension = mstrExtension
End Property
Friend Property Let Extension(ByVal pvstrExtension As String)
mstrExtension = pvstrExtension
End Property
Friend Property Get SearchLike() As String
SearchLike = mstrSearchLike
End Property
Friend Property Let SearchLike(ByVal pvstrSearchLike As String)
mstrSearchLike = pvstrSearchLike
End Property
Friend Property Get SubFolders() As Boolean
SubFolders = mblnSubFolders
End Property
Friend Property Let SubFolders(ByVal pvblnSubFolders As Boolean)
mblnSubFolders = pvblnSubFolders
End Property
Friend Property Get CaseSenstiv() As Boolean
CaseSenstiv = mblnCaseSenstiv
End Property
Friend Property Let CaseSenstiv(ByVal pvblnCaseSenstiv As Boolean)
mblnCaseSenstiv = pvblnCaseSenstiv
End Property
Friend Property Get NewSearch() As Boolean
NewSearch = mblnNewSearch
End Property
Friend Property Let NewSearch(ByVal pvblnNewSearch As Boolean)
mblnNewSearch = pvblnNewSearch
End Property
Friend Function Execute(Optional ByVal opvenmSortBy As SORT_BY = Sort_by_None, _
Optional ByVal opvenmSortOrder As SORT_ORDER = Sort_Order_Ascending) As Long
If NewSearch Then FileCount = 0
Call FindFiles(FolderPath)
If FileCount > 1 And opvenmSortBy  Sort_by_None Then _
Call QuickSort(1, FileCount, opvenmSortBy, opvenmSortOrder)
Execute = FileCount
End Function
Private Sub FindFiles(ByVal pvstrFolderPath As String)
#If Win64 Then
Dim lngSearch As LongPtr
#Else
Dim lngSearch As Long
#End If
Dim udtWFD As WIN32_FIND_DATA
Dim strDirName As String
On Error GoTo ErrorHandling
If Right$(pvstrFolderPath, 1)  "\" Then pvstrFolderPath = pvstrFolderPath & "\"
lngSearch = FindFirstFileA(pvstrFolderPath & "*.*", udtWFD)
If lngSearch  INVALID_HANDLE_VALUE Then
Call GetFilesInFolder(pvstrFolderPath)
If SubFolders Then
Do
If (udtWFD.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY Then
strDirName = Left$(udtWFD.cFileName, InStr(udtWFD.cFileName, vbNullChar) - 1)
If (strDirName  ".") And (strDirName  "..") Then _
Call FindFiles(pvstrFolderPath & strDirName)
End If
Loop While FindNextFileA(lngSearch, udtWFD)
End If
Call FindClose(lngSearch)
End If
Exit Sub
ErrorHandling:
Call MsgBox("Fehler " & CStr(Err.Number) & vbLf & vbLf & _
Err.Description, vbCritical, "Fehler")
End Sub
Private Sub GetFilesInFolder(ByVal pvstrFolderPath As String)
#If Win64 Then
Dim lngSearch As LongPtr
#Else
Dim lngSearch As Long
#End If
Dim udtWFD As WIN32_FIND_DATA
Dim strFilename As String
Dim udtFiletime As FILETIME, udtSystemtime As SYSTEMTIME, udtTempFile As FILEINFO
On Error GoTo ErrorHandling
If Right$(pvstrFolderPath, 1)  "\" Then pvstrFolderPath = pvstrFolderPath & "\"
lngSearch = FindFirstFileA(pvstrFolderPath & Extension, udtWFD)
If lngSearch  INVALID_HANDLE_VALUE Then
Do
If (udtWFD.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY)  FILE_ATTRIBUTE_DIRECTORY Then
strFilename = Left$(udtWFD.cFileName, InStr(udtWFD.cFileName, vbNullChar) - 1)
If IIf(CaseSenstiv, strFilename, LCase$(strFilename)) Like _
IIf(CaseSenstiv, SearchLike, LCase$(SearchLike)) Then
With udtTempFile
.Path = pvstrFolderPath & strFilename
.Filename = strFilename
.Size = udtWFD.nFileSizeLow
End With
Call FileTimeToLocalFileTime(udtWFD.ftCreationTime, udtFiletime)
Call FileTimeToSystemTime(udtFiletime, udtSystemtime)
With udtSystemtime
udtTempFile.DateCreate = CDate(DateSerial(.wYear, .wMonth, .wDay) + _
TimeSerial(.wHour, .wMinute, .wSecond))
End With
Call FileTimeToLocalFileTime(udtWFD.ftLastAccessTime, udtFiletime)
Call FileTimeToSystemTime(udtFiletime, udtSystemtime)
With udtSystemtime
udtTempFile.LastAccess = CDate(DateSerial(.wYear, .wMonth, .wDay) + _
TimeSerial(.wHour, .wMinute, .wSecond))
End With
Call FileTimeToLocalFileTime(udtWFD.ftLastWriteTime, udtFiletime)
Call FileTimeToSystemTime(udtFiletime, udtSystemtime)
With udtSystemtime
udtTempFile.LastModify = CDate(DateSerial(.wYear, .wMonth, .wDay) + _
TimeSerial(.wHour, .wMinute, .wSecond))
End With
FileCount = FileCount + 1
ReDim Preserve maudtFiles(1 To FileCount)
Files(FileCount) = udtTempFile
End If
End If
Loop While FindNextFileA(lngSearch, udtWFD)
Call FindClose(lngSearch)
End If
Exit Sub
ErrorHandling:
Call MsgBox("Fehler " & CStr(Err.Number) & vbLf & vbLf & _
Err.Description, vbCritical, "Fehler")
End Sub
Private Sub QuickSort(ByVal pvlngLBorder As Long, ByVal pvlngUBorder As Long, _
ByVal pvenmSortBy As SORT_BY, ByVal pvenmSortOrder As SORT_ORDER)
Dim lngIndex1 As Long, lngIndex2 As Long
Dim udtBuffer As FILEINFO
Dim vntTemp As Variant
lngIndex1 = pvlngLBorder
lngIndex2 = pvlngUBorder
Select Case pvenmSortBy
Case Sort_by_Name
vntTemp = Files((pvlngLBorder + pvlngUBorder) \ 2).Filename
Case Sort_by_Path
vntTemp = Files((pvlngLBorder + pvlngUBorder) \ 2).Path
Case Sort_by_Size
vntTemp = Files((pvlngLBorder + pvlngUBorder) \ 2).Size
Case Sort_by_Last_Access
vntTemp = Files((pvlngLBorder + pvlngUBorder) \ 2).LastAccess
Case Sort_by_Last_Modyfy
vntTemp = Files((pvlngLBorder + pvlngUBorder) \ 2).LastModify
Case Sort_by_Date_Create
vntTemp = Files((pvlngLBorder + pvlngUBorder) \ 2).DateCreate
End Select
Do
Select Case pvenmSortBy
Case Sort_by_Name
If pvenmSortOrder = Sort_Order_Ascending Then
Do While Files(lngIndex1).Filename  vntTemp
lngIndex1 = lngIndex1 + 1
Loop
Do While vntTemp > Files(lngIndex2).Filename
lngIndex2 = lngIndex2 - 1
Loop
End If
Case Sort_by_Path
If pvenmSortOrder = Sort_Order_Ascending Then
Do While Files(lngIndex1).Path  vntTemp
lngIndex1 = lngIndex1 + 1
Loop
Do While vntTemp > Files(lngIndex2).Path
lngIndex2 = lngIndex2 - 1
Loop
End If
Case Sort_by_Size
If pvenmSortOrder = Sort_Order_Ascending Then
Do While Files(lngIndex1).Size  vntTemp
lngIndex1 = lngIndex1 + 1
Loop
Do While vntTemp > Files(lngIndex2).Size
lngIndex2 = lngIndex2 - 1
Loop
End If
Case Sort_by_Last_Access
If pvenmSortOrder = Sort_Order_Ascending Then
Do While Files(lngIndex1).LastAccess  vntTemp
lngIndex1 = lngIndex1 + 1
Loop
Do While vntTemp > Files(lngIndex2).LastAccess
lngIndex2 = lngIndex2 - 1
Loop
End If
Case Sort_by_Last_Modyfy
If pvenmSortOrder = Sort_Order_Ascending Then
Do While Files(lngIndex1).LastModify  vntTemp
lngIndex1 = lngIndex1 + 1
Loop
Do While vntTemp > Files(lngIndex2).LastModify
lngIndex2 = lngIndex2 - 1
Loop
End If
Case Sort_by_Date_Create
If pvenmSortOrder = Sort_Order_Ascending Then
Do While Files(lngIndex1).DateCreate  vntTemp
lngIndex1 = lngIndex1 + 1
Loop
Do While vntTemp > Files(lngIndex2).DateCreate
lngIndex2 = lngIndex2 - 1
Loop
End If
End Select
If lngIndex1  lngIndex2
If pvlngLBorder 
Gruß
Nepumuk
Anzeige
AW: Aktualisierung auf 64 bit
10.10.2022 14:42:29
volti
Hallo Hans-Jürgen,
mit diesen Declares für VBA7 sollte es funktionieren. Ist aber von mir ungetestet, weil Du natürlich Deinen Code zumindest bzgl. der Handles auch anpassen musst.
Und diesen Teil Deines Codes hast Du ja nicht hier eingestellt.
Nur die Declares anpassen reicht nicht.
Code:


Private Declare PtrSafe Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" ( _ ByVal lpFileName As String, _ lpFindFileData As WIN32_FIND_DATA) As LongPtr Private Declare PtrSafe Function FindNextFile Lib "kernel32" Alias "FindNextFileA" ( _ ByVal hFindFile As LongPtr, _ lpFindFileData As WIN32_FIND_DATA) As Long Private Declare PtrSafe Function FindClose Lib "kernel32" (ByVal hFindFile As LongPtr) As Long Private Declare PtrSafe Function FileTimeToSystemTime Lib "kernel32" ( _ lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Private Type WIN32_FIND_DATA dwFileAttributes As Long ftCreationTime As FILETIME ftLastAccessTime As FILETIME ftLastWriteTime As FILETIME nFileSizeHigh As Long nFileSizeLow As Long dwReserved0 As Long dwReserved1 As Long cFileName(0 To MAX_PATH - 1) As Byte cAlternate(0 To 13) As Byte End Type Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Aktualisierung auf 64 bit
10.10.2022 16:00:00
Hans-Jürgen
Hallo an alle,
IHR SEID DIE BESTEN ! Das Makro läuft zwar noch, aber das ist völlig normal. Er scheints gefressen zu haben ;-)
Untertänigste Grüße
Hans-Jürgen
;

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
Anzeige

Infobox / Tutorial

Aktualisierung von VBA-Code für 64-Bit Excel


Schritt-für-Schritt-Anleitung

Um den VBA-Code für die Verwendung auf 64-Bit-Systemen zu aktualisieren, folge diesen Schritten:

  1. Öffne den VBA-Editor in Excel, indem du ALT + F11 drückst.
  2. Suche nach den Private Declare Function Anweisungen. Diese sind normalerweise rot markiert, wenn sie nicht korrekt sind.
  3. Füge das PtrSafe Attribut hinzu:
    • Ändere jede Declare-Anweisung, um PtrSafe hinzuzufügen. Zum Beispiel:
      Private Declare PtrSafe Function FindFirstFileA Lib "kernel32.dll" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
  4. Ändere den Rückgabewert von Long zu LongPtr, wenn es sich um Handles handelt.
  5. Füge die #If Win64 Then Direktive hinzu:
    • Um sicherzustellen, dass der Code sowohl für 32-Bit als auch für 64-Bit funktioniert, verwende die #If Win64 Then Bedingung.
    • Beispiel:
      #If Win64 Then
      ' 64-Bit Code hier
      #Else
      ' 32-Bit Code hier
      #End If
  6. Teste den Code nach den Änderungen, um sicherzustellen, dass keine Fehler mehr auftreten.

Häufige Fehler und Lösungen

  • Fehler beim Kompilieren: "Der Code in diesem Projekt muss für die Verwendung auf 64-Bit-Systemen aktualisiert werden."

    • Lösung: Überprüfe die Declare-Anweisungen und stelle sicher, dass sie das PtrSafe Attribut und LongPtr verwenden.
  • PtrSafe attribute 64 bit error:

    • Lösung: Stelle sicher, dass alle verwendeten Funktionen korrekt deklariert sind und das PtrSafe Attribut enthalten.

Alternative Methoden

Wenn du nicht sicher bist, ob dein Code korrekt aktualisiert wurde, kannst du folgende Alternativen ausprobieren:

  • Verwende eine VBA-Bibliothek, die bereits für 64-Bit konzipiert ist. Diese Bibliotheken bieten oft eine einfachere Schnittstelle.
  • Nutze Online-Foren oder Communities wie Stack Overflow, um spezifische Fragen zu deinem Code zu stellen.

Praktische Beispiele

Hier ist ein Beispiel für eine aktualisierte Declare-Anweisung für 64-Bit:

#If Win64 Then
Private Declare PtrSafe Function FindFirstFileA Lib "kernel32.dll" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
#Else
Private Declare Function FindFirstFileA Lib "kernel32.dll" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As Long
#End If

In diesem Beispiel wird die Funktion FindFirstFileA korrekt für 64-Bit und 32-Bit deklariert.


Tipps für Profis

  • Nutze die LongPtr Datentypen für alle Handles, wenn du mit APIs arbeitest.
  • Führe regelmäßige Tests durch, um sicherzustellen, dass dein Code reibungslos funktioniert, insbesondere nach großen Änderungen.
  • Dokumentiere Änderungen im Code, um die Nachverfolgung und Fehlersuche zu erleichtern.

FAQ: Häufige Fragen

1. Was bedeutet PtrSafe? PtrSafe ist ein Attribut, das angibt, dass eine Funktion in 64-Bit VBA korrekt funktioniert. Es ist notwendig, um sicherzustellen, dass der Code auf 64-Bit-Versionen von Excel ausgeführt werden kann.

2. Was ist der Unterschied zwischen Long und LongPtr? LongPtr ist ein Datentyp, der je nach Plattform (32-Bit oder 64-Bit) die richtige Größe hat. In 64-Bit-Systemen hat LongPtr die Größe eines Zeigers (8 Bytes), während Long immer 4 Bytes hat.

3. Wie finde ich alle Declare-Anweisungen in meinem Code? Du kannst im VBA-Editor einfach nach Declare suchen, um alle Declare-Anweisungen in deinem Projekt zu finden. Achte darauf, dass du alle Anweisungen überprüfst und anpasst.

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