2013-09-07 8 views
12

काम नहीं करता है, मैं क्लिपबोर्ड पर टेक्स्ट सेट करने के लिए एक्सेल वीबीए में विंडोज एपीआई कॉल का उपयोग करने में सक्षम होता था। लेकिन 64-बिट ऑफिस 2013 में अपग्रेड करने के बाद से, मैं नहीं कर सकता। नीचे कुछ कोड है जो त्रुटि नहीं करता है, लेकिन यह क्लिपबोर्ड पर कोई भी टेक्स्ट सेट नहीं कर रहा है। क्या कोई मुझे परीक्षण और समस्या निवारण में मदद कर सकता है?एक्सेल 2013 64-बिट वीबीए: क्लिपबोर्ड एपीआई

वीबीए में कोड मॉड्यूल में कोड को पेस्ट करने के बाद, आप Clipboard_SetData("Copy this to the clipboard.") टाइप करके तत्काल विंडो में इसका परीक्षण कर सकते हैं और इसे क्लिपबोर्ड पर उस टेक्स्ट को सेट करना चाहिए और आप इसे किसी अन्य एप्लिकेशन में पेस्ट करने में सक्षम होंगे।

(मैं Windows 8 का उपयोग कर रहा है, इसलिए मैं क्लिपबोर्ड में हेरफेर करने के लिए Microsoft प्रपत्र या डेटा ऑब्जेक्ट उपयोग नहीं कर सकते यह Windows 8 पर ठीक से काम नहीं करता है।)

अद्यतन और संपादित करें: नीचे कोड दिया गया है संशोधित और अब 64-बिट एक्सेल में ठीक से काम करता है, जेसन कुर्टज़ के उत्तर के लिए धन्यवाद। यदि आपको यह उपयोगी लगता है, तो कृपया उसका उत्तर दें। के बाद सभी एपीआई घोषणाओं के लिए घोषित

http://msdn.microsoft.com/en-us/library/office/ff192913.aspx

डालने PtrSafe को छोड़कर:

Option Explicit 

'Found 64-bit API declarations here: http://spreadsheet1.com/uploads/3/0/6/6/3066620/win32api_ptrsafe.txt 
Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As LongPtr) As LongPtr 
Private Declare PtrSafe Function GlobalFree Lib "kernel32" (ByVal hMem 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 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 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 lstrcpy Lib "kernel32" (ByVal lpString1 As Any, ByVal lpString2 As Any) As LongPtr 

Private Const GMEM_MOVEABLE = &H2 
Private Const GMEM_ZEROINIT = &H40 
Private Const GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT) 

Public Const CF_TEXT = 1 
Public Const MAXSIZE = 4096 

Sub ClipBoard_SetData(MyString As String) 
'32-bit code by Microsoft: http://msdn.microsoft.com/en-us/library/office/ff192913.aspx 
    Dim hGlobalMemory As LongPtr, lpGlobalMemory As LongPtr 
    Dim hClipMemory As LongPtr, X As Long 

    ' Allocate moveable global memory. 
    hGlobalMemory = GlobalAlloc(GHND, Len(MyString) + 1) 

    ' Lock the block to get a far pointer to this memory. 
    lpGlobalMemory = GlobalLock(hGlobalMemory) 

    ' Copy the string to this global memory. 
    lpGlobalMemory = lstrcpy(lpGlobalMemory, MyString) 

    ' Unlock the memory. 
    If GlobalUnlock(hGlobalMemory) <> 0 Then 
     MsgBox "Could not unlock memory location. Copy aborted." 
     'Debug.Print "GlobalFree returned: " & CStr(GlobalFree(hGlobalMemory)) 
     GoTo OutOfHere 
    End If 

    ' Open the Clipboard to copy data to. 
    If OpenClipboard(0&) = 0 Then 
     MsgBox "Could not open the Clipboard. Copy aborted." 
     Exit Sub 
    End If 

    ' Clear the Clipboard. 
    X = EmptyClipboard() 

    ' Copy the data to the Clipboard. 
    hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory) 

OutOfHere: 
    If CloseClipboard() = 0 Then 
     MsgBox "Could not close Clipboard." 
    End If 
End Sub 
+2

पर चल 'SetClipboardData()' कॉल सफल होने करता है पर काम कर रहा? यदि नहीं, तो 'GetLastError()' रिपोर्ट क्या है? –

