VBA excel variable referencing for a value - vba

I'm still getting to grips with VBA and have an issue with something I'm trying to do and was hoping i can get some help. (sorry if it doesn't make much sense, I don't have the lingo).
This part of the code is where I need it to put a value in the last cell on col A from col I (row dependant of my variable).
Range("A" & Cells.Rows.Count).End(xlUp).Offset(1, 0).Value = Range("I" & RowCount)
If i replace the variable "RowCount" with "1" it gives me what I want. I have used the same wording for "Range("I" & RowCount)" multiple times with in the macro but for some reason doesn't like it in this...
Any help?

Related

How to create formula to sum with dynamic ranges? I just can't make the right syntax

So what I would like to do is add a sum formula to a cell, so it can be edited later(normally, not through vba). It sums up some cells, but the amount of cells is not always the same. Sometimes it's 4 cells, sometimes it's 10. So I'm trying to have:
lastrow = Sheets(7).Cells(Sheets(7).Rows.Count, "A").End(xlUp).Row
then using it:
Sheets(7).Range("B" & lastrow + 1).Formula = "=SUM(b2:b&"lastrow")"
My problem is the syntax actually, I can't seem to make it right. How to add lastrow to this formula?
Hope it's understandable, English is not my native language.
You're missing to concatenate.
Sheets(7).Range("B" & lastrow + 1).Formula = "=SUM(b2:b" & lastrow & ")"
Instead of using the .End(xlUp) method, I'd suggest that using Named Ranges and in particular the built-in structured referencing of Excel Tables/ListObjects would make for more robust and simpler code.
Using Named Ranges avoids hard-coding references in your code. If you hard code cell address into your code, those references will be pointing at the wrong place if you (or a user) later adds new rows/columns above/to the left of those hard-coded references. Using Names avoids this, and makes for more robust code.
I almost always use Excel Tables aka ListObjects to hold any data that VBA interacts with for the same reason...ListObjects are dynamic named ranges that Excel automatically expands/contracts to suit the data, and unlike .End(xlUp) they won't throw your code off if the column contains blanks.
So I'd do it like this:
Range("SomeNamedRange") = "=SUM(" & Range("SomeTable[SomeColumn]").Address & ")"
...or more likely, I'd use the [] shorthand notation:
[SomeNamedRange] = "=SUM(" & [SomeTable[SomeColumn]].Address & ")"

Dynamic Array Formula using VBA

the problem I am trying to figure out is a bit complicated and detailed but I will try to simplify it with an example.
I am looking to use vba to change the array formula with a conditional statement. An example of what the code would look like is below
If (InStr(1, Range("E" & i).Value, "X")) > 0 Then
With outputSheet
Range("I" & i).FormulaArray = Sumproduct(('Sheet1'!$A$57:$A$104=$B2)*('Sheet1'!$E$56:$AZ$56=$H2),'Sheet1'!$E$57:$AZ$104)
End With
Else [Same code as above for Array formula]
End If
Initially I was using the following code to copy the Array formula down however using that I cannot use a conditional statement where the formula is dynamic according to cells.
Range("G2").AutoFill .Range("G2:G" & OutputLastRow)
If however, I can somehow make the $B2 into B&i then that would do the trick for me.
On just a highlevel, the idea was that the output cell would look at some conditions in the same row and different columns and change array formula according to the conditions. It would look at it for each cell and move down until it hits the last row
Any suggestions on how this can be tackled. I hope the problem is clear. Thanks so much!!

VBA Error method of '_default' if object 'range' failed when inserting formula into cell

