Defined Variable as a reference in an Offset Range - vba

I have run into trouble writing a code in VBA that will allow me to describe a range of non-consecutive cells when one of those cells is a variable. When I run this line of code I get an error at the line beginning with Range(copyToRange) = Application.WorksheetFunction.Average(copyFromRange). Sorry if this is a simple fix, I've been banging my head against a wall all day:
Sub GetPCData()
'Get PC response ratios
PCanalytes = Array("Furosemide", "Caffeine", "Ketoprofen", "Phenylbutazone", "Flunixin")
PCanalytePositions = Array("J32", "J33", "J34", "J35", "J36")
Set SQWorkbook = Application.ActiveWorkbook
Dim sourceSheet, targetSheet As Worksheet
Dim copyFromRange, copyToRange As Range
Dim Y As Range
Set targetSheet = ThisWorkbook.Sheets("QC data")
For i = 0 To SQWorkbook.Worksheets.Count
Set sourceSheet = SQWorkbook.Worksheets(PCanalytes(i))
Set Y = sourceSheet.Range("A7").End(xlDown)
Set copyToRange = targetSheet.Range(PCanalytePositions(i))
Set copyFromRange = sourceSheet.Range(("H8"), Y.Offset(0, 7))
Range(copyToRange) = Application.WorksheetFunction.Average(copyFromRange)
Next i
End Sub

Incorrect syntax!
Try this:
copyToRange.Value = Application.WorksheetFunction.Average(copyFromRange)
Why?, because you are telling Excel "copyToRange" is a RANGE already:
Dim copyFromRange, copyToRange As Range
Hope this help you.

Related

Naming a chart created with .shapes.chart

I've been trying to figure out what i'm doing wrong but I can't find the answer. I've got the following code:
Sub CreatePivotChart()
Dim sh As Shape
Dim ws As Worksheet
Dim ch As Chart
Dim pt As PivotTable
DeleteAllChartObjects
'setting ws and sh will be done alot here. It's basically making it easy for yourself by making a new (short name):
Set ws = Worksheets("Analysis")
Set sh = ws.Shapes.AddChart(XlChartType:=xlColumn, Width:=400, Height:=200)
'This part to make sure that when there's no cell selected when running the code) within the pivottable, it still works
Set ch = sh.Chart
'Acipivot is created as title for the pivottable in sbCreativpivot:
Set pt = Worksheets("PivotTable").PivotTables("Acpivot")
ch.SetSourceData pt.TableRange1
'align the chart with the table:
sh.Top = pt.TableRange1.Top
sh.Left = pt.TableRange1.Left + pt.TableRange1.Width + 10
End Sub
Everything works fine, except I can't name the chart. I've tried several methods that I found online, but none of them seem to work.
Here's my latest attempt:
'This part to make sure that when there's no cell selected when running the code) within the pivottable, it still works
Set ch = sh.Chart
With ch
With .Parent.Name = "test"
End With
End With
But if I then try to reference it like here:
Sub EditPivotChart()
Dim pt As PivotTable
Dim ch As Chart
Dim pf As PivotField
Set ch = Charts("test")
Set pt = ch.PivotLayout.PivotTable
For Each pf In pt.VisibleFields
pf.Orientation = xlHidden
Next pf
End Sub
I get an error
vba ran out of memory
Does anyone see what wrong I am doing?
Thanks!
You can remove all of the following segment
With ch
With .Parent.Name = "test"
End With
End With
and simply replace it with
sh.Name = "test"
That should do the trick.

Error 13 - Type mismatch - Index Match

