اذهب الي المحتوي
أوفيسنا

الردود الموصى بها

قام بنشر

السلام عليكم ورحمة الله وبركاته

الحمد لله والشكر لله 

الأخوة الكرام / حفظكم الله

أقدم لكم أكواد للتعامل مع الحافظة (Clipboard) للنواتين 32x و 64x

1- كود لنسخ ولصق النصوص

2- كود لنسخ ولصق الملفات بجميع أنوعها

------------------------------------------------------------------------------------------------------------------

1- كود لنسخ ولصق النصوص قم بعمل MODULE جديد ثم أنسخ الكود إليه

  * المصدر {https://www.devhut.net/vba-save-string-to-clipboard-get-string-from-clipboard/} وستجدون في هذا الموقع العديد من الاكواد الاحترافية.

   


Option Explicit

#If VBA7 Then
    Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
    Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
    Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
    Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
    Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
    Private Declare PtrSafe Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As LongPtr) As LongPtr

    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 Long
    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
#Else
    Private Declare Function CloseClipboard Lib "user32" () As Long
    Private Declare Function EmptyClipboard Lib "user32" () As Long
    Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
    Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
    Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As Long) As Long

    Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
    Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long

    Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyW" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long 'bug in Microsoft File!
#End If
Const CF_UNICODETEXT As Long = 13&

#If VBA7 Then
    Public Sub SetClipboard(sUniText As String)
        Dim iStrPtr         As LongPtr
        Dim iLen            As LongPtr
        Dim iLock           As LongPtr
        Dim iUnlock         As LongPtr
        Const GMEM_MOVEABLE As Long = &H2
        Const GMEM_ZEROINIT As Long = &H40
        'Const CF_UNICODETEXT As Long = &HD

        iLen = LenB(sUniText) + 2&
        iStrPtr = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, iLen)
        iLock = GlobalLock(iStrPtr)
        lstrcpy iLock, StrPtr(sUniText)
        GlobalUnlock iStrPtr

        OpenClipboard 0&
        EmptyClipboard
        SetClipboardData CF_UNICODETEXT, iStrPtr
        CloseClipboard
    End Sub

    Public Function GetClipboard() As String
        Dim iStrPtr         As LongPtr
        Dim iLen            As Long
        Dim iLock           As LongPtr
        Dim sUniText        As String
        'Const CF_UNICODETEXT As Long = 13&

        OpenClipboard 0&
        If IsClipboardFormatAvailable(CF_UNICODETEXT) Then
            iStrPtr = GetClipboardData(CF_UNICODETEXT)
            If iStrPtr Then
                iLock = GlobalLock(iStrPtr)
                iLen = GlobalSize(iStrPtr)
                sUniText = String$(iLen \ 2& - 1&, vbNullChar)
                lstrcpy StrPtr(sUniText), iLock
                GlobalUnlock iStrPtr
            End If
            GetClipboard = sUniText
        End If
        CloseClipboard
    End Function
#Else
    Public Sub SetClipboard(sUniText As String)
        Dim iStrPtr As Long
        Dim iLen As Long
        Dim iLock As Long
        Const GMEM_MOVEABLE As Long = &H2
        Const GMEM_ZEROINIT As Long = &H40
        'Const CF_UNICODETEXT As Long = &HD

        iLen = LenB(sUniText) + 2&
        iStrPtr = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, iLen)
        iLock = GlobalLock(iStrPtr)
        lstrcpy iLock, StrPtr(sUniText)
        GlobalUnlock iStrPtr

        OpenClipboard 0&
        EmptyClipboard
        SetClipboardData CF_UNICODETEXT, iStrPtr
        CloseClipboard
    End Sub

    Public Function GetClipboard() As String
        Dim iStrPtr As Long
        Dim iLen As Long
        Dim iLock As Long
        Dim sUniText As String
        'Const CF_UNICODETEXT As Long = 13&

        OpenClipboard 0&
        If IsClipboardFormatAvailable(CF_UNICODETEXT) Then
            iStrPtr = GetClipboardData(CF_UNICODETEXT)
            If iStrPtr Then
                iLock = GlobalLock(iStrPtr)
                iLen = GlobalSize(iStrPtr)
                sUniText = String$(iLen \ 2& - 1&, vbNullChar)
                lstrcpy StrPtr(sUniText), iLock
                GlobalUnlock iStrPtr
            End If
            GetClipboard = sUniText
        End If
        CloseClipboard
    End Function