I am trying to use VBA to put a formula into a cell. This is the formula.
Range(Cells(2, 15)).FormulaR1C1 = "=SUMPRODUCT(COUNTIF('All Failing Classes'R7C2:r7clrow,Classes!R[]C[-13]))"
The error is inside the quotes on the right. I've tried taking off range, using A1 notation, and everything else I can think of. I have several extremely similar lines before and after that all work fine, so I'm not quite sure what I'm missing. Thanks for any help.
EDIT: Here is the line several people have suggested:
Cells(2, 15).FormulaR1C1 = " =SUMPRODUCT(COUNTIF('All Failing Classes'!$G$2:$G$" & lrow & ",Classes!B2))"
or
Cells(2, 15).FormulaR1C1 = "=SUMPRODUCT(COUNTIF('All Failing Classes'R7C2:r7C" & lrow & ",Classes!R[]C[-13]))"
Which is the same as far as I can tell.
While Mat was helping me I accidentally added a space in front of the = to create the line:
Cells(2, 15).FormulaR1C1 = " =SUMPRODUCT(COUNTIF('All Failing Classes'R7C2:r7C" & lrow & ",Classes!R[]C[-13]))"
and that line goes in just fine? When I move to XL and take the space out, the formula works as intended. Does this help narrow down what I'm doing wrong?
Edit 2: Here is what I was doing wrong - I had redefined a variable before that line that referenced another sheet. When I did that the program apparently kept referencing that sheet, and gave me my issues. When I changed and added the sheet before the cells (sheets(blah).cellc(blah) then it worked. Thanks to everyone (especially Mat) who helped out.
Does =SUMPRODUCT(COUNTIF('All Failing Classes'R7C2:r7clrow,Classes!R[]C[-13])) work as a formula?
If it doesn't work (and no, it doesn't), then Excel itself can't assign the broken formula to the cell you're typing it in - for the exact same reason, VBA won't be able to do it either.
So you mean lrow to be evaluated by VBA before it's inserted into the formula, right? For this to happen, VBA needs to be able to see that lrow variable. Being in a string literal, it doesn't, and it can't guess at your intentions either: as far as VBA is concerned, this is what's happening:
SomeObject.SomeProperty = "some string literal"
That's all.
You need to concatenate the variable's value into the string literal, the way you concatenate strings in VBA:
SomeObject.SomeProperty = "some " & someVariable & " string literal"
In other words make the right-hand side of the assignment a string-valued expression, not just a literal:
"=SUMPRODUCT(COUNTIF('All Failing Classes'R7C2:r7c" & lrow & ",Classes!R[]C[-13]))"
Try this
Cells(2, 15).FormulaR1C1 = "=SUMPRODUCT(COUNTIF('All Failing Classes'R7C2:r7c" & lrow & ",Classes!R[]C[-13]))"
I'm guessing that lrow is a variable...

repost: copy pasting data instead of formula excel VBA

ok i have to repost this as my original thread was tagged as a duplicate with "the original" thread not having anything to do with my issue and the person who tagged it as a dupe cannot provide the answer.
there's a reason why i'm using activecell in my code as it does something with interaction with outlook and validation of certain conditions from other cells.
ActiveCell.Cells(1, 37).Copy Destination:=wsTest.Range("A" & Rows.Count).End(xlUp).Offset(1)
now i tried :
ActiveCell.Cells(1, 37).Copy Destination:=wsTest.Range("A" & Rows.Count).End(xlUp).Offset(1).pastespecial
but i'm getting error 1004.
if someone will point me here: how to paste only values in excel
please tell me which of the 4 answers will actually work, because none of them is working on my end.
Reverse the procedure and pass over the value directly.
wsTest.Range("A" & Rows.Count).End(xlUp).Offset(1) = ActiveCell.Cells(1, 37).value
The .Value is the raw underlying value in a cell or the result from a formula if the cell contains a formula. .Value2 strips the value further where a date like 18-Feb-2015 becomes 42,053. If you have used number formatting in the cell (e.g. 18-Feb-2015) and wish to retain it, use .Text in place of .Value.

Identifying and using Relative variable in excel VBA Macro?

