How to combine indirect and direct references in VBA? - vba

Issue:
I need to call direct and indirect references. I have a column that shifts to the right every time the program is run. The column is being used to collect the sum of the preceding columns. (I'm aware I can combine the sheet1 within the with, however there are pieces of code between the with and sheet select and this particular question focuses on just the .value section.)
Code 1:
Sheets("Sheet1").Select
With Range("AL2")
.Value = "=SUM(B2:RC[-1])"
End With
B2 is being inserted as a string, instead of as a cell name.
I've also tried:
Sheets("Sheet1").Select
With Range("AL2")
.Value = "=SUM(range("B2") & ":RC[-1])"
End With
Sheets("Sheet1").Select
With Range("AL2")
.Value = "=SUM("& B2 & ":RC[-1])"
End With
This particular set of code does not run correctly and returns:
SYNTAX ERROR

So, the problem in this specific instance is that you are mixing R1C1 and A1 style notation.
Anyway, I'd change your code to set the .Formula property instead of the .Value property, and specifically change it to .FormulaR1C1 if you want to use that notation or leave it as .Formula for A1 notation.
Anyway, your original code:
Sheets("Sheet1").Select
With Range("AL2")
.Value = "=SUM(B2:RC[-1])"
End With
This is setting B2 as a string because Excel is recognizing the RC notation, correctly interpreting that "RC[-1]" is a cell reference, but then not understanding what "B2" means.
So, I'd use something like this:
With Sheets("Sheet1").Range("AL2")
.FormulaR1C1 = "=SUM(R2C2:RC[-1])"
End With
That however would leave $B$2 as an absolute cell reference, and AK2 as a relative reference, which is kind of gross. Depending on your needs you could do this:
With Sheets("Sheet1").Range("AL2")
.FormulaR1C1 = "=SUM(R2C2:R2C37)"
End With
Which would lead to both being absolute references.
If you want something more dynamic, you'll need to use string manipulation on the string you're inputting into the worksheet. For instance, if you have r1 as a range object (with address B2) and r2 as a range object (with address AK2), you could do this:
With Sheets("Sheet1").Range("AL2")
.Formula = "=SUM(" & r1.address ":" & r2.address & ")"
End With
If you have questions, let me know.

Related

GoalSeek only within VBA, without depending on a WorkSheet Cell

Very shortly: Instead of ActiveCell of ActiveCell.GoalSeek Goal:=0, ChangingCell:=Range("GM")formula, how can I use a variable? So I want to use something like GoalSickVariable.GoalSeek Goal:=0, ChangingCell:=Range("GM")
.
As a detail:
I am trying to shorten my current GoalSeek formulation and I'm stucked on the last line.
So far, I was running my codes within WorkSheet but as I can't assume which part of the Worksheet will be empty, I was going to a cell which is away from the reference cell by .Offset(0,25) but as user can also use that cell, I would like not to use any range within WorkSheet - if it's possible.
...
ActiveCell.Offset(0, 25).Select
ActiveCell.Formula = "=ROUNDUP(SellPrice,-3)"
RoundedCellAddress = ActiveCell.Address
ActiveCell.Offset(0, 1).Select
ActiveCell.Formula = "=(" & RoundedCellAddress & "-" & "SellPrice" & ")"
'SellPrice is a NamedRange from this current Worksheet
ActiveCell.GoalSeek Goal:=0, ChangingCell:=Range("GM")
'GM is also a NamedRange from this WS and it changes SellPrice's value.
...
While it's a very bad practice with many ActiveCell and a Assuming Cell Reference, this above code is working without any problem. Anyway as I explained above, I don't want to assume this .Offset(0,25) cell and don't want to use these ActiveCells.
So here below how I transformed my code into a good practice:
...
RoundedSellPrice = Application.WorksheetFunction.RoundUp(ws4.Range("SellPrice"), -3)
GoalSick = RoundedSellPrice - ws4.Range("SellPrice")
GoalSick.GoalSeek Goal:=0, ChangingCell:=ws4.Range("GM")
...
But now as you can easily guess, it gives me Invalid Qualifier error on GoalSick.GoalSeek line because GM and SellPrice are variables defined within WorkSheet so they are (I think) not able to run GoalSeek formula from VBA module without exactly referring to any cell(contains formula) within the WorkSheet.
If somehow I can not do this formulation without referring to a cell within the WorkSheet, how should I suppose to do without assuming a dummy cell like .Offset(50,150) or without creating a new empty WorkSheet?

