Possible to have a variable inside a range property? - excel

Is it possible to pass a variable into the .range property?
I would like the following function to work, but I can't seem to get it to work. My guess is it is something to do with how I'm calling the range property.
function computeNVEndTime()
Dim lastTime As Range
Dim totalTimes As Integer
Dim prod As New ProductionWebObj
dim ws as WorkSheet
set ws = ActiveSheet
totalTimes = prod.FindNumberOfRanges("time")
Set lastTime = ws.Range("time_" & totalTimes)
If isEmptyString(lastTime) Then
computeNVEndTime = ""
Else: computeNVEndTime = lastTime.Value
End If
End Function

It appears that totalTimes was returning 0 instead of 10, like I expected. The named ranges were not on the "ActiveSheet," but the next sheet over. Thanks for your help #TimWilliams and #peege!

Related

VBA code working when I step through it, but not when it's run

I have some basic VBA that is allowing a user to take a field from one table and use it to update another table. It works fine when I step through it, but nothing happens when I run it using F5. I don't get any errors, just nothing happens.
I think it could possibly be that the value hasn't been assigned to one of the variables before the next step occurs, but I've never had that problem before, and I've always assumed VBA wouldn't move to the next step until it had completed the one it's on?
My code is below:
Option Explicit
Sub acceptDateComp()
'set data type
Dim dtType As String
dtType = "opportunity"
'declare sheets
Dim wsComp As Worksheet
Set wsComp = ThisWorkbook.Sheets(dtType & "Comp")
Dim wsBCE As Worksheet
Set wsBCE = ThisWorkbook.Sheets(dtType & "Snapshot")
Dim wsOffline As Worksheet
Set wsOffline = ThisWorkbook.Sheets(dtType & "Database")
'declare tables
Dim bce As ListObject
Set bce = wsBCE.ListObjects(dtType & "Snapshot")
Dim offline As ListObject
Set offline = wsOffline.ListObjects(dtType & "Database")
Dim dateComp As ListObject
Set dateComp = wsComp.ListObjects(dtType & "DateComp")
'declare heights and areas
Dim offlineRange As Range
Set offlineRange = offline.ListColumns(1).DataBodyRange
'check for acceptance, then change values
Dim i As Long
Dim dateID As Long
Dim offlineRow As Long
Dim bceDate As String
For i = 2 To dateComp.ListRows.Count + 1
If dateComp.ListColumns(6).Range(i).Value = "Yes" Then
dateID = dateComp.ListColumns(1).Range(i).Value
offlineRow = Application.WorksheetFunction.Match(dateID, offlineRange, 0)
bceDate = dateComp.ListRows(i - 1).Range(5).Value
offline.ListRows(offlineRow).Range(12).Value = bceDate
End If
Next i
Call opportunityComp
End Sub

Is there a way to reassign a Range variable to a different range?

