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

Ahmos

عضو جديد 01
  • Posts

    14
  • تاريخ الانضمام

  • تاريخ اخر زياره

مشاركات المكتوبه بواسطه Ahmos

  1. في فكرة تانية جت فدماغي
    دلوقتي ان شاء الله الفكرة دي هتضمنلك نتيجة 100% بإذن الله

    1- عايزين نحذف ما قبل اسم الكتاب وما بعد الرقم
    2- الجزء المتبقي معانا هيبقي فيه احتمالين

    - ان يكون في اسم كتاب تاني

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

    يبقي احنا دلوقتي هنروح نضيف اسماء الكتب في كولكشين ونمنع التقرار
    وبعدين نعمل لوب كولكشين دي جوة نتيجة البحث اذ كان في حاجه فيهم موجودة بين اسم الكتاب والرقم معنا كدا ان الرقم ده خاص بالكتاب اللي موجود في الكولكشين فنستبعد النتيجة دي

     

    إن شاء الله هتظبط وهتدعيلي

    • Thanks 1
  2. دلوقتي عملت تعديل
    بعد حذف الجزء ما قبل اسم الكتب والبحث عن الرقم في الجزء المتبقي
    ظهرت الحالة التالية

    image.png.c08fde2c0e315ce3113e60ffe483bef7.png

    فمحاولتي الان هي ان يتم التميز بين النتائج واختيار الرقم الأقرب لأسم الكتاب

    هذه هي الفكرة التي أعمل عليها الان حتي نتأكد من اختيار الناتج الصحيح

    ولكن عندي سؤال

    هل دائماً نبحث عن الرقم لو قد نبحث عن 73/2 

     

     

  3. بعد مراجعة هذا الجزء مرة أخرى

    اقتباس

    لذلك لا بد من البحث عن الرقم بعد اسم الكتاب وما قبله لا اعتبار له

    لذلك انا عندما كنت أجري التجارب الأولية -لكوني أعشق التجارب- خطر على بالي إعداد نص خاص للبحث يحذف كل النص الذي قبل اسم الكتاب المطلوب ليكون البحث فيما بعده، وهذا يقتضي أن أعد نصا خاصا لكل اسم كتاب .. وهذا حل غير عملي بالطبع 😁

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

    Public Function cutString(ByVal fullText As String, _
                                ByVal cutBy As String, _
                                Optional ByVal lrSide As String = "leftSide") As String
                                
        On Error GoTo ErrorHandler
        
        If fullText = "" Then
            'Debug.Print "Error: fullText is empty"
            cutString = ""
            Exit Function
        End If
        
        If cutBy = "" Then
            'Debug.Print "Error: cutBy is empty"
            cutString = fullText
            Exit Function
        End If
        
        If Len(cutBy) > Len(fullText) Then
            'Debug.Print "Error: cutBy is longer than fullText"
            cutString = fullText
            Exit Function
        End If
        
    
        Select Case LCase(lrSide)
            Case "leftside", "rightside"
                
            Case Else
                'Debug.Print "Warning: Invalid lrSide value '" & lrSide & "'. Using default 'leftSide'."
                lrSide = "leftSide"
        End Select
        
    
        Dim position As Long
        position = InStr(1, fullText, cutBy, vbTextCompare)
        
        If position > 0 Then
            Select Case LCase(lrSide)
                Case "leftside"
                    cutString = Mid(fullText, position)
                    'Debug.Print "Info: Returning left side from '" & cutBy & "'"
                Case "rightside"
                    cutString = Left(fullText, position + Len(cutBy) - 1)
                    'Debug.Print "Info: Returning right side up to '" & cutBy & "'"
            End Select
        Else
            'Debug.Print "Warning: '" & cutBy & "' not found in fullText. Returning original string."
            cutString = fullText
        End If
    
    ExitFunction:
        Exit Function
    
    ErrorHandler:
        Select Case Err.Number
            Case 13 ' Type mismatch
                Debug.Print "Error 13: Type mismatch. Ensure all arguments are strings."
            Case 5  ' Invalid procedure call or argument
                Debug.Print "Error 5: Invalid argument. Check the function call."
            Case Else
                Debug.Print "Unexpected Error " & Err.Number & ": " & Err.Description
        End Select
        cutString = fullText
        Resume ExitFunction
    End Function

    ويمكن استخدامها مباشرةً
    باستبدال هذا الجزء من الكود
     

    sqlStr = "SELECT TAB.MNO, TAB.NASS " & _
                            "FROM TAB " & _
                            "WHERE TAB.NASS LIKE '*" & Nz(!BookName, "") & "*' " & _
                            "AND InStr(cutString([NASS],'" & Trim(!BookName) & "','leftSide'),'" & Nz(!B_Hno, "") & "') > 0;"

    ولكن زاد وقت المعالجة
    إلي 
    It Takes | 661MS | To resolve | 21 | Records.

     

     

    لقد كنت أجهز للمشاركة ولم اري ردك
    شوف اقم بالتجربة
    وسأنتظر ردك بعد تجربة الوظيفة والاضافة الجديدة

    • Thanks 1
  4. بالنسبة لرسالة الخطأ الاولي
    فيمكن حلها بأكثر من طريقة

    استبدل الكود

    tabRS.MoveLast
                    tabRS.MoveFirst

    بهذا

     

    On Error Resume Next
                    tabRS.MoveLast
                    tabRS.MoveFirst
                    On Error GoTo 0

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

    في حال كان هناك أكثر من ناتج اقم بتحديد موقع الرقم ومن ثم اذهب الي الوراء حتي اجد اول الرقم ومن ثم اذهب للأمام حتي اجد اخر الرقم
    وذلك حتي نتمكن من استخراج الرقم ومقارنته بالرقم الأصلي فاذا تطابق  نعتمد هذا الناتج وذلك حتي نستطيع التمييز بين 312 و 1312

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

    • Thanks 1
  5. أرجو لك من الله التوفيق

    وبانتظار نتائج تجاربك

    لقد قمت بالتعديل علي الملف الأخير الذي قمت بمشاركته

    1- اضفت موديول لحساب الوقت حتي تتمكن من حساب وقت العملية

    2- قمت بالتطبيق علي الكود ( It Takes | 14MS | To resolve | 21 | Records. )

    3- قمت بتعديل (

    Dim totalRec        As String

    ) إلي (

    Dim totalRec        As Long

    )

    النسخة بالمرفقات

    والأكواد المعدلة في أخر الموضوع

    كما أود الإشارة الي هذا السطر في الكود

    If totalRec Mod 1000 = 0 Then DoEvents

    وظيفته بشكل مختصر هي توقف تنفيذ الكود كل 1000 سجل حتي يتمكن البرنامج من التحرر وتلقي التحديثات ويحد من مشكلة عدم الاستجابة "Not Responding"

    لذا يمكنك التعديل علي الرقم 1000 بما يتناسب مع استخدامك مع الاخذ في الاعتبار ان هذا يؤثر علي الوقت الإجمالي للعملية
    يوجد فيديوهات تشرح الامر بالتفصيل ( 

    كما يمكنك الاطلاع علي الرابط التالي

    https://wellsr.com/vba/2018/excel/vba-doevents-and-when-to-use-it/
     

    1- Timer Class MODULE ATTACHED

    2- الكود بعد التعديل وتطبيق استخدام (Timer Class MODULE)

    Public Sub mnoSmartSearch()
    
        Dim db              As DAO.Database
        Dim rs              As DAO.Recordset
        Dim tabRS           As DAO.Recordset
        Dim tblName         As String
        Dim sqlStr          As String
        Dim foundMno        As String
        Dim exNum           As String
        Dim stext           As String
        Dim totalRec        As Long
        Dim sPos            As Long
        Dim startPos        As Long
        Dim endPos          As Long
        Dim i               As Long
        Dim sTimer          As ahmosTimer
        Dim itTakes         As String
        
        
        tblName = "BOOKS"
        
        If DCount("*", tblName) = 0 Then
            MsgBox "There are no records in the table " & tblName, vbExclamation + vbOKOnly, "No Records Exist Error"
            Exit Sub
        End If
        
        Set sTimer = New ahmosTimer
        sTimer.StartTimer
        
        Set db = CurrentDb
    
        Set rs = db.OpenRecordset(tblName, dbOpenDynaset)
        With rs
            .MoveLast
            .MoveFirst
            totalRec = .RecordCount
            Do While Not .EOF
                sqlStr = ""
                foundMno = ""
                If Not IsNull(!BookName) And Not IsNull(!B_Hno) Then
                    sqlStr = "SELECT TAB.MNO, TAB.NASS " & _
                            "FROM TAB " & _
                            "WHERE TAB.NASS LIKE '*" & Nz(!BookName, "") & "*' " & _
                            "AND InStr([NASS],'" & Nz(!B_Hno, "") & "') > 0;"
                    Set tabRS = db.OpenRecordset(sqlStr, dbOpenSnapshot)
                    tabRS.MoveLast
                    tabRS.MoveFirst
                    If tabRS.RecordCount = 0 Then
                        ' No Results found
                        Debug.Print "NotFound", !BookName, !B_Hno
                    ElseIf tabRS.RecordCount = 1 Then
                        ' One Result Found and that what we want
                        foundMno = Nz(tabRS!MNO, "")
                        If foundMno <> "" Then
                            .Edit
                            !MNO = foundMno
                            .Update
                        End If
                    Else
                        ' more than one record found and that shouldn't happen
    '                    Debug.Print "Found Times is : " & tabRS.RecordCount, rs!BookName, rs!B_Hno
                        Do While Not tabRS.EOF
                            sPos = 0
                            i = 0
                            startPos = 0
                            endPos = 0
                            exNum = ""
                            stext = ""
                            
                            stext = tabRS!NASS
                            sPos = InStr(1, stext, rs!B_Hno)
                            
                            i = sPos
                            Do While i > 0 And IsNumeric(Mid(stext, i, 1))
                                i = i - 1
                            Loop
                            startPos = i + 1
                            
                            ' Move forward to find the end of the number
                            i = sPos
                            Do While i <= Len(stext) And IsNumeric(Mid(stext, i, 1))
                                i = i + 1
                            Loop
                            endPos = i - 1
                            
                            exNum = Mid(stext, startPos, endPos - startPos + 1)
                        
                            If rs!B_Hno = exNum Then
                                .Edit
                                !MNO = Nz(tabRS!MNO, "")
                                .Update
                                Exit Do
                            End If
                        tabRS.MoveNext
                        Loop
                    End If
    
                    If Not tabRS Is Nothing Then
                        tabRS.Close
                        Set tabRS = Nothing
                    End If
    
                Else
                    ' BookName or B_Hno are Empty
                    Debug.Print "BookName or B_Hno are Empty"
                End If
            
            .MoveNext
        If totalRec Mod 1000 = 0 Then DoEvents
        Loop
        End With
        If Not rs Is Nothing Then
            rs.Close
            Set rs = Nothing
        End If
        If Not db Is Nothing Then Set db = Nothing
        
        sTimer.StopTimer
        itTakes = sTimer.GetElapsedTime
        If Not sTimer Is Nothing Then Set sTimer = Nothing
    
        Debug.Print "It Takes | " & itTakes & " | To resolve | " & totalRec & " | Records."
    End Sub

     

    Smart_Search03_byAhmos.accdb ahmosTimer.zip

    • Thanks 1
  6. السلام عليكم ورحمة الله وبركاته

    صبحكم الله بالخير والنور والسرور
    بارك الله فيكم وفي جهودكم الطيبة
    أخي الكريم جرب هذا الكود "إن شاء الله يعمل معك"
    عند التطبيق وجدت اختلاف في قيمة واحدة وهي بالصورة التالية:

    image.png.1c845d12df39cf39d04c6aa68c5af209.png

    Public Sub mnoSmartSearch()
    
        Dim db              As DAO.Database
        Dim rs              As DAO.Recordset
        Dim tabRS           As DAO.Recordset
        Dim sqlStr          As String
        Dim tblName         As String
        Dim foundMno        As String
        Dim totalRec        As String
        Dim exNum           As String
        Dim stext           As String
        Dim sPos            As Long
        Dim startPos        As Long
        Dim endPos          As Long
        Dim i               As Long
        
        tblName = "BOOKS"
        
        If DCount("*", tblName) = 0 Then
            MsgBox "There are no records in the table " & tblName, vbExclamation + vbOKOnly, "No Records Exist Error"
            Exit Sub
        End If
        
        Set db = CurrentDb
    
        Set rs = db.OpenRecordset(tblName, dbOpenDynaset)
        With rs
            .MoveLast
            .MoveFirst
            totalRec = .RecordCount
            Do While Not .EOF
                sqlStr = ""
                foundMno = ""
                If Not IsNull(!BookName) And Not IsNull(!B_Hno) Then
                    sqlStr = "SELECT TAB.MNO, TAB.NASS " & _
                            "FROM TAB " & _
                            "WHERE TAB.NASS LIKE '*" & Nz(!BookName, "") & "*' " & _
                            "AND InStr([NASS],'" & Nz(!B_Hno, "") & "') > 0;"
                    Set tabRS = db.OpenRecordset(sqlStr, dbOpenSnapshot)
                    tabRS.MoveLast
                    tabRS.MoveFirst
                    If tabRS.RecordCount = 0 Then
                        ' No Results found
                        Debug.Print "NotFound", !BookName, !B_Hno
                    ElseIf tabRS.RecordCount = 1 Then
                        ' One Result Found and that what we want
                        foundMno = Nz(tabRS!MNO, "")
                        If foundMno <> "" Then
                            .Edit
                            !MNO = foundMno
                            .Update
                        End If
                    Else
                        ' more than one record found and that shouldn't happen
    '                    Debug.Print "Found Times is : " & tabRS.RecordCount, rs!BookName, rs!B_Hno
                        Do While Not tabRS.EOF
                            sPos = 0
                            i = 0
                            startPos = 0
                            endPos = 0
                            exNum = ""
                            stext = ""
                            
                            stext = tabRS!NASS
                            sPos = InStr(1, stext, rs!B_Hno)
                            
                            i = sPos
                            Do While i > 0 And IsNumeric(Mid(stext, i, 1))
                                i = i - 1
                            Loop
                            startPos = i + 1
                            
                            ' Move forward to find the end of the number
                            i = sPos
                            Do While i <= Len(stext) And IsNumeric(Mid(stext, i, 1))
                                i = i + 1
                            Loop
                            endPos = i - 1
                            
                            exNum = Mid(stext, startPos, endPos - startPos + 1)
                        
                            If rs!B_Hno = exNum Then
                                .Edit
                                !MNO = Nz(tabRS!MNO, "")
                                .Update
                                Exit Do
                            End If
                        tabRS.MoveNext
                        Loop
                    End If
    
                    If Not tabRS Is Nothing Then
                        tabRS.Close
                        Set tabRS = Nothing
                    End If
    
                Else
                    ' BookName or B_Hno are Empty
                    Debug.Print "BookName or B_Hno are Empty"
                End If
            
            .MoveNext
        If totalRec Mod 1000 = 0 Then DoEvents
        Loop
        End With
        If Not rs Is Nothing Then
            rs.Close
            Set rs = Nothing
        End If
        If Not db Is Nothing Then Set db = Nothing
    End Sub

     

    • Like 2
  7. بالعكس العذر منك لان إجابتي لم تكن كافية من البداية

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

    مثال : إذا كان لدي ارقام 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")))

     

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

    بالتوفيق

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

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

  8. 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

     

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

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

    بالتوفيق

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

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

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

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

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

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

    بالتوفيق

    SampleExcelClipboardFunctions.xls

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

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

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

    أقدم لكم أكواد للتعامل مع الحافظة (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
×
×
  • اضف...

Important Information