Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Anzeige
Inhaltsverzeichnis

VBA ClipBoard (API) für 32- und 64-Bit

Forumthread: VBA ClipBoard (API) für 32- und 64-Bit

VBA ClipBoard (API) für 32- und 64-Bit
05.01.2025 16:51:54
Joschi Witchcraft
Hallo Forum.

Bisher hatte ich Excel mit Markos nur auf meinem PC mit Windows 10 und Office 365 im 32-Bit-Mode eingesetzt. Nun möchte ich meine Makros auf auf dem Laptop mit Windows 11 und Office 365 im 64-Bit-Mode lauffähig machen. Dank der Unterstützung durch dieses Forum wurde ein großes Problem bereits gelöst,

Mein Aktuelles Problem: ClipBoard (API).

Meinen alten Code habe ich auf der Basis von Beispielen im Internet soweit lauffähig bekommen, dass das Setzen und Löschen von Daten im ClipBoard auf dem alten PC seit Jahren problemlos funktioniert.

Nun habe ich versucht, eine Version zu erstellen, welche auf beiden Systemen mit demselben Code lauffähig ist.
Auf dem 32-Bit-System habe ich das Problem, dass ich vom gespeicherten String immer nur das erste Zeichen erhalte; die Länge des Strings wird allerdings richtig bereitgestellt. Trotz intensiver Suche konnte ich die Ursache nicht finden.

Wenn ich für den Test auf dem 32-Bit-System meinen alten Code einsetze, erhalte ich den gespeicherten String komplett zurück.

Meine beiden Versionen habe ich als getrennte Text-Files bereitgestellt. Bei der alten Version habe ich den Namen der Funktion jeweils ein "Old" vorangestellt, so dass beide Versionen durcheinander verwendet werden können.

Neuer Code: https://www.herber.de/bbs/user/174673.txt
Alter Cide: https://www.herber.de/bbs/user/174674.txt

Mein Aufruf:
Sub Starten()
ClipBoardCut "Das ist ein Test " & Time()
Debug.Print ">" & ClipBoardPaste & ""
Debug.Print ">" & OldClipBoardPaste & ""
ClipBoardCut vbNullString
Debug.Print "Clipboard gelöscht"
Debug.Print ">" & ClipBoardPaste & ""

OldClipBoardCut "Das ist ein Old-Test " & Time()
Debug.Print ">" & ClipBoardPaste & ""
Debug.Print ">" & OldClipBoardPaste & ""
End Sub

Ich hoffe, dass sich jemand findet, welcher mein Problem unter 32-Bit lösen kann.

Beim Test auf dem 64-Bit-Rechner wurde die Definition
#If Win64 Then
Dim iStrPtr As LongPtr
beanstandet.
Ich habe das nachträglich auf "Long" geändert. Allerdings bekomme ich einen weiteren Fehler "Typen unverträglich" in der Zeile mit dem Inhalt "ClipText = String$(iLen \ 2& - 1&, vbNullChar)" .
Nachdem ich auch ILen als Long definiert hatte, bekam ich in der genannten Zeile einen Laufzeitfehler 5

Es sieht so aus, dass ich - wieder einmal - auf externe Hilfe angewiesen bin.

Natürlich musste für den Test auf dem 64-Bit-System der alte Code entfernt werden. Aber das brauche ich den Profis nicht sagen,

Gruß Joschi
Anzeige

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA ClipBoard (API) für 32- und 64-Bit
05.01.2025 18:55:50
Oberschlumpf
Hi,

nur ma so ne Frage: Wieso zeigst du per Upload nicht gleich Excel-Bsp-Dateien mit deinem Code, sondern nur txt-Dateien?

Ciao
Thorsten
AW: VBA ClipBoard (API) für 32- und 64-Bit
06.01.2025 09:26:27
Joschi Witchcraft
Hallo Thorsten.

in einer 64-Bit-Excel-Umgebung hätte der reine 32-Bit-Code viele Fehlermeldung erzeugt, ohne dass der restliche Code ausführbar gewesen wäre. Deshalb habe ich die beiden Versionen als getrennte Textfiles bereitgestellt.
Anzeige
Also für 32 Bit...
05.01.2025 19:31:48
Case
Moin, :-)

