Maintaining VBscript in property set code to updated API version - Help

Maintaining VBscript in property set code to updated API version - Help

cyberflow
Advisor Advisor
2,103 Views
31 Replies
Message 1 of 32

Maintaining VBscript in property set code to updated API version - Help

cyberflow
Advisor
Advisor

Hi all,

I'm in the process of update my code that worked fine with my C3D 2023 and now adding the code to cover 2025 i've received error messages "PLN is null or empty)" :

cyberflow_0-1739546189313.png

 



I've always found that VBscript always execute oddly - Might be an impression or i'm just really missing something here ...

I've adjusted/added lines 14 to 18 : 

Dim oCivilApp, oDocument, oPipeNetworks, oPipeNetwork, oPipe, oNetworkObjectID, found, InputHandle, sPipeNetworkName, sAcadVer
Dim fs, logFile, sC3DVer

RESULT = "--"
On Error Resume Next

InputHandle = "[Handle]" ' Replace with the actual handle you want to search for
found = False

' Initialize the AutoCAD application object
Set oApp = GetObject(, "AutoCAD.Application")
sAcadVer = oApp.Version

If InStr(sAcadVer, "25.0") > 0 Then
	sC3DVer = "13.7"
ElseIf InStr(sAcadVer, "24.3") > 0  Then
	sC3DVer = "13.6"
ElseIf InStr(sAcadVer, "24.2") > 0  Then
	sC3DVer = "13.5"
ElseIf InStr(sAcadVer, "24.1") > 0  Then
	sC3DVer = "13.4"
ElseIf InStr(sAcadVer, "24.0") > 0  Then
	sC3DVer = "13.3"
ElseIf InStr(sAcadVer, "23.1") > 0  Then
	sC3DVer = "13.2"
ElseIf InStr(sAcadVer, "23.0") > 0  Then
	sC3DVer = "13.1"
End if

Dim interfaceVersion
interfaceVersion = "AeccXUiPipe.AeccPipeApplication." & sC3DVer
Set oCivilApp = oApp.GetInterfaceObject(interfaceversion)

' Access the active document
On Error Resume Next
Set oDocument = oCivilApp.ActiveDocument

' Get the pipe networks collection
Set oPipeNetworks = oDocument.PipeNetworks

' Iterate through pipe networks
For Each oPipeNetwork In oPipeNetworks   
    If Not IsNull(oPipeNetwork.Pipes) And Not IsEmpty(oPipeNetwork.Pipes) Then
        For Each oPipe In oPipeNetwork.Pipes
            If oPipe.Handle = InputHandle Then
                sPipeNetworkName = oPipeNetwork.Name
                found = True
                Exit For
            End If
        Next
    End If
    If found Then
        Exit For
    End If