Creating an absolute, yet variable, reference in VBA

First time poster here, I've been searching for the last hour without success so I'm turning to asking for help... My limited VBA knowledge might be a factor here.
I'm creating a quick macro that will sum values cumulatively. I regularly use =SUM($A$2:A2) and AutoFill down to get a cumulative sum. While I can be very quick at doing this, I have to do it several times per day in various sheets. My goal was to have the absolute $A$2 reference to be variable based on the current selected cell.
So let's assume I am trying to add this formula to cell B2. I know I can do:
ActiveCell.FormulaR1C1 = "=SUM(R2C1:RC[-1])"
However, this formula is unusable if my starting cell is anything but B2 and I am trying to cumulatively sum data in various columns.
Is it possible to have VBA count the number of columns between the selected cell and A2 and use this as a variable to set the absolute reference? Such as:
ActiveCell.FormulaR1C1 = "=SUM(R2Cvar:RC[-1])"
where var is =COUNTA(R2C1:ActiveCell)+COUNTBLANK(R2C1:ActiveCell)-1
I know the above code isn't valid, but it's the only way I can think of explaining what I'm trying to achieve.
You'll have to concatenate your formula eg
ActiveCell.FormulaR1C1 = "=SUM(R2C" & var & ":RC[-1])"
But to get your variable you can do
var = (ActiveCell.Column - 1)
Something like:
Sub ytrewq()
Dim s As String
With ActiveCell
s = .Offset(0, -1).Address(0, 0)
.Formula = "=SUM($A$2:" & s & ")"
End With
End Sub
The Offset() generates the address of the cell "just to the left".

Excel use cell value as range in VBA

I have an excel file. There is a changable row quantity for column A for every time and that's why I need to make dynamic formula. For example;
I want to write "=LEN(B1)" formula on B1. And when make double click on right down corner of the cell, it's going to the end of until when column A values ends. That's why, before all this process, I wrote "=COUNT(A:A)" on cell C1.
In my VBA, I want to write;
Dim TEMP As String
TEMP = Range("C1").Value
Range("B1").Select
ActiveCell.FormulaR1C1="=+LEN(RC[-1])"
Selection.AutoFill Destination:=Range("B1:TEMP")
But there is something wrong in this process. As a result, I just want to use a cell value in my VBA as a range or string or number.
Thanks for your support.
Two notes:
It's best practice to always qualify your objects (workbooks, worksheets, ranges, etc.) beforehand
When you use R1C1 notation, you can just write the formula directly to the range (with no need for AutoFill or FillDown)
Try this:
Dim ws as Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1") 'edit for your sheet name
Dim lRow as Long
lRow = ws.Range("A" & ws.Rows.count).End(xlup).Row
ws.Range("B1:B" & lRow).FormulaR1C1 = "=Len(RC[-1])"
And just as a side note worth mentioning the way you wrote Range("B1:TEMP") is not proper syntax. Correct syntax would be Range("B1:B" & TEMP), which, of course, would only work if TEMP was indeed a numerical value :)

Referring Cell range contained in variable in SUM formula