+0

बस कोशिश की। Clipboard_SetData ("fjdkla; jfd") \ डिबग आउटपुट: \ hGlobalMemory 287,253,201,176 \ lpGlobalMemory 287,450,358,016 \ lpGlobalMemory 287,362,598,488 \ hClipMemory है 287,253,201,176 \ LastDLLError 0 \ मुझे आश्चर्य है कि क्यों lstrcopy GlobalLock तुलना में एक अलग पते रिटर्न है है। मैंने [lstrcopy एपीआई पेज] की जांच की (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647490 (v = vs.85) .aspx) और माइक्रोसॉफ्ट हमें चेतावनी दे रहा है कि इसका इस्तेमाल न करें। मुझे आश्चर्य है कि क्या इसे किसी प्रकार की विंडोज 8 सुरक्षा सुविधा से अक्षम किया जा रहा है। किसी को भी पता है कि कैसे VBA में [StringCchCopy] (http://bit.ly/15N1jBR) का उपयोग करना है? – Baodad

+1

उल्लिखित फ़ाइल 'win32api_ptrsafe।txt 'अब' Office 2010 सहायता फ़ाइलों से डाउनलोड किया जा सकता है: 64-बिट समर्थन के साथ Win32API_PtrSafe '(http://www.microsoft.com/en-us/download/details.aspx?id=9970) –

उत्तर

9

ठीक है, मैं यह अब मिल गया ...

आप कोड के अपने संस्करण में इस लाइन को बदलने की जरूरत:

Private Declare PtrSafe Function lstrcpy Lib "kernel32" (ByVal lpString1 As String, ByVal lpString2 As String) As LongPtr 
इस के लिए

:

Private Declare PtrSafe Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, ByVal lpString2 As Any) As LongPtr 

आप के माध्यम से कदम हैं जैसा कि आपके पास था, कोड आप देखेंगे कि lpglobalMemory का मान बदलता है जब lstrcopy कहा जाता है। जब किसी को भी बदल दिया जाता है, तो मान वही रहता है।

विंडोज 7 पर मेरे लिए काम करता है। उम्मीद है कि यह आपके लिए काम करता है!

+0

धन्यवाद, यह काम करता है: और मुझे लगता है कि आप रिटर्न प्रकार के रूप में एक पॉइंटर का उपयोग कर रहे हैं, लंबे समय तक पूर्णांक नहीं - लांग या लॉन्गलांग का उपयोग करके अन्य साइटों पर कोड है, जो तब तक ठीक काम करेगा जब तक यह नहीं होता है। –

0

जैसा कि यहाँ दिखाया वास्तव में कोड का प्रयोग करें।

कोड स्वयं मॉड्यूल में होना चाहिए।

इस तरह:

Option Explicit 

Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) _ 
    As Long 
Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As Long) _ 
    As Long 
Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, _ 
    ByVal dwBytes As Long) As Long 
Declare PtrSafe Function CloseClipboard Lib "User32"() As Long 
Declare PtrSafe Function OpenClipboard Lib "User32" (ByVal hwnd As Long) _ 
    As Long 
Declare PtrSafe Function EmptyClipboard Lib "User32"() As Long 
Declare PtrSafe Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, _ 
    ByVal lpString2 As Any) As Long 
Declare PtrSafe Function SetClipboardData Lib "User32" (ByVal wFormat _ 
    As Long, ByVal hMem As Long) As Long 

Public Const GHND = &H42 
Public Const CF_TEXT = 1 
Public Const MAXSIZE = 4096 

Function ClipBoard_SetData(MyString As String) 
    Dim hGlobalMemory As Long, lpGlobalMemory As Long 
    Dim hClipMemory As Long, X As Long 

    ' Allocate moveable global memory. 
    '------------------------------------------- 
    hGlobalMemory = GlobalAlloc(GHND, Len(MyString) + 1) 

    ' Lock the block to get a far pointer 
    ' to this memory. 
    lpGlobalMemory = GlobalLock(hGlobalMemory) 

    ' Copy the string to this global memory. 
    lpGlobalMemory = lstrcpy(lpGlobalMemory, MyString) 

    ' Unlock the memory. 
    If GlobalUnlock(hGlobalMemory) <> 0 Then 
     MsgBox "Could not unlock memory location. Copy aborted." 
     GoTo OutOfHere2 
    End If 

    ' Open the Clipboard to copy data to. 
    If OpenClipboard(0&) = 0 Then 
     MsgBox "Could not open the Clipboard. Copy aborted." 
     Exit Function 
    End If 

    ' Clear the Clipboard. 
    X = EmptyClipboard() 

    ' Copy the data to the Clipboard. 
    hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory) 

