im trying to record a macro. my formula in excel is:
=IF(AND(OR(B2={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15 ","16 "}),OR(J2={"Q1","Q2","Q3","Q4"})),CONCATENATE(J2," ",IF(K2="p","pre",""),"-"," ",IF(A2="",0,A2)),"")
(this formula basically changes the names of my product according to quarter and type, while taking into consideration previous quarters )
note: once i record it. it looks like this in vba:
Selection.FormulaR1C1 = _
"=IF(AND(OR(RC[-6]={""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9"",""10"",""11"",""12"",""13"",""14"",""15 "",""16 ""}),OR(RC[2]={""Q1"",""Q2"",""Q3"",""Q4""})),CONCATENATE(RC[2],"" "",IF(RC[3]=""p"",""pre"",""""),""-"","" "",IF("& _
"""",0,RC[-7])),"""")"
and yet, it gives me a syntax error...whats wrong?!
thank you
IF(A2="",0,A2)),"") Is being converted to IF(""",0,RC[-7])),"""")
Assuming that If your original formula is in Range("H2")
"=IF(AND(OR(RC[-6]={""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9"",""10"",""11"",""12"",""13"",""14"",""15 "",""16 ""}),OR(RC[2]={""Q1"",""Q2"",""Q3"",""Q4""})),CONCATENATE(RC[2],"" "",IF(RC[3]=""p"",""pre"",""""),""-"","" "",IF(RC[-7]="""",0,RC[-7])),"""")"
I don't see the need to surround number with quotes when using formula contants
"=IF(AND(OR(RC[-6]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}),OR(RC[2]={""Q1"",""Q2"",""Q3"",""Q4""})),CONCATENATE(RC[2],"" "",IF(RC[3]=""p"",""pre"",""""),""-"","" "",IF(RC[-7]="""",0,RC[-7])),"""")"
Don't start a line continuations in the middle of a double escape pattern """". I prefer to place them between statements when possible
The easiest way to convert a formula to R1C1 notation is to use the Immediate Window
?Chr(34) & Replace(Range("H2").FormulaR1C1,chr(34),Chr(34) & Chr(34)) & Chr(34)
Build and test your strings in the Immediate Window when possible. It will complain when it is wrong
You can even use create variables in the Immediate Window when writing concatenations
The only thing that's wrong is the "& _ part. It should be replaced by RC[-7]=. See the corrected line below.
Selection.FormulaR1C1 = _
"=IF(AND(OR(RC[-6]={""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9"",""10"",""11"",""12"",""13"",""14"",""15 "",""16 ""}), OR(RC[2]={""Q1"",""Q2"",""Q3"",""Q4""})), CONCATENATE(RC[2],"" "",IF(RC[3]=""p"",""pre"",""""),""-"","" "",IF(RC[-7]="""",0,RC[-7])),"""")"
I have a problem with :
Function Create_Model(adress As range, name As String) As String
Dim Msg As String
On Error GoTo ErrorHandler
ActiveWorkbook.Names.add "toto", "=Interface!$I$19"
Create_Model=name
Exit Function
ErrorHandler:
If Err.Number <> 0 Then
Msg = "Error # " & Str(Err.Number) & " was generated by " _
& Err.Source & Chr(13) & "Error Line: " & Erl & Chr(13) & Err.Description
MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
End If
Resume Next
End Function
Indeed, if I run this, I get :
"Error # 1004 was generated by VBAProject
Error Line: 0
Application-defined or object-defined error"
It seems that the problem come from the use of "Function" because if I try to execute this with a "Sub", it's working.
Someone could please explain me why I can't do this with a "Function" and how I could replicate this function otherwise?
P.S : If I compile using Debug->Compile VBAProject. I don't get any message.
P.S.2 : This function aims to be used in excel formula.
P.S.3 : Argument used are : adress = J18:L20 and name = "Test". And finnaly, I would like replace "toto" by name and "=Interface!$I$19" by adress.
Thanks for your help.
After the comments below, I got to thinking, and realized that my original answer (see below) is perhaps more based in (my own!) best practice than being technically correct.
The main difference between a Function and a Subroutine is that a Function can return a value, while a Subroutine cannot.
I have heard of other issues in using Function rather than Subroutine but can't find a list right now. You have apparently found one, though! These (perhaps) rumors of issues, is why I tend to limit actions to Subroutines, and returning values to Functions.
After doing some digging, I've found the following resources that may help with further explanation of the difference between the two.
From Chip Pearson's site: a page called Macros and Functions
From ExcelFunctions.net: a page called Excel VBA Tutorial Part 4 - VBA Functions & Subroutines
Looks like I learned something today.
==ORIGINAL ANSWER==
Short answer and super high-level
Functions are typically not the best place to perform actions (on a worksheet, cell, file, create objects, etc). They are really good at returning values, and that is what they are designed for.
Subs or procedures are built for taking action.
I have never seen this particular issue, but have run into many things that trying to do them in a Function causes problems.
I am currently working on a small VBA code that needs to compare a piece of string. If I would type this directly into excel I would do following:
=IF(C14 = "ABC",1,0)
Now, since this is a VBA code, it needs to do this as a relative reference. Instead it would look something like this:
=IF(RC[-5] = "ABC",1,0)
Problem: Now, the latter IF statement gives a compile error - why so?
If I where to type in
=IF(RC[-5] = 2,1,0)
This does not give any compile error. So it appears that the String comparisment gives me problems.
For vba code try this
ActiveCell.FormulaR1C1 = "=IF(RC[-5]=""ABC"",1,0)"
Followup from comments.
Howcome the double "" is needed? – SteewDK 3 mins ago
We need the extra " to encompass the double quotes to pass it as a string. You could use Chr(34) as well. For example
ActiveCell.FormulaR1C1 = "=IF(RC[-5]=" & Chr(34) & "ABC" & Chr(34) & ",1,0)"
BTW if you do not want to use a formula then you can use OFFSET as well
For example
If ActiveCell.Offset(0,-5).Value = "ABC" Then _
ActiveCell.Value = 1 Else ActiveCell.Value = 0
I am needing to insert a formula in using vba coding.
at the moment the line of code is
=IF(
AND(
Compliance="No",
OR(
Delivery <> "",
C31 <> ""
)
),
"Please Delete Compliance Data",
IF(
AND(
E11="",
E13="",
E23="",
E25="",
E26="",
E28="",
E30="",
E31=""),
VLOOKUP(C15,'Extrapolated RV Calculator'!B:S,18,0),
"Please complete form / SC request"
)
)"
It seems to error out on the text portions inside the code.
Any help would be appreciated.
Here are four ways to use quotation marks inside strings in VBA:
Replace "" with Chr$(34). 34 is the ASCII code for quotation marks
Use String(2,Chr$(34)) to make double quotes
Use two double quotation marks for every one (per Tim's comment)
Replace two double quotation marks with a different method, like ISBLANK for worksheet functions.
None of these is better. I usually use two double quotation marks to escape them. But sometimes I get so many quotation marks together that it's hard to read and maintain, so I'll use a different method. Here's an example:
Dim aFormula(1 To 5) As String
aFormula(1) = "=IF(AND(Compliance=""No"",OR(Delivery<>" & String(2, Chr$(34))
aFormula(2) = ",C31<>" & String(2, Chr$(34)) & ") ),"
aFormula(3) = Chr$(34) & "Please Delete Compliance Data" & Chr$(34)
aFormula(4) = ",IF(AND(ISBLANK(E11),ISBLANK(E13),ISBLANK(E23),ISBLANK(E25),ISBLANK(E26),ISBLANK(E28),ISBLANK(E30),ISBLANK(E31)),"
aFormula(5) = "VLOOKUP(C15,'Extrapolated RV Calculator'!B:S,18,0),""Please complete form / SC request""))"
Sheet1.Range("R13").Formula = Join(aFormula, vbNullString)
To empower you for the future I strongly recommend you do the following when you want to use functionality in Excel in your VBA code that you are not acquainted with yet.
Go to the developer menu and press the record macro button.
Now fill in a formula in a cell, Clear a cells content by pressing delete and clearing a cells content by going into the cell and deleting all the characters and press enter.
Now stop the macro. And go to the VBA window. See how the code is structured to accomplish these things.
Apply this also whenever you want to do other things to get a good idea of what you can use to get the results you want without having to browse around on the internet for ages!
Also watch the local variables in the locals window or Debug.Print the string you try to build to see hwat it looks so far