I am trying to run a macro which is not defined anywhere but in a string.
For example I have the following string:
Public Sub testMacro()
Dim MC As Range
Set MC = ActiveSheet.Range("A15")
Dim i As Integer
For i = 1 To 10
MC.Offset(i, 0) = i
Next i
End Sub
I want to execute the code stored in this string from another program (Doors DXl). I know that you can execute a sub using Application.Run, but this only works using the name of the macro if the macro is already written in an Excel file.
I repeat that this sub does not and will not exist anywhere but in the previous string.
You can try using
Eval
You can use the Eval function to evaluate an expression that results
in a text string or a numeric value.
You can construct a string and then pass it to the Eval function as if
the string were an actual expression. The Eval function evaluates the
string expression and returns its value. For example, Eval("1 + 1")
returns 2.
If you pass to the Eval function a string that contains the name of a
function, the Eval function returns the return value of the function.
For example, Eval("Chr$(65)") returns "A".
Eval(stringexpr)
from
https://msdn.microsoft.com/en-us/library/office/aa172212%28v=office.11%29.aspx
Related
I want to check whether the input contains special characters(#"[~`!##$%^&*()-+=|{}':;.,<>/?]") or not in vb.net?
How can I check that in vb.net code?
If you want to check if any of the mentioned characters are contained in the string you can use the following function:
Function ContainsSpecialChars(s As String) As Boolean
Return s.IndexOfAny("[~`!##$%^&*()-+=|{}':;.,<>/?]".ToCharArray) <> -1
End Function
Or if you want to check if the string just contains letters, digits or whitespace, you can use the following function:
Function ContainsSpecialChars(s As String) As Boolean
Return s.Any(Function(c) Not (Char.IsLetterOrDigit(c) OrElse Char.IsWhiteSpace(c)))
End Function
If the string can only contain letters or digits(0-9) or white-spaces:
Dim noSpecialCharacters = text.
All(Function(c) Char.IsLetterOrDigit(c) OrElse Char.IsWhiteSpace(c))
Dim containsSpecialCharacters = Not noSpecialCharacters
I've written this function:
Function Resolveq(Equacao As String, Variavel As String, Valor As Double) As Double
Resolveq = Evaluate(Replace(Equacao, Variavel, Valor))
End Function
and tested it with:
the expression (passed to Equacao) 25*EXP(-x/100)
the variable (Variavel) x
the values 18 and 18.25
With the value 18 (or any other integer) the expression is calculated correctly; with 18.25 (or any other non-integer value) Excel returns a #Value! error.
But calculating the same expression with the expression written in a cell, it goes well, with integer and non-integer values.
Can someone, please, give me a light here?
The problem is the parameters of the Replace function are not being used correctly. They are:
Replace (string1, find, replacement, [start, [count, [compare]]] )
The replacement parameter is expecting a string and you are passing a Double.
Convert the Double to a string before you pass it to the function.
Function Resolveq(Equacao As String, Variavel As String, Valor As Double) As Double
Dim ValourStr as String
ValourStr = CStr(Valor)
Resolveq = Evaluate(Replace(Equacao, Variavel, ValourStr))
End Function
This works for me
Sub test()
Dim var As Variant
var = Resolveq("25*EXP(-x/100)", "x", 18.25)
End Sub
And this entered in a cell also works for me
=Resolveq("25*EXP(-x/100)", "x", 18.25)
I am trying to evaluate a logical expression by concatenating the operands and operator. Is there a formula to convert from text to logical in Excel 2016, similar to how VALUE() converts from text to number? I'm looking to a solution for this so I can dynamically change the condition without changing the actual Excel formula. I've searched and read through the Excel function descriptions, but nothing is jumping out as a solution.
'The operands and operator
A1: 1
A2: >
A3: 0
'Concatenation
B4: =CONCAT(A1:A3) 'This evaluates to 1>0
B5: =A1&A2&A3 'This also evaluates to 1>0
'Some checks
C4: =ISTEXT(B4) 'This evaluates to TRUE.
C5: =ISTEXT(B5) 'This also evaluates to TRUE
D4: =ISLOGICAL(B4) 'This evaluates to FALSE
D5: =ISLOGICAL(B5) 'This also evaluates to FALSE
'Vain attempts
E4: =AND(B4,TRUE) 'This ALWAYS is TRUE, even when my desired output is FALSE
E5: =OR(B5) 'This spits out a #VALUE! error
Since I'm looking for something dynamic, I want to avoid a solution such as
=IF(A2=">",A1>A3,FALSE). I also would prefer to avoid a UDF but am willing to go that route if no built in function exists to convert a logical expression in text and evaluate it as logical.
To write a UDF calling Evaluate, that can handle either a Range or Variant/String input, try the following:
Function L(exp As Variant) As Variant
Dim vExp As Variant
vExp = exp
L = Application.Evaluate(vExp)
End Function
Why does it work?
The line vExp = exp does the magic. If exp is a Range then the assigment uses the default .Value property and copies as a Variant/String (because we are not using Set). If it's a Variant/String, then it's a straight copy.
It does have the downside of using Application.Evaluate (downside as explained
here )
A version to also handle the possibility of being called from VBA, try
Function L(exp As Variant) As Variant
If TypeName(exp) = "Range" Then
L = exp.Worksheet.Evaluate(exp.Value)
Else
If IsError(Application.Caller) Then
'Calls from VBA are hanbled here.
' Note: Best to fully qualify any range references in exp
' to avoid unexpected references to the active sheet
L = ActiveSheet.Evaluate(exp)
Else
L = Application.Caller.Worksheet.Evaluate(exp)
End If
End If
End Function
Based on the comments that no built-in function takes care of this, I made a user-defined function ("UDF") called L() for logical, taking after the built-in functions N() and T() which are for numbers and text.
Function L(exp As Variant) As Variant
Dim limit As Integer
Dim counter As Integer
'Set an upper limit to how many cycles the loop may run
limit = 1000
'Assuming the possibility of nested functions, loop until the expression resolves to logical or to an error or until the loop limit has been reached
Do
exp = [exp] 'This avoids Error 2015 if exp is a Range reference. Comment if there's a better way!
exp = Application.Evaluate(exp) 'Evaluate the expression
counter = counter + 1 'Increment the loop counter
Loop Until Application.IsLogical(exp) Or Application.IsError(exp) Or counter >= limit
'Return the evaluated expression
L = exp
End Function
This function works even when I throw some silly things its way like =L(TRUE) or =L(CONCAT(A1:A2)&A3) or even =l(CONCAT(A1:A2)&"""foo"""). But it does not throw errors in cases where it probably should, such as =l(123) or =l("123"). In these cases, thank goodness for the counter limit because 123 and "123" will never evaluate to a logical or an error.
I have a function which returns value as string.
Function Trimcell(cellvalue As varnant) As String
Trimcell = Replace(CStr(cellvalue), " ", "")
End Function
I want to change the data type string to long . Any help.
Change your function to this:
Function Trimcell(cellvalue As varnant) As Long
Trimcell = Val(Replace(CStr(cellvalue), " ", ""))
End Function
You have a spelling error - varnant instead of Variant.
A better option than using Replace is to use Val which removes blanks, tabs, and linefeed characters from a string and returns a Double. It also stops reading the string at the first non-numeric character apart from period (.) which it recognises as the decimal separator.
As you have declared cellvalue As Variant you shouldn't need CStr either.
Function Trimcell2(cellvalue As Variant) As Long
Trimcell = Val(cellvalue)
End Function
I have a piece of Excel-VBA code of which the following behavior escapes my understanding
option explicit
....
private sub XYZ()
dim s as string
dim ser as series
dim diagram as chart
...
s = function_returning_string(....)
' Following line throws runtime exception 13
set ser = diagram.seriesCollection.item(s)
....
end sub
If I try to get a named item in the seriesCollection of the chart object as outlined above, it throws (the german) errors laufzeitfehler '13' typen unverträglich which would be Run-time error 13: Type mismatch in english.
Changing the offending line to
set ser = diagram.seriesCollection.item(CStr(s))
makes to error go away.
I have no idea why that is. CStr() is supposed to convert something (here: s) into a string, but s is already a string.
CStr converts the type of a variable into a String data type.
If you have a function s = function_returning_string(....) where s is already typed a string, doing for example this:
dim s as string
dim sString as string
sString = cstr(s)
would be meaningless.
In other cases, this may be useful.
Sometimes people use it for example to convert a string to a date, using cDate.
Or to take string, cut off some parts and use cDbl or cInt to convert towards a Double or Integer datatype.
Check your function "function_returning_string" if it is defined as :
Public Function function_returning_string() as string
In this case, the seriesCollection only allows String typed variables to be added in the collection.