Excel VBA - If cells is part of merged cells pass the value? - vba

I'm having some trouble to prepare macro which would help me to pass the value to another cell if the specified cell is a part of merged cells.
As you can see, cells A1-A15 are merged, in B1 I've written =A1 in B2 I did =A2, so what I want to achieve is that whenever I assign somewhere cell which is part of merged cells(A1-A15) the 'test' value is passed so there is no difference if I write =A1 or =A15 or =A10
I would appreciate any help of advice.

You can detect if a Cell is part of a Merged Cell using If Range("A1").MergeCells = True.
Get the number of rows you have in your MergedArea using Range("A" & i).MergeArea.Rows.Count.
More explanation inside the code below.
Code
Option Explicit
Sub CheckifMergedCell()
Dim MergeRows As Long, i As Long
i = 1
While i < 100 ' 100 is just for example , change it later according to your needs
If Range("A" & i).MergeCells = True Then
MergeRows = Range("A" & i).MergeArea.Rows.Count ' number of merged cells
Else ' not merged >> single row
MergeRows = 1
End If
Range("B" & i).Resize(MergeRows, 1).Value = Range("A" & i).Value
i = i + MergeRows
Wend
End Sub

In B1,
=INDEX(A:A, MATCH("zzz", A$1:A1))
Fill or copy down.

what I want to achieve is that whenever I assign somewhere cell which is part of merged cells(A1-A15) the 'test' value is passed so there is no difference if I write =A1 or =A15 or =A10
What you want to accomplish can't be done easily. You could do it with an VBA code that checks every single time you type something, but it's not worth it. The other answer you got here are worth it.
What you want to do is not possible because Excel works in a weird way. Let's say you have cells A1:A15 merged. The value is ALWAYS in first cell of merged area (in this case in A1). So when you reference a cell inside the merged area, it will have a 0 value (a blank cell) always, unless it is the first one.
So my advice, would be:
Use 1 of the other answers, because both are really helpful
If you insist in using normal formulas, then instead of typing =A1, try with absolute references, try =$A$1. If you click and
drag, that formula will work for you to complete adjacent cells to
merged area.
I insist, use 1 of the other answers.

Related

How to highlight a cell based on another cells value VBA?

This question has been asked before but I went about doing it another way. I am trying to highlight a cell if it is greater than the value of another cell.
Here is my code:
Sub Error_Search()
Dim Summary As Worksheet
Dim lr As Long
Set Summary = Worksheets("Summary")
lr = Cells(Rows.Count, 20).End(xlUp).Row
With Summary
For i = lr To 3 Step -1
If Range("L" & i).Value > Range("$Q$2:$R$3").Value Then Range("L" & i).Font.Color = -16776961
Next i
End With
End Sub
Range("$Q$2:$R$3") is a merged cell and it is the cell I want to compare the cell I want to highlight to.
I keep getting a mismatch error.
Any help would be greatly appreciated.
Thanks,
G
As mentioned in the comments, the problem is that a multiple-cells Range doesn't have a single Value, even if the cells are merged: Range.Value yields a 2D variant array whenever more than a single cell is involved. So you can fix the bug by only referring to the top-left cell of the merged range instead.
That said...
You don't need any VBA code to do this; conditional formatting handles it quite neatly.
=$C4>$M$3
Note the $ dollar signs: $M$3 would be your merged cell (only the leftmost cell matters), and $C4 is just the first cell you're defining the conditional format into; leaving the row non-absolute (i.e. no $ on the row number) allows you to apply the format to an entire range of cells by specifying the Applies to range:
Note that the format formula is the same regardless of whether we're looking at $M$3 or $M$3:$N$3 merged cells.
Conditional formats will perform much better than any VBA code you can write.

VBA creating formulas referencing a range