Getting the above error on the Index/Match. Will try and keep this short and sweet but I am a VBA noob. Everything that is called has data in. One thing I noticed was that RefCol (a range of numbers) has leading and trailing whitespace when I do a Debug Print. However when I tested the length of the value it returned the correct values.
I can't understand what is breaking it, I did an index match in the workbook itself and it works perfectly.
Private Sub Ref_Change()
Dim ws As Worksheet
Dim tbl As ListObject
Set ws = Worksheets("Details")
Set tbl = ws.ListObjects("Call_Log")
Dim RefCol As Range
Dim NameCol As Range
Dim PhoneCol As Range
Dim DateCol As Range
Set RefCol = tbl.ListColumns("Ref Number").DataBodyRange
Set NameCol = tbl.ListColumns("Caller Name").DataBodyRange
Set PhoneCol = tbl.ListColumns("Telephone").DataBodyRange
Set DateCol = tbl.ListColumns("Date").DataBodyRange
Me.CallDate.Value = Application.WorksheetFunction.Index(DateCol, Application.Match(Me.Ref.Value, RefCol, 0))
End Sub
Have I set this up correctly?
Thanks
Evan
As stated most likely the Match is not being found and an error is being passed to the INDEX.
Pull the MATCH out and test for the error before finding the correct cell in the data.
Private Sub Ref_Change()
Dim ws As Worksheet
Dim tbl As ListObject
Set ws = Worksheets("Details")
Set tbl = ws.ListObjects("Call_Log")
Dim RefCol As Range
Dim NameCol As Range
Dim PhoneCol As Range
Dim DateCol As Range
Set RefCol = tbl.ListColumns("Ref Number").DataBodyRange
Set NameCol = tbl.ListColumns("Caller Name").DataBodyRange
Set PhoneCol = tbl.ListColumns("Telephone").DataBodyRange
Set DateCol = tbl.ListColumns("Date").DataBodyRange
Dim mtchRow As Long
mtchRow = 0
On Error Resume Next
mtchRow = Application.WorksheetFunction.Match(Me.ref.Value, RefCol, 0)
On Error GoTo 0
If mtchRow > 0 Then
Me.CallDate.Value = DateCol.Cells(mtchRow, 1).Value
Else
MsgBox "'" & Me.ref.Value & "' not found, or lookup array is more than one column or row"
End If
End Sub

someExcel VBA: Cannot create a range object successfully

