Hy, I have an excel workbook consisting an Excel Sheet which contains images, shapes, arrows and many more shapes. The structure of the sheet looks like this.
In the above picture, I circle all the textboxes, arrows, Ovels, shapes which I want to delete. I have written a code to delete text boxes which are checking the existence of textboxes and if found delete them. In the other hand, if not exist show pop-up that text-box, does not exist. The code is as under.
Sub resetall()
Dim ws As Worksheet
Dim arow As Shapes
Dim txtbox As TextBox
Set ws = ActiveSheet
If ws.TextBoxes.Count < 0 Then
MsgBox "No Text Box Exist."
Exit Sub
End If
ws.TextBoxes.Delete
MsgBox "Text Box has been deleted successfully."
End Sub
This code is working fine, but I could not find the code for Arrows, and Oval Shapes, and Circles. Please check my code and guide me. I tried to use the shapes. Oval reference from the library but could not succeed. Please guide me. Thank you.
https://www.thespreadsheetguru.com/the-code-vault/vba-delete-all-shapes
Sub DeleteAllShapes()
'PURPOSE: Remove All Shape Objects From The Active Worksheet
'SOURCE: www.TheSpreadsheetGuru.com/the-code-vault
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
shp.Delete
Next shp
End Sub
Optionally, add a test inside the loop for a specific type from msoShapeType
Try the next code, please:
Sub DeleteallShapesExceptRect()
Dim ws As Worksheet, s As Shape, boolRect As Boolean
Set ws = ActiveSheet
For Each s In ws.Shapes
If s.Type = msoAutoShape Then
If s.AutoShapeType = msoShapeRectangle Then
boolRect = True
End If
End If
If Not boolRect Then s.Delete
boolRect = False
Next
The next variant excepts any Rectangle shape type:
Sub DeleteallShapesExceptAllRect()
Dim ws As Worksheet, s As Shape, boolRect As Boolean
Set ws = ActiveSheet
For Each s In ws.Shapes
If s.Type = msoAutoShape Then
If s.AutoShapeType = msoShapeRectangle Or _
msoShapeRoundedRectangle Or msoShapeRound1Rectangle Or _
msoShapeSnip2DiagRectangle Then
boolRect = True
End If
End If
If Not boolRect Then s.Delete
boolRect = False
Next
End Sub
The following variant deletes all shapes from a specific range:
Sub DeleteAllShapesOnRange()
Dim ws As Worksheet, s As Shape, rngDel As Range
Set ws = ActiveSheet: Set rngDel = ws.Range("A1:W6")
For Each s In ws.Shapes
If Not Intersect(rngDel, s.TopLeftCell) Is Nothing Then
s.Delete
End If
Next
End Sub
And the next one deletes all shapes which are Not on the specific range:
Sub DeleteAllShapesNotOnRange()
Dim ws As Worksheet, s As Shape, rngNoDel As Range, boolFound As Boolean
Set ws = ActiveSheet: Set rngNoDel = ws.Range("A1:W6")
For Each s In ws.Shapes
If Not Intersect(rngNoDel, s.TopLeftCell) Is Nothing Then
boolFound = True
End If
If Not boolFound Then s.Delete
Next
End Sub
And finally, a version deleting all shapes not having text:
Sub DeleteAllShapesNotHavingText()
Dim ws As Worksheet, s As Shape, boolFound As Boolean
Set ws = ActiveSheet
For Each s In ws.Shapes
If Not Len(s.TextFrame2.TextRange.Text) = 0 Then
boolFound = True
End If
If Not boolFound Then s.Delete
Next
End Sub
Note: Each such a code is able to ask for permission before deletion, but it will not make big difference between the manual deletion and the one done in code... If you insist to have such a condition, please specify which of the above versions to be adapted.
Anyhow, the next Sub returns (in Immediate Window) all (mentioned) shapes type. You can change their names. The following code check their real type, which is returned like Long:
Sub EnumerateShapesType()
Dim ws As Worksheet, s As Shape, boolRect As Boolean, arrS As Variant, arrEl As Variant, El As Variant
arrS = Split("Rectangle|1,Round Rectangle|5,Oval|9,Right Arrow|33,Down Arrow|36", ",")
Set ws = ActiveSheet
For Each s In ws.Shapes
If s.Type = msoAutoShape Then
For Each El In arrS
If s.AutoShapeType = Split(El, "|")(1) Then
Debug.Print s.Name, Split(El, "|")(0): Exit For
End If
Next
End If
Next
End Sub
Office 365 answer:
Go to the Home tab
Go to Find & Select
Go to Selection Pane
You now have the names of the shapes in your worksheet.
As an example, you could use ActiveSheet.Shapes.Range(Array("Straight Arrow Connector 1")).Delete to remove a single item.
Related
I am new to VBA and UserForms.
I have a ComboBox where the user will enter a unique Sales Order # (SalesOrder). I want my form to take this input and find it in the workbook and then update the status with the user's inputs in later ComboBoxes (CommentBox & OrderStatus). The issue I am facing is the actual code to find the Sales Order # in the workbook. I've tried what is seen below in several different variations.
If I replace all the ComboBox inputs with the actual inputs as a string, the code runs fine in a module.
Ideally, the code will loop through the sheet array finding all the lines with the Sales Order # and apply the inputs to the row.
Sub AddDataToList()
Dim shtarray As Variant, shtname As Variant
Dim Data As Worksheet, ws As Worksheet
Dim wbk As Workbook
Dim Strg As String
shtarray = Array("EMAUX", "Irene", "Cassandra", "Patricia", "EMREL", "Maria", "Jason", "Peedie", "MICRO", "PARTS", "NAVY", "DELTA")
Set wbk = ThisWorkbook
For Each shtname In shtarray
Set ws = Nothing
On Error Resume Next
Set ws = wbk.Worksheets(shtname)
On Error GoTo 0
If Not (ws Is Nothing) Then
ActiveSheet.Cells.Find(StatusUpdateForm.SalesOrder.Text).Offset(0, 17).Select
ActiveCell.Value = CommentBox.Text
ActiveCell.Offset(0, 2).Value = OrderStatus.Text
End If
Next
MsgBox SalesOrder.Value & "was updated."
End Sub
Thank you for the assistance!
More Information ***
Below is the code for the Update command button. This is a standard two button system, one updates the records and the other cancels the form.
Private Sub UpdateButton_Click()
If Not EverythingFilledIn Then Exit Sub
Me.Hide
AddDataToList
Unload Me
End Sub
And code for the EverthingFilledIn
Private Function EverythingFilledIn() As Boolean
Dim ctl As MSForms.Control
Dim AnythingMissing As Boolean
EverthingFilledIn = True
AnythingMissing = False
For Each ctl In Me.Controls
If TypeOf ctl Is MSForms.TextBox Or TypeOf ctl Is MSForms.ComboBox Then
If ctl.Value = "" Then
ctl.BackColor = rgbPink
Controls(ctl.Name & "Label").ForeColor = rgbRed
If Not AnythingMissing Then ctl.SetFocus
AnythingMissing = True
EverythingFilledIn = False
End If
End If
Next ctl
End Function
Try this (my first comment notwithstanding):
Sub AddDataToList()
Dim shtarray As Variant, shtname As Variant
Dim Data As Worksheet, ws As Worksheet
Dim wbk As Workbook
Dim Strg As String
Dim r As Range
shtarray = Array("EMAUX", "Irene", "Cassandra", "Patricia", "EMREL", "Maria", "Jason", "Peedie", "MICRO", "PARTS", "NAVY", "DELTA")
Set wbk = ThisWorkbook
For Each shtname In shtarray
Set ws = wbk.Worksheets(shtname)
Set r = ws.Cells.Find(StatusUpdateForm.SalesOrder.Text) 'better to specify all parameters
If Not r Is Nothing Then
r.Offset(0, 17).Value = CommentBox.Text
r.Offset(0, 2).Value = OrderStatus.Text
End If
Next
MsgBox SalesOrder.Value & "was updated."
End Sub
There is no need to select things.
I would like to make the all specified shapes gone from more than 1 sheet. It applies roughly to the "Cables" sheets.
It's related with my previous query:
VBA Excel select & delete all shapes with the same ID and remove
According to my query regarding the PDF saving
VBA excel excluding specified sheets when saving the .PDF version
I prepared the code, which looks as follows:
Sub Firestopshapes()
Dim shp As Shape
Dim Ws As Worksheet
If Ws.Name Like "*Cables*" Then
'Set Ws = ActiveSheet
For Each shp In Ws.Shapes
If shp.Name = "Firestop" Then
shp.Delete
End If
Next shp
End If
End Sub
Unfortunately I am getting error:
Object variable or With block variable not set
What have I done wrong here?
To close this question out... you forgot the loop through all the worksheets:
For Each Ws in ThisWorkbook.Worksheets
If Ws.Name Like "*Cables*" Then
...
End If
Next
Consider:
Sub Firestopshapes()
Dim shp As Shape
Dim Ws As Worksheet
For Each Ws In Sheets
If InStr(Ws.Name, "Cables") > 0 And Ws.Shapes.Count > 0 Then
For Each shp In Ws.Shapes
If shp.Name = "Firestop" Then
shp.Delete
End If
Next shp
End If
Next Ws
End Sub
I would like to iterate through a list of sheets where the list is determined by a Range.
If I hard-code the list everything is fine.
what I'd like is to refer to a range that contains the sheet names (as it's variable).
Set mySheets = Sheets(Array("sheetOne", "sheetTwo", "sheetThree"))
With ActiveWorkbook
For Each ws In mySheets
'do the stuff here
Next ws
End With
so something like this:
Set mySheets = Sheets(Range("A1:E1"))
Any ideas?
This will work:
Sub MySub()
On Error Resume Next
Set mySheets = Sheets(removeEmpty(rangeToArray(Range("A1:E1"))))
If Err.Number = 9 Then
MsgBox "An error has occurred. Check if all sheet names are correct and retry.", vbCritical
Exit Sub
End If
On Error GoTo 0
With ActiveWorkbook
For Each ws In mySheets
'do the stuff here
Next ws
End With
End Sub
'This will transpose a Range into an Array()
Function rangeToArray(rng As Range) As Variant
rangeToArray = Application.Transpose(Application.Transpose(rng))
End Function
'This will remove empty values and duplicates
Function removeEmpty(arr As Variant) As Variant
Dim result As New Scripting.Dictionary
Dim element As Variant
For Each element In arr
If element <> "" And Not result.Exists(element) Then
result.Add element, Nothing
End If
Next
removeEmpty = result.Keys
End Function
This will load dynamically Sheets contained in your Range.
Edit
Added Function removeEmpty(...) to remove empty values and duplicates.
Note: the Function rangeToArray() is needed to return data in Array() format.
I hope this helps.
I would provide this solution, which does load the sheetnames into an array:
Notice that you have to transpose the Data if the values are ordered horizontal.
Public Sub test()
Dim mySheet As Variant
Dim sheet As Variant
mySheet = Application.Transpose(Tabelle1.Range("A1:E1").Value) 'load your Values into an Array, of course the range can also be dynamic
For Each sheet In mySheet
Debug.Print sheet 'print the sheet names, just for explaining purposes
'it may be necessary to use CStr(sheet) if you want to refer to a sheet like Thisworkbook.Worksheets(CStr(sheet))
'Do something
Next sheet
Erase mySheet 'delete the Array out of memory
End Sub
I demonstrate the code below which does what you want using an animated gif (click for better detail)
Option Explicit
Sub iterateSheets()
Dim sh As Worksheet, shName As String, i As Integer
i = 0
For Each sh In ThisWorkbook.Worksheets
shName = sh.Range("A1").Offset(i, 0)
Worksheets(shName).Range("A1").Offset(i, 0).Font.Color = vbRed
i = i + 1
Next
End Sub
you could do like this:
Sub DoThat()
Dim cell As Range
For Each cell In Range("A1:E1").SpecialCells(xlCellTypeConstants)
If Worksheets(cell.Value2) Is Nothing Then
MsgBox cell.Value2 & " is not a sheet name in " & ActiveWorkbook.Name & " workbook"
Else
With Worksheets(cell.Value2)
'do the stuff here
Debug.Print .Name
End With
End If
Next
End Sub
or the other way around:
Sub DoThatTheOtherWayAround()
Dim sht As Worksheet
For Each sht In Worksheets
If Not IsError(Application.Match(sht.Name, Range("A1:E1"), 0)) Then
'do the stuff here
Debug.Print sht.Name
End If
Next
End Sub
but in this latter case, you wouldn't be advised in case of any A1:E1 value not corresponding to actual sheet name
Hi everyone i made a button on excel using VBA modules,The code works on the active sheet but what im looking for is to be applied to more sheets, not just the active sheet where the button is placed.
Sub Botón1_Haga_clic_en()
Call Worksheet_Calculate
End Sub
'apply cells colors from single-cell formula dependencies/links
Private Sub Worksheet_Calculate()
Dim Cel As Range
Dim RefCel As Range
On Error Resume Next
For Each Cel In ActiveSheet.UsedRange
If Cel.HasFormula Then
Set RefCel = Evaluate(Mid(Cel.Formula, 2))
Cel.Interior.Color = RefCel.Interior.Color
End If
Next Cel
End Sub
Try the code below :
Option Explicit
Sub Botón1_Haga_clic_en()
Dim wsName As String
Dim ws As Worksheet
wsName = ActiveSheet.Name
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name Like wsName Then '<-- is worksheet's name doesn't equal the ActiveSheet's
ApplyCellColors ws ' <-- call you Sub, with the worksheet object
End If
Next ws
End Sub
'=======================================================================
'apply cells colors from single-cell formula dependencies/links
Private Sub ApplyCellColors(ws As Worksheet)
Dim Cel As Range
Dim RefCel As Range
On Error Resume Next
For Each Cel In ws.UsedRange
If Cel.HasFormula Then
Set RefCel = Evaluate(Mid(Cel.Formula, 2))
Cel.Interior.Color = RefCel.Interior.Color
End If
Next Cel
End Sub
Your problem can be translated to something like How to loop over all sheets and ignore one of them?
This is a good way to do it:
Option Explicit
Option Private Module
Public Sub TestMe()
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
If wks.name = "main" Then
Debug.Print "Do nothing here, this is the active sheet's name"
Else
Debug.Print wks.name
End If
Next wks
End Sub
Pretty sure, that you should be able to fit it in your code.
I would like to have a code that unchecks all checkboxes named "CheckBox1" for all sheets across the workbook. My current code unfortunately doesn't work, and I'm not sure why - it only works for the active sheet.
Private Sub CommandButton1_Click()
Dim Sheet As Worksheet
For Each Sheet In ThisWorkbook.Worksheets
Select Case CheckBox1.Value
Case True: CheckBox1.Value = False
End Select
Next
End Sub
This code iterates through all sheets (except sheets named Sheet100 and OtherSheet) and unchecks all your ActiveX checkboxes named CheckBox1
Sub uncheck_boxes()
Dim ws As Worksheet
Dim xbox As OLEObject
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Sheet100" And ws.Name <> "OtherSheet" Then
For Each xbox In ws.OLEObjects
ws.OLEObjects("CheckBox1").Object.Value = False
Next
End If
Next
End Sub
To uncheck all ActiveX checkboxes in all sheets disregarding the names used
Sub uncheck_all_ActiveX_checkboxes()
Dim ws As Worksheet
Dim xbox As OLEObject
For Each ws In ThisWorkbook.Worksheets
For Each xbox In ws.OLEObjects
ws.OLEObjects(xbox.Name).Object.Value = False
Next
Next
End Sub
To uncheck all Form Control checkboxes on a spreadsheet use
Sub uncheck_forms_checkboxes()
Dim ws As Worksheet
Dim xshape As Shape
For Each ws In ThisWorkbook.Worksheets
For Each xshape In ws.Shapes
If xshape.Type = msoFormControl Then
xshape.ControlFormat.Value = False
End If
Next
Next
End Sub
[edited following comments]
Try this:
Sub test()
Dim ws As Excel.Worksheet
Dim s As Object
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Definitions" And ws.Name <> "fx" Then
Set s = Nothing
On Error Resume Next
Set s = ws.OLEObjects("CheckBox1")
On Error GoTo 0
If Not s Is Nothing Then
s.Object.Value = False
End If
End If
Next ws
End Sub
This is a global function (it doesn't belong to a particular sheet), but you can put it inside CommandButton1_Click() if you want.
You might not need the error blocking if your sheets (other than Definitions and fx) always contain CheckBox1. Alternatively remove that if statement.