After several hours of research, I still can't solve what seems to be a pretty simple issue. I'm new to VBA, so I will be as specific as possible in my question.
I'm working with a DDE link to get stock quotes. I have managed to work out most of the table, but I need a VBA to create a finished formula (i.e., without cell referencing) in order to the DDE link to work properly.
My first code is as follows:
Sub Create_Formulas()
Range("J1").Formula = "=Trade|Strike!" & Range("A1").Value
End Sub
Where J2 is the blank cell and A2 contains the stock ticker. It works fine, but when I try to fill out the rows 2 and bellow, it still uses A1 as a static value.
Sub Create_Formulas()
Dim test As Variant
ticker = Range("A1").Value
'Test to make variable change with each row
'Range("J1:J35").Formula = "=Trade|Strike!" & Range("A1:A35").Value
'not working
Range("J1:J35").Formula = "=Trade|Strike!" & ticker
'not working
End Sub
I couldn't find a way to solve that, and now I'm out of search queries to use, so I'm only opening a new topic after running out of ways to sort it by myself. Sorry if it is too simple.
You are referencing absolute cell adresses here. Like you would do when using $A$1 in a normal excel formula.
What you want to do is:
Dim row as Integer
For row = 1 to 35
Cells(row,10).Formula = "=Trade|Strike!" & Cells(row,1).Value
Next row
This will fill the range J1 to J35 with the formula. Since (row,10) indicates the intersection of row and column 10 (J)
Firstly, in your second set of code, you define a variable "test", but never give it a value.
You assign a value to the variable "ticker", and then never reference it.
Secondly, the value you have assigned to ticker is a static value, and will not change when it is entered in a different row.
Thirdly, I think your issue could be solved with a formula in Excel rather than VBA.
The "INDIRECT" function can be quite useful in situations like this.
Try inserting the formula
=INDIRECT("'Trade|Strike'!"&A1)
into cell A1, then copy down.
Note the ' ' marks around "Trade|Strike". This is Excels syntax for referencing other sheets.

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".

Formula to remain after running macro