#End If

مثال للاستخدام

حتي تنسخ نص الي الحافظة
Call SetClipboard(Me.txt_FirstName)

حتي تستخدم النص الموجود بالحافظة
Me.txt_FirstName = GetClipboard()

2- كود لنسخ ولصق الملفات بجميع أنوعها قم بعمل MODULE جديد ثم أنسخ الكود إليه

  وجدت كود يعمل علي 32X وقمت بتعديله "بفضل الله" ليدعم النواتين 32x و 64x

  * مصدر الكود يدعم 32x فقط {https://learn.microsoft.com/en-us/answers/questions/893207/copy-file-into-clipboard-for-excel-64bit}

Option Explicit

' Required data structures
Private Type POINTAPI
    x As Long
    y As Long
End Type

#If VBA7 Then
    ' Clipboard Manager Functions
    Private Declare PtrSafe Function EmptyClipboard Lib "user32" () 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 SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As LongPtr) As Long
    Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
    Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
    
    ' Other required Win32 APIs
    Private Declare PtrSafe Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop As LongPtr, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) As Long
    Private Declare PtrSafe Function DragQueryPoint Lib "shell32.dll" (ByVal hDrop As LongPtr, lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) 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 GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
    Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#Else
    ' Clipboard Manager Functions
    Private Declare Function EmptyClipboard Lib "user32" () As Long
    Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function CloseClipboard Lib "user32" () As Long
    Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
    Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
    Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
      
    ' Other required Win32 APIs
    Private Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop As Long, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) As Long
    Private Declare Function DragQueryPoint Lib "shell32.dll" (ByVal hDrop As Long, lpPoint As POINTAPI) As Long
    Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
    Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
      
#End If
' Predefined Clipboard Formats
Private Const CF_TEXT = 1
Private Const CF_BITMAP = 2
Private Const CF_METAFILEPICT = 3
Private Const CF_SYLK = 4
Private Const CF_DIF = 5
Private Const CF_TIFF = 6
Private Const CF_OEMTEXT = 7
Private Const CF_DIB = 8
Private Const CF_PALETTE = 9
Private Const CF_PENDATA = 10
Private Const CF_RIFF = 11
Private Const CF_WAVE = 12
Private Const CF_UNICODETEXT = 13
Private Const CF_ENHMETAFILE = 14
Private Const CF_HDROP = 15
Private Const CF_LOCALE = 16
Private Const CF_MAX = 17

' New shell-oriented clipboard formats
Private Const CFSTR_SHELLIDLIST As String = "Shell IDList Array"
Private Const CFSTR_SHELLIDLISTOFFSET As String = "Shell Object Offsets"
Private Const CFSTR_NETRESOURCES As String = "Net Resource"
Private Const CFSTR_FILEDESCRIPTOR As String = "FileGroupDescriptor"
Private Const CFSTR_FILECONTENTS As String = "FileContents"
Private Const CFSTR_FILENAME As String = "FileName"
Private Const CFSTR_PRINTERGROUP As String = "PrinterFriendlyName"
Private Const CFSTR_FILENAMEMAP As String = "FileNameMap"

' Global Memory Flags
Private Const GMEM_FIXED = &H0
Private Const GMEM_MOVEABLE = &H2
Private Const GMEM_NOCOMPACT = &H10
Private Const GMEM_NODISCARD = &H20
Private Const GMEM_ZEROINIT = &H40
Private Const GMEM_MODIFY = &H80
Private Const GMEM_DISCARDABLE = &H100
Private Const GMEM_NOT_BANKED = &H1000
Private Const GMEM_SHARE = &H2000
Private Const GMEM_DDESHARE = &H2000
Private Const GMEM_NOTIFY = &H4000
Private Const GMEM_LOWER = GMEM_NOT_BANKED
Private Const GMEM_VALID_FLAGS = &H7F72
Private Const GMEM_INVALID_HANDLE = &H8000
Private Const GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT)
Private Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)

