hexagon logo

Script to make a change in all programs?

All of our programs are set up to automatically save reports to a specific directory based on part number. IT has decided they need to re-map our entire network which means I need to edit all of our programs to save reports according to the new network mapping scheme. Is it possible to use a script for this task? If so, does anyone have an example of how to do this?
  • Thanks, it's working just fine now. However I do have another question. Currently this changes only the path in my print command. I have paths called out in other commands as well, script, stats, assignments, file/open, file/close, etc. I've been able to get those to change using this script by copy/paste and changing some code.

    Is there a way to just straight up look for a string of text ("J:\") throughout the whole program, like find/replace, without looking for a specific command? I only ask because not all programs have the same commands. I would need to modify this script to include all commands where a path is called out. I don't have a problem doing this; I understand if a program does not have that command it will skip over it. I'm just curious...


    Without doing any testing, I would assume the path is usually stored in a PCDLRN.ENUM_FIELD_TYPES.FILE_NAME property underneath any command. In our loop that evaluates the command and modifies the path property, we could try taking out the conditional statement that filters out anything but print commands (notice I put an apostrophe at the beginning of the line that checked the command type; this comments out that line so it does not execute when the application is run):

    Try
                pcdParts.Open(FilePath, "CMM1")
                pcdActivePart = pcdApp.ActivePartProgram
                pcdCommands = pcdActivePart.Commands
                For i As Integer = 0 To pcdCommands.Count
                    pcdCommand = pcdCommands.Item(i)
                    If pcdCommand Is Nothing Then Continue For
                    [COLOR="#008000"]'If Not pcdCommand.Type = PCDLRN.OBTYPE.PRINT_REPORT Then Continue For[/COLOR]
                    Dim tmpText = pcdCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.FILE_NAME, 1)
                    If tmpText.Contains(ChangeFrom) Then
                        pcdCommand.PutText(tmpText.Replace(ChangeFrom, ChangeTo), PCDLRN.ENUM_FIELD_TYPES.FILE_NAME, 1)
                    End If
                Next
                pcdActivePart.Close()
                Return True
            Catch ex As Exception
                Console.WriteLine("ConvertPrintPath : " & ex.Message)
                Return False
            End Try


    The whole application would now look like this:

    Imports System.Threading
    Imports System.IO
    
    Module Module1
    
        Const ProgramDir = "J:\TEMP\"
        Const ProgramFileExt = "*.PRG"
        Const ChangeFromPath = "J:\"
        Const ChangeToPath = "S:\"
    
        Private pcdApp As PCDLRN.Application
        Private pcdParts As PCDLRN.PartPrograms
        Private pcdActivePart As PCDLRN.PartProgram
        Private pcdCommands As PCDLRN.Commands
        Private pcdCommand As PCDLRN.Command
    
        Sub Main()
    
            If ConnectPCD() = True Then
                Dim tmpFiles() As String = GetFiles(ProgramDir)
                Try
                    For Each tmpFile As String In tmpFiles
                        If ConvertPrintPath(tmpFile, ChangeFromPath, ChangeToPath) = False Then Exit For
                    Next
                Catch ex as Exception
                    Console.Writeline(ex.Message)
                End Try
                Console.WriteLine("Complete!")
            End If
    
            DisconnectPCD()
    
            Console.ReadLine()
    
        End Sub
    
        Function GetFiles(ByVal RootDir As String) As String()
    
            Return Directory.GetFiles(RootDir, ProgramFileExt, SearchOption.AllDirectories)
    
        End Function
    
        Function ConnectPCD() As Boolean
    
            Try
                pcdApp = GetObject("", "PCDLRN.Application")
                pcdApp.WaitUntilReady(60)
                Thread.Sleep(2000)
                pcdApp.Visible = True
                pcdApp.Maximize()
                pcdParts = pcdApp.PartPrograms
                If pcdParts.Count <> 0 Then
                    Throw New Exception("Please close all open PC-DMIS part programs.")
                End If
                Return True
            Catch ex As Exception
                Console.WriteLine("ConnectPCD : " & ex.Message)
                Return False
                pcdParts = Nothing
                pcdApp = Nothing
                GC.Collect()
            End Try
    
        End Function
    
        Sub DisconnectPCD()
    
            pcdCommand = Nothing
            pcdCommands = Nothing
            pcdActivePart = Nothing
            pcdParts = Nothing
            pcdApp = Nothing
            GC.Collect()
    
        End Sub
    
        Function ConvertPrintPath(ByVal FilePath As String, ByVal ChangeFrom As String, ByVal ChangeTo As String) As Boolean
    
            Console.WriteLine("Converting file: " & FilePath)
    
            Try
                pcdParts.Open(FilePath, "CMM1")
                pcdActivePart = pcdApp.ActivePartProgram
                pcdCommands = pcdActivePart.Commands
                For i As Integer = 0 To pcdCommands.Count
                    pcdCommand = pcdCommands.Item(i)
                    If pcdCommand Is Nothing Then Continue For
                    [COLOR="#008000"]'If Not pcdCommand.Type = PCDLRN.OBTYPE.PRINT_REPORT Then Continue For[/COLOR]
                    Dim tmpText = pcdCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.FILE_NAME, 1)
                    If tmpText.Contains(ChangeFrom) Then
                        pcdCommand.PutText(tmpText.Replace(ChangeFrom, ChangeTo), PCDLRN.ENUM_FIELD_TYPES.FILE_NAME, 1)
                    End If
                Next
                pcdActivePart.Close()
                Return True
            Catch ex As Exception
                Console.WriteLine("ConvertPrintPath : " & ex.Message)
                Return False
            End Try
    
        End Function
    
    End Module
  • Without doing any testing, I would assume the path is usually stored in a PCDLRN.ENUM_FIELD_TYPES.FILE_NAME property underneath any command. In our loop that evaluates the command and modifies the path property, we could try taking out the conditional statement that filters out anything but print commands (notice I put an apostrophe at the beginning of the line that checked the command type; this comments out that line so it does not execute when the application is run):



    For whatever reason the Stats/Transfer command uses the PCDLRN.ENUM_FIELD_TYPES.TRANSFER_DIR property. I will have to look through my programs and see what commands are used with a network path. Luckily, as currently written I think this should take care of about 95% or my programs. There are only a few that have extra commands due to specific customer requirements for data capture.

    Your help is much appreciated! I am better off with the knowledge you have shared; thank you!
  • For whatever reason the Stats/Transfer command uses the PCDLRN.ENUM_FIELD_TYPES.TRANSFER_DIR property. I will have to look through my programs and see what commands are used with a network path. Luckily, as currently written I think this should take care of about 95% or my programs. There are only a few that have extra commands due to specific customer requirements for data capture.

    Your help is much appreciated! I am better off with the knowledge you have shared; thank you!


    It sounds like you're picking up the code! Another cool thing you can do is export BASIC scripts of entire programs out of PC-DMIS (File > Export > BASIC), and it will be almost identical to how you need to call things from VB.Net.

    If I'm trying to figure out what one specific PC-DMIS command looks like in BASIC code, I will write a simple PC-DMIS program that only calls that one command and export the BASIC file. For example, I write a PC-DMIS program that looks like this:

    PART NAME  : EricTemp
    REV NUMBER : 
    SER NUMBER : 
    STATS COUNT : 1
     
    STARTUP    =ALIGNMENT/START,RECALL:,LIST=YES
                ALIGNMENT/END
                MODE/MANUAL
                FORMAT/TEXT,OPTIONS, ,HEADINGS,SYMBOLS, ;NOM,TOL,MEAS,DEV,OUTTOL, , 
                LOADPROBE/MD01_SM_STAR
                TIP/T1A0B0, SHANKIJK=0, 0, 1, ANGLE=0
                STATS/TRANSFER,DIRECTORY=J:\


    When I export the BASIC code, it looks like this:

    Dim DmisApp As Object
    Dim DmisPart As Object
    Dim DmisCommands As Object
    Dim DmisCommand As Object
    
    Sub Part1
      Set DmisApp = CreateObject("PCDLRN.Application")
      Set DmisPart = DmisApp.ActivePartProgram
      Set DmisCommands = DmisPart.Commands
      CommandCount = DmisCommands.Count
      Set DmisCommand = DmisCommands.Item(CommandCount)
      DmisCommands.InsertionPointAfter DmisCommand
      Set DmisCommand = DmisCommands.Add(START_ALIGN, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Id  = STARTUP
        retval = DmisCommand.PutText ("STARTUP", ID, 0)
      ' Set Reference Id Item 1 = 
        retval = DmisCommand.PutText ("", REF_ID, 1)
      ' Set Alignment List  = YES
        retval = DmisCommand.SetToggleString (2, ALIGN_LIST, 0)
      
      Set DmisCommand = DmisCommands.Add(END_ALIGN, TRUE)
        DmisCommand.Marked = TRUE
      
      Set DmisCommand = DmisCommands.Add(MAN_DCC_MODE, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Mode  = MANUAL
        retval = DmisCommand.SetToggleString (2, MODE_TYPE, 0)
      
      Set DmisCommand = DmisCommands.Add(DIMENSION_FORMAT, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Dimension Text  = TEXT
        retval = DmisCommand.SetToggleString (1, DIM_TEXT, 0)
      ' Set Dimension Text Options  = OPTIONS
        retval = DmisCommand.SetToggleString (2, DIM_TEXT_OPTIONS, 0)
      ' Set Show Headings  = HEADINGS
        retval = DmisCommand.SetToggleString (3, SHOW_HEADINGS, 0)
      ' Set Show Symbols  = SYMBOLS
        retval = DmisCommand.SetToggleString (4, DEVIATION_SYMBOLS, 0)
      ' Set Standard Deviation  =  
        retval = DmisCommand.SetToggleString (7, STANDARD_DEVIATION, 0)
      ' Set Dimension Heading Item 1 = NOM
        retval = DmisCommand.SetToggleString (1, DIM_HEADING, 1)
      ' Set Dimension Heading Item 2 = TOL
        retval = DmisCommand.SetToggleString (2, DIM_HEADING, 2)
      ' Set Dimension Heading Item 3 = MEAS
        retval = DmisCommand.SetToggleString (3, DIM_HEADING, 3)
      ' Set Dimension Heading Item 4 = DEV
        retval = DmisCommand.SetToggleString (5, DIM_HEADING, 4)
      ' Set Dimension Heading Item 5 = OUTTOL
        retval = DmisCommand.SetToggleString (6, DIM_HEADING, 5)
      
      Set DmisCommand = DmisCommands.Add(GET_PROBE_DATA, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Filename  = MD01_SM_STAR
        retval = DmisCommand.PutText ("MD01_SM_STAR", FILE_NAME, 0)
      
      Set DmisCommand = DmisCommands.Add(SET_ACTIVE_TIP, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Id  = T1A0B0
        retval = DmisCommand.PutText ("T1A0B0", ID, 0)
      ' Set Tip I  = 0
        retval = DmisCommand.PutText ("0", TIP_I, 0)
      ' Set Tip J  = 0
        retval = DmisCommand.PutText ("0", TIP_J, 0)
      ' Set Tip K  = 1
        retval = DmisCommand.PutText ("1", TIP_K, 0)
      ' Set Theoretical Angle  = 0
        retval = DmisCommand.PutText ("0", THEO_ANGLE, 0)
      
    [COLOR="#FF0000"]  Set DmisCommand = DmisCommands.Add(STATISTICS, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Statistics Type  = TRANSFER
        retval = DmisCommand.SetToggleString (3, STATS_TYPE, 0)
      ' Set Transfer Directory  = J:\
        retval = DmisCommand.PutText ("J:\", TRANSFER_DIR, 0)[/COLOR]
      
    End Sub
    
    Sub Main
    
      Part1
    
      DmisPart.RefreshPart
    End Sub


    I can then look at the Stats command, and see that PC-DMIS is calling a "STATISTICS" command and the TRANSFER_DIR property is holding the path:

    [COLOR="#FF0000"]  Set DmisCommand = DmisCommands.Add(STATISTICS, TRUE)
        DmisCommand.Marked = TRUE
      ' Set Statistics Type  = TRANSFER
        retval = DmisCommand.SetToggleString (3, STATS_TYPE, 0)
      ' Set Transfer Directory  = J:\
        retval = DmisCommand.PutText ("J:\", TRANSFER_DIR, 0)[/COLOR]


    Going back to our console application, I can now add another line into our loop that reads the text in the "TRANSFER_DIR" property, as well as a test for the folder string we're looking for and a command to replace it:

    Try
                pcdParts.Open(FilePath, "CMM1")
                pcdActivePart = pcdApp.ActivePartProgram
                pcdCommands = pcdActivePart.Commands
                For i As Integer = 0 To pcdCommands.Count
                    pcdCommand = pcdCommands.Item(i)
                    If pcdCommand Is Nothing Then Continue For
                    [COLOR="#008000"]'If Not pcdCommand.Type = PCDLRN.OBTYPE.PRINT_REPORT Then Continue For[/COLOR]
                    Dim tmpText = pcdCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.FILE_NAME, 1)
                    If tmpText.Contains(ChangeFrom) Then
                        pcdCommand.PutText(tmpText.Replace(ChangeFrom, ChangeTo), PCDLRN.ENUM_FIELD_TYPES.FILE_NAME, 1)
                    End If
                    [COLOR="#FF0000"]tmpText = pcdCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRANSFER_DIR, 0)
                    If tmpText.Contains(ChangeFrom) Then
                        pcdCommand.PutText(tmpText.Replace(ChangeFrom, ChangeTo), PCDLRN.ENUM_FIELD_TYPES.TRANSFER_DIR, 0)
                    End If[/COLOR]
                Next
                pcdActivePart.Close()
                Return True
            Catch ex As Exception
                Console.WriteLine("ConvertPrintPath : " & ex.Message)
                Return False
            End Try
  • I did not know you could export dmis to basic like this. This is actually awesome. yay geek moment.