thang_nguyen1
Thành viên hoạt động



- Tham gia
- 6/10/16
- Bài viết
- 136
- Được thích
- 8
Mọi người giúp mình với ạChào các bạn. Cho mình hỏi có thể dùng VBA chuyển hỉnh ảnh từ File Excel lên form được không? Mong các bạn giúp mình với. Mình xin cảm ơn!
Chèn đoạn code này vào Module.Chào các bạn. Cho mình hỏi có thể dùng VBA chuyển hỉnh ảnh từ File Excel lên form được không? Mong các bạn giúp mình với. Mình xin cảm ơn!
Option Explicit
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
#If VBA7 Then
Private Type uPicDesc
Size As Long
Type As Long
hPic As LongPtr
hPal As LongPtr
End Type
Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As LongPtr
Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32" (PicDesc As uPicDesc, _
RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Declare PtrSafe Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As LongPtr, ByVal lpszFile As String) As LongPtr
Private Declare PtrSafe Function CopyImage Lib "user32" (ByVal Handle As LongPtr, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As LongPtr
#Else
Private Type uPicDesc
Size As Long
Type As Long
hPic As Long
hPal As Long
End Type
Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, _
RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long
Private Declare Function CopyImage Lib "user32" (ByVal Handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
#End If
Function PictureFromObject(ByVal Target As Object, Optional ByVal bType As Boolean = True) As IPictureDisp
#If VBA7 Then
Dim hPtr As LongPtr, hCopy As LongPtr
#Else
Dim hPtr As Long, hCopy As Long
#End If
Dim PicType As Long
Const CF_BITMAP = 2
Const CF_PALETTE = 9
Const CF_ENHMETAFILE = 14
Const IMAGE_BITMAP = 0
Const LR_COPYRETURNORG = &H4
Const PicType_BITMAP = 1
Const PicType_ENHMETAFILE = 4
Target.CopyPicture , IIf(bType, xlBitmap, xlPicture)
PicType = IIf(IsClipboardFormatAvailable(CF_BITMAP) <> 0, CF_BITMAP, CF_ENHMETAFILE)
If IsClipboardFormatAvailable(PicType) <> 0 Then
If OpenClipboard(0) > 0 Then
hPtr = GetClipboardData(PicType)
If PicType = CF_BITMAP Then
hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)
Else
hCopy = CopyEnhMetaFile(hPtr, vbNullString)
End If
CloseClipboard
If hPtr <> 0 Then
Dim uPicInfo As uPicDesc, IID_IDispatch As GUID, IPic As IPictureDisp
With IID_IDispatch
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With
With uPicInfo
.Size = Len(uPicInfo)
.Type = IIf(PicType = CF_BITMAP, PicType_BITMAP, PicType_ENHMETAFILE)
.hPic = hCopy
End With
OleCreatePictureIndirect uPicInfo, IID_IDispatch, True, IPic
Set PictureFromObject = IPic
End If
End If
End If
End Function
Private Sub UserForm_Initialize()
Image1.Picture = PictureFromObject(Sheets("sheet1").Shapes("Picture 2"))
End Sub
Cảm ơn bạn. Cho mình hỏi thêm nếu mà nhiều ảnh khác nhau thì có show được lên không ạ?Chèn đoạn code này vào Module.
Tiếp theo thêm đoạn code này vào UserForm.Mã:Option Explicit Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type #If VBA7 Then Private Type uPicDesc Size As Long Type As Long hPic As LongPtr hPal As LongPtr End Type Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As LongPtr Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32" (PicDesc As uPicDesc, _ RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long Private Declare PtrSafe Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As LongPtr, ByVal lpszFile As String) As LongPtr Private Declare PtrSafe Function CopyImage Lib "user32" (ByVal Handle As LongPtr, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As LongPtr #Else Private Type uPicDesc Size As Long Type As Long hPic As Long hPal As Long End Type Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, _ RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long Private Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long Private Declare Function CopyImage Lib "user32" (ByVal Handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long #End If Function PictureFromObject(ByVal Target As Object, Optional ByVal bType As Boolean = True) As IPictureDisp #If VBA7 Then Dim hPtr As LongPtr, hCopy As LongPtr #Else Dim hPtr As Long, hCopy As Long #End If Dim PicType As Long Const CF_BITMAP = 2 Const CF_PALETTE = 9 Const CF_ENHMETAFILE = 14 Const IMAGE_BITMAP = 0 Const LR_COPYRETURNORG = &H4 Const PicType_BITMAP = 1 Const PicType_ENHMETAFILE = 4 Target.CopyPicture , IIf(bType, xlBitmap, xlPicture) PicType = IIf(IsClipboardFormatAvailable(CF_BITMAP) <> 0, CF_BITMAP, CF_ENHMETAFILE) If IsClipboardFormatAvailable(PicType) <> 0 Then If OpenClipboard(0) > 0 Then hPtr = GetClipboardData(PicType) If PicType = CF_BITMAP Then hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG) Else hCopy = CopyEnhMetaFile(hPtr, vbNullString) End If CloseClipboard If hPtr <> 0 Then Dim uPicInfo As uPicDesc, IID_IDispatch As GUID, IPic As IPictureDisp With IID_IDispatch .Data1 = &H7BF80980 .Data2 = &HBF32 .Data3 = &H101A .Data4(0) = &H8B .Data4(1) = &HBB .Data4(2) = &H0 .Data4(3) = &HAA .Data4(4) = &H0 .Data4(5) = &H30 .Data4(6) = &HC .Data4(7) = &HAB End With With uPicInfo .Size = Len(uPicInfo) .Type = IIf(PicType = CF_BITMAP, PicType_BITMAP, PicType_ENHMETAFILE) .hPic = hCopy End With OleCreatePictureIndirect uPicInfo, IID_IDispatch, True, IPic Set PictureFromObject = IPic End If End If End If End Function
Việc còn lại là cho UserForm nó Show lên.Mã:Private Sub UserForm_Initialize() Image1.Picture = PictureFromObject(Sheets("sheet1").Shapes("Picture 2")) End Sub
Mình hiện đã làm được cái này rồi. Mình muốn hỏi là khi mình bấm chuột vào ảnh nào thì ảnh trên form hiện theo ảnh mình bấm chuột không? Có giải pháp nào cho vấn đề này không?Cảm ơn bạn. Cho mình hỏi thêm nếu mà nhiều ảnh khác nhau thì có show được lên không ạ?
Cho mình hỏi là có cách nào tên "Picture" trên Textbox nó nhảy luôn theo hình ảnh mà ko dùng combobox được không?Thử cách này xem thế nào?
Ý bạn là xoá nó đi luôn như này ạ?Cho mình hỏi là có cách nào tên "Picture" trên Textbox nó nhảy luôn theo hình ảnh mà ko dùng combobox được không?
Ý mình là click vào "picture 1" hiện form. Rồi kích "picture 2" ở sheet thì form nó load theo hình "picture 2 " luôn. Nhưng điều này chắc hơi khóÝ bạn là xoá nó đi luôn như này ạ?
![]()
là như này đúng không ạ?Ý mình là click vào "picture 1" hiện form. Rồi kích "picture 2" ở sheet thì form nó load theo hình "picture 2 " luôn. Nhưng điều này chắc hơi khó
Sub ClickMe()
Unload PicFrm
PicFrm.Show False
End Sub
Rất cảm ơn bạn. Mình muốn làm cái add-in thì có được không nhỉ. Vì đây đưa macro trực tiếp vào ảnhlà như này đúng không ạ?
![]()
Bạn có thể tham khảo việc thêm code sau ạ!
Mã:Sub ClickMe() Unload PicFrm PicFrm.Show False End Sub
Mình nghĩ chắc là được á.Rất cảm ơn bạn. Mình muốn làm cái add-in thì có được không nhỉ. Vì đây đưa macro trực tiếp vào ảnh
Hoàn toàn làm được việc tạo Add-Ins, nhưng sẽ có nhiều vấn đề phức tạp phát sinh. Việc cơ bản là vẫn phải gắn Assign Macro cho Shape, việc này vẫn tự động được, nhưng khi mang file sang máy khác sẽ bị dính lỗi không có mang Add-ins theo, vã lại khi tự động thì sẽ gây khó khăn khi có nhu cầu thay đổi kích thước hình, di chuyển hình,... Còn nhiều thức phức tạp khác.Rất cảm ơn bạn. Mình muốn làm cái add-in thì có được không nhỉ. Vì đây đưa macro trực tiếp vào ảnh
Em nghĩ là khi bạn ấy tạo add-in là muốn xem popup hình trên 1 file bình thường (.xlsx) bất kỳ. Khi bật add-in thì có thêm tính năng click vào hình để xem.Hoàn toàn làm được việc tạo Add-Ins, nhưng sẽ có nhiều vấn đề phức tạp phát sinh. Việc cơ bản là vẫn phải gắn Assign Macro cho Shape, việc này vẫn tự động được, nhưng khi mang file sang máy khác sẽ bị dính lỗi không có mang Add-ins theo, vã lại khi tự động thì sẽ gây khó khăn khi có nhu cầu thay đổi kích thước hình, di chuyển hình,... Còn nhiều thức phức tạp khác.
Em vừa thử cách này thì không được nó báo như hình sau ạ!Em nghĩ là khi bạn ấy tạo add-in là muốn xem popup hình trên 1 file bình thường (.xlsx) bất kỳ. Khi bật add-in thì có thêm tính năng click vào hình để xem.
Ý tưởng là:
Trong add-in Chạy một đoạn mã tự động gán OnAction = "ClickMe" cho mọi ảnh trong ActiveSheet, trong đó thì ClickMe được lấy từ trong add-in ra. Có thể là OnAction = "'" & addInName & "'!" & macroName
Bạn viết sao thì tui không biết chứ tui viết chạy phát ngon cành đào. Còn vụ Add-Ins thì bạn nghĩ quá đơn giản, đụng thử vô đi sẽ thấy vấn đề phát sinh ngay, còn vấn đề gì thì bạn có thể thử suy nghĩ xâu hơn chút ví dụ đóng file mà không lưu, đóng file mà lưu, trên sheet có những shape trang trí, áp dụng cho file này còn file kia (đang mở) tính sao,... Thôi tui xin kết thúc vấn đề ở chủ đề này vì có lẽ cái mà chủ thớt cần đã được giải quyết, còn vụ Add-Ins là phát sinh không phù hợp với chủ đề này.Em vừa thử cách này thì không được nó báo như hình sau ạ!
View attachment 303471
Dạ đúng ạ. Nếu mà làm add-in thì chỉ làm theo hướng show list image trên form và mình chọn hình theo list đó thôi ạ. Cảm ơn hai bạn đã nhiệt tình giúp đỡ mình.Bạn viết sao thì tui không biết chứ tui viết chạy phát ngon cành đào. Còn vụ Add-Ins thì bạn nghĩ quá đơn giản, đụng thử vô đi sẽ thấy vấn đề phát sinh ngay, còn vấn đề gì thì bạn có thể thử suy nghĩ xâu hơn chút ví dụ đóng file mà không lưu, đóng file mà lưu, trên sheet có những shape trang trí, áp dụng cho file này còn file kia (đang mở) tính sao,... Thôi tui xin kết thúc vấn đề ở chủ đề này vì có lẽ cái mà chủ thớt cần đã được giải quyết, còn vụ Add-Ins là phát sinh không phù hợp với chủ đề này.
Cho mình hỏi thêm làm sao để nó chạy trong được nhiều Sheet khác nhau. Như code trên thì chỉ chạy tđc trên "sheet 1"Bạn viết sao thì tui không biết chứ tui viết chạy phát ngon cành đào. Còn vụ Add-Ins thì bạn nghĩ quá đơn giản, đụng thử vô đi sẽ thấy vấn đề phát sinh ngay, còn vấn đề gì thì bạn có thể thử suy nghĩ xâu hơn chút ví dụ đóng file mà không lưu, đóng file mà lưu, trên sheet có những shape trang trí, áp dụng cho file này còn file kia (đang mở) tính sao,... Thôi tui xin kết thúc vấn đề ở chủ đề này vì có lẽ cái mà chủ thớt cần đã được giải quyết, còn vụ Add-Ins là phát sinh không phù hợp với chủ đề này.
Cảm ơn bạn rất nhiều ạTrong UserForm sửa lại code như này.
Mã:Set pic = ActiveSheet.Pictures(PicName)