I was wondering how I can have a formula stay on column J2:J600. The formula is =R2 and would go all the way down to =R600. I thought I could manually put the formula in but every time I run my macro, the formulas disappear. Is there a way to embed the formula into the column? Thanks.
EDIT
Sub FormatCounsel()
Sheet2.Range("J2").FormulaR1C1 = "=RC[0]"`
Sheet2.Range("J2").AutoFill Destination:=Range("J2:J600"), Type:=xlFillDefault
End Sub
This is what I put in and I'm getting an error.
EDIT 2
Sorry I just realized that I want the formula =R2 in cells J2:J600. Sorry if I caused any confusion.
I see a big red flag in your code: you're using circular referencing! This means that you're saying J2 = J2. In other words, your formula refers to itself for a value, so it calculates to find the value, but to find the value it needs to calculate, etc...
Entering circular referencing should always give you an error when you manually enter circular referencing. However, when using VBA to enter the CR, I was only able to raise an error by setting Application.Calculation to xlCalculationManual, and then calculating the sheet.
You may have just made a typo, and that explains why there's circular referencing in your code, but I figured I'd explain it anyway. :)
R1C1 formulas use relative references to refer to cells. So when you say RC[0], you're saying that you want to use the cell in the same row and the same column. Let's see some examples. In our example, the formula will be in B2.
Dim r As Range
Set r = Range("B2")
r = "=RC" '<~~~ the equivalent to what you used in your code. Refers to B2.
r = "=R[-1]C" '<~~~ Refers to B1 (current row minus 1).
r = "=RC[1]" '<~~~ Refers to C2 (current column plus 1).
r = "=R[1]C[1]" '<~~~ Refers to C3 (current row and current column plus 1).
r = "=R[-1]C[-1]" '<~~~ Refers to A1 (current row and current column minus 1).
Now, as far as entering formulas into cells, it can be done all at once and very easily. Consider the example below:
Sub FormatCounsel()
Sheet2.Range("J2:J600") = "=RC[1]" '<~~ Each cell will refer to the cell to the right.
End Sub
Any time you write something else to those cells or clear them with the macro, you will lose those formulas. You need to find the place in your code where you are overwriting or clearing them, and modify that code. The other option is writing those formulas back to the cells at the end of the macro. You can accomplish this with:
Range("J2").FormulaR1C1 = "=RC[0]"
Range("J2").AutoFill Destination:=Range("J2:J600"), Type:=xlFillDefault

Excel & VBA: Skip calculating formula in Macro

I'm having a rather simple issue with Macro. In it, I assign a formula to a cell. I would like it not to calculate it at first and do calculation only after some other part of Macro is finished. I thought I would do something like this:
Application.Calculation = xlCalculationManual
Cells(StartRow, 4 + i).Formula = "FORMULA"
...
Application.Calculation = xlCalculationAutomatic
But that doesn't work. It stops automatic calculations, but not for that cell - it still performs the calculation right after I assign the formula. Is there a way to skip it?
To clarify the exact prupose of this: in my actual code I'm assigning a formula to a group of cells in a cycle. Everytime I assign it to one cell - it calculates it. I figured if I will first assign them all and then do the calculation - it would be faster. As a matter of fact it is. So instead of assigning it in a cycle, I assign it to the first cell and then do autofill. Autofilled formulas wait until I enable automatic calculation and I get a much faster macro. However, the initial assignemnt is still calculated which makes macro almost twice as slow.
place the formula in the cell with a prefix character
continue the macro
"activate" the formula
for example:
Sub dural()
With Range("A1")
.Value = "'=1+2"
MsgBox " "
.Value = .Value
End With
End Sub
#Alex, you can delay the calculation as #Gary answer. However, you was asking the question because you need "SPEED to CYCLE through cells" while assign a formula, right?
If yes, from my point of view, if you are NOT using the formulas until ALL the formulas are assigned in the excel sheet, you will gain a lot of speed by writing all the formulas at once using an array (a single step in VBA).
The procedure is: first put all the formulas to an VBA array of strings, and later on to use for example Range("B1:B100").Formula = ArrayWithFormulas. In that example you are assigning 100 formulas at once, without recalculation in between.
You will see a large improve in SPEED if use an array to write all the cells at ones instead of writing cell by cell! (Don't loop using cells(r,c+i) if you have a lot of cells to go through). Here one example:
Sub CreateBunchOfFormulas()
Dim i As Long
Dim ARRAY_OF_FORMULAS() As Variant 'Note: Don't replace Variant by String!
ReDim ARRAY_OF_FORMULAS(1 To 100, 1 To 1)
' For Vertical use: (1 to NumRows,1 to 1)
' for Horizontal: (1 to 1,1 to NumCols)
' for 2D use: (1 to NumRows,1 to NumCols)
'Create the formulas...
For i = 1 To 100
ARRAY_OF_FORMULAS(i, 1) = "=1+3+" & i ' Or any other formula...
Next i
' <-- your extra code here...
' (New formulas won't be calculated. They are not in the Excel sheet yet!
' If you want that no other old formula to recalculate use the old trick:
' Application.Calculation = xlCalculationManual )
'At the very end, write the formulas in the excel at once...
Range("B1:B100").Formula = ARRAY_OF_FORMULAS
End Sub
If you want an extra delay in the new formula, then you can use #Gary trick, but applied to a range, not to a single cell. For that start the formulas with a ' like '=1+2 and add the following code at the end:
'... previous code, but now formulas starting with (')
Range("B1:B100").Formula = ARRAY_OF_FORMULAS
'Formulas not calculated yet, until next line is executed
Range("B1:B100").Value = Range("B1:B100").Value ' <~~ #Gary's trick
End Sub
Last, a small snipped: if your formulas are in a horizontal arrangement (Means one formula for column A, other for column B, etc) and just a small number of columns, then you can keep in mind the a shorter version of previous code:
Dim a as Variant 'Note that no () needed
a = Array("=1+3","=4+8","=5*A1","=sum(A1:C1)")
Range("A1:D1").Formula = ARRAY_OF_FORMULA ' Just a single row
' or...
Range("A1:D100").Formula = ARRAY_OF_FORMULA ' If you want to repeat formulas
' in several rows.
Finally, You can use the method .FormulaR1C1 instead of .Formula in all the previous code examples, if you want an easy way to use relative references in your formula...
Hope this helps!