Làm sao lấy số dòng và số cột của vùng copy trong Excel (1 người xem)

  • Thread starter Thread starter vba_gpe
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

vba_gpe

Thành viên thường trực
Tham gia
15/12/10
Bài viết
296
Được thích
44
Nghề nghiệp
Thất nghiệp
Em có vấn đề này nhờ anh chị trong diễn đàn mình giúp đỡ
- Trong Excel, khi copy một vùng nào đó, Excel có biểu tượng đường gạch xung quanh vùng copy.
1. Làm sao mình biết được địa chỉ của vùng copy, số dòng, số cột của Vùng copy.
2. Nếu copy trên một file Excel khác thì làm sao xác định được những thông số trên nhỉ.
3. Trong dữ liệu Clipboard của Windows có cách nào phân biệt khi nào Clipboard ở dạng range khi nào là một định dạng khác không?
Em tìm trên diễn đàn cũng có một bài tương tự của A Tuân nhưng chưa thấy ai giải quyết xong.
Mong được sự giúp đỡ của mọi người.
Trân trọng
 
Em có vấn đề này nhờ anh chị trong diễn đàn mình giúp đỡ
- Trong Excel, khi copy một vùng nào đó, Excel có biểu tượng đường gạch xung quanh vùng copy.
1. Làm sao mình biết được địa chỉ của vùng copy, số dòng, số cột của Vùng copy.
2. Nếu copy trên một file Excel khác thì làm sao xác định được những thông số trên nhỉ.
3. Trong dữ liệu Clipboard của Windows có cách nào phân biệt khi nào Clipboard ở dạng range khi nào là một định dạng khác không?
Em tìm trên diễn đàn cũng có một bài tương tự của A Tuân nhưng chưa thấy ai giải quyết xong.
Mong được sự giúp đỡ của mọi người.
Trân trọng

"chưa thấy ai giải quyết xong" thì bây giờ siwtom giải quyết.
---------------
Giả sử ta chưa biết làm thế nào và ta đang tìm hướng đi.
Ta tư duy chút bạn nhé.
Bạn đã bao giờ copy vùng trên Excel rồi dán vào vd. WORD chưa? Khi bạn chọn trong WORD Paste Special thì bạn có nhiều lựa chọn: dán ở dạng text thường, text Unicode, RTF, Picture, Bitmap, HTML Format, Microsoft Office Excel Worksheet Object.

Như vậy rõ ràng khi bạn copy thì trong Clipboard dữ liệu được ghi ở rất nhiều dạng. Những dạng đó là những dạng nào? Tôi thử dùng hàm API EnumClipboardFormats và GetClipboardFormatName (dùng trong hàm ListClipboardFormats ở tập tin đính kèm) thì được những Format như sau (bạn có thể tự chạy code của ListClipboardFormats thì thấy):

Mã:
Format = 49161, FormatName = DataObject
Format = 14, FormatName = 
Format = 3, FormatName = 
Format = 2, FormatName = 
Format = 49644, FormatName = Biff12
Format = 49629, FormatName = Biff8
Format = 49631, FormatName = Biff5
Format = 4, FormatName = 
Format = 5, FormatName = 
Format = 49643, FormatName = XML Spreadsheet
Format = 49357, FormatName = HTML Format
Format = 13, FormatName = 
Format = 1, FormatName = 
Format = 49632, FormatName = Csv
Format = 49415, FormatName = Hyperlink
Format = 49404, FormatName = Rich Text Format
Format = 49163, FormatName = Embed Source
Format = 49156, FormatName = Native
Format = 49155, FormatName = OwnerLink
Format = 49166, FormatName = Object Descriptor
Format = 49165, FormatName = Link Source
Format = 49167, FormatName = Link Source Descriptor
Format = 49628, FormatName = Link
Format = 129, FormatName = 
Format = 49154, FormatName = ObjectLink
Format = 49171, FormatName = Ole Private Data
Format = 16, FormatName = 
Format = 7, FormatName = 
Format = 8, FormatName = 
Format = 17, FormatName =

Khi bạn đọc từ vd. "HTML Format" rồi ghi ra "hichic.html" thì bạn sẽ được một trang web có vỏn vẹn 1 table là vùng được copy

Tôi nhìn Format "ObjectLink" thấy có vẻ đầy hứa hẹn nên tôi thử đọc ra dữ liệu được ghi ở dạng này.

Tôi mở tập tin "máy tự động" của tôi. Tôi mở tập tin "c:\hichic.xls". Ở sheet1 tôi copy vùng E6:K8. Trở lại tập tin "máy tự động" tôi nhấn Button1 và trong cell A1 tôi có

