VBA to delete multiple RangeNames for single Range - excel

I have searched for an answer for hours, and can't search anymore. Have Seen lots of discussions about deleting all range names from a workbook or a worksheet. However, I need to delete multiple Range Names from a single Range while leaving other Range Names for other ranges on the same sheet and/or within the same workbook alone. Might the code look something like this?:
Sub Delete_My_Named_Ranges()
Dim nName As Name
Dim wbk As Workbook
Dim Sht As Worksheet
Dim rgNm As Range, aCell As Range
Set wbk = Workbooks("testRgNmDelete.xlsm")
Set Sht = wbk.Worksheets("Sheet1")
Set rgNm = Sht.Range("$A$1")
For Each nName In ThisWorkbook.Names
Set aCell = Range(nName)
If Not Intersect(aCell, rgNm) Is Nothing Then
nName.Delete
End If
Next
End Sub
OK, the above code works for a fixed range ("$A:$1"). But I need to be able to set rgNm as a variable instead of as a fixed range. here is an example, the error now is on the statement "Set aCell = Range(nName)."
Private Sub cboProductType_Change()
Dim wbSKUM As Workbook
Dim ws As Worksheet, wsLUL As Worksheet, wsLU As Worksheet
Dim rgPTL As Range, rgTable1 As Range, rgA1 As Range, rgA1LU As Range
Dim rgNm As Range, rgFormula As Range, aCell As Range
Dim sFormula As String
Dim nName As Name
Set wbSKUM = Workbooks("XBS_SKU_Master.xlsm")
Set ws = wbSKUM.Worksheets("SKUMaster")
Set wsLUL = wbSKUM.Worksheets("LookupLists")
Set wsLU = wbSKUM.Worksheets("Lookup")
Set rgPTL = wsLUL.Range("ProdTypeLookUp")
Set rgTable1 = ws.Range("Table1")
sFormula = "=SUBSTITUTE(SUBSTITUTE(F2,"" "",""_""),""-"","""")"
'clear Product Type Lookup List (Column D) to be sure no data remains
wsLUL.Activate
Range(Range("F2"), Range("F2").End(xlDown)).Select
Selection.Cells.Value = vbNullString
Set rgNm = Selection
For Each nName In ThisWorkbook.Names
Set aCell = Range(nName)
If Not Intersect(aCell, rgNm) Is Nothing Then
nName.Delete
End If
Next
Thanks again!

You are getting that error becuase you have not set rgName after declaring it.
Here is my understanding of your question.
Lets say there is a Range A1:A10 in Sheet1 and Cell A2 has a name NM1 and Cell A5 has a name NM2 and cell D10 has a name NM3
And you want a piece of code which deletes the Names in Range A1:A10 i.e NM1 and NM2 and not NM3
If the above is what you want then try this
Option Explicit
Sub Sample()
Dim rgName As Range, aCell As Range
Dim nName As Name
Set rgName = Sheets("Sheet1").Range("A1:A10")
For Each nName In ThisWorkbook.Names
Set aCell = Range(nName)
If Not Intersect(aCell, rgName) Is Nothing Then nName.Delete
Next
End Sub
And if I have misunderstood your question then you might want to rephrase it?
FOLLOWUP
This has been an extremely useful site to me as a new VBA user, but I have ABSOLUTELY no idea how to add to this site, beyond these little notes. Please try to imagine the Name Manager in Excel 2010 - in Name Manager there are say 10 unique names, all for =Sheet1!$A$1. I want all of these names which pertain to Sheet1!$A$1 to be deleted by VBA code. I DO NOT want other names to be deleted anywhere. – LostInData 3 mins ago
Based on your above comment try this
Option Explicit
Sub Sample()
Dim nName As Name
For Each nName In ThisWorkbook.Names
If nName.RefersTo = "=Sheet1!$A$1" Then nName.Delete
Next
End Sub

I think there is something missing in the solution given above.
In order to refer to the range of a named range with the range object you must use the name property of your named range. Therefore, not Set aCell = Range(nName) but rather Set aCell = Range(nName.Name).
Like this:
Option Explicit
Sub Sample()
Dim rgName As Range, aCell As Range
Dim nName As Name
Set rgName = Sheets("Sheet1").Range("A1:A10")
For Each nName In ThisWorkbook.Names
Set aCell = Range(nName.Name)
If Not Intersect(aCell, rgName) Is Nothing Then nName.Delete
Next
End Sub

Related

Delete a row but button should only work in specified table

I have a budget template with tables for each budget category. I have buttons for users to add rows to each budget category with the rows in each category being set as a table so that my total functions work no matter how many rows are added where. But Id like users to also be able to delete rows like if they add too many or if roles change during the time the budget is changed, etc. I don't want users to be able to delete rows such as headers or totals. Protecting the rows doesn't work since the row number can change at any time with new rows being added at any time. The delete selected row code is below as well as my add a row code for the first category which is full time employee salary.
delete selected row - not good since can delete important rows
Sub DeleteSelectedRow()
Rows(ActiveCell.Row).Delete
End Sub
add row to category - good since adds rows to table to keep formulas working
Sub AddConsultant()
Dim ws As Worksheet
Dim tbl As ListObject
Set ws = ActiveSheet
Set tbl = ws.ListObjects("Consultants")
tbl.ListRows.Add
End Sub
Try this:
Sub AddConsultant()
Dim ws As Worksheet
Dim tbl As ListObject
Set ws = ActiveSheet
Set tbl = ws.ListObjects("Consultants")
tbl.ListRows.Add
End Sub
Sub DeleteSelectedRow()
Dim ws As Worksheet
Dim tbl As Range
Set ws = ActiveSheet
Set tbl = ws.ListObjects("Consultants").Range
If InRange(ActiveCell, tbl) Then
Rows(ActiveCell.Row).Delete
Else
MsgBox ("Cannot Delete")
End If
End Sub
Function InRange(Range1 As Range, Range2 As Range) As Boolean
' returns True if Range1 is within Range2
Dim InterSectRange As Range
Set InterSectRange = Application.Intersect(Range1, Range2)
InRange = Not InterSectRange Is Nothing
Set InterSectRange = Nothing
End Function
You can check whether the selection (or part of the selection) range is inside the table of interest.
For example:
Sub AddConsultant()
AddRow "Consultants"
End Sub
Sub RemoveConsultant()
RemoveSelectedRow "Consultants"
End Sub
Sub AddSite()
AddRow "Sites"
End Sub
Sub RemoveSite()
RemoveSelectedRow "Sites"
End Sub
'methods to add/remove rows from the specified table
Sub AddRow(tableName As String)
ActiveSheet.ListObjects(tableName).ListRows.Add
End Sub
Sub RemoveSelectedRow(tableName As String)
Dim rng As Range, ok As Boolean
If TypeName(Selection) = "Range" Then 'is a range selected?
'is the range in the required table?
Set rng = Application.Intersect( _
ActiveSheet.ListObjects(tableName).DataBodyRange, Selection)
If Not rng Is Nothing Then
rng.EntireRow.Delete
ok = True
End If
End If
'didn't delete anything?
If Not ok Then MsgBox "First select one or more rows in " & _
tableName & " table"
End Sub

VBA userform to write down timestamp to range on sheet

In my excel file I have a worksheet for every person. This worksheet is copied according a template sheet after entering data.
Now for the next part I would like to add data to a specific range on the sheet of that person.
Let's start with a simple date stamp to Range E4:E53 for the specified sheet. I'm using a combobox so you can select someone from the list and this is where i'm struggling;
After selecting someone from the list, my code does not write down the data.
As shown in the picture, the Worksheet is set to nothing. How do I set the worksheet according to the selected person from the combobox?
Public Sub CommandButton1_Click()
Dim lRow As String
Dim Rng As Range
Dim Rng2 As Range
Dim ws As Worksheet
Set ws = ComboBox1.List(I, 0)
Set Rng = Range("C4, C53")
Set Rng2 = Range("E4, Q53")
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
With ws
Rng.Cells.lRow.Value = Format(Time, "DD:MM:YYYY:HH:MM")
End With
End sub
I assume that your list contains names of worksheets for each person, like {"Monica", "Adam"...}, right?
The problem in your case is that you try to use string value from ComboBox1 to define worksheet which is an object in worksheets collection.
You should get string value (name) of worksheet and then use it to set your ws object.
Here is simple code snippet, hope it is what you wanted to achieve :)
Private Sub ComboBox1_click()
Dim ws As Worksheet
'Define worksheet from worksheets collection
Set ws = worksheets(ComboBox1.Value)
ws.Range("A5").Value = "Hello!"
End Sub
Private Sub UserForm_Initialize()
Dim ws As Worksheet
'Make list of all worksheets
For Each ws In worksheets
ComboBox1.AddItem ws.Name
Next ws
End Sub

Variable Range not recognized as a property of Worksheets

I'm trying to use both worksheets and ranges as variables, but I'm having some problems.
If I declare a worksheet as a variable and then use the range property it works just fine.
However, when I declare a variable Range and try to use it reference it, it throws me the error 438, object doesn't have property or method.
Sub try()
Dim ws As Worksheet
Set ws = Worksheets("Code")
ws.Range("A3", "B6").Value = "sheets"
Dim r As Range
Set r = Range("D1", "F3")
Worksheets("DATOS").r.Value = "ranges"
End Sub
My end goal would be to have both the Worksheet and the range as variables, so I could reference it such as
ws.r.Value = "123"
Thanks in advance, I hope my question isn't too basic and you can help me.
When you set a Range object, it is not a universal cell address to be used like what you did, each Range refers to a specific Worksheet that you can see under its Worksheet property. (documentation)
You did not specify the Worksheet in Set r = Range("D1", "F3") so VBA assumes that you are referring to the ActiveSheet which can be anything. (which is also why you are recommended to always fully qualify your range reference)
As mentioned in your comment - Since your objective is to use the same range for multiple worksheets, you can define the range address in a String variable and use that variable as shown below:
Sub try()
Const r As String = "D1:F3"
Worksheets("DATOS").Range(r).Value = "ranges"
Worksheets("Code").Range(r).Value = "ranges"
End Sub
You can't use range variable in this way. Rather qualify range mentioning sheet name. Try below codes.
Try below codes.
Sub try()
Dim ws As Worksheet
Set ws = Worksheets("Code")
ws.Range("A3", "B6").Value = "sheets"
Dim r As Range
Set r = Worksheets("DATOS").Range("D1", "F3")
r = "ranges"
End Sub
It is not possible to refer to the range in the way you want.
If you want to use a VBA variable to refer to ranges, you can do this:
' Get a range
Set Sht1 = ThisWorkbook.Worksheets("Sheet1")
Set Rng1 = Sht.Range("A2:B2")
' Set the contents of another range to the same value
Set Sht2 = ThisWorkbook.Worksheets("Sheet2")
Set Rng2 = Sht2.Range("C2:D2")
Rng2.value = Rng1.Value
You already seem to have a grasp of doing it this way.
If you want to refer to a range by a name, here is a method that creates a named range:
' Delete the named range if it exists and create it again.
Sub CreateNamedRange(Wbk As Workbook, Txt As String, Rng As Range)
On Error Resume Next
Wbk.Names(Txt).Delete
If Err.Number <> 0 Then Err.Clear
On Error GoTo 0
Wbk.Names.Add Txt, Rng
End Sub
Here we create a named range Name1 and retrieve it using Sht.Range("Name1"):
Sub CreateNamedRangeAndUseIt()
Dim Sht As Worksheet
Dim Rng As Range
' Set the value of the range to 42
Set Sht = ThisWorkbook.Worksheets("Sheet2")
Set Rng = Sht.Range("A2")
Rng.Value = 42
' Create a name for the range
CreateNamedRange ThisWorkbook, "Name1", Rng
' Activate some other sheet to make sure it works when the
' sheet with the named range is not active.
ThisWorkbook.Worksheets("Sheet1").Activate
' Get the named range and output the value of the range to the
' immediate window.
Set Rng = Sht.Range("Name1")
' This would also work, even though the named range does not
' exist on Sheet1:
' Set Rng = ThisWorkbook.Worksheets("Sheet1").Range("Name1")
' Or this (provided you don't have several workbooks open and
' another workbook is selected)
' Set Rng = Range("Name1")
Debug.Print Rng.Value
' Then select the range.
' We must activate the sheet first to select ranges in it.
Rng.Worksheet.Activate
Rng.Select
End Sub
The named range will still exist if you close and reopen the workbook, provided you save the workbook before closing it. So you only need to name the range once.

Excel VBA: If Equal Not to, then show error message

Can't figure out what's wrong with the code.
I have a code where I need to check if in certain sheet can be found certain products' ID before making an order.
Private Sub Pardot_Click()
Dim xlRange As Range
Dim xlCell As Range
Dim xlSheet As Worksheet
Dim valueToFind As String
valueToFind = pardID
Set xlSheet = ActiveWorkbook.Worksheets("Noliktava")
Set xlRange = xlSheet.Range("A1:A500")
For Each xlCell In xlRange
If xlCell.Value <> valueToFind Then
MsgBox ("This product wasn't found in the database - ID: " & pardID.Text)
Exit Sub
End If
Next xlCell
End Sub
Basically, I launch the userform and type in the ID (i.e. 1) in the box and click "Okay" or whatever, if the ID can't be found in the range (ID:1) I want it to show the error Msg.
Code works if I change <> to =, but that's not the needed result.
Without changing your code too much, and probably saving some time, instead of checking each cell in the range, just use CountIf()?
Private Sub Pardot_Click()
Dim xlRange As Range
Dim xlCell As Range
Dim xlSheet As Worksheet
Dim valueToFind As String
valueToFind = pardID
Set xlSheet = ActiveWorkbook.Worksheets("Noliktava")
Set xlRange = xlSheet.Range("A1:A500")
If WorksheetFunction.CountIf(xlRange,valuetoFind) = 0 then
msgbox "This product wasn't found in the database - ID: " & parId.textEnd
End If
End Sub
Note: this will look for exactly the text the user inserted. Use wildcards if it can be somewhere in a string (i.e. search for "dog" in "doggone", "dog food","dog")

Setting a Sheet and cell as variable

I am new in VBA coding. Lets say I am retrieving value from Sheet3.Cell(23, 4) for a value, is there any way in the VBA code which let me set this as a variable?
For example, I have changed the interface and let the value stay at Sheet4.Cell(20,1), everywhere in my code which refer to Sheet3.Cell(23, 4) need to be changed to Sheet4.Cell(20, 1). I am thinking is there any best practice for coding VBA for situation like this?
Yes. For that ensure that you declare the worksheet
For example
Previous Code
Sub Sample()
Dim ws As Worksheet
Set ws = Sheets("Sheet3")
Debug.Print ws.Cells(23, 4).Value
End Sub
New Code
Sub Sample()
Dim ws As Worksheet
Set ws = Sheets("Sheet4")
Debug.Print ws.Cells(23, 4).Value
End Sub
Yes, set the cell as a RANGE object one time and then use that RANGE object in your code:
Sub RangeExample()
Dim MyRNG As Range
Set MyRNG = Sheets("Sheet1").Cells(23, 4)
Debug.Print MyRNG.Value
End Sub
Alternately you can simply store the value of that cell in memory and reference the actual value, if that's all you really need. That variable can be Long or Double or Single if numeric, or String:
Sub ValueExample()
Dim MyVal As String
MyVal = Sheets("Sheet1").Cells(23, 4).Value
Debug.Print MyVal
End Sub

Resources