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?
  • To avoid getting myself into this sort of situation I have a text file that contains all of the components of my file paths that I don't have direct control over. I read in this text file at the beginning of every program and use the information to create the paths for saving off data. This way if something like what just happened to you happens to me I can just change a few lines in that text file and all of my programs will adapt to the new directory structure without any modification. This won't be much help to you with your current situation but may be something to consider in the future.
  • Question: are the paths hard-coded in the File- Printing - Report Window Setup, or are they hard-coded in a Print Command?


    To avoid getting myself into this sort of situation I have a text file that contains all of the components of my file paths that I don't have direct control over. I read in this text file at the beginning of every program and use the information to create the paths for saving off data. This way if something like what just happened to you happens to me I can just change a few lines in that text file and all of my programs will adapt to the new directory structure without any modification. This won't be much help to you with your current situation but may be something to consider in the future.


    +1, excellent elegant "preventative measures" solution.
  • I do something kind of like DaSalo, except that I utilize drive mappings on the computer.

    My CMMs have their default directories pointing to a simple folder structure on a "P:" drive:

    Programs - P:\PROGRAMS\
    Probes - P:\PROBES\
    Recall - P:\RECALL\
    Subroutines - P:\SUBROUTINES\

    These are also the paths I will use to recall any scripts or subroutines from (e.g. "P:\SUBROUTINES\DOSTUFF.BAS")

    If we want to change the location of where all these folders are I can just remap my P: drive to a new location, I just have to make sure I maintain the same structure of subfolders (PROGRAMS / PROBES / etc.)
  • By the way N3WPV, do you have any experience scripting in something outside of PC-DMIS (i.e. VB.NET/VBA/VBScript/Powershell/etc.)? If you give us an example of what commands/values you're trying to modify, we could probably help you write something.
  • Question: are the paths hard-coded in the File- Printing - Report Window Setup, or are they hard-coded in a Print Command?


    By the way N3WPV, do you have any experience scripting in something outside of PC-DMIS (i.e. VB.NET/VBA/VBScript/Powershell/etc.)? If you give us an example of what commands/values you're trying to modify, we could probably help you write something.




    I have a Print Command at the end of each program that saves the report to a specific folder based on part number with a filename based on user input data.

    PRINT/REPORT,EXEC MODE=END,$              
    TO_FILE=ON,OVERWRITE="[COLOR=#ff0000]J[/COLOR]:\Quality\Enginetics Part Numbers\5000 - 5999\5307188-01\CMM Reports\5307188-01 - Lot "+ LOT +" - #"+ SERNUM +".rtf",$
    TO_PRINTER=OFF,$
    TO_DMIS_REPORT=OFF,FILE_OPTION=INDEX,FILENAME=,$
    REPORT_THEORETICALS=NONE,REPORT_FEATURE_WITH_DIMENSIONS=NO,$
    PREVIOUS_RUNS=KEEP_INSTANCES



    Everything on our "J" drive has been moved to the "S" drive. I wasn't sure if a script to change this was possible since PCD programs are not true text files, unless I'm mistaken. If a script is possible I do not know how to do it. I've taken scripts here and studied how they work and have been able to modify them to meet my needs but to create one from scratch is above me.

    I also have some other commands I may need to modify ie., scripts, stats, custom data exports, etc. Being able to use a script to do a global "find...replace" would be a big time saver! I like the idea of reading in a text file for path structure and will look into this.
  • Isn't it possible to create a new drive letter (J in this case) pointing to the S-drive folder?

    Then there would be no need to edit all your programs...
  • If you can just remap your J: to the location of your new S: drive, that would be the easiest way to go. If your J: drive is a network share that you still need access to, you may need to map it to something else, but then your PC will probably be different from all the others in your company.

    If you want to script a batch conversion, you can paste this into a new VB.NET console application. You'll need to change the constant 'ProgramDir' value (right at the top) to whatever root directory you want to start the conversion in (maybe "J:\Quality\" based on your example.) It would probably be wise to copy a few programs to another location to test this, and then copy all of your programs to another location for doing a full run.

    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
                    If Not pcdCommand.Type = PCDLRN.OBTYPE.PRINT_REPORT Then Continue For
                    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
    
  • So I'm finally getting around to trying this. I created a new console app in VB 2010 Express and copied the above code into the code window. I'm getting the following in the error list:



    I'm assuming it's because I need to add the PCD reference library to VB 2010 Express. My question is which file(s) do I need to add?
  • Before you do anything else, keep in mind that this code is doing a batch processing of files, and has the potential to do some damage. With that said...

    ---

    You should by default have a "Solution Explorer" window on the right side of your screen that lists the items in your solution, otherwise you can open it from the View menu.

    On the very first item in your solution (should be named whatever you assigned as the overall project name), right click and choose "Add Reference..." from the context menu.

    When the "Add Reference" dialog appears, click the "COM" tab and wait a few seconds/minutes for the list of registered COM assemblies to populate.

    Once the list if populated, scroll down until you find an item to the effect of "PC-DMIS XXXXX Object Library". There should be an entry for any versions of PC-DMIS you have installed (i.e. "PC-DMIS 4.2 Object Library".) If there is more than one, choose the one that best matches whatever you are currently running.

    Highlight the item as described above, and click OK. The errors in your list should go away.

    ---

    Once you're getting ready to start running the code, I would recommend that you change the constant paths to a location with a few files you can test on.

    I would also recommend putting a breakpoint in the program and stepping through so you understand what the code is doing. You can add a breakpoint by clicking on the grey vertical bar on the left side of the editor window:



    When you run the application (pressing the F5 key), it will pause on this point so you can step through one command at a time with the F8 key.
  • 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...