Checking data types at runtime
In this article, I will show a simple way to check any data type using the Visual Basic language. If you don’t already know how to check data types, I think this article will prove to be very useful for you. I use this technique very often when I write code and I suspect you will as well.
The TypeName Function
The TypeName function is very simple to use. You pass any variable to the function and it returns the type of data assigned to that variable. It is most often used with objects but it can be used with value types as well. Value types are data types that hold values like string, integer, double and so on rather than references to objects. The general syntax goes like this,
strType = TypeName(variable)
An example
Let’s look at it in action with a very common example. Often times you might record a macro with a CATPart active and open in its own window – all goes smoothly and the macro replays fine. Then the next day you replay it again but this time you may have some other document type open or maybe a part is open but it is in a product assembly. Usually the macro will fail because when the code was recorded, a part was the active document, but now it is not. This is a great opportunity to use TypeName to check the type of the active document so you can take additional actions to either have the user select a part or end the program smoothly. Here is an example code snippet:
'Declare variables Dim strType As String Dim strMsg As String Dim objPart As Part Dim strReturn As String Dim objSel As Object Dim varFilter(0) As Variant 'Get the type of the active document strType = TypeName(CATIA.ActiveDocument) 'Decide what to do based on the active doc type Select Case strType Case “PartDocument” 'If a part is the active document then get the part object 'from the active document Set objPart = CATIA.ActiveDocument.Part Case “ProductDocument” 'If a product document is active, assume there is a part in 'the assembly that the user wants to run the program on. 'Give the user a warning to let them know they 'will need to select a part. strMsg = “This program requires a part!” &vbcrlf &vbcrlf strMsg = strMsg &“After clicking OK, please select a part in the assembly…” Msgbox strMsg, 64, “Instructions” 'Begin an interactive selection to get the part. Use a filter 'to only allow the user to either select a part or they may cancel. varFilter(0) = “Part” Set objSel = CATIA.ActiveDocument.Selection objSel.Clear strReturn = objSel.SelectElement2(varFilter, “Select a part…”, false) 'Check the result of the interactive selection If strReturn = “Normal” Then 'The selection was successful, so get the selected part Set objPart = objSel.Item2(1).Value Else 'The selection failed or was canceled by the user, 'so end the program early. Msgbox “Selection failed so the program will end.”, 64, “Selection failed” Exit Sub End If Case Else 'Some other type of document is active (maybe a drawing or other) 'so just warn the user and end the program early strMsg = “This program only works with a part. Please try again…” Msgbox strMsg, 64, “Part required” Exit Sub End Select 'If the code execution gets to here without exiting early, then objPart must 'be a valid part object and we can carry on with the rest of the script 'I will simply display the name of the part. Msgbox objPart.Name
Conclusions
In the example above, you can see that the TypeName function is very easy to use. It is just one line of code. However, the rest of the example is much longer. This is because you need to think ahead and form a plan of what you intend to do if the data type you checked is not the one you expect. The minimum action taken should be to immediately end the program because if you continue an error is sure to result and the user will get an ugly error message. Not good.
If you have the time and the desire to write quality code, by all means do it! The users of your programs will appreciate it, believe me. This is the path I took in the example above. Sure, it took a few more minutes to write the extra lines of code but you have to admit it really improves the usability of the program.
If you like this article, please rate it!
Add to: del.icio.us,
StumbleUpon,
Digg,
Google
Simply Excellent article for newbies like me.
The content and the way of describing it is fantastic.
Please & please increase the frequency of publishing the articles.
Please add your identity on site.
Regards,
Abhay
Hi,
Its again a wonderful intiative to educate the fellow people on the net.
It is always hard to find the ability and limitaion of the a application. i would be greatful if u post articles regading the ability and limition if VB, VBA , VBScript , CATScript.
Thank you
Glad to hear you like the content. Each article focuses in on a specific functionality or technique and I generally try to point out limitations and things to watch out for related to that topic. …Are you interested in limitations related to something specific?
Hi,
i am part time code writer, i used to write VB codes in CATIA and MS-Excel.
most of the time i feel that i m repeating a set of procedures in the same or different program.
Is there any possibility to create a library to store and use a procedure? something like .dll.
Regards,
Ashok
I understand and have this on my list as an upcoming topic to be posted in January. I think many people face the same issue.
Hi,
I don’t know if we can use comments to ask technical questions, so I try.
I’m trying to use the selectionElement2 feature like in this topic but with a “Face”.
I would like to use this selection (face) in reference to make a constraint. So when I do it, I get the surface reference, sample : selection_Rsur:(Face:(….)
But now, to set the reference with CreateReferenceFromName I need the path of this face like : Produit1/test.1/ ( can be long )
How can I get this path ?
Aim :Set reference1 = product1.CreateReferenceFromName(“Produit1/test.1/!Selection_RSur:(Face:(….)..
Thanks.
Regards,
Julian
No problem – the question is a bit off topic from the above post, but I’ll try to explain anyway.
Maybe I should do an article on Reference objects soon???
I assume you understand the concept of instances?…For any given part in the assy, there may be one or more instances of it. Each of those instances is based on some reference part. Anytime you make an interactive selection, the selected object is always returned in relation to the reference. But often in a product context, we need to know which instance the selection was made in (like when you need to create a reference). You can get that instance from the SelectedElement.LeafProduct property. So, in your case, you would do something like this,
‘I assume the part is directly below the root product
Dim objProd as Product
Dim objSel As Object
Dim strInstanceName As String
Dim strGeometryName As String
Dim strReturn As String
Dim objRef As Reference
Set objProd = CATIA.ActiveDocument.Product
Set objSel = CATIA.ActiveDocument.Selection
objSel.Clear
strReturn = objSel.SelectElement2(Array(“Face”), “Select the face…”, False)
If strReturn = “Normal” Then
strInstanceName = objSel.Item2(1).LeafProduct.Name
strGeometryName = objSel.Item2(1).Reference.DisplayName
Set objRef = objProd.CreateReferenceFromName(strInstanceName &”/!” &strGeometryName)
End If
Hi,
thank you very much, your explanations are vey clear and precise, like usual. Last week, I called the catia’s hotline, and they said “It’s not simple” and finally I got no explanation. So thanks a lot and keep going your excellent job, please…
Hello Mike,
(I presume it isn’t Mr Berry) ;-)
I am really keen on your blog – its very clear and containts helpful stuff
Especially if you’re a Newbie.
Hope to find some more goodies here..
Keep up the good work
Thx. man
Kind regards,
Jan
The Netherlands
hello, I have a doubt regarding interfacing of catia with vba. how it is possible to interface vb and catia
Hai Thank u very much for your clear explation.
Alternatively you could do this so it automatically identifies the active part in the assembly by the active instance or part level, or it will return the partdocument if the active document is a part the only failure mode is if the active level is the root node.
Madaxe
Private Function Get_PartDocument() As PartDocument
Dim oCATIA As Application
Dim oDocument As Document
Dim oSelection As Selection
Dim oPart As Part
Set oCATIA = CATIA
Set oDocument = CATIA.ActiveDocument
Set oSelection = oDocument.Selection
oSelection.Clear
‘—————————————————‘
If (InStr(oDocument.Name, “.CATPart”)) = 0 Then
oSelection.Search (“type=Part,in”)
On Error Resume Next
Set oPart = oSelection.FindObject(“CATIAPart”)
If Err.Number 0 Then
MsgBox “A Part or Part Instance Must be Active.” & vbLf & “Exiting The Script”
oSelection.Clear
Exit Function
End If
On Error GoTo 0
Else
Set oPart = oDocument.Part
End If
oSelection.Clear
‘—————————————————‘
Set Get_PartDocument = oPart.Parent
Set oPart = Nothing
Set oSelection = Nothing
Set oDocument = Nothing
Set oCATIA = Nothing
End Function