OutOfHere2: 

    If CloseClipboard() = 0 Then 
     MsgBox "Could not close Clipboard." 
    End If 

    End Function 
+0

यह कोड नहीं है 64-बिट एक्सेल 2013 में काम करें। कर्नेल 32 एपीआई घोषणाएं LongPtr नहीं हैं। ग्लोबल अनलॉक में यह त्रुटियां। प्रश्न के मुख्य भाग में मेरा कोड त्रुटि नहीं करता है और एपीआई 64-बिट के लिए घोषित किया जाता है। लेकिन कोशिश करने के लिए धन्यवाद। – Baodad

6

दूसरों के लिए पूर्ण कोड पोस्ट करना। परीक्षण किया गया और Excel 2007, 2010, 2013, 2016 और 64 बिट Excel 2013 सभी 32 बिट संस्करण विंडोज 10

'http://stackoverflow.com/questions/14738330/office-2013-excel-putinclipboard-is-different 
Option Explicit 
#If VBA7 Then 
    Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr 
    Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr 
    Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As LongPtr) As LongPtr 
    Declare PtrSafe Function CloseClipboard Lib "User32"() As Long 
    Declare PtrSafe Function OpenClipboard Lib "User32" (ByVal hwnd As LongPtr) As LongPtr 
    Declare PtrSafe Function EmptyClipboard Lib "User32"() As Long 
    Declare PtrSafe Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, ByVal lpString2 As Any) As LongPtr 
    Declare PtrSafe Function SetClipboardData Lib "User32" (ByVal wFormat As Long, ByVal hMem As LongPtr) As LongPtr 
#Else 
    Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long 
    Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long 
    Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long 
    Declare Function CloseClipboard Lib "User32"() As Long 
    Declare Function OpenClipboard Lib "User32" (ByVal hwnd As Long) As Long 
    Declare Function EmptyClipboard Lib "User32"() As Long 
    Declare Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long 
    Declare Function SetClipboardData Lib "User32" (ByVal wFormat As Long, ByVal hMem As Long) As Long 
#End If 

Public Const GHND = &H42 
Public Const CF_TEXT = 1 
Public Const MAXSIZE = 4096 

Function ClipBoard_SetData(MyString As String) 
    #If VBA7 Then 
     Dim hGlobalMemory As LongPtr, lpGlobalMemory As LongPtr, hClipMemory As LongPtr 
    #Else 
     Dim hGlobalMemory As Long, lpGlobalMemory As Long, hClipMemory As Long 
    #End If 
    Dim x As Long 
    ' Allocate moveable global memory. 
    '------------------------------------------- 
    hGlobalMemory = GlobalAlloc(GHND, Len(MyString) + 1) 

    ' Lock the block to get a far pointer 
    ' to this memory. 
    lpGlobalMemory = GlobalLock(hGlobalMemory) 

    ' Copy the string to this global memory. 
    lpGlobalMemory = lstrcpy(lpGlobalMemory, MyString) 

    ' Unlock the memory. 
    If GlobalUnlock(hGlobalMemory) <> 0 Then 
     MsgBox "Could not unlock memory location. Copy aborted. Please contact 14Fathoms." 
     GoTo OutOfHere2 
    End If 

    ' Open the Clipboard to copy data to. 
    If OpenClipboard(0&) = 0 Then 
     MsgBox "Could not open the Clipboard. Copy aborted. Please contact 14Fathoms." 
     Exit Function 
    End If 

    ' Clear the Clipboard. 
    x = EmptyClipboard() 

    ' Copy the data to the Clipboard. 
    hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory) 

OutOfHere2: 

    If CloseClipboard() = 0 Then 
     MsgBox "Could not close Clipboard. Please contact 14Fathoms." 
    End If 

End Function 
Sub TestCOPYPASTE() 
    Call ClipBoard_SetData("Hello World " & now()) 
    'Open notepad or in the immediate window and hit control-v 
End Sub