VBA Excel select a range of cells within a named range - vba

I have a Named Range col_9395 it is an entire column. I want to set a range within this Named range. I want the range to start at row 3 to row 200 of same column. Whats the best way to do this?
Original working line without Named Range:
Set rngBlnk = Sheet108.Range("T3:T200").SpecialCells(xlCellTypeBlanks)
This is the code I tried with no luck:
Set rngBlnk = Range("col_9395)(3,1):Range("col_9395)(200,1).SpecialCells (xlCellTypeBlanks)

Might be wrong, but I find this the easiest one:
Private Sub Test()
Dim rngBlnk As Range
Set rngBlnk = Range("col_9395").Rows("3:200").SpecialCells(xlCellTypeBlanks)
End Sub

You can see the sort of logic with
Option Explicit
Sub test()
Dim colToUse As Long
colToUse = ThisWorkbook.Worksheets("Sheet1").Range("ol_9395").Column
With ThisWorkbook.Worksheets("Sheet1")
Debug.Print .Range(.Cells(3, colToUse), .Cells(200, colToUse)).Address
End With
End Sub

Sub t()
Dim rng As Range
Set rng = Range("col_9395") ' for easier use
Dim blnkRng As Range
Set blnkRng = Range(Cells(rng.Rows(3).Row, rng.Column), Cells(rng.Rows(200).Row, rng.Column)).SpecialCells(xlCellTypeBlanks)
blnkRng.Select
End Sub
What I did was assign your named range to a variable (just for easier referencing). Then using the Range() property, I used the 3rd and 200th row of your named range to set the range to look for blank cells.
The idea is that this will help you in the event your named range isn't simply an entire column. It will get the relative 3rd and 200th row from your named range.

Option Explicit
Public Sub TestMe()
Dim rngBlnk As Range
Dim firstCell As Range
Dim lastCell As Range
Set firstCell = [col_9395].Cells(3, 1)
Set lastCell = [col_9395].Cells(200, 1)
If WorksheetFunction.CountBlank(Range(firstCell, lastCell)) > 0 Then
Set rngBlnk = Range(firstCell, lastCell).SpecialCells(xlCellTypeBlanks)
End If
End Sub
A kind of a problem with SpecialCells and assigning to them is that if there are no cells from the specific type, it throws an error.
Thus, there is a check with WorksheetFunction.CountBlank()>0, before the setting of rngBlnk to the special cells.

I'm late to the party, I know, but maybe this will help someone. I've stumbled on a technique that I don't see presented as an option in any of the handful of "range-in-a-range" questions here.
I discovered you can ask VBA for a range of a range directly. I have formatted some data as a Table, but it could be simply a Named Range, or even an unnamed range I suppose. My code that is working looks like this:
With Workbooks(Filename)
.Worksheets(tabName).Activate
.Worksheets(tabName).Range("SummaryBand").Range("B2:R2").Copy
End With
My Table is named SummaryBand, which due to a previous step was not necessarily always in the same absolute position on the spreadsheet, but I wanted an absolute Range within SummaryBand. In this example, "B2:R2" is the absolute position within the Table, with the top left cell of the Table being A1.

Related

Application.Caller / Storing worksheet name as string

Im trying to store the CurrentWorksheet name in order to reference it in a different Sub routine.
The code I currently have is as follows:
Private Sub InsertNewBill_Click()
Dim rng As Range
Set rng = Worksheets(CurrentWorksheet).Range("A30:L30")
rng.Insert Shift:=xlDown
End Sub
Current Worksheet Function:
Function CurrentWorksheet()
CurrentSheet = Application.Caller.Worksheet.Name
End Function
I need to try to reference the "CurrentSheet" variable in the "InsertNewBill" Sub routine.
The function of this is to insert a new line of cells between "A30:L30" on the currently selected worksheet.
Thanks in advance
I didn't plan to write this as answer, but to explain to Batteredburrito how to deal with objects rather than names:
Option Explicit
Private Sub InsertNewBill_Click()
Dim rng As Range
Set rng = currentWorksheet.Range("A31:AC31")
rng.Insert Shift:=xlDown
End Sub
Current Worksheet Function
Function currentWorksheet() As Worksheet
set currentWorksheet = ActiveSheet
End Function
This is doing exactly the same as your version (so you can stick with that), it's just to show how to deal with objects. But there are situations where it is much better to deal with objects that with name - especially if you are dealing with multiple Workbooks (that might have the same sheet names).
And, of course, in the end you could get rid of the function completely by simply writing
...
Set rng = ActiveSheet.Range("A31:AC31")
...
Thank you all for your help and direction.
I have resolved the issue with the following
Insert new cells between a range of cells on button press:
Private Sub InsertNewBill_Click()
Dim rng As Range
Set rng = Worksheets(CurrentWorksheet).Range("A31:AC31")
rng.Insert Shift:=xlDown
End Sub
Current Worksheet Function:
Function CurrentWorksheet()
CurrentWorksheet = ActiveSheet.Name
End Function

