VBA Range using a variable to set a location - vba

I want to have my program begin a count at a specific location defined by a variable. I know that you can use rn = sh.Cells(9, 1) for example, and the variable rn is now holding the location of cells(9,1). But when I use the variable rn in my count command, I am getting the following error:
Method 'Range' of object' _worksheet' failed
Here's my code:
Option Explicit
Sub Struc_Equa()
Dim n As Integer
End sub
Sub countN(n)
Dim sh As Worksheet
Dim rn As Range
Dim SheNa As String
SheNa = ActiveSheet.Name
Set sh = ThisWorkbook.Sheets(SheNa)
Set rn = sh.Cells(9, 1)
' The command below does not work
'n = sh.Range(rn, sh.Range(rn).End(xlToRight)).Columns.Count
' I am able to do what I want but in a inefficient way (shown below)
'n = sh.Range("A9", sh.Range("A9").End(xlToRight)).Columns.Count
rn.Activate
MsgBox (n)
End Sub
Why is this error happening?

Try this:
n = sh.Range(rn, rn.End(xlToRight)).Columns.Count
It follows the Range([Cell1],[Cell2]) syntax.
Remember that rn is already a fully referenced range address so you can use it directly as arguments to Range object. More about Range Syntax.
Why does your original code fail?
Because based on this article, in Range(arg) syntax, arg names the range.And take note that Range Object's default property is Value.
So your code:
sh.Range(rn).End(xlToRight)
is actually evaluating the value of rn and supplies it as arg for the Range(arg) syntax. If the value of that cell is not a valid cell or range address (or name as the article mentioned), it will throw an error. Above actually evaluates like below:
sh.Range("value from rn range object").End(xlToRight)
If you try changing the value of that cell with a valid cell or range name/address, it will work. For example:
With sh
Set rn = .Cells(9, 1)
rn.Value2 = "A9"
n = .Range(rn, .Range(rn).End(xlToRight)).Columns.Count
MsgBox n
End With
In short:
Range(arg) expects a valid range name or address.
Range([cell1],[cell2]) expects a valid range object reference.

Related

VLookUp not working - Property could not be assigned

My problem is, that when using the VlookUp I do get the Error:
The VLookup-Property of the WorksheetFunction-Object could not be assigned
' LookUp missing Data
Dim lookupRange As Range
Set lookupRange = Sheets("Kundenlisten HLK 2018").Range("A1:Y10354")
' Fill in Companyname
Dim tmp As String
tmp = Values(0)
tmp = TrueTrim(tmp)
testing.Cells(8, counter) = Application.WorksheetFunction.VLookup(tmp, lookupWS.Range("A2:Y10354"), 2, False)
Values = None
counter = counter + 1
lookupWS is the Name of the Worksheet
As you can see the table I am trying to lookup is filled with values from A to Y. The first column is the key I am trying to look up, but then the error from above occurs. The tmp variable is a String with a unique ID to look up the missing values, while the "2" is supposed to be the company name in the second column of the Range.
I looked up on the docs, but the types and everything are fine, I even checked while debugging.
testing.Cells(8, counter) can't be the source of the problem aswell, since I am using it before like this
testing.Cells(28, counter) = Left(mail.ReceivedTime, 10)
and it works
It's difficult to know what the problem is without any data, but here's something to help you in the right direction.
It's better to use Find and Offset than
WorksheetFunction.Vlookup in VBA
Something like this gives you exactly the same result, but you have much more control:
Sub Test()
Dim valueFound As Range
Set valueFound = lookupWS.Range("A2:A10354").Find(What:="Something", lookat:=xlWhole) 'xlWhole is equivalent to FALSE in VLOOKUP
If valueFound Is Nothing Then
MsgBox "Nothing found"
Else
MsgBox valueFound.Offset(0, 1) 'offsetting by 1 is equivalent to using 2 in a VLOOKUP
End If
End Sub

deactivate the current sheet before going to another sheet

