hexagon logo

Why is writing to PC-DMIS from VBA so slow?

I have two scripts that do very similar things : Read scan point data from PC-DMIS and then write scan point data back into PC-DMIS. One version of the script is written and executed in PC-DMIS basic. The other is written in Excel VBA and is executed through Excel by calling the macro from a very simple PC-DMIS script.

The PC-DMIS only version writes the scan data out to a temp file and then reads it back out of the file and writes to PC-DMIS. The excel version reads the data out into memory in a 2D array and then writes it back into PC-DMIS from the array, no external files involved.

I figured the Excel version would be faster since everything is in memory. It turns out that it is wicked slow and takes about 11 seconds to write a 64 point scan while the PC-DMIS version does it in less than 1 second. All the time is in the writing via the Puttext method. Reading from PC-DMIS into the array takes a fraction of a second but writing it back out into PC-DMIS takes 11 seconds. In the PC-DMIS only version both operations take a fraction of a second.

Is VBA just inherently slow for this kind of thing? Anyone else experienced this?
  • Thanks again for the suggestions. I'll try to implement and report back if the improvement is significant. Even without any of these other improvements the speed is now easily fast enough for production use.
  • another way to speed things up would be a Parallel.For loop. It does not exist in VBA because VBA is not multi threaded but it does in VB.NET so the conversion should be pretty easy.

    Parallel.For(0, 10, Sub(i)
                                    Console.WriteLine(i)
                                End Sub)
    
  • Any time I am reading from PCDMIS with an external app I just grab the edit window text and parse line by line. It's wicked fast, as long as the text has the info you need. I can process 6000 lines even before the form shows. I'm going to try Application.Visible for writing TO PCDMIS though!!

    Dim progText As String = Pcdapp.ActivePartProgram.EditWindowTextAll
    Dim prgLines() As String = Split(progText, Chr(10))
    For t As Integer = 0 To prgLines.Length - 1
    'parse lines here, for example:
    If prgLines(t).Contains("THEO/") Then
    'process text here
    End If
    Next
  • Slick solution, bjacobson!


    +1

    It's odd how a .bas run from pc-dmis can do it in the blink of an eye, but a compile vb / .net application is quite ponderous.

    Could it be anything to do with early vs late binding I wonder?
  • That is an interesting solution bJacobson. Does the text have to be visible in the edit window? What happens with a feature parameter that is not shown when that feature is in a group that is collapsed? In other words, text that is hidden multilevels deep.
  • Ninja Badger:

    The late vs. early binding is what Gomofazter was getting at when he suggested that I specify the object types precisely instead of using the generic "Object". When you declare something as "Object" it is late bound and when you specify the exact type of object it is early bound.

    I haven't had a chance to test it yet but I will and will report back.
  • Does the text have to be visible in the edit window? What happens with a feature parameter that is not shown when that feature is in a group that is collapsed? In other words, text that is hidden multilevels deep.


    A quick test indicates that WYSIWYG, i.e. What You See in the Edit Window (Command Mode) Is What You Get. Groups are not automatically expanded. No good for groups or FCF dimensions, etc.

    OTOH, it seems to give the Command Mode text even when the EW is in Summary Mode...
  • Yes WYSIWYG, anytime I need additional info, hit points from an auto circle for instance, I just retrieve the command from PCDMIS and process it (for example: Dim cmd as Command = cmds.Item(cmdName)). It's still pretty fast. You could probably also expand the groups before grabbing the text, and collapse them immediately after? We don't use groups very often.

    As far as binding...I typically always declare as the particular object type (early binding?) and see no difference in speed. I mostly do it because of the auto complete in VS. Slight smile

    Dim cmd As PCDLRN.Command
    Dim cmds As PCDLRN.Commands
  • Using generic objects and variants creates some additional overhead while determining what type of object or datatype is being dealt with.


    I tested the speed difference caused by specifying objects as PCDLRN types instead of as generic "Object". There was no significant difference in speed even on a very long filtering routine that processes 10's of thousands of points. I agree that it is best practice to do this but it doesn't really improve execution speed in a significant way.

    Command.FeatCmd.SetHit could combine 3 separate Command.PutText calls into one.


    This one has a huge effect. Switching from .puttext to .sethit reduced run time by ~83%! I went from an average of 247 seconds down to 41 seconds.