Am I using the Columns() property improperly, and if so, is there a good workaround?

I'm currently in the process of solving a
type mismatch error
in a macro I'm writing, and I've written a short subroutine to drill down on the specific issue. This subroutine should loop through all of Column A, entering the numbers 1-10 in rows 1-10.
Sub looptest()
Dim rRange As Range
Dim rCell As Range
Dim i As Integer
Set rRange = ThisWorkbook.Worksheets(1).Columns(1)
i = 0
For Each rCell In rRange
If i < 10 Then
i = i + 1
rCell.Value2 = i
End If
Next rCell
End Sub
Instead this fills every cell in Column A with 1. Stepping through it in debug mode shows that instead of referencing a single cell, rCell references the entire column.
I have found that if I replace
Set rRange = ThisWorkbook.Worksheets(1).Columns(1)
with
Set rRange = ThisWorkbook.Worksheets(1).Range("A1:A100")
the macro works as intended, however I'd prefer to be able to use Columns() or something similar in my production code.
Am I using the Columns() property improperly, and if so, is there a good workaround?
Begin with these changes:
Set rRange = ThisWorkbook.Worksheets(1).Columns(1).Cells
Dim i As Long
Using the .Cells lets us loop over the cells in a column rather than columns in a worksheet.

Remove error values from array