Next

    If Not IsNull(oPipeNetwork) Then
        Set PLN = oPipeNetwork.ReferencePartList
        ' Check if part list is valid
        If Not IsNull(PLN) And Not IsEmpty(PLN) Then
                ' Determine result based on part list name
                 Select Case PLN.Name
	Case "AIR COMPRIMÉ EXISTANT"
		RESULT = "AIR COMPRIMÉ EXISTANT"
	Case "AIR COMPRIMÉ PROPOSÉ"
		RESULT = "AIR COMPRIMÉ PROPOSÉ"
	Case "AQUEDUC DÉMOLITION", "AQUEDUC DÉSAFFECTER", "AQUEDUC EXISTANT", "AQUEDUC PROPOSE", "AQUEDUC FUTURE"
		RESULT = "A"
	Case "GAZ EXISTANT"
		RESULT = "G"
                    Case "PLUVIAL EXISTANT", "PLUVIAL PROPOSE", "PLUVIAL DÉMOLITION", "PLUVIAL DÉSAFFECTER", "PLUVIAL FUTURE", "PONCEAU EXISTANT", "PONCEAU PROPOSE"
                        RESULT = "P"
                    Case "REFOULEMENT PLUVIAL EXISTANT", "REFOULEMENT PLUVIAL PROPOSE"
                        RESULT = "RFP"
                    Case "REFOULEMENT SANITAIRE EXISTANT", "REFOULEMENT SANITAIRE PROPOSE"
                        RESULT = "RFS"
                    Case "REFOULEMENT UNITAIRE EXISTANT", "REFOULEMENT UNITAIRE PROPOSE"
                        RESULT = "RFU"
                    Case "SANITAIRE EXISTANT", "SANITAIRE PROPOSE", "SANITAIRE DÉMOLITION", "SANITAIRE DÉSAFFECTER", "SANITAIRE FUTURE"
                        RESULT = "S"
                    Case "UNITAIRE EXISTANT", "UNITAIRE PROPOSE", "UNITAIRE DÉMOLITION", "UNITAIRE DÉSAFFECTER", "UNITAIRE FUTURE"
                        RESULT = "U"
					Case "MASSIF ÉLECTRIQUE EXISTANT (BÉTON ARMÉ)", "MASSIF ÉLECTRIQUE EXISTANT (BÉTON)", "MASSIF ÉLECTRIQUE PROPOSE (BÉTON ARMÉ)", "MASSIF ÉLECTRIQUE PROPOSÉ (BÉTON)"
						RESULT = "MASSIF ÉLEC."
					Case "MASSIF FIBRE OPTIQUE EXISTANT (BÉTON ARMÉ)", "MASSIF FIBRE OPTIQUE EXISTANT (BÉTON)", "MASSIF FIBRE OPTIQUE PROPOSE (BÉTON ARMÉ)", "MASSIF FIBRE OPTIQUE PROPOSE (BÉTON)"
						RESULT = "MASSIF FIBRE OPTIQUE"
					Case "MASSIF TÉLÉPHONIE EXISTANT (BÉTON ARMÉ)", "MASSIF TÉLÉPHONIE EXISTANT (BÉTON)", "MASSIF TÉLÉPHONIE PROPOSE (BÉTON ARMÉ)", "MASSIF TÉLÉPHONIE PROPOSE (BÉTON)"
						RESULT = "MASSIF TEL."
                    Case Else
                        RESULT = "--"
                End Select
            'Else
                'RESULT = "PLN.Name is not a string. It is a " & TypeName(PLN.Name)
            'End If
        Else
            RESULT = "PLN is null or empty"
        End If
    Else
        RESULT = "Object not retrieved from handle"
    End If



 
Anyone see's something i'm missing out here ?

Frank Freitas

CAE/CAD/BIM Coordinator & Support Specialist

LinkedIn
0 Likes
2,104 Views
31 Replies
Replies (31)
Message 21 of 32

cyberflow
Advisor
Advisor

Anton is right : What happens if someone outside the company has the drawing ?

Pretty sure it wont work.

Frank Freitas

CAE/CAD/BIM Coordinator & Support Specialist

LinkedIn
0 Likes
Message 22 of 32

Jeff_M
Consultant
Consultant

@Anton_Huizinga Good question! As it was posted, no, I have it saving the sysvar to the registry only. It can be changed so it is saved to the dwg, but I would need to test whether it would be available to others. Will do that today.

Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 23 of 32

Anton_Huizinga
Advocate
Advocate

Now I think about it, that wouldn't help either. Saving a 2025 variable is not valid when opening the drawing in 2024.

0 Likes
Message 24 of 32

Jeff_M
Consultant
Consultant

Okay, yes, by changing the StorageType in the xml file from User to Database it is available to a user without the bundle. However, if a user without the bundle opens the drawing in a different release than what it was last saved in the AECCVER will be different than the currently loaded C3D.

 

What I found in my quick test: in the PackageContents.xml I set the 2024 portion to save to the database and the 2021 portion to not load. I then opened a dwg in 2024, verified the AECCVER sysvar was added and working, saved the dwg. I then opened C3D 2021, verified that the AECCVER sysvar was not actually available to edit, then opened the subject dwg and verified that the PSet property was finding the AECCVER sysvar...except it was for the incorrect value (13.6), however the properties with formulas using that still worked! I'm guessing it is because I have that also on the same machine.

 

Additional testing is suggesting that saving to the drawing is not working well when multiple Civil 3D releases may be in use. Sometimes it worked, other times it would be getting an older AECCVER and stop the formulas from working.

 

