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

VBA Makro für 32bit und 64bit VBA7

Forumthread: VBA Makro für 32bit und 64bit VBA7

VBA Makro für 32bit und 64bit VBA7
28.05.2021 15:28:45
GuideThomas
Hallo!
Ich bin mit Excel von der 32bit Version auf die 64bit Version umgestiegen. Jetzt läuft ein für mich wichtiges Makro leider nicht mehr, welches nun bei mir auf der 64bit Version als auch weiterhin auf einem Rechner mit Excel 32bit laufen sollte.
Es geht in diesem Makro darum Unicode bzw. UTF8 Sonderzeichen in einen sauberen String umzuwandeln.
Ich bin mit der Ergänzung von PtrSafe und dem Definieren von LongPtr anstelle von Long im VBA7 Code schon ein Stück weit gekommen ... dennoch steht der Ablauf (u.a. bei 1NC = 1Bytes) immer wieder aufgrund unverträglicher Typen im Block für VBA7.
Findet zufällig jemand auf den ersten Blick den Fehler?

Option Explicit
Private Const CP_UTF8 = 65001
#If VBA7 Then
Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _
ByVal CodePage As Long, ByVal dwFlags As Long, _
ByVal lpMultiByteStr As LongPtr, ByVal cchMultiByte As LongPtr, _
ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As LongPtr) As LongPtr
Public Function getTranslation(ByVal url As String) As String
Dim sResponse As String
With CreateObject("MSXML2.ServerXMLHTTP.6.0")
.Open "GET", url, False: .Send
sResponse = StrConv(.responseBody, vbUnicode)
getTranslation = sUTF8ToUni(StrConv(sResponse, vbFromUnicode))
End With
End Function
Public Function sUTF8ToUni(bySrc() As Byte) As String
' Converts a UTF-8 byte array to a Unicode string
Dim lBytes As LongPtr, lNC As Long, lRet As LongPtr
lBytes = UBound(bySrc) - LBound(bySrc) + 1
lNC = lBytes
sUTF8ToUni = String$(lNC, Chr(0))
lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bySrc(LBound(bySrc))), lBytes, StrPtr(sUTF8ToUni), lNC)
sUTF8ToUni = Left$(sUTF8ToUni, lRet)
End Function
#Else
Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _
ByVal CodePage As Long, ByVal dwFlags As Long, _
ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, _
ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Public Function getTranslation(ByVal url As String) As String
Dim sResponse As String
With CreateObject("MSXML2.ServerXMLHTTP.6.0")
.Open "GET", url, False: .Send
sResponse = StrConv(.responseBody, vbUnicode)
getTranslation = sUTF8ToUni(StrConv(sResponse, vbFromUnicode))
End With
End Function
Public Function sUTF8ToUni(bySrc() As Byte) As String
' Converts a UTF-8 byte array to a Unicode string
Dim lBytes As Long, lNC As Long, lRet As Long
lBytes = UBound(bySrc) - LBound(bySrc) + 1
lNC = lBytes
sUTF8ToUni = String$(lNC, Chr(0))
lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bySrc(LBound(bySrc))), lBytes, StrPtr(sUTF8ToUni), lNC)
sUTF8ToUni = Left$(sUTF8ToUni, lRet)
End Function
#End If
Anzeige

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA Makro für 32bit und 64bit VBA7
28.05.2021 16:05:27
Nepumuk
Hallo Thomas,
teste mal:
Code:

[Cc][+][-]

Option Explicit #If Win64 Then Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32.dll" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As String, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As String, _ ByVal cchWideChar As Long) As Long #Else Private Declare Function MultiByteToWideChar Lib "kernel32.dll" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As String, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As String, _ ByVal cchWideChar As Long) As Long #End If Private Const CP_UTF8 As Long = 65001 Public Function getTranslation(ByVal url As String) As String Dim sResponse As String With CreateObject("MSXML2.ServerXMLHTTP.6.0") .Open "GET", url, False: .Send sResponse = StrConv(.responseBody, vbUnicode) getTranslation = sUTF8ToUni(StrConv(sResponse, vbFromUnicode)) End With End Function Public Function sUTF8ToUni(bySrc() As Byte) As String ' Converts a UTF-8 byte array to a Unicode string Dim lBytes As Long, lNC As Long, lRet As Long lBytes = UBound(bySrc) - LBound(bySrc) + 1 lNC = lBytes sUTF8ToUni = String$(lNC, Chr(0)) lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bySrc(LBound(bySrc))), lBytes, StrPtr(sUTF8ToUni), lNC) _ sUTF8ToUni = Left$(sUTF8ToUni, lRet) End Function