Say that I have a UDF function:
Dim arr() as variant, rng as range
set rng = some range
arr=rng
Function=worksheetfunction.sum(arr)
If rng contains errors a values, how would I go about removing them from the arrray and not from the sheet?
I'd rather not do For each-statement looping through ranges in rng. I'd rather be able to remove them from the array.
This is more a general questions than anything.
I would suggest to add them to a Collection, since these works better with dynamic size (you could also use Scripting.Dictionary. Then loop through the range, and add non-error cell values to the collection.
I know the example doesn't meet your requirement for not looping each element. But unless you have a specific reason to keep your data as a range, I don't really see an advatage of this. There are other data structures, which are more suited for further processing of the data.
Simple example:
Sub FindNonErrorCells()
Dim rng As Range
Dim cell As Range
Dim coll As Collection
'Insert your range here
Set rng = Sheets("Sheet1").Range("C1:C5")
Set coll = New Collection
For Each cell In rng
If Not IsError(cell) Then
coll.Add cell.Value
End If
Next cell
End Sub

return absolute reference number

I am using follow code to find maximum value in a column. I need to know absolute reference number of where that value is found. I am hoping to use that absolute reference number in FOR loop and check what is in adjacent cells of where that value is found.
rng = Application.WorksheetFunction.Max(Columns("H"))
I have tried using match but I am getting error 2042.
adrs = Application.Match(rng, Range("H:H"), 0)
Is there a way to find out where that maximum value resides?
Please note I am searching for time stamps so wrapping rng in CLNG is not an option.
Or simply this?
Dim rng As Range
Set rng = Columns("H").Find(Application.Max(Columns("H")))
If Not rng Is Nothing Then
MsgBox rng.Address(0, 0)
End If
Try this:
Dim rng As Range
Dim maxValue As Integer
'you set your area that you get mxaimum value from
Set rng = Range("H:H")
'determine the maximum value
maxValue = Application.WorksheetFunction.Max(rng)
'select cell which contains found value
'(Find returns Range objects, so you can use it as you like)
rang.Find(maxValue).Select
You need to make sure that you are using the correct references.
For example, if the code is running off Sheet1 and the data is in Sheet2 then it is possible you will get errors. Trying this as an example I got the Error 2042 for the adrs variable when the code and the data were on different WorkSheets.
Also, always remember to Option Explicit this will force you to delcare your variables.
Try the following:
Option Explicit
Sub FindMaxValueAndReturnRowNum()
Dim SomeWorkSheet As Worksheet
'Here you can change the Sheet1 to that of you data sheet name
Set SomeWorkSheet = ThisWorkbook.Sheets("Sheet1")
Dim MaxNum As Long
Dim adrs As Long
'Notice the reference to where the code needs to evaluate
'if there is no reference to a specific sheet then it will use the active sheet.
MaxNum = Application.WorksheetFunction.Max(SomeWorkSheet.Columns("H"))
'adrs will return the row number
adrs = Application.Match(MaxNum , SomeWorkSheet.Range("H:H"), 0)
End Sub

Excel VBA "Autofill Method of Range Class Failed"

The following VBA code (Excel 2007) is failing with Error 1004, "Autofill Method of Range Class Failed.". Can anyone tell me how to fix it?
Dim src As Range, out As Range, wks As Worksheet
Set wks = Me
Set out = wks.Range("B:U")
Set src = wks.Range("A6")
src.AutoFill Destination:=out
(note: I have Googled, etc. for this. It comes up fairly often, but all of the responses that I saw had to do with malformed range addresses, which AFAIK is not my problem.
At someone's suggestion I tried replacing the autofill line with the following:
src.Copy out
This had the effect of throwing my Excel session into an apparent infinite loop consuming 100% CPU and then just hanging forever.
OK, apparently the source has to be part of the destination range for autofill. So my code now looks like this:
Dim src As Range, out As Range, wks As Worksheet
Set wks = Me
Set out = wks.Range("B1")
Set src = wks.Range("A6")
src.Copy out
Set out = wks.Range("B:U")
Set src = wks.Range("B1")
src.AutoFill Destination:=out, Type:=xlFillCopy
Same error on the last line.
From MSDN:
The destination must include the
source range.
B:U does not contain A6 and thus there is an error. I believe that you probably want out to be set to A6:U6.
Specifiying just the column name means that you want to fill every row in that column which is unlikely to be the desired behvaiour
Update
Further to the OP's comment below and update to the original answer, this might do the trick:
Dim src As Range, out As Range, wks As Worksheet
Set wks = Me
Set out = wks.Range("B1")
Set src = wks.Range("A6")
src.Copy out
Set out = wks.Range("B1:U1")
Set src = wks.Range("B1")
src.AutoFill Destination:=out, Type:=xlFillCopy
Set out = wks.Range("B:U")
Set src = wks.Range("B1:U1")
src.AutoFill Destination:=out, Type:=xlFillCopy
AutoFill is constrained to a single direction (i.e. horizontal or vertical) at once. To fill a two-dimensional area from a single cell you first have to auto-fill a line along one edge of that area and then stretch that line across the area
For the specific case of copying the formatting and clearing the contents (by virtue of the source cell being empty), this is better:
Dim src As Range, out As Range, wks As Worksheet
Set wks = Sheet1
Set out = wks.Range("B:U")
Set src = wks.Range("A6")
src.Copy out
To make AutoFill work, you need to make the range of AutoFill more than the source range. If the AutoFill range is same as of Source range then there is nothing to AutoFill in that range and hence you would get an error
1004: AutoFill method of Range class failed.
So make AutoFill range more than the source range and error will gone.
If you want to autofill you just do something like...
Private Sub Autofill()
'Select the cell which has the value you want to autofill
Range("Q2").Select
'Do an autofill down to the amount of values returned by the update
Selection.AutoFill Destination:=Range("Q2:Q10")
End Sub
This would autofill down to the specified range.
Does ths help?
Not sure if this helps anyone, but I needed something similar. Selecting the cells as destination works;
dim rowcount as integer
Sheets("IssueTemplate").Select ' Whatever your sheet is
rowcount = 0
rowcount = Application.CountA(Range("A:A"))'get end range
Cells(4, 3).Select 'select the start cell
'autofill to rowcount
Selection.AutoFill Destination:=Range("C4:C" & rowcount), Type:=xlFillDefault
in my example I had to auto-generate a list of folder names from OA100 to OA###?, and this worked fine.