xin giúp sửa code chèn ảnh vào excel bỏ tham số LinkToFile

Liên hệ QC

ok95sonok

Thành viên mới
Tham gia
20/5/22
Bài viết
24
Được thích
1
Em chào mọi người!
Em có 1 code chèn ảnh hàng loạt vào excel sử dụng hàm picture.insert nên khi xóa ảnh trong ổ đĩa là mất ảnh trong excel ạ.
Các Anh/Chị có thể giúp em thay hàm khác để bỏ tham số LinkToFile được không ạ? Thanks!
 

File đính kèm

  • 1chenanh.xlsm
    18.3 KB · Đọc: 4
ai giúp em với ạ!! :((
CSS:
Sub chenanh()
    Dim FilesToOpen As Variant
    Dim numberOfPics As Integer
    Dim numberOfPicsPerRow As Integer
    Dim numberOfRows As Integer
    Dim picWidth As Double, picHeight As Double, gap As Double
    Dim count As Integer

    FilesToOpen = Application.GetOpenFilename(Title:="chon anh", MultiSelect:=True)
    
    
    numberOfPics = UBound(FilesToOpen)
    numberOfPicsPerRow = [A1]
    picWidth = [B1]
    picHeight = [C1]
    gap = [D1]
    count = 1
    
    numberOfRows = WorksheetFunction.Ceiling(numberOfPics / numberOfPicsPerRow, 1)
    
    For i = 1 To numberOfRows
        For j = 1 To numberOfPicsPerRow
            If count <= numberOfPics Then
            
                With ActiveSheet.Pictures.Insert(FilesToOpen(count))
                    With .ShapeRange
                        .LockAspectRatio = True
                        .Width = picWidth
                        .Height = picHeight
                    End With
                    .Left = gap * j + picWidth * (j + 1)
                    .Top = gap * i + picHeight * (i + 1)
                End With
                
            End If
            count = count + 1
        Next j
    Next i
End Sub
 
Upvote 0
Thay
Mã:
FilesToOpen = Application.GetOpenFilename(Title:="chon anh", MultiSelect:=True)

bằng

Mã:
FilesToOpen = Application.GetOpenFilename(FileFilter:="Anh (*.bmp; *.gif; *.jpg; *.png), *.bmp; *.gif; *.jpg; *.png", Title:="chon anh", MultiSelect:=True)

Thay
Mã:
With ActiveSheet.Pictures.Insert(FilesToOpen(count))
    With .ShapeRange
        .LockAspectRatio = True
        .Width = picWidth
        .Height = picHeight
    End With
    .Left = gap * j + picWidth * (j + 1)
    .Top = gap * i + picHeight * (i + 1)
End With

bằng

Mã:
ActiveSheet.Shapes.AddPicture FilesToOpen(count), msoFalse, msoTrue, gap * j + picWidth * (j + 1), gap * i + picHeight * (i + 1), picWidth, picHeight
 
Upvote 0
Thay
Mã:
FilesToOpen = Application.GetOpenFilename(Title:="chon anh", MultiSelect:=True)

bằng

Mã:
FilesToOpen = Application.GetOpenFilename(FileFilter:="Anh (*.bmp; *.gif; *.jpg; *.png), *.bmp; *.gif; *.jpg; *.png", Title:="chon anh", MultiSelect:=True)

Thay
Mã:
With ActiveSheet.Pictures.Insert(FilesToOpen(count))
    With .ShapeRange
        .LockAspectRatio = True
        .Width = picWidth
        .Height = picHeight
    End With
    .Left = gap * j + picWidth * (j + 1)
    .Top = gap * i + picHeight * (i + 1)
End With

bằng

Mã:
ActiveSheet.Shapes.AddPicture FilesToOpen(count), msoFalse, msoTrue, gap * j + picWidth * (j + 1), gap * i + picHeight * (i + 1), picWidth, picHeight
cảm ơn anh rất nhiều!
cho e hỏi thêm là làm thế nào để giữ nguyên chất lượng ảnh được ạ. em chèn xong ảnh mờ quá
 
Upvote 0
cảm ơn anh rất nhiều!
cho e hỏi thêm là làm thế nào để giữ nguyên chất lượng ảnh được ạ. em chèn xong ảnh mờ quá
Tôi chịu.

Nhưng tôi có chút tò mò. Ảnh nhìn thấy trên sheet và ảnh thực ngoài đĩa có khác nhau nhiều về kích thước không? Vd. ảnh ngoài đĩa so với trên sheet rất nhỏ (rất to).

Nhưng tôi nói rồi - tôi chịu. Hay là thử mở ảnh thực trên sheet sau khi click, và thu lại như cũ khi click lần nữa? Nhưng tôi cũng không biết ảnh thực trên sheet chất lượng sẽ như thế nào. Vì tôi chưa gặp trường hợp ảnh kém chất lượng nhưng từng nghe có người phàn nàn.
 
Upvote 0
Tôi chịu.

Nhưng tôi có chút tò mò. Ảnh nhìn thấy trên sheet và ảnh thực ngoài đĩa có khác nhau nhiều về kích thước không? Vd. ảnh ngoài đĩa so với trên sheet rất nhỏ (rất to).

Nhưng tôi nói rồi - tôi chịu. Hay là thử mở ảnh thực trên sheet sau khi click, và thu lại như cũ khi click lần nữa? Nhưng tôi cũng không biết ảnh thực trên sheet chất lượng sẽ như thế nào. Vì tôi chưa gặp trường hợp ảnh kém chất lượng nhưng từng nghe có người phàn nàn.
em cho kích thước ảnh to ra được rồi ạ. cảm ơn pro nhiều ạ! (*%(*%
ảnh ngoài đĩa chất lương cao nhưng khi vào sheet vỡ ảnh cho đoạn này to ra là được ạ, mới đầu em để 100*100
HTML:
picWidth = [B1]
picHeight = [C1]
 
Upvote 0
em cho kích thước ảnh to ra được rồi ạ. cảm ơn pro nhiều ạ! (*%(*%
ảnh ngoài đĩa chất lương cao nhưng khi vào sheet vỡ ảnh cho đoạn này to ra là được ạ, mới đầu em để 100*100
HTML:
picWidth = [B1]
picHeight = [C1]
Tôi giúp bạn thì bạn cũng phải giúp tôi.

Tôi viết rất rõ
Nhưng tôi có chút tò mò. Ảnh nhìn thấy trên sheet và ảnh thực ngoài đĩa có khác nhau nhiều về kích thước không? Vd. ảnh ngoài đĩa so với trên sheet rất nhỏ (rất to).
Tôi muốn biết tại sao ảnh lại kém chất lượng. Tôi muốn biết nguyên nhân. Rất có thể câu trả lời của bạn sẽ cho tôi một gợi ý.
 
Upvote 0
Tôi giúp bạn thì bạn cũng phải giúp tôi.

Tôi viết rất rõ

Tôi muốn biết tại sao ảnh lại kém chất lượng. Tôi muốn biết nguyên nhân. Rất có thể câu trả lời của bạn sẽ cho tôi một gợi ý.
em thấy ảnh trong sheet theo code để 100*100
còn ảnh thực tế 2048*1365
sau khi em cho trong sheet lên 300*200 ảnh đã cải thiện rất là nhiều ạ
 

File đính kèm

  • AutoaddIMG.xlsm
    63.4 KB · Đọc: 7
  • 4wvuq0i4ozs1q - Copy.jpg
    4wvuq0i4ozs1q - Copy.jpg
    127.7 KB · Đọc: 7
Upvote 0
em thấy ảnh trong sheet theo code để 100*100
còn ảnh thực tế 2048*1365
sau khi em cho trong sheet lên 300*200 ảnh đã cải thiện rất là nhiều ạ
Thì đúng rồi. Chiều dài thu nhỏ tận 20 lần, chiều cao thu nhỏ 13 lần. Do 2 chiều thu nhỏ không đều nên ảnh còn bị méo.
 
Upvote 0
Thì đúng rồi. Chiều dài thu nhỏ tận 20 lần, chiều cao thu nhỏ 13 lần. Do 2 chiều thu nhỏ không đều nên ảnh còn bị méo.
Vâng anh. em mới biết đến 4rum và đọc một vài bài viết thấy anh rất nhiệt tình giúp đỡ mọi người. tiện thể cho em hỏi thêm có thể tạo 1 trường hợp chèn ảnh nữa tương tự code của em ở trên được không ạ?
Chúc anh thật nhiều sức khỏe! :))
Bài đã được tự động gộp:

@batman1
Em có 24 ảnh trong ổ đĩa số từ 1 đến 24
em muốn chèn ảnh vào 4 cột trong sheet vòng lặp các hàng tiếp theo (mỗi ô trong cột Width = 300, Height = 200)
như code hiện tại em phải CTRL + A rồi di chuyển 24 ảnh vào vị trí muốn chèn
giờ em muốn khi chèn ảnh sẽ tự Center vào ô mình muốn có được không ạ?
em gửi file đính kèm ạ
Thanks pro
 

File đính kèm

  • chenanh.xlsm
    1.8 MB · Đọc: 2
Lần chỉnh sửa cuối:
Upvote 0
Tôi giúp bạn thì bạn cũng phải giúp tôi.

Tôi viết rất rõ

Tôi muốn biết tại sao ảnh lại kém chất lượng. Tôi muốn biết nguyên nhân. Rất có thể câu trả lời của bạn sẽ cho tôi một gợi ý.
Cái này em đoán là khi trèn ảnh lên không bị giảm độ phân giải.Mà khi lưu file lại nó tự động điều chỉnh độ phân giải về với kích thước ảnh hiện có nên khi phóng to ra sẽ bị vỡ ảnh.
 
Upvote 0
Cái này em đoán là khi trèn ảnh lên không bị giảm độ phân giải.Mà khi lưu file lại nó tự động điều chỉnh độ phân giải về với kích thước ảnh hiện có nên khi phóng to ra sẽ bị vỡ ảnh.
Không phải anh ạ, em chưa lưu. em để rộng 100, cao 100 chắc nhỏ quá nên nó vỡ luôn lúc chèn vào. ảnh gốc rộng 2048*1365
 
Upvote 0
Cái này em đoán là khi trèn ảnh lên không bị giảm độ phân giải.Mà khi lưu file lại nó tự động điều chỉnh độ phân giải về với kích thước ảnh hiện có nên khi phóng to ra sẽ bị vỡ ảnh.
Với code chèn ảnh của tôi tuy ảnh nhỏ do tác giả muốn thu nhỏ về 300 x 200 nhưng ảnh gốc to vẫn luôn có. Tuần sau tôi thêm code vào để gọi ảnh gốc thì sẽ hiển thị ảnh gốc to như nguyên bản. Nó không phải là ảnh nhỏ 300 x 200 được phóng to như ảnh gốc mà nó đúng là ảnh khi ta chọn trên đĩa.

Em có 24 ảnh trong ổ đĩa số từ 1 đến 24
em muốn chèn ảnh vào 4 cột trong sheet vòng lặp các hàng tiếp theo (mỗi ô trong cột Width = 300, Height = 200)
như code hiện tại em phải CTRL + A rồi di chuyển 24 ảnh vào vị trí muốn chèn
giờ em muốn khi chèn ảnh sẽ tự Center vào ô mình muốn có được không ạ?
Tức có 24 khung là 24 ô E2:H7. Bây giờ bạn muốn chèn 24 ảnh vào 24 ô đó. Và chèn vĩnh viễn (LinkToFile = False) và không vừa khít khung mà CENTER trong khung?

Nếu thế thì hãy đọc kỹ bài #2


Quan trọng nhất là sub InsertPicture. Tùy tình huống mà dùng vòng FOR và trong vòng For thì gọi InsertPicture để chèn ảnh. Với InsertPicture bạn có thể chèn ảnh vào khung là 1 hoặc nhiều ô mà không cần merge cell, chèn ảnh thực hoặc vừa khít ô hoặc center, và chèn vĩnh viễn (LinkToFile = False) hoặc chỉ chèn link.
 
Lần chỉnh sửa cuối:
Upvote 0
Với code chèn ảnh của tôi tuy ảnh nhỏ do tác giả muốn thu nhỏ về 300 x 200 nhưng ảnh gốc to vẫn luôn có. Tuần sau tôi thêm code vào để gọi ảnh gốc thì sẽ hiển thị ảnh gốc to như nguyên bản. Nó không phải là ảnh nhỏ 300 x 200 được phóng to như ảnh gốc mà nó đúng là ảnh khi ta chọn trên đĩa.


Tức có 24 khung là 24 ô E2:H7. Bây giờ bạn muốn chèn 24 ảnh vào 24 ô đó. Và chèn vĩnh viễn (LinkToFile = False) và không vừa khít khung mà CENTER trong khung?

Nếu thế thì hãy đọc kỹ bài #2


Quan trọng nhất là sub InsertPicture. Tùy tình huống mà dùng vòng FOR và trong vòng For thì gọi InsertPicture để chèn ảnh. Với InsertPicture bạn có thể chèn ảnh vào khung là 1 hoặc nhiều ô mà không cần merge cell, chèn ảnh thực hoặc vừa khít ô hoặc center, và chèn vĩnh viễn (LinkToFile = False) hoặc chỉ chèn link.
Hí anh. em vừa đọc bài và lấy file của a về chỉnh sửa. anh cho em hỏi làm thế nào để tên ở ô nào, cột nào thì ảnh ở đấy được không ạ?
 

File đính kèm

  • Anh.rar
    3.1 MB · Đọc: 5
Upvote 0
Hí anh. em vừa đọc bài và lấy file của a về chỉnh sửa. anh cho em hỏi làm thế nào để tên ở ô nào, cột nào thì ảnh ở đấy được không ạ?
Trong tập tin bạn có vùng cố định B5:E10 rồi còn gì, sao lại phải .Cells(Rows.Count, "E").End(xlUp).Row làm gì?

Hay là không hẳn là bắt đầu từ dòng 5 và không hẳn kết thúc ở dòng 10? Và phải biết xét những dòng nào.

Vd. vùng cần xét LUÔN LUÔN từ dòng 5, cột LUÔN LUÔN là B:E. Và cột B luôn chứa dòng cuối cùng có dữ liệu (vì nếu giả sử trong tập tin bạn chỉ nhập tới E10 còn B10, C10, D10 rỗng thì cột B không chứa đòng cuối cùng có dữ liệu là dòng 10) ...

Để dễ bảo trì thì tôi định nghĩa 3 hằng số:

Const dong_dau = 5 ' chỉ số dòng đầu
Const cot_dau = "B" ' tên cột đầu
Const so_cot = 4 ' số cột.

Trong trường hợp cụ thể thì sửa 3 hằng số này.

Nếu tên ở ô nào thì ảnh ở ô đó thì phải là cell_ chứ sao lại là cell_.Offset(0, 1)?

À, có một điều quan trọng bạn đã làm sai. Không được sửa code của sub InsertPicture. Đây là sub tổng quát, bất di bất dịch. Khi muốn chèn ảnh vĩnh viễn, hay chèn center, hay chèn ảnh kích thức thực thì truyền True, False khi GỌI InsertPicture. Nhưng code của sub InsertPicture không động vào - nguy hiểm chết người!

Trong tập tin bạn đã sửa lại code của InsertPicture, ít nhất là 1 chỗ.

Của tôi viết là
Mã:
If LinkToFile Then
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoTrue, msoFalse, Target.left, Target.top, 0, 0)
Else
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoTrue, Target.left, Target.top, 0, 0)
End If

Trong tập tin của bạn có
Mã:
If LinkToFile Then
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoTrue, Target.left, Target.top, 0, 0)
Else
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoFalse, Target.left, Target.top, 0, 0)
End If
--------------------------
Mã:
Sub chen_anh()
Const dong_dau = 5
Const cot_dau = "B"
Const so_cot = 4
Dim lastRow As Long, vung As range, cell_ As range
    With ThisWorkbook.Worksheets("Sheet1")
        lastRow = .Cells(Rows.Count, cot_dau).End(xlUp).Row ' dong cuoi cung co du lieu trong cot B
        If lastRow < dong_dau Then Exit Sub
        Set vung = .range(cot_dau & dong_dau).Resize(lastRow - dong_dau + 1, so_cot)
    End With
    For Each cell_ In vung
        InsertPicture ThisWorkbook.path & "\Anh\" & cell_.Value & ".jpg", cell_, False, True, False
    Next cell_
End Sub

Code trên chèn ảnh vĩnh viễn. Nếu chỉ muốn chèn link thì tham số cuối là TRUE. Code chèn ảnh CENTER. Nếu muốn vừa khít khung thì tham số trước cuối là FALSE.

Tôi gửi lại code InsertPicture. Không đụng vào sub này - nguy hiểm chết người.

Mã:
Sub InsertPicture(ByVal PicFilename As String, Optional Target As range = Nothing, _
                Optional original As Boolean = False, Optional center As Boolean = False, _
                Optional LinkToFile As Boolean = False)
'    Target: vung nhap anh. Co the la nhieu cell
'    Neu Target = Nothing thi Target = ActiveCell
'    Neu original = True thi nhap anh kich thuoc thuc.
'    Neu original = FALSE thi neu center = True thi anh se center trong vung Target,
'    nguoc lai thi se vua khit vung Target
'    LinkToFile = False thi khong can giu anh tren dia, nguoc lai bat buoc phai giu anh de moi lan mo thi co
Dim w As Double, h As Double, shp As Shape, fso As Object
    If Target Is Nothing Then Set Target = ActiveCell
    On Error Resume Next
    Target.Parent.Shapes(Target.Address).Delete
    On Error GoTo 0
  
    Set fso = CreateObject("Scripting.FileSystemObject")
  
    If fso.FileExists(PicFilename) Then
        If LinkToFile Then
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoTrue, msoFalse, Target.left, Target.top, 0, 0)
        Else
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoTrue, Target.left, Target.top, 0, 0)
        End If
        If Not shp Is Nothing Then
            With shp
                If original Then
                    .ScaleWidth 1, msoTrue
                    .ScaleHeight 1, msoTrue
                ElseIf center Then
                    .ScaleWidth 1, msoTrue
                    .ScaleHeight 1, msoTrue
                    w = Target.Width
                    h = w * .Height / .Width
                    If h > Target.Height Then
                        h = Target.Height
                        w = h * .Width / .Height
                    End If
                    .left = Target.left + (Target.Width - w) / 2
                    .top = Target.top + (Target.Height - h) / 2
                    .Width = w
                    .Height = h
                Else
                    .Width = Target.Width
                    .Height = Target.Height
                End If
                shp.Name = Target.Address
                shp.Placement = xlMoveAndSize
            End With
        End If
    End If
   
     Set fso = Nothing
 End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Trong tập tin bạn có vùng cố định B5:E10 rồi còn gì, sao lại phải .Cells(Rows.Count, "E").End(xlUp).Row làm gì?

Hay là không hẳn là bắt đầu từ dòng 5 và không hẳn kết thúc ở dòng 10? Và phải biết xét những dòng nào.

Vd. vùng cần xét LUÔN LUÔN từ dòng 5, cột LUÔN LUÔN là B:E. Và cột B luôn chứa dòng cuối cùng có dữ liệu (vì nếu giả sử trong tập tin bạn chỉ nhập tới E10 còn B10, C10, D10 rỗng thì cột B không chứa đòng cuối cùng có dữ liệu là dòng 10) ...

Để dễ bảo trì thì tôi định nghĩa 3 hằng số:

Const dong_dau = 5 ' chỉ số dòng đầu
Const cot_dau = "B" ' tên cột đầu
Const so_cot = 4 ' số cột.

Trong trường hợp cụ thể thì sửa 3 hằng số này.

Nếu tên ở ô nào thì ảnh ở ô đó thì phải là cell_ chứ sao lại là cell_.Offset(0, 1)?

À, có một điều quan trọng bạn đã làm sai. Không được sửa code của sub InsertPicture. Đây là sub tổng quát, bất di bất dịch. Khi muốn chèn ảnh vĩnh viễn, hay chèn center, hay chèn ảnh kích thức thực thì truyền True, False khi GỌI InsertPicture. Nhưng code của sub InsertPicture không động vào - nguy hiểm chết người!

Trong tập tin bạn đã sửa lại code của InsertPicture, ít nhất là 1 chỗ.

Của tôi viết là
Mã:
If LinkToFile Then
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoTrue, msoFalse, Target.left, Target.top, 0, 0)
Else
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoTrue, Target.left, Target.top, 0, 0)
End If

Trong tập tin của bạn có
Mã:
If LinkToFile Then
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoTrue, Target.left, Target.top, 0, 0)
Else
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoFalse, Target.left, Target.top, 0, 0)
End If
--------------------------
Mã:
Sub chen_anh()
Const dong_dau = 5
Const cot_dau = "B"
Const so_cot = 4
Dim lastRow As Long, vung As range, cell_ As range
    With ThisWorkbook.Worksheets("Sheet1")
        lastRow = .Cells(Rows.Count, cot_dau).End(xlUp).Row ' dong cuoi cung co du lieu trong cot B
        If lastRow < dong_dau Then Exit Sub
        Set vung = .range(cot_dau & dong_dau).Resize(lastRow - dong_dau + 1, so_cot)
    End With
    For Each cell_ In vung
        InsertPicture ThisWorkbook.path & "\Anh\" & cell_.Value & ".jpg", cell_, False, True, False
    Next cell_
End Sub

Code trên chèn ảnh vĩnh viễn. Nếu chỉ muốn chèn link thì tham số cuối là TRUE. Code chèn ảnh CENTER. Nếu muốn vừa khít khung thì tham số trước cuối là FALSE.

Tôi gửi lại code InsertPicture. Không đụng vào sub này - nguy hiểm chết người.

Mã:
Sub InsertPicture(ByVal PicFilename As String, Optional Target As range = Nothing, _
                Optional original As Boolean = False, Optional center As Boolean = False, _
                Optional LinkToFile As Boolean = False)
'    Target: vung nhap anh. Co the la nhieu cell
'    Neu Target = Nothing thi Target = ActiveCell
'    Neu original = True thi nhap anh kich thuoc thuc.
'    Neu original = FALSE thi neu center = True thi anh se center trong vung Target,
'    nguoc lai thi se vua khit vung Target
'    LinkToFile = False thi khong can giu anh tren dia, nguoc lai bat buoc phai giu anh de moi lan mo thi co
Dim w As Double, h As Double, shp As Shape, fso As Object
    If Target Is Nothing Then Set Target = ActiveCell
    On Error Resume Next
    Target.Parent.Shapes(Target.Address).Delete
    On Error GoTo 0
 
    Set fso = CreateObject("Scripting.FileSystemObject")
 
    If fso.FileExists(PicFilename) Then
        If LinkToFile Then
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoTrue, msoFalse, Target.left, Target.top, 0, 0)
        Else
            Set shp = Target.Parent.Shapes.AddPicture(PicFilename, msoFalse, msoTrue, Target.left, Target.top, 0, 0)
        End If
        If Not shp Is Nothing Then
            With shp
                If original Then
                    .ScaleWidth 1, msoTrue
                    .ScaleHeight 1, msoTrue
                ElseIf center Then
                    .ScaleWidth 1, msoTrue
                    .ScaleHeight 1, msoTrue
                    w = Target.Width
                    h = w * .Height / .Width
                    If h > Target.Height Then
                        h = Target.Height
                        w = h * .Width / .Height
                    End If
                    .left = Target.left + (Target.Width - w) / 2
                    .top = Target.top + (Target.Height - h) / 2
                    .Width = w
                    .Height = h
                Else
                    .Width = Target.Width
                    .Height = Target.Height
                End If
                shp.Name = Target.Address
                shp.Placement = xlMoveAndSize
            End With
        End If
    End If
  
     Set fso = Nothing
 End Sub
Đạ tạ tiền bối. Thực sự em cũng mới biết về VBA. Cảm ơn anh rất nhiều ạ!
 
Upvote 0
Web KT

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

Back
Top Bottom