Alright, so I have a spreadsheet, and I want to use this code (and more) but I'm getting problems. I want to take row A and Find the [-x] I should be using (see RC[StartColumn]) and autofill the rest. I then want to be able to repeat the steps for columns A-AF.
So essentially I want to perform the first calculation below, and the second one right next to that, and I want to be able to start it anywhere on the document. I then want to be able to copy that down each row for every column leading up to the first cell I chose.
Problem is I'm incredibly new to Macros, I put that together by observing my record macro results and playing around a little, but this is becoming too advanced for my current level and I want to finish this by today if possible. Could someone please show me the way, in a way that could teach me so I could do this on my own in the future?
Sub ConcatenateStep1()
Dim StartColumn As Integer
StartColumn = 1 - ActiveCell.Column
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC14=R[1]C14),IF(OR(ISNUMBER(FIND(LOWER(RC[StartColumn]),LOWER(R[1]C[StartColumn]),1)),ISNUMBER(FIND(LOWER(R[1]C[StartColumn]),LOWER(RC[StartColumn]),1))),IF(LEN(RC[StartColumn])<LEN(R[1]C[StartColumn]),R[1]C[StartColumn],RC[StartColumn]),CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn])),IF(AND(RC14<>R[1]C14,RC14<>R[-1]C14),RC[StartColumn],"" ""))"
Range("AK2").Select
Set SourceRange = Range("AK2")
Set fillRange = Range("AK2:AK22000")
SourceRange.AutoFill Destination:=fillRange
Range("AL2").Select
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC14=R[1]C14,RC14<>R[-1]C14),IF(OR(R[1]C[-1]="" "",ISNUMBER(FIND(LOWER(RC[-1]),LOWER(R[1]C[-1]),1)),ISNUMBER(FIND(LOWER(R[1]C[-1]),LOWER(RC[-1]),1))),IF(LEN(RC[-1])<LEN(R[1]C[-1]),R[1]C[-1],RC[-1]),CONCATENATE(RC[-1],"", "",R[1]C[-1])),IF(AND(RC14<>R[1]C14,RC14<>R[-1]C14),RC[-1],"" ""))"
Set SourceRange = Range("AL2")
Set fillRange = Range("AL2:AL22000")
SourceRange.AutoFill Destination:=fillRange
Range("AL2").Select
End Sub
This is only a partial answer.
Are these incredibly long and complicated formulae the best way of achieving whatever you want to achieving?
There are two errors in the first formula that prevent it being accepted by Excel when the macro attempts to place it in a cell.
The formula is a long string containing StartColumn. But StartColumn is a variable. You need to replace every occurence of StartColumn with " & StartColumn & ".
Within a string each double quote required in the result must be replaced by two double quotes. Within CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn]) the double quotes have not been doubled although those at the end of the formula have.
Excel will accept the following (which means it is syntactically correct) although I do not understand its purpose so it may be logically incorrect:
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC14=R[1]C14),IF(OR(ISNUMBER(FIND(LOWER(RC[" & StartColumn & _
"]),LOWER(R[1]C[" & StartColumn & "]),1)),ISNUMBER(FIND(LOWER(R[1]C[" & _
StartColumn & "]),LOWER(RC[" & StartColumn & "]),1))),IF(LEN(RC[" & _
StartColumn & "])<LEN(R[1]C[" & StartColumn & "]),R[1]C[" & StartColumn & _
"],RC[" & StartColumn & "]),CONCATENATE(RC[" & StartColumn & _
"],"""", """",R[1]C[" & StartColumn & _
"])),IF(AND(RC14<>R[1]C14,RC14<>R[-1]C14),RC[" & StartColumn & "],"" ""))"
If I have parsed this formula correctly, CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn]) has the same output as CONCATENATE(RC[StartColumn],R[1]C[StartColumn])
I agree with MP24, you must clarify your question before I or someone else can help you further. The Macro Recorder records syntactically correct VBA but it is not good VBA. It does not know your objective so records individual keyboard actions when a skilled programmer would combine them. It is almost never a good idea to use Select or to work with the ActiveCell but the Macro Recorder has no choice but to do so.
Part 2
Although Excel allowed the macro to place the first forumula, it later complained the formula contains a circular reference. Its gone midnight here, I will look at it tomorrow.
Part 3
Having looked at your first formula again, I believe I incorrectly parsed it last night. I now believe the concatenate function is correct. Also it appears that the circular reference depends on the location of the ActiveCell when the macro starts. I was able to clear this error by selecting a different start position.
My current attempt to parse your formula gives:
Outer: "=IF(X1,X2,X3)"
X1: AND(RC14=R[1]C14)
X2: IF(X4,X5,X6)
X3: IF(X7,RC[StartColumn],"" "")
X4: OR(X8,X9)
X5: IF(X10,R[1]C[StartColumn],RC[StartColumn])
X6: CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn])
X7: AND(RC14<>R[1]C14,RC14<>R[-1]C14)
X8: ISNUMBER(X11)
X9: ISNUMBER(X12)
X10: LEN(RC[StartColumn])<LEN(R[1]C[StartColumn])
X11: FIND(LOWER(RC[StartColumn]),LOWER(R[1]C[StartColumn]),1)
X12: FIND(LOWER(R[1]C[StartColumn]),LOWER(RC[StartColumn]),1)
I have used macros to place formulae so they can later give changing results as the user enters values. Do you want changing results? If not, replacing this formula with VBA would almost certainly give more understandable and more maintainable code.
I do not approve of formulae like this. I am aware that many people use complex formulae successfully and are pleased with the results. However, I have spent too much of my life picking up the pieces left by over clever people who have moved on. How long does it take to get a formula like this correct? How long does it take to amend when six or twelve months later a slightly different result is required? Too often, in my experience, the person who has to amend it six or twelve months later is not the original author. With VBA the author can leave comments saying what the code is doing but with formulae the author cannot. Over clever authors don't always leave the comments they should but at least VBA code is usually easier to decode than a complex formula.