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.
Related
This may sound trivial, but what is the difference between
Dim v As String()
and
Dim v() As String
in VB.NET?
No difference. From the VB.NET Language Specification on Arrays:
Array types are specified by adding a modifier to an existing type name. The modifier consists of a left parenthesis, a set of zero or more commas, and a right parenthesis.
...
A variable may also be declared to be of an array type by putting an array type modifier or an array initialization modifier on the variable name. In that case, the array element type is the type given in the declaration, and the array dimensions are determined by the variable name modifier. For clarity, it is not valid to have an array type modifier on both a variable name and a type name in the same declaration.
Originally, in Basic, you had to define arrays, but not variables. And the types of variables were defined by a suffix character: A$ was a string, while A% was an integer and A# was double precision. (and all three were distinct and could be used at the same time) (For single-precision, you could use A!, but that was the default if you just used A)
Eventually, programmers came to realize that those were incredibly bad design choices.
To rectify this, Microsoft added "Option Explicit" which required you to predefine every variable. To lessen the effect on the language, they hijack the "DIM" command, which was used to define arrays, to define scalar variables as well.
So originally:
DIM A(50) ' define 51-element single-precision array
Then
DIM A(50) ' define 51-element single-precision array
DIM A$ ' define a string
Then to get rid of the suffixes, they added the "As {type} syntax"
DIM A(50) ' define 51-element single-precision array
DIM B as String
DIM C(50) as String ' define 51-element string array.
Then they made array size variable.
DIM A() ' define single-precision array
DIM B as String
DIM C() as String ' define string array.
This left a conflict in definition style, so they allowed both:
DIM A() ' define single-precision array
DIM B as String
DIM C() as String ' define string array.
DIM D as String() ' define string array.
There is no difference.
Both Dim v As String() and Dim v() As String will create a string array
Traditionally, in Basic, you would put the parenthesis after the variable name. In VB.Net it is allowed to put them after the type instead if you wish. The result is the same so there is no difference using either syntax. The reason for this addition though is because how you can constuct an array. Consider the following code:
Public Sub MethodThatExpectsAnArray(ByVal arr() As String)
'...
End Sub
Public Sub Main()
Me.MethodThatExpectsAnArray(New String() {"Hello", "World"})
End Sub
In the call I construct the array "on the fly" without any assignment except directly to the method argument. Since there are no variable here I must set the paranthesis after the type. To allow this syntax Microsoft had the choice to either change how you traditionally declare arrays in Basic or allow for both syntaxes. They of course opted for the latter.
There is no difference.
It's mostly semantics. The first reads as create variable "v" of type string array and the 2nd reads as create array "v" of type string. Either way the result is the same array of strings.
There is no difference in the meaning of the two.
If you like to declare several variables in one dim statement, the second form provides more flexibility:
dim v(),v2 as string allows you to declare array types and non array types in the same statement.
I've been stuck trying different methods of doing this for a while, usually not getting anywhere productive. I've tried going down each operator and splitting the string and evaluating there, I've tried looping through each character and then checking the next character but nothing seems to work very well and efficiently.
Is there a way to do this easily? I'd want to input a string, for example, "4*4+1/1" and receive an output of 17. Or, "4^2*2" = 14
The following will compute a string.
Private Sub CompteString()
Dim equation As String = "2+3"
Dim result = New DataTable().Compute(equation, Nothing)
Debug.Print(result.ToString)
End Sub
The idea is passing the complete content of a listobject.databodyrange to an array to make operations in memory and not having to access the sheets cells values repeatedly which is very time consuming.
this is the code.
Dim theArray As Variant
theArray = mylistObject.DataBodyRange.value
MsgBox (theArray(1, 1)) '= column 1 row 1 = first element
It works, so far so good.
but!!! since theArray is dimensioned as Variant, their elements are NOT strings, So when passing every of the values of theArray into a function that requires a string an error appears.
what to do?
Note: I know I might change the data type of the function itself to variant, but this function is called from so many routines that i dont dare to touch it. I rather prefer try to look for the way to transform the content of that variant into a string
like theArray(i,j) to str(thearray(i,j)) (which does not work)
some help, some ideas?
EDIT 1:
this is the line of the error:
Dim theclaims As Variant
theclaims = rawClsTbl.DataBodyRange.value
For i = LBound(theclaims, 1) To UBound(theclaims, 1)
myText = deleteRefSigns(theclaims(i, 2))
etc
error: byref argument type missmatch
where:
Function deleteRefSigns(txT As String) As String
i will be trying the solutions proposed.
thx
Related questions:
I asked in overflow myself this question some time ago:
Passing Listobject Range to array and getting error "out of range"
and read also this one
Excel VBA Type Mismatch Error passing range to array
and several others.
The following should work:
Dim MyStr As String
MyStr = CStr(TheArray(1, 1))
Note: Always declare it as a forced array not just as Variant …
Dim TheArray() As Variant 'Variant array (can only be an array)
Dim TheArray As Variant 'Variant (can be a value or array)
… to ensure it contains an array. Otherwise it will contain only a value if you do
TheArray = Range("A1").Value
which might easily fail if your range is dynamic.
If you read a range into an array like
Dim TheArray() As Variant
TheArray = Range("A1:C20").Value
then there is no possibility to declare the array as String it is forced to be Variant by design.
It looks like you don't want deleteRefSigns to modify the argument passed by the calling procedure. If so, you can pass the argument by value...
Function deleteRefSigns(ByVal txT As String) As String
I am using windows 7, Excel 2010, VBA. I am getting an error
"ByRef Argument Type Mismatch". I am assuming it is a problem with my variable type. I found lots of questions like mine but I can't find anything that has helped me figure out my problem.
Variable Declarations
'Force explicit variable declaration
Option Explicit
Private dptData(8) As String
Private TSdata(8) As String
Private fiscalYear(8) As String
Calling Function
parseUserData fiscalYear, dptData, TSdata
Called function Prototype
Function parseUserData(fiscalYear As String, dptDataAs String, TSdata As String)
You're passing an array to a String. Change the function's signature to accept a Variant instead.
Public Function parseUserData(fiscalYear As Variant, dptDataAs Variant, TSdata As Variant)
Debug.Assert IsArray(fiscalYear) And IsArray(dptDataAs) And IsArray(TSdata)
A String parameter can only ever accept a String argument1. Variant on the other hand, can accept anything - including an array - but then you'll want to Assert that you're dealing with an array, so that you halt execution (and prevent a bug) if that's not the case.
Why use a Variant over a typed array?
Using a typed array would work, but a typed array can't be coerced from a Variant parameter - which means this:
Public Sub DoSomething(ByRef args() As String)
...can't be invoked with this otherwise perfectly valid array of strings:
DoSomething Array("string1", "string2", "string3") ' can't pass a variant array!
Changing the signature to DoSomething(ByRef args As Variant) makes it work. All you need to do is to use a meaningful, descriptive, pluralized name to your variant array parameters, so that when IntelliSense is shown when you invoke that procedure, the name tells you everything you need to know.
But... 'Variant' is evil!
No different than many other languages, type safety in VBA is essentially smokes and mirrors. Variant is a very powerful tool and does have its uses - avoid it when you can doesn't mean unlearn its existence. Using it to pass array references around between procedures doesn't hurt the code's readability, maintainability, or stability. Variant enables duck typing and late-binding, and is a legitimate COM type.
It's a hammer. Just make sure not everything becomes a nail, and you'll do great.
1VBA will implicitly convert other value types to a String, but an array can't be coerced into a string, implicitly or explicitly.
It seems you wanted a string array after all but it may be worth mentioning that you can declare a fixed width string var.
Dim dptData As String * 8
dptData = "abc"
Debug.Print Len(dptData) & "|" & dptData & "|"
'result from Immediate window
'8|abc |
dptData = "abcdefghijk"
Debug.Print Len(dptData) & "|" & dptData & "|"
'result from Immediate window
'8|abcdefgh|
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