... kann ich nicht testen. Aber 64 Bit hast du schon einen Fehler (habe es auch nur schnell überflogen): ;-)

Bei #If VBA7 Then schreibst du:
Private Declare PtrSafe Function GlobalSize Lib "kernel32.dll" (ByVal hMem As Long) As Long

hMem muss aber LongPtr sein - denn da arbeitest du später auch mit. ;-)

Hier mal 2 funktionierende Alternativen (getestet unter Win 11 und Office 365 64 Bit): ;-)
https://www.devhut.net/vba-save-string-to-clipboard-get-string-from-clipboard/

Und hier der zweite Code (der erste Code funktioniert nicht - steht aber auch im Kommentar): ;-)
https://gist.github.com/lundeen-bryan/f927033a8ecba8a3ad1933b20211dea0

Servus
Case
Anzeige
AW: Und hier noch als...
06.01.2025 09:27:47
Joschi Witchcraft
Hallo Case.

Danke für Deine Links. Ich werde sie mir in Ruhe anschauen.
AW: VBA ClipBoard (API) für 32- und 64-Bit
05.01.2025 19:52:26
volti
Hallo Joschi,

wenn Du demnächst öfter was umsetzen willst, empfehle ich Dir meinen API-Viewer. Der kann teilweise sogar selbständig von 32 auf 64 Bit umstellen.
https://www.clever-excel-forum.de/Thread-API-Viewer

Auch kannst Du gerne eine meiner Versionen der API-Zwischenablagefunktionen verwenden.
Stelle ich bei Bedarf hier gerne bereit.


Aber Du kannst auch Deine hier gepostete alte Version weiternutzen. Ich habe sie Dir umgesetzt.
Auch hier gilt wieder, was ich Dir letztens schon schrieb. Falls Du kein uraltes Excel (VBA6) mehr einsetzt, benötigst Du keine Trennung. Es reicht der einmalige VBA7 Code.

Den neuen Code habe ich mir nicht näher angeschaut. M.E. brauchst Du das nicht, was da drin steht.

PS:
#If Win64 Then
Dim iStrPtr As LongPtr

iStrPtr ist ein Zeiger, der unter 64 Bit unbedingt auf Longlong bzw. besser auf LongPtr gesetzt werden muss und keineswegs auf Long.

Probiere es halt mal aus....