Gruß
Nepumuk
Anzeige
VarPtr wird in 64Bit Office nicht mehr unterstützt
29.05.2021 00:09:40
GuideThomas
Hallo Nepumuk und danke für dein Feedback.
Ich frage deshalb nur VBA7 und nicht Win64 ab, da grundsätzlich bei uns im Unternehmen Win64 genutzt wird jedoch mit einer Office 32 Bit Installation - Der Grund dafür ist, dass es SAP Business One anscheinend nur in 32 Bit gibt und somit auch nur mit Office 32 Bit nahtlos zusammenarbeitet ...
Ich habe bei weiterer Recherche einen Beitrag von dir aus dem Jahr 2018 im ActiveVB Forum entdeckt. In diesem schreibst du:
VarPtr, StrPtr und ObjPtr werden im 64Bit-Office nicht mehr unterstützt. Microsoft selbst rät von der Verwendung der 64Bit-Version ab.
Und genau beim Block VarPtr bleibt er hängen im Makro mit der Meldung "Typen unverträglich". Das bedeutet es gibt hier in diesem Fall wohl keine Lösung?

Option Explicit
Private Const CP_UTF8 = 65001
#If VBA7 Then
Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _
ByVal CodePage As Long, _
ByVal dwFlags As Long, _
ByVal lpMultiByteStr As Long, _
ByVal cchMultiByte As Long, _
ByVal lpWideCharStr As Long, _
ByVal cchWideChar As Long) As Long
#Else
Private Declare Function MultiByteToWideChar Lib "kernel32" ( _
ByVal CodePage As Long, _
ByVal dwFlags As Long, _
ByVal lpMultiByteStr As Long, _
ByVal cchMultiByte As Long, _
ByVal lpWideCharStr As Long, _
ByVal cchWideChar As Long) As Long
#End If
Public Function sUTF8ToUni(bySrc() As Byte) As String
' Converts a UTF-8 byte array to a Unicode string
Dim lBytes As Long, lNC As Long, lRet As Long
lBytes = UBound(bySrc) - LBound(bySrc) + 1
lNC = lBytes
sUTF8ToUni = String$(lNC, Chr(0))
lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bySrc(LBound(bySrc))), lBytes, StrPtr(sUTF8ToUni), lNC)
sUTF8ToUni = Left$(sUTF8ToUni, lRet)
End Function
Public Function getTranslation(ByVal url As String) As String
Dim sResponse As String
With CreateObject("MSXML2.ServerXMLHTTP.6.0")
.Open "GET", url, False: .Send
sResponse = StrConv(.responseBody, vbUnicode)
getTranslation = sUTF8ToUni(StrConv(sResponse, vbFromUnicode))
End With
End Function

Anzeige
AW: VarPtr wird in 64Bit Office nicht mehr unterstützt
29.05.2021 07:07:17
Nepumuk
Hallo,
teste mal:

Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _
ByVal CodePage As Long, _
ByVal dwFlags As Long, _
ByVal lpMultiByteStr As LongPtr, _
ByVal cchMultiByte As Long, _
ByVal lpWideCharStr As LongPtr, _
ByVal cchWideChar As Long) As Long
Gruß
Nepumuk
Anzeige
AW: VarPtr wird in 64Bit Office nicht mehr unterstützt
29.05.2021 08:01:03
GuideThomas
Hallo Nepumuk,
fantastisch, das hat nun so funktioniert. Vielen Dank!
AW: VBA Makro für 32bit und 64bit VBA7
28.05.2021 16:07:00
Herbert_Grom
Hallo Thomas,
probiers mal damit als erster Zeile:

'#If VBA7 Or Win64 Then
Servus
AW: VBA Makro für 32bit und 64bit VBA7
28.05.2021 16:09:23
Herbert_Grom
genau und das wollte ich auch noch sagen, die "Public Functions" musst du außerhalb der "#If VBA7 Or Win64 Then" setzen.
Anzeige
;

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

VBA Makro für 32bit und 64bit VBA7


Schritt-für-Schritt-Anleitung

