Nhờ giúp đỡ lấy path của file/folder khi kéo thả file/folder vào userform!

Liên hệ QC

hodangbinh47

Thành viên mới
Tham gia
29/8/13
Bài viết
2
Được thích
0
Xin chào các anh chị GPE ạ, em có xem qua một video trên youtube và cũng đã google để tìm cách làm nhưng không có kết quả, em là newbie ạ

Có cách nào để mình drag folder vào trong file excel và nó sẽ trả kết quả là path của folder đó ạ. Em xin cám ơn.

Nếu bài viết có vấn đề vi phạm nội quy, xin Mod nhắc nhở ạ.

 
Xem tập tin. Kéo các tập tin và / hoặc thư mục lẫn lộn và thả vào Form.
 

File đính kèm

  • Book1.xlsm
    23.4 KB · Đọc: 16
  • DragAcceptFiles.xlsm
    30.4 KB · Đọc: 12
Upvote 0
Cám ơn anh đã giúp đỡ, với tập tin em đã update Declare statements với PtrSafe để chạy x64 ạ. Nhưng lại bị lỗi ở đoạn này ạ:


Mã:
Private Sub UserForm_Initialize()
    hWindow = FindWindow("ThunderDFrame", Me.Caption)
    DragAcceptFiles hWindow, 1
    lpPrevWndProc = SetWindowLong(hWindow, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Xin nhờ anh coi qua. Em cám ơn.
 

File đính kèm

  • Book1.xlsm
    20.8 KB · Đọc: 2
Upvote 0
Cám ơn anh đã giúp đỡ, với tập tin em đã update Declare statements với PtrSafe để chạy x64 ạ. Nhưng lại bị lỗi ở đoạn này ạ:


Mã:
Private Sub UserForm_Initialize()
    hWindow = FindWindow("ThunderDFrame", Me.Caption)
    DragAcceptFiles hWindow, 1
    lpPrevWndProc = SetWindowLong(hWindow, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Xin nhờ anh coi qua. Em cám ơn.
Tôi rất ngại thử, ngại dò, nhưng lại có sẵn tập tin khác nên tôi đính kèm luôn trong bài đầu của tôi.
Tập tin DragAcceptFiles.xlsm tôi hoàn thành sau đó, có khai báo lại đầy đủ và phục vụ các đường dẫn có ký tự tiếng Việt. Tôi cũng sắp xếp lại code để sao cho code trong UserForm đơn giản nhất. Code trong Form chỉ gọi sub từ module thôi.
Trong tập tin tôi có ghi hướng dẫn đầy đủ.
Bạn hãy tải tập tin DragAcceptFiles, thử nghiệm và cho biết kết quả nhé.
 
Upvote 0
Từ code của anh Batman1, mình test thì với Excel 32-bit thì chạy tốt nhưng để chạy chạy trên Windows 10 64-bit, Excel 64 bit thì cần chỉnh như sau:
Chỉnh sửa nhánh #VBA7, #WIN64:
SetWindowLongA thành SetWindowLongPtrA
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
thành
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr

Mã nguồn fix hoàn chỉnh đính kèm các bạn tải về:
 

File đính kèm

  • DragAcceptFiles32_64.xlsm
    26.1 KB · Đọc: 15
Upvote 0
Từ code của anh Batman1, mình test thì với Excel 32-bit thì chạy tốt nhưng để chạy chạy trên Windows 10 64-bit, Excel 64 bit thì cần chỉnh như sau:
Chỉnh sửa nhánh #VBA7, #WIN64:
SetWindowLongA thành SetWindowLongPtrA
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
thành
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr

Mã nguồn fix hoàn chỉnh đính kèm các bạn tải về:
Đúng là bây giờ nhìn lại mới thấy khai báo sai:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Nhưng bạn sửa lại vẫn chưa đúng.

Tôi chạy code đã sửa khai báo của bạn:

1. Trên Windows 10 64 bit + Excel 2007 32 bit thì không có lỗi. Cũng dễ hiểu vì Excel 2007 thì sẽ dùng SetWindowLong ở nhánh #Else nên không có lỗi.

2. Tôi chạy trên XP 32 bit + Excel 2010 32 bit thì có lỗi

xp.JPG

3. Tôi chạy trên Windows 8 32 bit + Excel 2013 32 bit thì có lỗi

win8.jpg

Ở điểm 2 và 3 (VBA7) thì dùng SetWindowLong ở nhánh #If VBA7 Then, và có lỗi.

Tôi đề nghị những ai có office 64 thử như sau:

Thay
Mã:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
trong khai báo của Tuân bằng
Mã:
#If Win64 Then
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
 
Upvote 0
Có một sơ suất mình upload file của bản chưa cập nhật phần chỉnh tương thích môi trường 32-bit mặc dù bản chính thức đã sửa. Bác Batman1 báo lại mình mới kiểm tra lại file upload là lỗi. Các bạn tải lại file trong bài này nhé.
 

File đính kèm

  • DragAcceptFiles32_64.xlsm
    28.8 KB · Đọc: 20
Upvote 0
Đúng là bây giờ nhìn lại mới thấy khai báo sai:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Nhưng bạn sửa lại vẫn chưa đúng.

Tôi chạy code đã sửa khai báo của bạn:

1. Trên Windows 10 64 bit + Excel 2007 32 bit thì không có lỗi. Cũng dễ hiểu vì Excel 2007 thì sẽ dùng SetWindowLong ở nhánh #Else nên không có lỗi.

2. Tôi chạy trên XP 32 bit + Excel 2010 32 bit thì có lỗi

View attachment 231453

3. Tôi chạy trên Windows 8 32 bit + Excel 2013 32 bit thì có lỗi

View attachment 231454

Ở điểm 2 và 3 (VBA7) thì dùng SetWindowLong ở nhánh #If VBA7 Then, và có lỗi.

Tôi đề nghị những ai có office 64 thử như sau:

Thay
Mã:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
trong khai báo của Tuân bằng
Mã:
#If Win64 Then
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
Liên quan tới api cho cháu hỏi một chút, một số api nhận tham số từ ngăn xếp, một số lại nhận tham số theo dạng thanh ghi eax, ecx... gì gì đấy. Vậy hai loại này khác nhau ở đâu, và làm sao vba nó biết cái api thuộc loại nào để nó gọi cho phù hợp.
 
Upvote 0
Liên quan tới api cho cháu hỏi một chút, một số api nhận tham số từ ngăn xếp, một số lại nhận tham số theo dạng thanh ghi eax, ecx... gì gì đấy. Vậy hai loại này khác nhau ở đâu, và làm sao vba nó biết cái api thuộc loại nào để nó gọi cho phù hợp.
eax, ecx thì đi với asembler chứ liên quan gì tới API?

Còn về ý bạn thì tôi không hiểu. Nói 1 câu có quá ngắn không? Bạn muốn hỏi gì thì lấy ví dụ cụ thể để người khác hiểu, bạn muốn hỏi gì.
 
Upvote 0
eax, ecx thì đi với asembler chứ liên quan gì tới API?

Còn về ý bạn thì tôi không hiểu. Nói 1 câu có quá ngắn không? Bạn muốn hỏi gì thì lấy ví dụ cụ thể để người khác hiểu, bạn muốn hỏi gì.
Cháu đang muốn nói tới calling conventions đó bác. Trong khai báo api với vba cháu không thấy có cái từ khóa nào liên quan tới calling conventions, phải chăng vba nó tự đoán được calling conventions của api để gọi cho phù hợp?
 
Upvote 0
Cháu đang muốn nói tới calling conventions đó bác. Trong khai báo api với vba cháu không thấy có cái từ khóa nào liên quan tới calling conventions, phải chăng vba nó tự đoán được calling conventions của api để gọi cho phù hợp?
Tôi không dám chắc là hiểu ý bạn nhưng VBA hay vd. Delphi thì cũng thế thôi. Ở những chỗ gọi hàm sẽ có những bước nhẩy tới địa chỉ của hàm ở trong RAM. Bạn mở một công cụ nào đấy rồi xem code ở chỗ ấy chỗ ấy của hàm XYZ trong thư viện ABC thì bạn sẽ thấy nó như thế nào. Người ta là những người thuộc đẳng cấp viết được compiler, biết asembler thì dĩ nhiên người ta sẽ tường tận nó phải như thế nào. Việc của bạn đâu phải lo những chuyện ấy. Còn nếu muốn thỏa sự tò mò thì tìm đọc thôi. Tôi không đi sâu về những vấn đề đó.
 
Upvote 0
Lộn thuốc tẹo bác ơi, cháu bị nhầm về việc gọi api với việc gọi một thành viên được tham chiếu, hihi!
 
Upvote 0
Web KT
Back
Top Bottom