I wish to read in a range that is based using a named cell reference.
The named cell reference is "AggStatsStart" and refers to AggOutput!$A$2
I also have a integer variable called "NoCohort" = 1000.
I want to use the two variables to read in the range C3:Q1000. Note the offset from AggStatsStart
So far I have the following:
Dim testRange As Range
Dim Input As Variant
With Sheets("AggOutput")
Set testRange = .Range("AggStatsStart", .Cells(NoCohort, 15))
End With
Input = Range(testRange)
After fixing several small syntax errors:
Sub BenWhite()
Dim testRange As Range
Dim Inputt As Variant
Dim NoCohort As Integer
NoCohort = 1000
With Sheets("AggOutput")
Set testRange = .Range(Range("AggStatsStart"), .Cells(NoCohort, 15))
MsgBox testRange.Address(0, 0)
End With
Inputt = testRange
End Sub
Related
I'm trying to set a range in VBA as the range of the inputted string that I am looking for. The full procedure is supposed to pop up a dialog box to look for a specific string, find the string, create a range called location, set this range to the range of the string that was found, move a finite amount of columns to the right, and with that new columns value, print a string into that range.
The problem right now is that for some reason It is not setting the range to the range of the string it finds.
There is only one instance of the string throughout the workbook.
I'm also relatively new to VBA so there are something commands I don't know or understand how they work.
Sub test()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim Inp As String
Dim Loc As Range
Dim Row As Integer
Dim Col As Integer
Dim NewLoc As Range
Dim Sh As Worksheet
Inp = InputBox("Scan ESD Tag")
For Each Sh In ThisWorkbook.Worksheets
With Sh.Columns("A")
Set Loc = .Find(What:=Inp)
End With
Next
Row = Loc.Row
Col = Loc.Column + (3 * 5)
Set NewLoc = Worksheets("Building 46").Cells(Row, Col)
NewLoc.Value = "Over Here"
Range("G2") = 6
End Sub
Your problem is probably that your final block should be inside the loop as otherwise Loc is likely to be Nothing (unless the term is found on the last sheet) and your code will error. You should also check first that it is found to avoid such errors.
Sub test()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim Inp As String
Dim Loc As Range
Dim Row As Integer
Dim Col As Integer
Dim NewLoc As Range
Dim Sh As Worksheet
Inp = InputBox("Scan ESD Tag")
For Each Sh In ThisWorkbook.Worksheets
With Sh.Columns("A")
Set Loc = .Find(What:=Inp)
If Not Loc Is Nothing Then
Row = Loc.Row
Col = Loc.Column + (3 * 5)
Set NewLoc = Worksheets("Building 46").Cells(Row, Col)
NewLoc.Value = "Over Here"
Range("G2") = 6 'should specify a sheet here
Exit Sub
End If
End With
Next
End Sub
I have a simple vba question. I want a macro that will add exactly 4 new columns in my table object, ("Table1"). I would also like these to be named in order, from left to right:
AHT, Target AHT, Transfers, Target Transfers
The code I have below adds the columns just fine, but I am not sure how to name one individually. Also, could someone please show me how to loop that section of code. Thanks!
Sub insertTableColumn()
Dim lst As ListObject
Dim currentSht As Worksheet
Set currentSht = ActiveWorkbook.Sheets("Sheet1")
Set lst = ActiveSheet.ListObjects("Table1")
'below is the code that I would like to have looped
lst.ListColumns.Add
lst.ListColumns.Add
lst.ListColumns.Add
lst.ListColumns.Add
End Sub
A variant array is a good place to store the variables in a looped sequence.
Sub insertTableColumn()
Dim lst As ListObject
Dim currentSht As Worksheet
Dim h As Long, hdrs As Variant
hdrs = Array("AHT", "Target AHT", "Transfers", "Target Transfers")
Set currentSht = ActiveWorkbook.Sheets("Sheet1")
Set lst = ActiveSheet.ListObjects("Table1")
With lst 'ActiveSheet.ListObjects("Table1")
For h = 0 To 3
.ListColumns.Add
.ListColumns(.ListColumns.Count).Name = hdrs(h)
Next h
End With
End Sub
When creating an array of strings in this manner, remember that the variant array's index is zero-based by default.
The following code creates an array of the column names you want to add, then loops as many times as there are headers to add and sets the name at the same time.
Sub insertTableColumn()
Dim lst As ListObject
Dim currentSht As Worksheet
Set currentSht = ActiveWorkbook.Sheets("Sheet1")
Set lst = ActiveSheet.ListObjects("Table1")
ColumnNames = Array("AHT", "Target AHT", "Transfers", "Target Transfers")
' below is the code that I would like to have looped
For iLoop = 0 to UBound(ColumnNames)
Set oLC = lst.ListColumns.Add
oLC.Name = ColumnNames(iLoop)
Next
End Sub
I have a simple function to copy the background color of cells with similar contents in different ranges (one range is failRange the other is toColor)
It fails at the line assigning the Interior.Color and the excel debugger gives me no information at all, it just stops. I have separated out ever variable so I can easily see all values using the debugger and they are all set just fine.
Does anyone see the problem???
Function ColorRange(failRange As Range, toColor As Range)
Dim targetCell As Range
Dim failCell As Range
Dim targetValue As String
Dim failValue As String
Dim colorValue As Long
Dim compareResult As Integer
Dim counter As Integer
For Each targetCell In toColor
targetValue = Left(targetCell.Text, 7)
For Each failCell In failRange
failValue = failCell.Text
compareResult = InStr(failValue, targetValue)
If compareResult > 0 Then
colorValue = failCell.Interior.ColorIndex
rem next line causes failure
targetCell.Interior.ColorIndex = colorValue
counter = counter + 1
Exit For
End If
Next failCell
Next targetCell
ColorRange= counter
End Function
A UDF called from a worksheet cell can only return a value to that cell. It cannot affect any cell's format.
If you want to change formats, use a sub.
I'm new to Excel VBA. I am trying to use a VBA function I found online that enables the user to use goalseek on multiple cells at a time. How do I call the function in a spreadsheet and how do I point to the cells that are supposed to be associated with the variables in the function (e.g. Taddr, Aaddr, gval). Do I have to write the cell values and ranges in the code itself and just run it that way?
Maybe I should redefine the function so that it takes these variables as input, so I can write a formula like =GSeekA(Taddr,Aaddr,gval)
Option Explicit
Sub GSeekA()
Dim ARange As Range, TRange As Range, Aaddr As String, Taddr As String, NumEq As Long, i As Long, j As Long
Dim TSheet As String, ASheet As String, NumRows As Long, NumCols As Long
Dim GVal As Double, Acell As Range, TCell As Range, Orient As String
' Create the following names in the back-solver worksheet:
' Taddr - Cell with the address of the target range
' Aaddr - Cell with the address of the range to be adjusted
' gval - the "goal" value
' To reference ranges on different sheets also add:
' TSheet - Cell with the sheet name of the target range
' ASheet - Cell with the sheet name of the range to be adjusted
Aaddr = Range("aaddr").Value
Taddr = Range("taddr").Value
On Error GoTo NoSheetNames
ASheet = Range("asheet").Value
TSheet = Range("tsheet").Value
NoSheetNames:
On Error GoTo ExitSub
If ASheet = Empty Or TSheet = Empty Then
Set ARange = Range(Aaddr)
Set TRange = Range(Taddr)
Else
Set ARange = Worksheets(ASheet).Range(Aaddr)
Set TRange = Worksheets(TSheet).Range(Taddr)
End If
NumRows = ARange.Rows.Count
NumCols = ARange.Columns.Count
GVal = Range("gval").Value
For j = 1 To NumCols
For i = 1 To NumRows
TRange.Cells(i, j).GoalSeek Goal:=GVal, ChangingCell:=ARange.Cells(i, j)
Next i
Next j
ExitSub:
End Sub
GSeekA is a Subprocedure, not a Function. Subprocedures cannot be called from worksheet cells like Functions can. And you don't want to convert GSeekA into a function. Functions should be used to return values to the cell(s) from which they're called. They shouldn't (and often can't) change other things on the sheet.
You need to run GSeekA as a sub. Now the problem becomes how you get user provided information into the sub. You can use InputBox to prompt the user to enter one piece of information. If you have too many, InputBox becomes cumbersome.
You can create areas in the spreadsheet where the user must enter information, then read from that area. That's how it's set up now. It's reading cells named asheet and tsheet. As long as those named ranges are present, the code works.
Finally, you can create a UserForm that the user will fill out. That's like putting a bunch of InputBoxes on one form.
Update Here's a simple procedure that you can start with and enhance.
Public Sub GSeekA()
Dim rAdjust As Range
Dim rTarget As Range
Dim dGoal As Double
Dim i As Long
'Set these three lines to what you want
Set rAdjust = Sheet1.Range("I2:I322")
Set rTarget = Sheet1.Range("J2:J322")
dGoal = 12.1
For i = 1 To rAdjust.Count
rTarget.Cells(i).GoalSeek dGoal, rAdjust.Cells(i)
Next i
End Sub
I have the following which errors on the "rTemp.Value = vaTemp" line. What am I doing wrong here? Am I on the right track?
Function CreateTempRange(rSource As range) As range
' Declarations
Dim rTemp As range
Dim vaTemp As Variant
Dim wsTemp As Worksheet
Dim wbTemp As Workbook
' Open temp worksheet
Set wbTemp = Workbooks.Add
Set wsTemp = wbTemp.Worksheets.Add
' Copy range into it and get a reference to the temp range
vaTemp = rSource.Value
Set rTemp = wsTemp.range("A1").Resize(UBound(vaTemp, 1), UBound(vaTemp, 2))
rTemp.Value = vaTemp
' Return the temp range
Set CreateTempRange = rTemp
End Function
Note: This function is intended to be used by other functions and not called directly from a cell.
Set rTemp = wsTemp.range("A1").Resize(UBound(vaTemp, 1), UBound(vaTemp, 2)
There'll be a type mismatch here ... i'm not sure it really makes any sense. ubound(a,2) is used for multi-dimensional arrays not ranges.
I'm guessing you want to take the value in the cell specified then copy it many times depending on it's value. Is that correct?
Hopefully the below should give you an example to work with. If not edit your post and i'll see if i can help.
Function CreateTempRange(rSource As Range) As Range
'' Declarations
Dim rTemp As Range
Dim vaTemp As Variant
Dim wsTemp As Worksheet
Dim wbTemp As Workbook
'' Open temp worksheet
Set wbTemp = Workbooks.Add
Set wsTemp = wbTemp.Worksheets.Add
'' Copy range into it and get a reference to the temp range
vaTemp = rSource.Value
''Set rTemp = wsTemp.Range("A1").Resize(UBound(vaTemp, 1), UBound(vaTemp, 2))
Dim iTemp As Integer
On Error Resume Next
iTemp = CInt(vaTemp)
On Error GoTo 0
If iTemp < 1 Then
iTemp = 1
End If
Set rTemp = wsTemp.Range("A1:A" & iTemp)
rTemp.Value = vaTemp
'' Return the temp range
Set CreateTempRange = rTemp
End Function
Sub test()
Dim r As Range
Dim x As Range
Set r = ActiveSheet.Range("A1")
Set x = CreateTempRange(r)
End Sub
vaTemp = rSource.Value
As you aren't specifying the RangeValueDataType parameter to the Value method of the Range object, it will default to xlRangeValueDefault which, for non-empty ranges, will return an array of values. Therefore, the UBound(..., 1) and UBound(..., 2) parts make sense.
This would be easier:
Function CreateTempRange(rSource As range) As range
' Declarations
Dim rTemp As range
Dim wsTemp As Worksheet
Dim wbTemp As Workbook
' Open temp worksheet
Set wbTemp = Workbooks.Add
Set wsTemp = wbTemp.Worksheets.Add
' Create new range on that sheet starting at cell A1
Set rTemp = wsTemp.Range(Cells(1, 1), Cells(rSource.Rows.Count, _
rSource.Columns.Count))
rTemp.Value = rSource.Value
' Return the temp range
Set CreateTempRange = rTemp
End Function
You would still need some code to deal with ranges which consist of multiple areas (use the Areas.Count property to check for that)
I would do it like this
Function CreateTempRange(src As Range) As Range
Dim wbk As Workbook: Set wbk = Workbooks.Add
Dim sht As Worksheet: Set sht = wbk.Worksheets.Add
Call src.Copy(sht.Cells(1, 1))
Set CreateTempRange = Range(rSource.Address).Offset(1 - rSource.Row, 1 - rSource.Column)
End Function
Explanation of the last line of code (as requested):-
Range(rSource.Address) - this refers to the range on the current worksheet (containing the code) with the same local address as the source range, so if the the source range is C3:E5 on 'Sheet X' then Range(rSource.Address) refers to C3:E5 on the current sheet.
Since we pasted the copied range into the current sheet starting at cell A1 rather than cell C3 (I assume this is your requirement), we then need to offset this reference accordingly. The .Offset(1 - rSource.Row, 1 - rSource.Column) offsets this range negatively by both the row index (3) minus 1 and column index (C or 3) minus 1 of the source range, so that the final resulting reference starts with cell A1 and keeps the same dimensions as the source range.
Hope that helps.
Deano, that code works for me as written. What is the error you're getting?