Um ein VBA-Makro sowohl für die 32-Bit- als auch für die 64-Bit-Version von Excel zu erstellen, befolge diese Schritte:

  1. Code-Header anpassen: Beginne deinen Code mit der Abfrage, ob VBA7 verwendet wird. Dies ist wichtig, um die Unterschiede zwischen 32-Bit und 64-Bit zu berücksichtigen.

    #If VBA7 Then
  2. Deklaration der Kernel32-Funktion: Deklariere die Funktion MultiByteToWideChar abhängig von der Bit-Version. Verwende LongPtr für 64-Bit.

    Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _
    ByVal CodePage As Long, ByVal dwFlags As Long, _
    ByVal lpMultiByteStr As LongPtr, ByVal cchMultiByte As LongPtr, _
    ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As LongPtr) As LongPtr
  3. String-Konvertierung: Implementiere die Funktion zur Umwandlung von UTF-8 zu Unicode.

    Public Function sUTF8ToUni(bySrc() As Byte) As String
    ' Konvertiert ein UTF-8 Byte-Array in einen Unicode-String
    End Function
  4. Verwendung von StrPtr und VarPtr: Diese Funktionen sind für die Adressierung von Strings in VBA wichtig. Achte darauf, dass sie in 64-Bit nicht direkt verwendet werden können, verwende stattdessen LongPtr.

    lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bySrc(LBound(bySrc))), lBytes, StrPtr(sUTF8ToUni), lNC)
  5. Testen des Codes: Überprüfe den Code in beiden Versionen, um sicherzustellen, dass er korrekt funktioniert.


Häufige Fehler und Lösungen

  • Typen unverträglich: Dies tritt häufig auf, wenn VarPtr in einer 64-Bit-Umgebung nicht korrekt verwendet wird. Stelle sicher, dass du LongPtr statt Long verwendest.

  • StrPtr Fehler: Wenn StrPtr nicht funktioniert, überprüfe die Verwendung in der Funktion. In 64-Bit musst du sicherstellen, dass alle Variablen korrekt deklariert sind.

  • Verwendung von #If-Direktiven: Falsche Platzierung kann dazu führen, dass der Code nicht ausgeführt wird. Stelle sicher, dass die Public Function außerhalb der #If-Direktive steht.


Alternative Methoden

Wenn du Schwierigkeiten mit VarPtr hast, kannst du die folgenden Alternativen ausprobieren:

  • Verwende ByVal anstelle von LongPtr in der Funktionsdeklaration für 32-Bit Office.
  • Implementiere die Private Declare Anweisung für beide Versionen in einer einzigen Funktion, indem du die erforderlichen Abfragen verwendest.

Beispiel:

#If VBA7 Or Win64 Then
Private Declare PtrSafe Function MultiByteToWideChar ...
#Else
Private Declare Function MultiByteToWideChar ...
#End If

Praktische Beispiele

Hier ist ein einfaches Beispiel für ein Makro, das UTF-8-Zeichen in Unicode umwandelt:

Public Function ConvertUTF8toUnicode(url As String) As String
    Dim response As String
    With CreateObject("MSXML2.ServerXMLHTTP.6.0")
        .Open "GET", url, False
        .Send
        response = StrConv(.responseBody, vbUnicode)
        ConvertUTF8toUnicode = sUTF8ToUni(StrConv(response, vbFromUnicode))
    End With
End Function

Stelle sicher, dass du diese Funktionen in einem Modul speicherst, um sie in anderen Teilen deines Projekts verwenden zu können.


Tipps für Profis

  1. Verwende Kommentare: Dokumentiere deinen Code gründlich, insbesondere wenn du mit #If-Direktiven arbeitest.

  2. Debugging: Nutze die Debugging-Tools von VBA, um Fehler schnell zu identifizieren und zu beheben.

  3. Optimierung: Achte darauf, dass die Funktionen optimiert sind, um die Leistung zu steigern, insbesondere bei großen Datenmengen.

  4. Testen in verschiedenen Umgebungen: Führe Tests sowohl in 32-Bit als auch in 64-Bit Umgebungen durch, um sicherzustellen, dass dein Code überall funktioniert.


FAQ: Häufige Fragen

1. Wie kann ich sicherstellen, dass mein Makro in beiden Excel-Versionen funktioniert? Stelle sicher, dass alle Funktionsaufrufe und Deklarationen entsprechend der Bit-Version angepasst sind. Verwende die #If VBA7 und #If Win64 Direktiven.

2. Warum funktioniert VarPtr in der 64-Bit-Version nicht? VarPtr und ähnliche Funktionen sind in 64-Bit VBA nicht mehr unterstützt. Verwende LongPtr, um Adressen in 64-Bit korrekt zu handhaben.

3. Welche Version von Excel benötige ich? Das Beispiel funktioniert sowohl in Excel 32-Bit als auch in Excel 64-Bit, vorausgesetzt, der Code wird korrekt implementiert.

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