Private Type DROPFILES
    #If VBA7 Then
        pFiles As LongPtr
    #Else
        pFiles As Long
    #End If
    
    pt As POINTAPI
    fNC As Long
    fWide As Long
End Type


Public Function ClipboardCopyFiles(Files() As String) As Boolean

    Dim data As String
    Dim df As DROPFILES
    #If VBA7 Then
        Dim hGlobal As LongPtr
        Dim lpGlobal As LongPtr
    #Else
        Dim hGlobal As Long
        Dim lpGlobal As Long
    #End If
    
    Dim i As Long

    ' Open and clear existing crud off clipboard.
    If OpenClipboard(0&) Then
        Call EmptyClipboard

        ' Build double-null terminated list of files.
        For i = LBound(Files) To UBound(Files)
            data = data & Files(i) & vbNullChar
        Next
        data = data & vbNullChar

        ' Allocate and get pointer to global memory,
        ' then copy file list to it.
        hGlobal = GlobalAlloc(GHND, Len(df) + Len(data))
        If hGlobal Then
            lpGlobal = GlobalLock(hGlobal)

            ' Build DROPFILES structure in global memory.
            df.pFiles = Len(df)
            Call CopyMem(ByVal lpGlobal, df, Len(df))
            Call CopyMem(ByVal (lpGlobal + Len(df)), ByVal data, Len(data))
            Call GlobalUnlock(hGlobal)

            ' Copy data to clipboard, and return success.
            If SetClipboardData(CF_HDROP, hGlobal) Then
                ClipboardCopyFiles = True
            End If
        End If

        ' Clean up
        Call CloseClipboard
    End If

End Function


Public Function ClipboardPasteFiles(Files() As String) As Long
    #If VBA7 Then
        Dim hDrop As LongPtr
    #Else
        Dim hDrop As Long
    #End If
    Dim nFiles As Long
    Dim i As Long
    Dim desc As String
    Dim filename As String
    Dim pt As POINTAPI
    Const MAX_PATH As Long = 260

    ' Insure desired format is there, and open clipboard.
    If IsClipboardFormatAvailable(CF_HDROP) Then
        If OpenClipboard(0&) Then

            ' Get handle to Dropped Filelist data, and number of files.
            hDrop = GetClipboardData(CF_HDROP)
            nFiles = DragQueryFile(hDrop, -1&, "", 0)

            ' Allocate space for return and working variables.
            ReDim Files(0 To nFiles - 1) As String
            filename = Space(MAX_PATH)

            ' Retrieve each filename in Dropped Filelist.
            For i = 0 To nFiles - 1
                Call DragQueryFile(hDrop, i, filename, Len(filename))
                Files(i) = TrimNull(filename)
            Next

            ' Clean up
            Call CloseClipboard
        End If

        ' Assign return value equal to number of files dropped.
        ClipboardPasteFiles = nFiles
    End If

End Function

Private Function TrimNull(ByVal sTmp As String) As String

    Dim nNul As Long

    '
    ' Truncate input sTmpg at first Null.
    ' If no Nulls, perform ordinary Trim.
    '
    nNul = InStr(sTmp, vbNullChar)
    Select Case nNul
        Case Is > 1
            TrimNull = Left(sTmp, nNul - 1)
        Case 1
            TrimNull = ""
        Case 0
            TrimNull = Trim(sTmp)
    End Select

End Function

Public Sub ClearClipboard()
    ' Open the clipboard
    If OpenClipboard(0&) Then
        ' Empty the clipboard
        Call EmptyClipboard
        ' Close the clipboard
        Call CloseClipboard
    End If
