Hi I keep getting "variable or with block variable not set" for the line in the for loop of the following code. Could anyone tell me where I am going wrong? Thanks
Public Sub TestFind()
Set wsNew = Worksheets.Add(after:=Worksheets(Worksheets.Count))
wsNew.Range(wsNew.Cells(1, 1), wsNew.Cells(1, 17)).Value _
= Array("ReturnId", "GridName", "Item", "TabName", "AltFldName", "FieldPos", "Reference", "Type", _
"SortPos", "FieldSize", "CalcField", "CellDesc", "DoNotExport", "SortStrategy", "Threshold", "IsInnerGridCell", "ReportLine")
Dim Nm As Name
Dim rng As Range
Dim wb As Workbook
Set wb = ThisWorkbook
For Each Nm In ThisWorkbook.Names
rng = Nm.RefersToRange.Value
Next
End Sub
You have two problems in the code:
1- Not all names refer necessarily to a named range. They may refer to constants, for example. So you need to add some checking before assuming that the name refers really to a range.
2- to assign a range object to a named range, you need to use Set
Try this:
Dim Nm As Name, rng As Range
For Each Nm In ThisWorkbook.Names
Debug.Print Nm.Name
On Error Resume Next
Set rng = Nm.RefersToRange ' <-- Use Set to assign object references
If Err.Number <> 0 Then GoTo NextNm ' <-- This name does not refer to a named range
On Error GoTo 0
Debug.Print rng.Address
' ... Do whatever you want with the named range
NextNm:
On Error GoTo 0
Next Nm
Adjustments made and commented.
Option Explicit
Sub wqewtr()
Dim Nm As Name
Dim rng As Range
Dim var As Variant '<~~ for numbers, dates and/or text
Dim wb As Workbook
Set wb = ThisWorkbook
For Each Nm In ThisWorkbook.Names
Debug.Print Nm.Name
'nm could a 'special internal name' that starts with an underscore
'skip over these
If Left(Nm.Name, 1) <> "_" Then
'show the address of the defined name range - could be more than one cell
Debug.Print Nm.RefersToRange.Address
'do not try to assign value to a range object unless that range already has been asinged a cell or cells
'rng = Nm.RefersToRange.Value
'Debug.Print rng
'this fails if Nm is more than a single cell
'var = Nm.RefersToRange.Value
'Debug.Print var
'this guarantees one cell
var = Nm.RefersToRange.Cells(1, 1).Value
Debug.Print var
End If
Next
End Sub
try the below and report back. You have not included some of your coded i am assuming...
Dim Nm As Name
Dim rng As Range
Dim wb As Workbook
Set wb = ThisWorkbook
For Each Nm In ThisWorkbook.Names
rng = Nm.RefersToRange.Value
Next
Related
I have a worksheet that contains approx 50 Named Ranges and I create a list of those named Ranges which contain data and hence need to be printed. The names of those containing data are stored in a column. I need to use these names as Print Areas in a macro to loop through and print each of these ranges on a separate page. My problem is how to select each Cell Value to use as the name of a Print Area. Any assistance would be greatly appreciated
Print Named Ranges From a List
Option Explicit
Sub PrintNamedRangesFromList()
' Define constants.
Const SRC_WORKSHEET_NAME As String = "Sheet1"
Const SRC_FIRST_CELL As String = "A2"
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source single-column range (containing the names).
Dim sws As Worksheet: Set sws = wb.Sheets(SRC_WORKSHEET_NAME)
Dim sfCell As Range: Set sfCell = sws.Range(SRC_FIRST_CELL)
Dim slCell As Range
Set slCell = sws.Cells(sws.Rows.Count, sfCell.Column).End(xlUp)
Dim srg As Range: Set srg = sws.Range(sfCell, slCell)
' For each cell of the source range, print the range
' defined by its name contained in the cell.
' Account for not existing names and names not referring to a range.
' Log the process ('Debug.Print') in the Immediate window (Ctrl+G).
Dim sCell As Range, prg As Range, pName As Name, pString As String
For Each sCell In srg.Cells
pString = CStr(sCell.Value)
On Error Resume Next ' prevent error if name not found
Set pName = wb.Names(pString)
On Error GoTo 0
If Not pName Is Nothing Then ' name found
On Error Resume Next ' prevent error if name not a range
Set prg = pName.RefersToRange
On Error GoTo 0
If Not prg Is Nothing Then ' name is a range
prg.PrintOut
Debug.Print "The range """ & pName.Name & """ referring to """ _
& pName.RefersTo & """ was processed."
Set prg = Nothing ' reset for the next iteration
Else ' name is not a range
Debug.Print "The name """ & pName.Name & """ refers to """ _
& pName.RefersTo & """ and was not processed."
End If
Set pName = Nothing ' reset for the next iteration
Else ' name not found
Debug.Print "The name """ & pString & """ was not found."
End If
Next sCell
' Inform.
MsgBox "Named ranges printed.", vbInformation
End Sub
Select the Cells and run this macro. It will loop through all the values and print the named ranges.
Sub printSelectedNamedRanges()
Dim rng as Range
set rng = Selection.Range
For Each cell In rng.Cells
shName = Range(cell.Value).Parent.Name
ActiveWorkbook.Worksheets(shName).Activate
Range(cell.Value).PrintOut
Next
End Sub
You can add this on top of previous code if You have named ranges in another named Range.
namedRange = "Put your main Named Range here "
sheetName = Range(namedRange).Parent.Name
ActiveWorkbook.Worksheets(sheetName).Activate
Range(namedRange).Select
So in you case the code will be
Sub printSelectedNamedRanges()
Dim rng as Range
namedRange = "Put your main Named Range here "
sheetName = Range(namedRange).Parent.Name
ActiveWorkbook.Worksheets(sheetName).Activate
set rng = Range(namedRange)
For Each cell In rng.Cells
shName = Range(cell.Value).Parent.Name
ActiveWorkbook.Worksheets(shName).Activate
Range(cell.Value).PrintOut
Next
End Sub
I'm trying to create a new sheet labeled with a different identifier from a range and also have two cells from other ranges included on each update. I can get the new sheets to create with a different label from a range, and have the first cell in the second range (xRg2) added to each subsequent sheet, but haven't been successful at iterating through the second range. I know I need another loop somewhere but my last nest created way too many sheet. See example below
Sub Add()
Dim xRg As Excel.Range
Dim xRg2 As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Dim wSh2 As Excel.Worksheet
Dim wSh3 As Excel.Worksheet
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Set wSh2 = ThisWorkbook.Sheets("List")
Set wSh3 = ThisWorkbook.Sheets("Template")
Set xRg2 = wSh2.Range("G66:G88")
Application.ScreenUpdating = False
For Each xRg In wSh2.Range("B66:B88")
With wBk
wSh3.Copy after:=.Sheets(.Sheets.Count)
On Error Resume Next
wSh.Name = xRg.Value
wSh.Cells(33,7) = xRg2.Value
If Err.Number = 1004 Then
Debug.Print xRg.Value & "already used as a sheet name"
End If
On Error GoTo 0
End With
Next xRg
Application.ScreenUpdating = True End Sub
So, to summarize, the goal here is to input the ranges into the code each time and have each new sheet include the first values from each range, then the second sheet the second values from each range, and so on until the xRg is at the end of it's list. I know there's only two ranges down here but the total will be 3. Also apologies on the poor variable discipline...
Thanks!
Try something like this (sorry do not like all those x... variable names)
Sub Add()
Dim c As Range
Dim wb As Workbook, ws As Worksheet, wsList As Worksheet
Set wb = ActiveWorkbook
Set wsList = wb.Worksheets("List")
Application.ScreenUpdating = False
For Each c In wsList.Range("B66:B88").Cells
ThisWorkbook.Sheets("Template").Copy after:=wb.Sheets(wb.Sheets.Count)
Set ws = wb.Sheets(wb.Sheets.Count) '<< get the just-created sheet copy
On Error Resume Next
ws.Name = c.Value
ws.Cells(33, 7) = c.EntireRow.Columns("G").Value
If Err.Number = 1004 Then
Debug.Print "'" & c.Value & "' already used as a sheet name"
End If
On Error GoTo 0
Next c
Application.ScreenUpdating = True
End Sub
I have an excel file with a list of names(names.xlsm), I want to create another new excel file(separate.xlsx) with different sheets. The name of each sheet in separate.xlsx is a name in names.xlsx and the first cell of each sheet is the same name value.
'''VBA
Sub copy_name()
Dim MyCell As Range, MyRange As Range, ws As Worksheet
Dim mybook As Workbook
Set mybook = Workbooks("names.xlsm")
Set MyRange = mybook.Sheets("names").Range("A2:A6") 'eg. five names'
Dim target As Workbook
Set target = Workbooks("separate.xlsx")
i = 1
For Each MyCell In MyRange
Set ws = target.Worksheets.Add(After:=Worksheets(Worksheets.Count)) ' create new worksheet in target file
ws.Name = MyCell.Value ' renames the new worksheet
target.Sheets(MyCell.Value).Cells(1, 1) = MyCell 'copy the value of Mycell to target sheets
i = i + 1
Next
Set mybook = Nothing
Set target = Nothing
End Sub
'''
Here is my code. It keeps showing errors and I do not know how to debug.
You can create the worksheet and name it in one line. No need to create it and then name it.
You need to fully qualify your objects
I am assuming that the workseets with the same name as in the names.xlsm do not exist in separate.xlsx. If it does then you will have to handle that separately.
Is this what you are trying?
Option Explicit
Sub Sample()
Dim wbNames As Workbook, wbSep As Workbook
Dim rng As Range, aCell As Range
Set wbNames = Workbooks("names.xlsm")
Set wbSep = Workbooks("separate.xlsx")
Set rng = wbNames.Sheets("Names").Range("A2:A6")
For Each aCell In rng
With wbSep
.Sheets.Add(After:=.Worksheets(.Worksheets.Count)).Name = aCell.Value
.Worksheets(aCell.Value).Cells(1, 1).Value = aCell.Value
End With
Next
End Sub
I'm trying to search for a string in a range using VBA. I've cobbled together some code but I keep getting a 1004 error at the "If Not" line:
Sub test1()
Dim wb As Workbook
Dim ws As Worksheet
Dim found_range As Range
Dim search_range As Range
Set wb = Workbooks("D1")
Set ws = wb.Sheets("Master data")
Set search_range = ws.Cells(147, 1).EntireRow
If Not Range(search_range).Find("Test") Is Nothing Then
'match found
Set found_range = Range(search_range).Find("Test")
Debug.Print found_range.Column
Else
MsgBox "No match found"
'no match found
End If
End Sub
Any ideas as to why I'm getting the error?
I'm kind of confused with the double .Find
If your Range.Find method already returns a Range object once, there's no need to set it twice.
Also search_range is already a Range object, so need to try to encapsulate it in another Range() object.
In fact it's the reason, you are getting the error, because it
expects a string inside the type-casted Range(<string>)
As #MathieuGuindon correctly pointed out:
It is the cause of the error, but the reason is because the
unqualified Range call is a child object of whatever the ActiveSheet
is, and you can't do Sheet1.Range(Sheet2.Cells(1, 1), Sheet2.Cells(1,> 10)) - error 1004 is thrown in OP's code because ws isn't the
ActiveSheet; qualifying the Range call with ws would have fixed the
error too... but yeah Range(someRange) is definitely redundant.
Sub test1()
Dim wb As Workbook
Dim ws As Worksheet
Dim found_range As Range
Dim search_range As Range
Set wb = Workbooks("D1")
Set ws = wb.Sheets("Master data")
Set search_range = ws.Cells(147, 1).EntireRow
Set found_range = search_range.Find("Test")
If Not found_range Is Nothing Then
Debug.Print found_range.Address
Else
MsgBox "No match found"
End if
End Sub
You could use:
Option Explicit
Sub test1()
Dim wb As Workbook
Dim ws As Worksheet
Dim found_range As Range, search_range As Range
Set wb = Workbooks("D1")
Set ws = wb.Sheets("Master data")
Set search_range = ws.Rows(147).EntireRow
Set found_range = search_range.Find(What:="Test", LookIn:=xlValues, LookAt:=xlWhole)
If Not found_range Is Nothing Then
Debug.Print found_range.Column
Else
MsgBox "No match found"
'no match found
End If
End Sub
Note:
i you want exact match you should use LookAt:=xlWhole
I'm trying to loop through the Names collection, and each Name that fits a certain size (column) requirement gets resized (called in a different sub).
When I try to pass the names returned to a Range I get below error.
"Run-time error '1004': Method 'Range' of object'_Global' failed.
Sub colCounts()
Dim wb as Workbook
Dim nm as Name
Dim rng as Range
Set wb = ActiveWorkbook
For Each nm in wb.Names
debug.print nm.Name ' verify loop returning as expected
Set rng = Range(nm.Name) 'this line throws the error when added
debug.print nm.Name & " " & rng.Columns.Count
Next nm
End Sub
I also tried passing the Name to a string first:
Dim str as String
.....
str = nm.Name
Set rng = Range(str)
Sub colCounts()
Dim wb As Workbook
Dim nm As Name
Dim rng As range
Set wb = ActiveWorkbook
For Each nm In wb.Names
Set rng = ThisWorkbook.Names(nm.Name).RefersToRange
Debug.Print nm.Name & " " & rng.Columns.Count
Next nm
End Sub