I am getting error while swapping with two sheets.
I open one sheet and paste some data in this,after that I call a function which opens another sheet.but when I again paste data in the first sheet it throws error.
For y = 1 To size
Set src = Workbooks.Open("C:Template\Mapping.xlsx")
Worksheets("Sheet1").Activate
Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc"
newValue= getNewValue()
rowCntr=rowCntr+1
Next
public Function getNewValue()
Dim newV=123
Set src = Workbooks.Open("C:Template\Mapping - Development v1.0.xlsx")
getNewValue=newV
End Function
For the first time it works properly but after calling the function getNewValue() it throws error "Subscript out of range" at Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc" line.
Please help.
Your code example is incomplete. Noteably, it doesn't define what src is, but that is exactly what the error is: I must assume that srcis a global variable and you set src in both your main function and in function getNewValue.
When getNewValue returns, src now points to another workbook in which your ranges don't exist.
Further I am not sure whether opening the workbook again and again results in it being reloaded, reset or that multiple copies will be opened. I suggest you open them only once, e.g.:
Dim src as Object
Dim src2 As Object
Function main (size As Integer)
Dim y As Integer
Dim rowCntr As Integer
Set src = Workbooks.Open("C:Template\Mapping.xlsx")
Set src2 = Workbooks.Open("C:Template\Mapping - Development v1.0.xlsx")
For y = 1 To size
src.Worksheets("Sheet1").Activate
src.Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc"
newValue= getNewValue()
rowCntr=rowCntr+1
Next
End Function
Public Function getNewValue()
Dim newV
newV = 123
'...whatever you want to do...
getNewValue = newV
End Function
no need for selection/activation, use objects (workbook, range) reference instead, like follows
Set src = Workbooks.Open("C:Template\Mapping.xlsx") '<~~ open workbook outside the loop since it doesn't depend on it
For y = 1 To size
src.Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc" '<~~ use "src" workbook reference to point to it whatever may be the currently active workbook
newValue= getNewValue()
rowCntr=rowCntr+1
Next

VBA Range is Nothing

Running the code below and what I'm hoping to see as a result is to have all columns with 0s on row 27 hidden - but depending on the frequency of the data, the range for those columns to be hidden is different. Basically anything that is in a sheet that starts with Daily/monthly/weekly will have to have columns hidden, all the rest of the sheets should be left alone.
It worked on a simple workbook using an if statement (sheets starting with X vs. all other), but when I added the case statement it broke...
The line marked down with bold is the one where I get an error:
Run-time error '1004'
Application-defined or object-defined error
I'm new to this, so please feel free to suggest a good vba tutorials website/book.
Sub Hide_Zero_Columns()
Dim WS As Worksheet
Dim Col_to_hide As Range
Dim Range_to_hide As Range
Dim X As Integer
For Each WS In ThisWorkbook.Sheets
Worksheets(WS.Name).Activate
With WS
Select Case Data_Frequency_Sheets
Case Left(WS.Name, 5) = "Daily"
Set Range_to_hide = Range("BDV$27:CWH$27")
Case Left(WS.Name, 5) = "Month"
Set Range_to_hide = Range("AY$27:CO$27")
Case Left(WS.Name, 5) = "Weekl"
Set Range_to_hide = Range("HF$27:NN$27")
Case Else
Set Range_to_hide = Range("A1:B1")
End Select
Select Case Data_Condition
Case Left(WS.Name, 5) = "Daily"
X = 1
Case Left(WS.Name, 5) = "Month"
X = 30
Case Left(WS.Name, 5) = "Weekl"
X = 7
Case Else
X = 999
End Select
If X <> 999 Then
For Each Col_to_hide In ActiveSheet.Range(Range_to_hide) '<-- Error here
If UCase(Col_to_hide) = 0 Then
Col_to_hide.EntireColumn.Hidden = True
Else: Col_to_hide.EntireColumn.Hidden = False
End If
Next Col_to_hide
End If
End With
Next
ActiveWorkbook.Worksheets("Registrations").Activate
End Sub
Since you have already defined a Range, you the problem is you are trying to evaluate: Sheet.Range(Range) which throws the error you are getting.
Since it appears you are wanting to iterate across the columns, all you need to do is change the line to this:
' Iterate across the columns in the defined range.
For Each Col_to_hide In Range_to_hide.Columns
' Each "Col_to_hide" will represent all cells within the column.
MsgBox Col_to_hide.Address
The error you're getting is because you're passing a Range object as the argument to Activesheet.Range() and it doesn't accept that because of the Range object's default value. It would be like doing this in the Immediate Window
?Range(Range("A1")).Address
You'll get the same error. Whereas with
?Range("A1").Address
You don't. You could do this too
?Range(Range("A1").Address).Address
So the thing is that when you don't specify a property for an object, like Range("A1") instead of Range("A1").Address, then the default property is used. The Range object is a bit strange, but in this case its default property is the Value property. So Activesheet.Range(Range_to_hide) is the same as Activesheet.Range(Range_to_hide.Value). And if Range_to_hide is a multi-cell range, then it's Value property returns an array, which you definitely can't pass into a Range's argument.
That's the explanation, the short answer is simply to use Range_to_hide, like
For Each Col_to_hide in Range_to_hide.Columns
Why the .Columns. Remember when I said that the Range object was a little strange. Well, unlike most objects, it has two default properties based on the context you're using it in. Earlier, the default property was Value, but in the context of a For..Each, the default value is Cells. If you don't specify .Columns in your For..Each, then it will loop through every cell in the Range. In fact, I always specify how the range is aggregated, even if it's the default Cells.