End Sub

 

مثال للاستخدام

لإضافة ملفات إلي الحافظة
يمكنك إضافة ملفات متنوعة من مسارات مختلفة
afile(2) الرقم 2 الموجود هنا يمثل إجمالي عدد الملفات - 1

Sub Test_CopyFilesToClipboard()
    
	Dim afile(2) As String
    
	afile(0) = "C:\Test\File1.jpg"
    afile(1) = "C:\Test\File2.pdf"
    afile(2) = "C:\Any\File3.xlsx"
    Debug.Print ClipboardCopyFiles(afile)

End Sub

 

بالتوفيق

 

  • Like 2
  • Thanks 2
قام بنشر (معدل)

بسم الله ،، ما شاء الله

تربت يداك على هذا الطرح الجميل ،

 

اسمح لي بسؤال صغير ، هل الحافظة Clipboard متعدد القيم في الحفظ مثل الحافظة مثلاً اللي في الجوال ؟؟

بمعنى آخر انه عند اللصق تستطيع اختيار احد النصوص التي تم نسخها إلى الحافظة !!!

 

وهل الفكرة شبيهة بكود النسخ

DoCmd.RunCommand acCmdCopy

وكود اللصق

DoCmd.RunCommand acCmdPaste

 

تم تعديل بواسطه Foksh
قام بنشر

الأخ الفاضل : @Foksh                                                            تحية طيبة وبعد ،،،

انا لست خبيراً حتي أجيب علي اسئلتك بشكل قاطع ولم أفهم السؤال بوضوح
ولكن أسمح لي بمشاركة ما لدي لعلك تجد ما يجيبك

     * https://flylib.com/books/en/4.460.1.29/1/

يوجد ملف بالمرفق به Class MODULE مع شرح أكثر وأمثلة للاستخدام ولكن لـ 32x فقط

أشكر لك تعليقك الجميل
وإذا استطعت أن توضح لي بمثال

حتي لو لم أكن أعرف الإجابة سأحول البحث عنها

بالتوفيق

SampleExcelClipboardFunctions.xls

قام بنشر

اخونا العزيز @Ahmos ، ما شاء الله عليك ، لا تقلل من شأن نفسك 🤗

 

مقصدي هو ان clipboard في الكود الذي ادرجته في مشاركتك ، هل يقوم بعمل نسخ لأكثر من نص والاحتفاظ بهذه النصوص التي تم نسخها في الحافظة ؟ وعند عملية اللصق تستطيع ان تختار النص الذي تريده من النصوص التي تم نسخها في الحافظة ؟؟

 

توضح السؤال ولا لأ !! 😅

  • Like 1
قام بنشر

1- الكود بصورته الحالية لا يمكنك من ذلك

الان انت تريد التعامل مع ذاكرة الحافظة بحيث تقوم مثلاً بـ 10 عمليات نسخ ثم تقوم باستدعاء ما تريد للـلصق

وهذا قد يكون متاح من خلال التعامل مع الـ Clipboard history التي أصبحت متاحة في ويندوز 10 و 11 لم أبحث الكيفية البرمجية بعد

يمكنك تفعيل الخاصية من هنا

image.png.4e3a01f28989a530c59e487fb998d64d.png

image.png.de3a77c07ff41e28f74f9ab0274d82d5.png

https://www.microsoft.com/en-us/windows/tips/clipboard-history

مثال علي سؤالك متاح الان في برامج الأوفيس يمكنك النسخ بحد أقصي 24 مرة وتظهر لك في قائمة خاصة 

المصدر : https://support.microsoft.com/en-us/office/copy-and-paste-using-the-office-clipboard-714a72af-1ad4-450f-8708-c2931e73ec8a

وإذا قمت بتفعيل خاصية الـ Clipboard history

فلن تحتاج الي التعامل مع الامر برمجياً

 

2- اما بخصوص سؤالك عن الشبة في طريقة العمل بـ

 