This is my first question here, so bear with me. I'm a security consultant working on a huge firewall migration, for which I got my VBA skill from under a thick layer of dust. So far I have managed to get all my issues resolved by searching, but this issue: I get errors when doing exactly how I find it everywhere.
What I want to do:
I have an array that contains (among other things), strings formatted like this: "A3:P59", representing a cell range.
Now, this are ranges within a table. When I get the address of a certain cell in the table, I want to test if it's in that range.
I wrote a test function:
Function TestCellRange() As Boolean
Dim tbl As ListObject
Dim cell, rng, test As range
Dim range As range
Dim bRow, eRow As Integer
Set tbl = shRulebase.ListObjects("tblBFFirewallRules")
shRulebase.Activate
With shRulebase
cell = tbl.DataBodyRange(5, 1).Address(False, False) 'it's this command that gives me issues
Set range = .range(.Cells(bRow, 1), .Cells(eRow, 16))
Debug.Print cell
'Set rng = shRulebase.range(range)
Debug.Print rng
Set test = Application.Intersect(cell, range(range(A3), range(P59)))
If test Is Nothing Then
MsgBox ("oops")
TestCellRange = False
Else
MsgBox ("yup yup")
TestCellRange = True
End If
End With
End Function
Now whatever I try, I keep getting blocked on the set range:
set range = .Range("A3:P59") -> will return "object required", on the "set test" line (if i use intersect (cell, range))
Set range = range("A3:P59") -> will return object variable or with block variale not set on the same line
Set range = .range(.Cells(bRow, 1), .Cells(eRow, 16)) -> will step through, but debug.print returns a type mismatch and "Set test = Application.Intersect(cell, range)" returns a "object required"
Any help would be really appreciated...I'm all to familiar with networks ip's and the bits and bytes of it, but here I am a bit out of my comfort zone and I need to finish this by tomorrow :(
Greetings,
Kraganov
EDIT Some More tries:
rng and cell as variant:
cell = tbl.DataBodyRange(5, 1).Address(False, False)
rng = .range("A3:P59").Address(False, False)
Set test = Application.Intersect(cell, rng)
==>I would get objects required
just using rng as range and trying to set it without "set"
rng = .range("A3:P59")
EDIT 2 : I found a way around using the range.
So what I was trying to do, was the following:
I had a table that contains information about firewall rules. However, not every line describes a rule. There are also lines that described the context in which the rules below that line were to be placed.
Outside of the table, aside of those lines there would be a cell with the range of cells for that context. I wanted to use that to describe the context for those rules, if I pulled them.
I ended up looping through the table rows and identifying those specific rows and setting a "context" variable when, a row like that was met.
Try setting the cell as well as following:
set cell = tbl.DataBodyRange(5, 1).Address(False, False)
What is cell? A Range?
You do not need to add 'set' to the range value assignment.
Try just
range = .Range("A3:P59")
Function TestCellRange() As Boolean
Dim tbl As ListObject
Dim cellToTest As Range
Dim testResult As Range
Set tbl = shRulebase.ListObjects("tblBFFirewallRules")
Set cellToTest = tbl.DataBodyRange.Cells(5, 1)
'or with one more level of indirection
'Set cellToTest = shRulebase.range(tbl.DataBodyRange.Cells(5, 1).Value)
Set testResult = Application.Intersect(cellToTest, [A3:P59])
If testResult Is Nothing Then
MsgBox ("oops")
TestCellRange = False
Else
MsgBox ("yup yup")
TestCellRange = True
End If
End Function
Thanks to the post of VincentG I found the working solution. Thanks for that.
Function TestCellRange() As Boolean
Dim tbl As ListObject
Dim cellToTest As range
Dim testResult As range
Set tbl = shRulebase.ListObjects("tblBFFirewallRules")
shRulebase.Activate
Set cellToTest = tbl.DataBodyRange.Cells(5, 1)
'or with one more level of indirection
'Set cellToTest = shRulebase.range(tbl.DataBodyRange.Cells(5, 1).Value)
Set testResult = Application.Intersect(cellToTest, range("A3:P59"))
If testResult Is Nothing Then
MsgBox ("oops")
TestCellRange = False
Else
MsgBox ("yup yup")
TestCellRange = True
End If
End Function

VB syntax (named arguments)

I have a VB script with a line that looks like this:
Set startCell = referenceCell.EntireColumn.Find(tmp).offset(0,columnOffset)
But I want to specify the find (to search exactly for the given word in each column) to something like:
Set startCell = referenceCell.EntireColumn.Find(tmp, lookat:=xlWhole).offset(0,columnOffset)
all according to
http://msdn.microsoft.com/en-us/library/office/ff839746(v=office.15).aspx
But that gives me a syntax error. (I hate VB)
I have also tried
Set tmp = "Precondition" & preconditionNumber
Set startCell = ReferenceCell.EntireColumn.Find(what:=tmp,lookat:=xlWhole).offset(0,columnOffset)
and even
Set startCell = ReferenceCell.EntireColumn.Find(what:=tmp).offset(0,columnOffset)
none of which works.
How should I call the Find function to get a Whole Word-Search?
The variable declaration looks like this:
Dim startCell
for preconditionNumber = 0 to 15
Set startCell = Nothing
tmp = "Precondition" & preconditionNumber
Set startCell = referenceCell.EntireColumn.Find(tmp).offset(0,columnOffset)
...
Here is the exact syntax error message.
Use something like:
Sub luxation()
Dim ReferenceCell As Range, rCol As Range, tmp As String
Dim GotIt As Range, MoveOver As Range, columnOffset As Long
Set ReferenceCell = Range("B9")
Set rCol = ReferenceCell.EntireColumn.Cells
tmp = "happiness"
columnOffset = 2
Set GotIt = rCol.Find(what:=tmp, after:=rCol(1), lookat:=xlWhole)
Set MoveOver = GotIt.Offset(0, columnOffset)
MoveOver.Select
End Sub
Fixing VBA hatred is even easier, just repeat:
VBA is my friend.
30 times every morning

Excel VBA - Cell(#,#) with variables

Im wondering if its possible to enter a variable that refers to a range into a Cell objects parameters. ie:
Dim visibleRows As Range
Dim visibleColumns As Range
Set visibleColumns = (G:P)
Set visibleRows = (10:20)
Cells(visibleRows, visibleColumns).Formula = "enter formula here"
I want to do this because the ranges within each of those variables will change based on parameters in the spreadsheet. Thanks in Advance.
You can do this as follows:
Dim visibleRows As Range
Dim visibleColumns As Range
Set visibleColumns = Range("G:P")
Set visibleRows = Range("10:20")
Dim r As Range
Set r = Application.Intersect(visibleRows, visibleColumns)
r.Formula = "enter formula here"
Better to use the Range object and refer to the top left corner and bottom right corner. For instance:
Range("G10", "P20").Formula = "enter formula here"