Code:


Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long Private Declare PtrSafe Function SetClipboardData Lib "user32" ( _ ByVal wFormat As Long, ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GetClipboardData Lib "user32" ( _ ByVal wFormat As Long) As LongPtr Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" ( _ ByVal wFormat As Long) As Long Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" ( _ ByVal wFlags As Long, ByVal dwBytes As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalLock Lib "kernel32" ( _ ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long Private Declare PtrSafe Function lstrcpy Lib "kernel32" Alias "lstrcpyW" ( _ ByVal lpString1 As LongPtr, ByVal lpString2 As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalSize Lib "kernel32" ( _ ByVal hMem As LongPtr) As Long Function ClipBoardCut(ClipText As String) 'sets the clipboard with parameter string Const GMEM_MOVEABLE As Long = &H2 Const GMEM_ZEROINIT As Long = &H40 Const CF_UNICODETEXT As Long = &HD Dim iStrPtr As LongPtr Dim iLen As Long Dim iLock As LongPtr OpenClipboard 0& EmptyClipboard iLen = LenB(ClipText) + 2& iStrPtr = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, iLen) iLock = GlobalLock(iStrPtr) lstrcpy iLock, StrPtr(ClipText) GlobalUnlock iStrPtr SetClipboardData CF_UNICODETEXT, iStrPtr CloseClipboard End Function Function ClipBoardPaste() As String 'gets the clipboard text in function name Const CF_UNICODETEXT As Long = 13& Dim iStrPtr As LongPtr Dim iLen As Long Dim iLock As LongPtr Dim ClipText As String OpenClipboard 0& If IsClipboardFormatAvailable(CF_UNICODETEXT) Then iStrPtr = GetClipboardData(CF_UNICODETEXT) If iStrPtr Then iLock = GlobalLock(iStrPtr) iLen = GlobalSize(iStrPtr) ClipText = String$(iLen \ 2& - 1&, vbNullChar) lstrcpy StrPtr(ClipText), iLock GlobalUnlock iStrPtr End If ClipBoardPaste = ClipText End If CloseClipboard End Function Sub Test() ClipBoardCut "Mein Clipboardtest" Debug.Print ClipBoardPaste End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz
Anzeige
AW: VBA ClipBoard (API) für 32- und 64-Bit
06.01.2025 09:31:10
Joschi Witchcraft
Hallo Karl-Heinz.

Auch Dir herzlichen Dank für Deine Informationen.

Was ich mit Excel und VBA bisher gemacht haben, war alles für den persönlichen Bereich. Als langjähriger Rentner macht es mir viel Spaß, wenn ich Dinge automatisieren kann.

Mit Excel und VBA habe ich mich bereits im aktiven Berufsleben beschäftigt. Basis war damals ein Buch über VBA und eine CD von Herber mit Beispielen. Mein Code wurde inzwischen mehrfach angepasst und ist auch nach fast 20 Jahren täglich im Einsatz. Mit meinem heutigen Wissen würde ich vieles anders machen.

Noch ist mein PC der wichtigste Rechner für meine Makros. Um komplette Mappen teilen zu können, sind die #IF's vorerst erforderlich.

Ich bin nachträglich froh darüber, dass - warum auch immer - Office 365 auf meinem 64-Bit-PC in der 32-Bit-Version installiert wurde. Eine Alternative hätte ich nicht gehabt, aber viele Makros, die nicht mehr funktioniert hätten.

Auch Deine Informationen werde ich mir in Ruhe anschauen, und natürlich auch den API-Viewer ausprobieren.

Wenn ein umgestellter 32-Bit-Code unter 64 Bit lauffähig ist, traue ich es mir zu, eine Version für beide Systeme erstellen zu können.

Für mich ist es schwierig, zu erkennen. wann LongPtr erforderlich ist. Das versuche ich dann über Beispiele im Internet zu ermitteln.
Anzeige
AW: VBA ClipBoard (API) für 32- und 64-Bit
06.01.2025 10:20:19
Joschi Witchcraft
Hallo Karl-Heinz.

Den Viewer habe ich mir (bisher) nicht heruntergeladen: ich müsste mich dazu zuerst registrieren. Irgendwann verliert man dann den Überblick.

Ich habe Deinen vorgeschlagenen Code auf meinem PC ausgeführt, und war erstaunt, dass der Code durchgelaufen ist. Erst danach wurde mir klar: mein Windows und mein Excel können 64 Bit. Und deshalb wurde der Code problemlos ausgeführt - ohne #IF's.

Wenn Excel im 32-Bit-Mode arbeitet, heisst das nicht, dass Excel nicht auch auf den Bereich oberhalb 32 Bit zugreifen könnte.

Wieder etwas dazugelernt. Und ein Problem weniger.

Nochmals: herzlichen Dank.

Gruß Joschi
Anzeige
AW: VBA ClipBoard (API) für 32- und 64-Bit
06.01.2025 10:24:29
volti
Rentner....

Na da haben wir ja eine Gemeinsamkeit :-)

Meine Programmiertätigkeiten fingen schon 1980 mit Maschinensprache (Chipprogrammierung) an und ging dann über mehrere Sprachen weiter. Aber auch alles mehr oder weniger hobbymäßig.
Konnte zwar sehr viel im Beruf verwenden, Programmieren war aber nie meine angestammte Aufgabe.

Unten noch mal eine meiner derzeitigen Versionen zum Vergleich und hier ein Link für weiteres Vergleichen.
https://www.clever-excel-forum.de/Thread-Excel-Range-als-Werte-in-die-Zwischenablage-kopieren

Alles, was bei den Declares mit kleinem h oder lp beginnt ist ein Handle oder Zeiger und muss LongPtr sein. Und jede Funktion, die so ein Handle zurückgibt muss auch LongPtr sein.
Und natürlich auch die im Code verwendeten Variablen entsprechend deklarieren, ggf. ebenfalls mit #IF-Schalter getrennt.

Warum z.B. in der offiziellen Deklarations-Dokumentionsdatei für GlobalSize ebenfalls LongPtr als Funktionstyp steht, ist mir allerdings unklar. Denn hier wird ja eigentlich nur eine Anzahl zurückgegeben. Es ist also nicht immer alles eindeutig und deshalb sollte man auf einen API-Viewer zurückgreifen, der aber für manche Situationen auch nicht immer passt.
Das Selberaustüfteln (hatte ich ja bei Deiner letzten Anfrage machen müssen) kann mal schnell zum Absturz führen. API ist empflindlch.

Ich bin übrigens mit meiner 64-Bit-Version voll zufrieden. Ist aber jetzt nur noch für den Hausgebrauch.

Code:


Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, _ ByVal dwBytes As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalSize Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long Private Declare PtrSafe Function lstrcpy Lib "kernel32" ( _ ByVal lpString1 As Any, ByVal lpString2 As Any) As LongPtr Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" ( _ ByVal wFormat As Long) As Long Private Declare PtrSafe Function SetClipboardData Lib "user32" ( _ ByVal wFormat As Long, ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GetClipboardData Lib "user32" ( _ ByVal wFormat As Long) As LongPtr Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long Private Const ciFormat As Long = 1 '1=TEXT, 2=BITMAP, 13=UNICODETEXT usw. Sub KopiereTextInZwischenablage(sCliptext As String) Dim hMem As LongPtr, lpGMem As LongPtr hMem = GlobalAlloc(&H42, Len(sCliptext) + 2) ' Speicher reservieren lpGMem = GlobalLock(hMem) ' Speicher blockieren lpGMem = lstrcpy(lpGMem, sCliptext) ' Daten kopieren If GlobalUnlock(hMem) = 0 Then If OpenClipboard(0&) <> 0 Then ' Zwischenablage öffnen EmptyClipboard ' Zwischenablage leeren SetClipboardData ciFormat, hMem ' TEXT in Zwischenablage CloseClipboard ' Zwischenablage schließen End If End If End Sub Function TextAusZwischenablage() As String Dim hMem As LongPtr, lpGMem As LongPtr, sCliptext As String If IsClipboardFormatAvailable(ciFormat) > 0 Then OpenClipboard 0& hMem = GetClipboardData(ciFormat) ' Handle zum Datenbereich If hMem > 0 Then lpGMem = GlobalLock(hMem) ' Speicher reservieren sCliptext = Space(CLng(GlobalSize(hMem)) - 1) ' Platz reservieren lstrcpy sCliptext, lpGMem ' Daten kopieren GlobalUnlock hMem ' Speicher freigeben TextAusZwischenablage = sCliptext End If CloseClipboard End If End Function '####### Kopieren per API ############### Sub KopiereTextInZwis() KopiereTextInZwischenablage "Mein Inhalt!!" End Sub Sub TestKopieAusZwis() Debug.Print TextAusZwischenablage() End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz
Anzeige
AW: VBA ClipBoard (API) für 32- und 64-Bit
06.01.2025 12:12:18
Joschi Witchcraft
Hallo Karl-Heinz.

Maschinensprache?

War rund 40 Jahre mein Thema. Auf verschiedenen IBM-Rechnern. Auch dort gab es Möglichkeiten, einen Code so bereitzustellen, dass der sogar auf (inzwischen) Fujitsu-Rechnern (BS 2000) läuft. In fast allen Bundesländern.

Leider konnte ich diese Wissen auf dem Windows-PC nicht sinnvoll einsetzen.

Gruß Joschi
Anzeige
AW: VBA ClipBoard (API) für 32- und 64-Bit
06.01.2025 13:43:32
volti
Respekt.

Bei mir war es nur eine kurze Zeit.
Beim privaten Elektronikbasteln seinerzeit habe ich eProms für 8086 und den 8031 programmiert.

Lang ist's her.

Gruß KH
Anzeige
Anzeige