16 ساعات مضت, Foksh said:
DoCmd.RunCommand acCmdCopy
DoCmd.RunCommand acCmdPaste

 

فهنا تحتاج الي وسيط لنسخ ولصق البيانات
اما من خلال الكود فيمكنك تمرير ناتج برمجي مباشرة

إذا كنت بحاجة الي تطبيق فكرة يمكنك طرحها وسأحاول جاهداً المساعدة

بالتوفيق

قام بنشر
6 دقائق مضت, Ahmos said:

1- الكود بصورته الحالية لا يمكنك من ذلك

 

شكراً لك أخي على التوضيح ، وصلتني الإجابة هنا . وعليه فأن 

DoCmd.RunCommand acCmdCopy
DoCmd.RunCommand acCmdPaste

يقومان بالمهمة التي اريدها ، ومن جهة الوسيط ، فهل لك أن توضح المقصود به :smile:

  • Like 1
قام بنشر

أقصد انه لا يمكنك استخدامهم بدون تحديد شي لنسخة واخر للنسخ إليه
اما من خلال الكود يمكن تمرير القيم دون الحاجة لذلك

قام بنشر

اخي الكريم ، أشكر لك صبرك على اسئلتي .

عند التفكير في عملية النسخ للنصوص فإنه لا بد لك من مصدر وهدف لتحقيق الغاية ( المصدر النص المراد نسخه ، والهدف المكان المراد اللصق فيه ) هذا متفق عليه لا جدال فيه .

من خلال الكود ما الذي يختلف عن هذا الحديث ؟؟؟؟؟

14 دقائق مضت, Ahmos said:

اما من خلال الكود يمكن تمرير القيم دون الحاجة لذلك

 

  • Like 1
قام بنشر

مشاركة لعل فيها فائدة

لنسخ النصوص او الملفات

كود نسخ
SendKeys ("^(c)"), True

كود لصق
SendKeys ("^(v)"), True


كود نسخ ولصق ملفات
On Error Resume Next
filecopy "c:\firstfolder\db1.mdb","e:\secondfolder\db1.mdb"
if Err then
       msgbox "copy error"
end if

 

  • Like 2
قام بنشر

بالعكس العذر منك لان إجابتي لم تكن كافية من البداية

يتعامل برنامجي كثيراً مع قواعد بيانات علي الانترنت 

مثال : إذا كان لدي ارقام 10 أجهزة وأريد الاستعلام عنهم واحداً تلو الأخر

فاذا اردت استخدام 

DoCmd.RunCommand acCmdPaste

فيجب أولاً ان أجهز الوسيط textbox ومن ثم تحديده ولصق المحتوي ومن ثم عمل تحديث

ثم يمكنني التعامل مع المحتوي برمجياً

اما بالكود فمباشرة

dim sClip              as string
sClip = GetClipboard

ومن ثم يمكنك التعامل مع النص

وكذلك نتيجة الاستعلام التي سأحصل عليها

Call SetClipboard(sClip)

وهذه الطريقة سهلت علي كثيراً
لقد قمت بعمل اختصار Ctrl+Shift+V
وفي كل نموذج يقوم بمعالجة ونسخ البيانات من الحافظة الي الأماكن التي اريدها 

مثال أخر

إذا اردت استخدام قيمة داخل خلية في جدول ما
استطيع ان اضعها مباشرة داخل الحافظة

Call SetClipboard(Cstr(DLookup("CompanyName", "Company", "CompanyID = 874")))

 

لا تتردد في أي سؤال بل أرجو أن أكون أهلاً للإجابة

بالتوفيق

أخي الكريم @ابوخليل                        تحية طيبة وبعد ،،،

أسعدني مرورك وتعليقك ، بارك الله فيك

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

زائر
اضف رد علي هذا الموضوع....

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • تصفح هذا الموضوع مؤخراً   0 اعضاء متواجدين الان

    • لايوجد اعضاء مسجلون يتصفحون هذه الصفحه
×
×
  • اضف...

Important Information