Mã:
Excel.Sheet.8
C:\hichic.xls
Sheet1!R6C5:R8C11

3 đoạn được cách bởi vbCrLf, và ở cuối có 3 vbCrLf

Như thế là quá rõ rồi, đúng không? Vùng copy là R6C5:R8C11 = E6:K8, nằm ở sheet1 trong tập tin "C:\hichic.xls"
-----------
Mã:
'Private Const GMEM_MOVEABLE As Long = &H2
'Private Const GMEM_DDESHARE As Long = &H2000
'Private Const CF_UNICODETEXT = 13

Private Declare Function GetLastError Lib "kernel32" () As Long

Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetClipboardData Lib "user32.dll" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function EmptyClipboard Lib "user32.dll" () As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function EnumClipboardFormats Lib "user32" (ByVal wFormat As Long) As Long
Private Declare Function GetClipboardFormatName Lib "user32" Alias "GetClipboardFormatNameA" (ByVal wFormat As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long
Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long

Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)

Function ListClipboardFormats() As String
Dim format As Long, formatname As String, size As Long, res As String, hData As Long, pData As Long, m() As Byte, Text As String
    If OpenClipboard(0) = 0 Then Exit Function
    format = EnumClipboardFormats(0)
    Do While format > 0
        formatname = String(64, Chr(0))
        size = GetClipboardFormatName(format, formatname, 64)
        formatname = Left(formatname, size)
        res = res & "Format = " & format & ", FormatName = " & formatname & vbCrLf
    
        format = EnumClipboardFormats(format)
    Loop
    ListClipboardFormats = res
    CloseClipboard
    
    Range("A1").Value = res
End Function

Sub GetClipboardObjectLinkFormat()
Dim Text As String, format As Long, m() As Byte, hData As Long, pData As Long, size As Long
Dim formatname As String
On Error Resume Next
    If OpenClipboard(0) = 0 Then Exit Sub
    format = EnumClipboardFormats(0)
    Do While format > 0
        formatname = String(64, Chr(0))
        size = GetClipboardFormatName(format, formatname, 64)
        formatname = Left(formatname, size)
        
        If formatname = "ObjectLink" Then
'            trong ClipBoard coě Format - ObjectLink, vâňy ta đoňc Handle cuŇa Data
            hData = GetClipboardData(format)
            If hData = 0 Then MsgBox GetLastError
'            muôěn đoňc Data thiĚ trýőěc hęět phaŇi coě "điňa chiŇ" cuŇa Data trong RAM - đoňc ra băĚng haĚm GlobalLock
            pData = GlobalLock(hData)
'            đôň lőěn cuŇa Data đoňc ra băĚng haĚm GlobalSize
            size = GlobalSize(hData)
'            chuâŇn biň maŇng coě đôň lőěn thiěch hőňp đęŇ đoňc Data
            ReDim m(0 To size - 1)
'            cheěp toaĚn bôň Data vaĚo maŇng
            CopyMemory m(0), ByVal pData, size
'            cuôěi cuĚng laĚ UnLock
            GlobalUnlock hData
            
            Text = m
            
            Text = StrConv(Text, vbUnicode)
            Text = Replace(Text, Chr(0), vbCrLf)
            
            Range("A1").Value = Text
            Exit Do
        End If
        format = EnumClipboardFormats(format)
    Loop
    CloseClipboard
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn anh siwtom
Dùng code này có thể lấy được đầy đủ 3 thông tin Source của file copy, địa chỉ của vùng cần copy.
Em không rành về API vì vậy em mạn phép sử dụng code của anh để áp dụng luôn, sẽ tìm hiểu sau.
Mong sẽ học hỏi được nhiều từ anh.
Trân trọng
 
Upvote 0
Cảm ơn anh siwtom
Dùng code này có thể lấy được đầy đủ 3 thông tin Source của file copy, địa chỉ của vùng cần copy.
Em không rành về API vì vậy em mạn phép sử dụng code của anh để áp dụng luôn, sẽ tìm hiểu sau.
Mong sẽ học hỏi được nhiều từ anh.
Trân trọng

Nếu bạn thay dòng
Mã:
If formatname = "[B][COLOR=#ff0000]ObjectLink[/COLOR][/B]" Then

bằng
Mã:
If formatname = "[B][COLOR=#ff0000]Link[/COLOR][/B]" Then

thì trong A1 bạn có hơi khác:
Mã:
Excel
C:\[hichic.xls]Sheet1
R6C5:R8C11
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom