Reputation: 11
I'm not a regular user of vba, so when I started doing this code I was totally blank. I already deleted all the images on the worksheet, including command buttons and a logo I didn't meant to delete.
This is my code
Private Sub CommandButton2_Click()
Dim Pic As Object
Range("D20:D3000").ClearContents
For Each Pic In ActiveSheet.Pictures
Pic.Delete
Next Pic
End Sub
As you can see I need it to delete the images on the D column, but it deletes the images of the whole sheet. I can't find a way to exclude command buttons (I'm using 2 on that sheet) of the deleting instruccion. Would some of you please, please, please help me? I'm a mess right now.
Upvotes: 1
Views: 865
Reputation: 5031
The following compares the picture's range with your range and deletes it if they intersect:
Private Sub CommandButton2_Click()
Dim objPicture As Object
Dim objPictureRange As Object
Dim objRange As Object
Set objRange = Range("D20:D3000")
objRange.ClearContents
For Each objPicture In ActiveSheet.Pictures
' Get Picture's range
Set objPictureRange = Range(objPicture.TopLeftCell.Address & ":" & objPicture.BottomRightCell.Address)
' Check if Picture is in Range
If Not Intersect(objRange, objPictureRange) Is Nothing Then
' Delete picture
objPicture.Delete
End If
Next Pic
End Sub
Upvotes: 0
Reputation: 71187
I need it to delete the images on the D column, but it deletes the images of the whole sheet.
You are iterating all pictures on the sheet, and never verify where on the sheet the picture is before you invoke its Delete
method.
Interestingly, if you have one picture and one ActiveX command button on Sheet1
, then Sheet1.Pictures.Count
returns, unexpectedly, 2
- that's why the loop is also deleting command buttons.
I'd suggest iterating the Shapes
collection instead: a Shape
object has an interface that makes it much easier to tell a picture apart from an ActiveX button, ...and to know where on the sheet it's at.
Using Shape.Type
we can know if we're looking at a msoPicture
, and with Shape.TopLeftCell
we can get a Range
object representing the top-left cell the picture is located at; if the Column
of that Range
is 4
, then we're looking at a shape whose upper-left corner is located in column D. Thus:
Dim currentShape As Shape
For Each currentShape In ActiveSheet.Shapes
If currentShape.Type = msoPicture And currentShape.TopLeftCell.Column = 4 Then
currentShape.Delete
End If
Next
Note how declaring an explicit type that isn't Object
for our loop variable, we get compile-time validation, and autocomplete/intellisense for every single one of these member calls, whereas calls made against Object
are all late-bound (i.e. compiles perfectly fine with typos, even if you have Option Explicit
at the top of your module) and will only blow up at run-time if anything is wrong (e.g. error 438 if you try to invoke a member that doesn't exist).
Upvotes: 1