I have two cell addresses stored in my two variables
saddr and eaddr (starting and ending cell addresses respectively)
I have to find the some of all cells in between the range and have the value assigned to another random cell. My code below throws an error. I am pretty sure i am not using the variable containing the cell addresses in the right format. Please help
Code:
saddr = Cells(x, 3).Address
eaddr = Cells(x, (3 + 6)).Address
Worksheets("Sheet2").Range("C2").Select
ActiveCell.Formula = "=Sum(Sheet1!:"&saddr&":"&eaddr&")"
The last line throws up this error. Can you tell me how to use the variable cell references correctly in the formula?
You probably want
ActiveCell.Formula = "=Sum(Sheet1!" & saddr & ":" & eaddr & ")"
Even if this gets you going, you better check/fix a few things.
I strongly recommend you check this.

Split a cell's formulaic elements into seperate cells

So I have a cell with the formula =A+B, A and B are external values for which the external spreadsheet is no longer open. I was wondering if excel remembers the formula elements and if it was possible to get those element values into other cells. i.e.
Row Formula Value
1 =A+B 45
2 =ELEMENT(A1, 1) 10
3 =ELEMENT(A1, 2) 35
I can't imagine it being that simple though? I could seperate out the formula in vba using the + as a pivot, but this is not ideal as it would require the external spreadsheet to be reopened. If the external spreadsheet has to be reopened then I needn't bother trying to seperate the formula in the first place. I hope this makes sense and has an answer.
Your formula is already accessing those values in order to sum them in the open workbook. You do NOT need to re-open the workbook in order to evaluate the reference values, nor to parse the formula in the active workbook.
Assuming your formula references a closed workbook, with a simple sum function like:
='C:\Users\david_zemens\Desktop\[test.xlsx]Sheet1'!$A$1 + ='C:\Users\david_zemens\Desktop\[test.xlsx]Sheet1'!$B$1
You can parse the formula either in VBA or using string functions on the worksheet. As you note, for this example, parsing by the + operator will suffice. Since I think you understand how to do this, my example does not demonstrate how to parse the formula.
As long as you know or can obtain the references from the formula, you should be able to access those cells' values via formula, or programmatically in VBA using ExecuteExcel4Macro.
Sub GetValsFromClosedWorkbook()
Dim fileName As String
Dim filePath As String
Dim sheetName As String
Dim cellref As String
Dim myFormula As String
'This example might be one of the two arguments in your "A+B" formula:
' 'C:\Users\david_zemens\Desktop\[test.xlsx]Sheet1'!A1
'## Assume you can properly parse the formula to arrive at these:
fileName = "test.xlsx"
filePath = "C:\Users\david_zemens\Desktop\"
sheetName = "Sheet1"
cellref = "A1"
'Concatenate in to R1C1 notation
myFormula = "='" & filePath & "[" & fileName & "]" & sheetName & "'!" & _
Range(cellref).Address(, , xlR1C1)
'## First, demonstrate that we can evaluate external references:
With Range("B1")
.Value = myFormula
MsgBox .Value
.Clear
End With
'## Evaluate the formula using ExecuteExcel4Macro:
MsgBox ExecuteExcel4Macro(Replace(myFormula, "=", vbNullString))
End Sub
Additional info
http://spreadsheetpage.com/index.php/tip/a_vba_function_to_get_a_value_from_a_closed_file/
Update
Based on OP's question of how this works (comments, below), I am not certain of how it works behind the scenes but here is my guess/explanation:
Firstly, keep in mind that a cell may have various properties like .Text, .Value, .Value2, .Formula etc. which in one way or another represent its contents.
The values aren't in the active file until the formula is evaluated, at which point Excel queries the external file and returns the current Value at that reference. Now the active file contains that Value as well as a Formula reference the external file.
As you continue working the active file preserves the Value and the reference, but may only update the value when prompted. For example, when you re-open the linked workbook, you will be prompted whether to "update external links".
if you say no, it will use the previously stored values (still preserves the Formula, it just doesn't evaluate it.
if you say yes, it will re-evaluate the formula (in case the value in the external file has changed) and return the new .Value
So, that's what I suspect is happening. If you're asking "How does Excel access the data inside an un-opened workbook" I don't really know how I just know that it does.