So, in conclusion, I feel it best to set the AECCVER to be saved with the User property and supply the bundle to anyone who may need the PropertySet data. Is this ideal? No, but, especially for use by a single organization, it is a workable option. Now if Autodesk would've only given us this simple, read-only, Sysvar in the OOTB product from the start, that would've been a far superior option... @TimYarris , what say you about getting this added so we don't have to jump through hoops?

Jeff_M, also a frequent Swamper
EESignature
Message 25 of 32

cyberflow
Advisor
Advisor

I do agree on your conclusion point

I'm wondering ... with VB Script in the property set isnt possible to read the version of the DLL's ?
And what if the DLL's are always relative to the same version folder ....

Isnt that a venue to test ?

Ill try to test something out soon.

Frank Freitas

CAE/CAD/BIM Coordinator & Support Specialist

LinkedIn
0 Likes
Message 26 of 32

Jeff_M
Consultant
Consultant

@cyberflow You seem to have a better grasp of teh VBScript than I so maybe you can find a way  to make this work. The following is what I have tried, without success. This is pretty much identical code (to get the current AeccApplication) that I use in many .NET, COM based, tools.

RESULT="--"
On Error Resume Next
Set oApp=GetObject(, "AutoCAD.Application")
Set oCivilApp=New AeccApplication()
oCivilApp.Init(oApp)
Set obj=oCivilApp.ActiveDocument.HandleToObject("[Handle]")
RESULT=obj.Name

I have used this method for many years, yet I sure can't get it working with the Psets.

Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 27 of 32

Anton_Huizinga
Advocate
Advocate

This:

Set oCivilApp=New AeccApplication()

Is not recognized. Maybe VBScript is too limited, compared to VBA.

 

In the end, I think my original idea of creating one formula property that returns the correct reference, will be an acceptable workaround. Then with a new version, only one formula property per drawing needs to be changed.

0 Likes
Message 28 of 32

cyberflow
Advisor
Advisor

That would be an agile way of maintaining the code @Anton_Huizinga !

Instead of maintaining several PS codes.

Anyone knows if there's a variable that stores the location of all the .dll in C3D or the version path "C:\Program Files\Autodesk\AutoCAD 2025\C3D" ?

Frank Freitas

CAE/CAD/BIM Coordinator & Support Specialist

LinkedIn
0 Likes
Message 29 of 32

cyberflow
Advisor
Advisor

Hey there

I noticed that AECCVERSION returns a bunch of text with the different modules and versions  i was wondering if there's a way of fetching the version of one of them in the vbscript ?

Frank Freitas

CAE/CAD/BIM Coordinator & Support Specialist

LinkedIn
0 Likes
Message 30 of 32

Anton_Huizinga
Advocate
Advocate

It could be possible to split the result and get the major and minor versions. But I'm not sure if this information is also translated in other languages. It looks something like this:

Anton_Huizinga_0-1740566743793.png

Get the third line, split on semicolon, remove spaces, split on point, combine the first two values (13.7).

 

But this value is only valid for the Aecc parts. If you want to use, e.g. convert functions from the AecBaseApplication, that has a different version number:

Anton_Huizinga_1-1740570369007.png

Which I had described in my blog: https://blog.huiz.net/2024/11/30/dynamische-of-statische-property-sets-in-civil-3d-1/

Message 31 of 32

cyberflow
Advisor
Advisor

Thanx for that share Anton !

I was thinking ... what about doing a loop that tests differente version numbers until it hits the correct one ?

Frank Freitas

CAE/CAD/BIM Coordinator & Support Specialist

LinkedIn
0 Likes
Message 32 of 32

Anton_Huizinga
Advocate
Advocate

The AeccPipeApplication and the AecBaseApplication have different numbers. I did not find a variable that returns the latter.

 

Another option is searching for the two files and read the file version. Here is an example of reading all files in all sub-folders:

 

https://www.vbsedit.com/scripts/storage/files/searchfiles.asp

 

and this for reading the file properties:

 

https://www.vbsedit.com/html/45588625-2d2b-4efa-95e1-6cf1feb8f3e7.asp

 

Which can be used to find the files AecBase.dbx (to read the file version 8.7, in civil 3D 2025) and AeccCoreBase.dbx (to read the file version 13.7, in Civil 3D 2025).

 

But I wouldn't advice that. I don't know if the result is cached, else every Property Set reprocessing will do haevy disc reading tasks.

 

 

0 Likes