Range object returns empty values

I have a set range to a variable in this fashion:
Dim srcRng As Range
Set srcRng = Range(hrwb.Worksheets(1).Range(yomColAddress)(1).Address, _
Cells(hrwb.Worksheets(1).Range(yomColAddress).row + 200, rightMostCol)(1).Address)
for some weird reason when I call
srcRng(1) 'actually instead of 1 is i that runs 1 to srcRng.Count
it doesn't return the upper leftmost cell value. Any ideas why?
(for those who are not familiar with this technique: http://www.cpearson.com/excel/cells.htm)
Informations:
at execution time the variables yomColAddress=$AL$9 and righMostCol=40
hrwb.Worksheets(1).Range(yomColAddress)(1) works as expected.
With MsgBox srcRng(1).Address & " value:" & srcRng(1).Value I get "$AL$9 value:"
The value of AL9 is the text "yom"
The actual code is:
Dim srcRng As Range
Set srcRng = Range(hrwb.Worksheets(1).Range(yomColAddress)(1).Address, Cells(hrwb.Worksheets(1).Range(yomColAddress).row + 200, rightMostCol)(1).Address)
Dim i As Integer
i = 1
While (weekDayCol = 0 And i <= srcRng.count)
If loneHebDayLetter("à", "ä", srcRng(i)) Then'loneHebDayLetter checks some conditions on a cell
weekDayCol = srcRng(i).Column
End If
i = i + 1
Wend
I think I get what goes wrong here:
The code itself is working well but not on the good data (This is a supposition but I just did some tests with a custom workbook)
Short version
Just add srcRng.Select after Set srcRng (no real interest but to understand what it does) and I think you will get what happens if my supposition is correct.
Longer version
When you do Set srcRng = ... it does create the correct Range but it is not linked to any sheet actually ... It just means remember a Range which goes from cell X to cell Y.
The point is: The sheet (let's say "sheet2") where your code is executed isn't the same as the one where the datas are (say "sheet1") so srcRng(1) is understood as Sheets("sheet2").srcRng(1) instead of Sheets("sheet1").srcRng(1) (<- that's what you want)
Even if not elegant, this should work:
Dim srcRng As Range
With hrwb.Worksheets(1)
Set srcRng = Range(.Range(yomColAddress)(1).Address, Cells(.Range(yomColAddress).row + 200, rightMostCol)(1).Address)
Dim i As Integer
i = 1
While (weekDayCol = 0 And i <= srcRng.count)
If loneHebDayLetter("à", "ä", .Range(srcRng.Address)(i).Value) Then 'I assume it take the value not the cell: if it take the cell you may get an error!
weekDayCol = srcRng(i).Column
End If
i = i + 1
Wend
End With
What is important is the use of .Range(srcRng.Address)(i).Value to access the value in the right worksheet! (That's why this trick is not needed here: srcRng(i).Column because colum numbers do not change from one sheet to an other)
(NOTE: I used with to optimize/clarify the code)
If something isn't clear tell me

excel VBA End method on Range object -- application-defined or object-defined error

I'm experiencing an error with using the End method of the range object.
The code below is an excerpt from my program, and when I get to the last line I get the following error: "Application defined or Object Defined error"
Sub DataGroup(testCell, j, k)
Dim archive As Range
Set dataCellsA = Worksheets("DATA").Range("B2")
Set dataCellsB = Worksheets("DATA").Range("I2")
For i = 0 To 30
Set currentLine = testCell.Offset(i, 0)
Set archive = Worksheets("ARCHIVE").Range("B4").End(x1Down)
However, in a later portion of my program I have what appears to be the same implementation, but I don't receive any errors with this portion.
Set dataCellsA = Worksheets("DATA").Range("C2")
Set dataCellsB = Worksheets("DATA").Range("J2")
Dim lastCellA As Range
Dim lastCellB As Range
Set lastCellA = dataCellsA.End(xlDown)
Set lastCellB = dataCellsB.End(xlDown)
Whats the difference between the two? I'm making sure to declare my variables as ranges, and I'm careful to use the "Set" prefex to ensure that it is an object, and not the value.
So, here is the answer: you have x1Down where you should have xlDown (1 instead of l)