VBA type question beginner - excel

I'm a newbie and I'm trying to learn VBA and i got a question about this code:
(Sorry for any mistake in English, I'm not a native speaker)
Option Explicit
Type rPaciente 'matriz de pacientes
CodPaciente As Long
PriorPaciente As Long
IntvChegDistr As String
Par1 As Double
Par2 As Double
Par3 As Double
Par4 As Double
IntvCheg As Double
InstCheg As Double
End Type
Public mPaciente() As rPaciente
Public glQtdPaciente As Long
What are these "things" between Type and End Type, are they cells of the range of my worksheet, cause I got columns like Par1,Par2,...,Par4 in my worksheet but I don't got columns named IntvCheg neither InstCheg. And what does the command Public someting() As otherthing means?
Thanks in advance for your help.

"Things" between Type and End Type are members of the rPaciente type. They are not mapped to anything, they only describe the set of data this type is meant to contain.
Probably there is a routine somewhere that maps the cells on your sheet to members of this type by creating an instance of the type and copying values from the sheet to the member variables of the instance.
Public someting() As otherthing is an array of type otherthing. The declaration does not include the dimensions for the array, so before it can be used, you must ReDim it to something:
ReDim someting(1 to 10)

The Type declaration simply declare a Visual Basic Type structure. Is something like (really simplified view) a struct in c++ or a class without methods in any labguage.
The instruction
Public mPaciente() As rPaciente
declare a dinamyc array of rPaciente objects that probably will be filled with every row inside your excel file.
The instruction
Public glQtdPaciente As Long
declare a variable of type Long with the name glQtdPaciente

Related

How to specify any/unknown/variant type in GDScript?

Is there a way to specify an unknown type in GDScript?
GDScript docs use the type Variant for this (for example in Array.count method).
Say, I'd like to write an identity function. I can do it like so:
func identity(x):
return x
But I'd like to declare that both the parameter type and return value could be anything. Something like:
func identity(x: Variant) -> Variant:
return x
This doesn't work though. Variant is not a known type name. I tried various names, bot nothing seems to work.
Is the only option to leave off the type?
Yes, the only option is to not specify the type.
This function:
func identity(x):
return x
Takes Variant and returns Variant.
There is a Variant class defined in Godot in C++. Which, as you have found out, we cannot use it by name in GDScript.
Please notice that the docs use a notation based on C++. For instance int count (Variant value) does not only differ from GDScript because of Variant, but also in that you specify the type after the parameters not before the name, also you use func.
This is how int count (Variant value) looks in GDScript: func count(value) -> int:, and this is the C++ definition: int Array::count(const Variant &p_value) const (source). Compare the C++ definition with the one on the documentation.
For another example, this is how Array duplicate (bool deep=false) looks like in GDSCript: func duplicate(deep:bool=false) -> Array:, and this is the C++ definition: Array Array::duplicate(bool p_deep) const. (source). Notice the C++ definition does not indicate the parameter will be optional, that information is added for the script binding.

Why declare function's type?

Sorry if this has been asked, but seriously can't find anything, so would also appreciate on how to search for this stuff.
So my question: what is the point of declaring the function's type in general? E.g. here 'as double'
Function myFunction(ByVal j As Integer) As Double
Return 3.87 * j
End Function
For a normal variable it has tons of benefits, like less memory, easier to see typos, but why here?
Edit: so, it's good because we can avoid errors, like it giving back a different type of values than expected.
Functions RETURN something. That type is the type of the return.
In your function:
Function myFunction(ByVal j As Integer) As Double
Return 3.87 * j
End Function
You are returning a decimal, so type Double make sense.
If you don't return anything, then you can declare it as a Sub.
And, for clarification, your function would throw a compile error. Unlike other languages, in VBA to return, we set the function name's value to the thing we want to return:
Function myFunction(ByVal j As Integer) As Double
myFunction=3.87 * j
End Function
Now we can call this function to get the Double value that it creates:
Sub testSub()
msgbox("This is the result of the function: " & myFunction(10))
End Sub
Which would launch a message box saying "This is the result of the function: 38.7"
Since I can't mark a comment the answer, let me quote:
#John Coleman
My opinion is that it a good thing to declare your return types because it increases the likelihood that the compiler will complain when you are doing something that really doesn't make sense.
Excel VBA is different from other programming languages in that it centers around a particular application: Excel.
Functions are useful in Excel VBA primarily because they can be typed directly into a cell on a sheet by an end user. User defined functions provide near infinite flexibility. The value the user defined function prints to Excel is formatted based on the function's type--and in a program which is about data visualization, formatting is a huge part.
For example, try putting these four functions into a blank worksheet module:
Function myInt(x, y) As Integer
myInt = x / y
End Function
Function myDouble(x, y) As Double
myDouble = x / y
End Function
Function myString(x, y) As String
myString = x / y
End Function
Function myVariant(x, y)
myVariant = x / y
End Function
Next, enter each of these functions into a different cell in the workbook. Use x=1 and y=2.
myInt produces "=0"
myDouble produces "=0.5"
myString produces "'0"
myVariant produces "=0.5"
If you're okay with Excel deciding how to format your result, that's your choice, but specifying the type offers an entire new level of control. For example, by simply declaring a function an integer, you can avoid having to devote a line of code to rounding. By declaring a function to be a string, you can avoid several lines of formatting code trying to get a number to be saved as text instead.

Excel VBA Enum Type Definitions: The member definition changes case

I will do my best to word this question properly.
The VBA IDE has this feature, where it will change the case of the characters in variable names to the case in which you type the variable name last.
For Instance, let us say I started off with the following line in a SUB:
VAR1 = 1
Now, let us say I type in the following line:
var1 = 2
The entire sub now becomes:
var1 = 1
var1 = 2
I know I can stop this from happening by declaring the variables using the Dim statement, or any of the scoping statements.
Problem:
I am using a Enum in a class module. And one of the class's Public Properties is associated with said Enum. I have capitalized certain characters in the member names to make it readable (camel case).
Now, when the user is setting that property in their standard code module, if they type it all in lowercase, the Enum definition in the class module changes along with it.
Is there a way to stop that from happening?
Is there a way to stop that from happening?s there a way to stop that
from happening?
It seems me that the answer is NO. For many years I put up it and simply keep in mind this behavior. Moreover it's right for standard modules too.
.
Option Explicit and Dim protects variable names. But it will not protect value names in enumerations.
Example:
Option Explicit
Private Enum MyEnum
Item1 = 1
iTem2 = 2
CamelCaseItem = 3
End Enum
Private CamelCaseVariable As Integer
Sub test()
Dim myVariable As MyEnum
myVariable = Item1 + CamelCaseItem
'myVariable = camelcaseitem
Debug.Print myVariable
'camelcasevariable = 3
End Sub
If you uncomment the 'myVariable = camelcaseitem then the letter case of the value name CamelCaseItem will change within the enumeration declaration.
If you uncomment the 'camelcasevariable = 3 then the letter case in this line will change but not the case in the declaration.
If you setup an enum like so:
Public Enum AccountCols
AccountNo = 1
ItemDate
Code
Amount
End Enum
You can refer to it while coding by the name of the enum, followed by a dot, at which point you can select the correct name. This way, you don't have to worry about the case changing, plus you get reminded of what values are in the enum. Using the example enum above, you might type:
Set rngAmount = Cells(lngRow, AccountCols.
at which point you would see the list of names and be able to choose the correct one. No worries about the case changing then. (And a bonus is that the name of the enum itself will change to the case given in the definition, rather than staying as written in the sub.)

Dynamically Size the Upper Bound of a VBA User Defined Type

I'm working with a two-dimensional array that stores a location and date under each iteration. I dynamically set the upper bound of that dimension using a counter variable ("i"), i.e.:
ReDim arrLocDt(1 To i, 0 To 1)
When debugging in the Watch window, I always found it cumbersome that I couldn't name the individual items, for example, instead of
arrLocDt(1,0) and arrLocDt(1,1)
I would like to see:
arrLocDt(1,Location), arrLocDt(1,Date), arrLocDt(2,Location), arrLocDt(2,Date), etc.
Recently, I learned about User-Define Types which would allow for just such labeling of items. Thus I tried the following:
1. Defined a new UDT
Public Type MyType
strLocation As String
strDate As String
End Type
2. Tried the following definition with a dynamic sizing of the upper bound
Dim test(1 to i) As MyType
The above failed because I got the error Constant Expression Required.
Please advise how I can dynamically size the upper bound of an UDT, and if that's not possible, an alternative that would still allow me to label my items.
It should be as easy as:
Dim arrLocDt() As MyType
ReDim arrLocDt(1 To x) As MyType
(The first Dim is actually not required. See this post for details.)
The reason you're running into problems is that you initialize (Dim) an array of any type with a variable size. E.g., this is illegal too:
Dim myStringArray(x) As String
...it's not just a UDT thing. Dynamically sizing or resizing an array can only be done at run-time with a ReDim.
That said, you could do this:
Dim arrLocDt(1 to 10) As MyType
And then later, when you need a different size, do this:
ReDim arrLocDt(1 To x) As MyType
...but you cannot simply start out with this:
Dim arrLocDt(1 to x) As MyType
So, again, if you don't know what the initial size is going to be, just declare the array without any bounds... Dim arrLocDt() As MyType and then ReDim as soon as you know the size and you need to use it.
Also, cool tip, if you need to resize a second time, and you want to keep what is in there, use the Preserve Key Word, like this:
ReDim Preserve arrLocDt(1 to y) As MyType 'resizing, but keeping my stuff

Returning user-defined types on Excel VBA

I've been fiddling with Excel VBA for some time, but I never had any formal training whatsoever. I have the following piece of code on a XLSM module :
Public Type ks_solution
W As Integer
NF As String
ID As Integer
End Type
Public Sub MySub()
//does some things
MyKSSolution = MyFunction(params)
End Sub
Public Function MyFunction(params) as ks_solution
//does stuff and returns a ks_solution
End Function
When I try to run the code, VBA compiler returns a "Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions" error.
Any help would be greatly appreciated.
--Yuri
Er, nevermind. Looks like the problem was in the var declarations.
I thought
Dim v1, v2 as ks_solution
was the same as
Dim v1 as ks_solution, v2 as ks_solution
but apparently, it isn't. In the first case, v1 gets declared as a Variant. Sorry to take your time.

Resources