I am very new to VBA, having started programming it yesterday. I am writing a data processing program which requires keeping track of two cells, one on each spreadsheet. The code which reproduces the errors I am experiencing is below. When I call the sub moveCell() in sub Processor(), nothing happens to DIRow and DIColumn, and the code spits out error 1004 at the line indicated. I have tried using DICell = DICell.Offset(), but it returns the same error.
How can I redefine a Range variable to be a different cell?
'<<Main Processor Code>>'
Sub Processor()
Dim PDRow As Integer
Dim PDColumn As Integer
Dim DIRow As Integer
Dim DIColumn As Integer
PDRow = 1
PDColumn = 1
DIRow = 1
DIColumn = 1
Dim PDCell As Range
Dim DICell As Range
Set PDCell = Worksheets("Processed Data").Cells(PDRow, PDColumn)
Set DICell = Worksheets("Data Input").Cells(DIRow, DIColumn)
Call moveCell(2, 0, "Data Input")
End Sub
'<<Function which moves the cell which defines the range>>'
Sub moveCell(r As Integer, c As Integer, sheet As String)
If sheet = "Processed Data" Then
PDRow = PDRow + r
PDColumn = PDColumn + c
Set PDCell = Worksheets("Data Input").Cells(PDRow, PDColumn)
ElseIf sheet = "Data Input" Then
DIRow = DIRow + r '<<<<<<This line does nothing to DIRow's value
DIColumn = DIColumn + c
Set DICell = Worksheets("Data Input").Cells(DIRow, DIColumn) '<<<<<<This line causes error 1004
End If
End Sub
As far as I can tell, you could instead use a quick Function instead. There doesn't seem to be any difference in your If statement results in the moveCell() function, except which worksheet you're using.
We can make this simpler by referring to the Range you're passing to moveCell.
Option Explicit ' forces you to declare all variables
Sub something()
Dim PDCell As Range
Set PDCell = Worksheets("Processed Data").Cells(1, 1)
Dim DICell As Range
Set DICell = Worksheets("Data Input").Cells(1, 1)
PDCell.Select ' can remove
Set PDCell = moveCell(2, 0, PDCell, PDCell.Worksheet.Name)
PDCell.Select ' can remove
Worksheets(DICell.Worksheet.Name).Activate ' can remove
DICell.Select ' can remove
Set DICell = moveCell(5, 0, DICell, DICell.Worksheet.Name)
DICell.Select ' can remove
End Sub
Function moveCell(rowsToMove As Long, colsToMove As Long, cel As Range, ws As String) As Range
Set moveCell = Worksheets(ws).Cells(cel.Row + rowsToMove, cel.Column + colsToMove)
End Function
I've included some rows you don't need (which I've marked with a comment afterwards), but that will show you how the routine works. You can step through with F8 to help see it step-by-step.
Edit: Although, you don't need a separate function at all. Just use OFFSET().
Set PDCell = ...whatever originally
Set PDCell = PDCell.Offset([rows],[cols])

Does Excel VBA WorksheetFunction need to use a select to be on the proper worksheet

I have the following code, but I have to select the worksheet otherwise the WorksheetFunction will return an error:
Function Find_Allocation_Acct_Row_Number(allocation_acct As String, allocation_cc As String)
Dim WS As Worksheet
Dim CC_row As Integer
Dim search_rng As Range
Set WS = Sheets(allocation_cc)
WS.Select
Set search_rng = WS.Range("E1:E2000")
CC_row = WS.Application.WorksheetFunction.Match(allocation_acct,search_rng, 0)
Find_Allocation_Acct_Row_Number = CC_row + 4
End Function
How can I select the right range on the right worksheet without using the Select command?
To be clear, I will ALWAYS find the value. I just need to return the row so I can create a range from it.
I have tried a number of different ways to change the "search_rng" to different variables or expressions of Range but no luck.
The error I am getting is:
Run-time error '1004':
Unable to get the Match property of the WorksheetFunction class
If the match is not found it will kick out an error and stop the code. If we late bind the match and send the result to a variant we can test for the error:
Function Find_Allocation_Acct_Row_Number(allocation_acct As String, allocation_cc As String) As Long
Dim WS As Worksheet
Set WS = Worksheets(allocation_cc)
Dim search_rng As Range
Set search_rng = WS.Range("E1:E2000")
Dim CC_row As Variant
CC_row = Application.Match(allocation_acct, search_rng, 0)
If Not IsError(CC_row) Then
Find_Allocation_Acct_Row_Number = CC_row + 4
Else
Find_Allocation_Acct_Row_Number = -1
End If
End Function
Now if a match cannot be found it will return -1

Runtime Error 9 on Loop

I have three workbooks; all with information on the same policies, but come from different documents. I'm trying to copy the value of the same cell from each worksheet that has the same worksheet name in workbooks 1 & workbook 3. This is the code that I have:
Sub foo()
Dim wbk1 As Workbook
Dim wbk2 As Workbook
Dim wkb3 As Workbook
Dim shtName As String
Dim i As Integer
Set wkb1 = Workbooks.Open("C:\Users\lliao\Documents\Trad Reconciliation.xlsx")
Set wkb2 = Workbooks.Open("C:\Users\lliao\Documents\TradReconciliation.xlsx")
Set wkb3 = Workbooks.Open("C:\Users\lliao\Documents\Measure Trad Recon LS.xlsx")
shtName = wkb2.Worksheets(i).Name
For i = 2 To wkb2.Worksheets.Count
wkb2.Sheets(shtName).Range("D3").Value = wkb1.Sheets(shtName).Range("D2")
wkb2.Sheets(shtName).Range("E3").Value = wkb1.Sheets(shtName).Range("E2")
wkb2.Sheets(shtName).Range("F3").Value = wkb1.Sheets(shtName).Range("F2")
wkb2.Sheets(shtName).Range("D4").Value = wkb3.Sheets(shtName).Range("D2")
wkb2.Sheets(shtName).Range("E4").Value = wkb3.Sheets(shtName).Range("E2")
wkb2.Sheets(shtName).Range("F4").Value = wkb3.Sheets(shtName).Range("F2")
Next i
End Sub
I don't understand how I'm using the subscript wrong. This is my first time coding VBA (first time in 5+ years), so I'm unfamiliar with coding errors.
Thank you!
Dim i As Integer
Set wkb1 = Workbooks.Open("C:\Users\lliao\Documents\Trad Reconciliation.xlsx")
Set wkb2 = Workbooks.Open("C:\Users\lliao\Documents\TradReconciliation.xlsx")
Set wkb3 = Workbooks.Open("C:\Users\lliao\Documents\Measure Trad Recon LS.xlsx")
shtName = wkb2.Worksheets(i).Name
Variable i is declared, but used before it's assigned - its value is therefore an implicit 0.
With VBA collections being 1-based, that makes wkb2.Worksheets(i) be out of bounds.
Dim i As Integer
i = 1
'...
shtName = wkb2.Worksheets(i).Name
Will fix it.
You probably want to move it inside the loop though.
may be you're after this:
For i = 2 To wkb2.Worksheets.Count
wkb2.Sheets(i).Range("D3:F3").Value = wkb1.Sheets(i).Range("D2:F2")
wkb2.Sheets(i).Range("D4:F4").Value = wkb3.Sheets(i).Range("D2:F2")
Next i

How do I use the returned values from the find function?

I just want to be able to search a range of cells for a value from a combobox then if found store it somewhere to be used in a bunch of other calculations but I can't get it to work at all.
I really don't understand what the find function is actually doing. Does it return a range variable that identifies where the input has been found? And if so how do I reference/use that range?
Please don't just post code without an explanation I would really like to understand what is going on here.
Sub run_averages()
Dim x As Integer
Dim rngFindValue As Range
Set dd = ActiveSheet.DropDowns("thing")
Set aa = ActiveSheet.DropDowns("otherthing")
With Range("E3:DI3")
Set rngFindValue = .Find(What:=" & aa &", _
After:=ActiveSheet.Range("E3"), LookIn:=xlFormulas)
With rngFindValue
rngFindValue.Active
End With
End With
End Sub
using the following code as you did:
Set rngFindValue = .Find(What:=" & aa....
You reference found cell as Range. Therefore if you want to work with values of that particular cell, you can work with it as with any Range() -> rngFindValue.Value
Try this out:
Dim x As Long
Dim myitem As String, rngFindValue As Range
x = Activesheet.Shapes("thing").ControlFormat.Value
myitem = Activesheet.Shapes("thing").ControlFormat.List(x)
With Range("E3:DI3")
Set rngFindValue = .Find(what:=myitem, after:=[DI3], LookIn:=xlFormulas)
rngFindValue.Select '~~> or do whatever you want with your found range
End With
I am going nuts here ! I cannot understand the error messaging that I'm being given.
Sub run_averages()
Dim x As Integer
Dim rngFindValue As Range
Dim rngFindstart As Range
Dim myitem As Integer
Set dd = ActiveSheet.DropDowns("thing_length")
Set aa = ActiveSheet.DropDowns("thing_date")
myitem = ActiveSheet.Cells(5, 1).Value
' using beans text to make sure error is not coming from drop down reference
Set rngFindValue = Range("E3:DI3").Find(What:="beans", After:=ActiveSheet.Range("E3"), LookIn:=xlFormulas)
With ActiveSheet
.Range(.Cells(3, 1), .Cells(rngFindValue.Row, rngFindValue.Column)).Select
End With
End Sub
It is telling me that "Run time error 91 Object variable or With block not set" if rngFindValue is the only object i am using then it has been set by the fact it is created..
What object does not exist ?
I am clearly missing something fundamental.
Thanks.
Wait. I'm a noob. There was no "beans" text in the document so it was giving me that error...

Resources