Xdata for element in OpenDesignFileForProgram

Fellow Microstation VBA users,

I neeed some basic code to add/modify Xdata for an element, in a cell, in a design file, opened with OpenDesignFileForProgram.  I'm uncertain how to do this.  My guess would be to utilize the Appplication.ObjectConnector or the mdlModelRef_loadReferenceModels?

Thanks in advance,

Christmas May

  • Also note:  The following code works when ran on an individual file.  However, it doesn't work when run via "Batch Process"?

    Private Sub sRepairABC(gObjCell As CellElement)
       Dim sIntIndex
       Dim sBlnABC As Boolean
       Dim sObjTempElement As Element
       Dim sStrXdata As String
       Dim sAryXdatum() As XDatum
       Dim theID As DLong

       'Step through the cell
       gObjCell.ResetElementEnumeration
       sIntIndex = 0
       Do While gObjCell.MoveToNextElement
          sIntIndex = sIntIndex + 1
          Set sObjTempElement = gObjCell.CopyCurrentElement
          If sIntIndex < 9 Then
             sStrXdata = "A" & CStr(sIntIndex)
          Else
             sStrXdata = "B" & CStr(sIntIndex - 8)
          End If
          'Build the new XDatum array.
          'AppendXDatum sAryXdatum, msdXDatumTypeControlString, "{"
          InsertXDatum sAryXdatum, 0, msdXDatumTypeString, sStrXdata   'Append or Insert really doesn't matter.
          'AppendXDatum sAryXdatum, msdXDatumTypeControlString, "}"

          'Then put it onto the element.
          sObjTempElement.DeleteAllXData
          sObjTempElement.SetXData "RevABC", sAryXdatum
          'sObjTempElement.Rewrite
          gObjCell.ReplaceCurrentElement sObjTempElement
          DeleteXDatum sAryXdatum, 0
       Loop
       gObjCell.Rewrite
    End Sub

    Please help,

    Christmas May

  • Unknown said:
    My guess would be to utilize the Appplication.ObjectConnector or the mdlModelRef_loadReferenceModels?

    Your question makes it hard to interpret what you want to do.

    Mention of the Application.ObjectConnector implies that you're writing VB/VBA code running outside MicroStation.

    Mention of mdlModelRef_loadReferenceModels suggests that you want to write MDL code running inside MicroStation.

    From your subsequent post it looks like you are writing VBA code to run inside MicroStation. Please clarify …

    1. Does your code run in MicroStation or some other product? If your code runs in MicroStation you don't need to use the Application.ObjectConnector — you're already connected to MicroStation
    2. Why would mdlModelRef_loadReferenceModels help with your goal of creating or modifying XData?

    Unknown said:
    It doesn't work when run via "Batch Process"

    Please explain what you mean by "Batch Process".

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • I've saved the following code in an Xdata.mvba file.  I then generated a BatchXdata.txt file that has a line something like:

    vba run [Xdata]Module1.Main

    It does run, however, doesn't change the Xdata for the element in the cell in the .dgn file.

    Public Sub Main()
        Dim enumModCell As ElementEnumerator    'enumerator to hold search results
        Dim sc As ElementScanCriteria           'scan criteria
        Dim booCellFound As Boolean
        Const CellName = "ABC"
       
    'search the model for cell
       Set sc = New ElementScanCriteria
       sc.ExcludeAllTypes
       sc.IncludeOnlyCell CellName
       sc.IncludeType msdElementTypeCellHeader
       
       Set enumModCell = ActiveModelReference.GraphicalElementCache.Scan(sc) 'scan the file, get all cells of CellName

       Do While enumModCell.MoveNext
          enumModCell.Current.Redraw msdDrawingModeHilite
          Call sRepairABC(enumModCell.Current)
       Loop
    End Sub

    Private Sub sRepairABC(gObjCell As CellElement)
       Dim sIntIndex
       Dim sBlnABC As Boolean
       Dim sObjTempElement As Element
       Dim sStrXdata As String
       Dim sAryXdatum() As XDatum
       Dim theID As DLong

       'Step through the cell
       gObjCell.ResetElementEnumeration
       sIntIndex = 0
       Do While gObjCell.MoveToNextElement
          sIntIndex = sIntIndex + 1
          Set sObjTempElement = gObjCell.CopyCurrentElement
          If sIntIndex < 9 Then
             sStrXdata = "A" & CStr(sIntIndex)
          Else
             sStrXdata = "B" & CStr(sIntIndex - 8)
          End If
          'Build the new XDatum array.
          'AppendXDatum sAryXdatum, msdXDatumTypeControlString, "{"
          InsertXDatum sAryXdatum, 0, msdXDatumTypeString, sStrXdata   'Append or Insert really doesn't matter.
          'AppendXDatum sAryXdatum, msdXDatumTypeControlString, "}"

          'Then put it onto the element.
          sObjTempElement.DeleteAllXData
          sObjTempElement.SetXData "RevABC", sAryXdatum
          'sObjTempElement.Rewrite
          gObjCell.ReplaceCurrentElement sObjTempElement
          DeleteXDatum sAryXdatum, 0
       Loop
       gObjCell.Rewrite
    End Sub

     

  • Unknown said:
    Set enumModCell = ActiveModelReference.GraphicalElementCache.Scan(sc)

    By default you scan the element cache, so that's an unusual call. Put more simply

    Set enumModCell = ActiveModelReference.Scan(sc)

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • In your subject line you mention using OpenDesignFileForProgram.
    However, in your code sample you show:
    Set enumModCell = ActiveModelReference.GraphicalElementCache.Scan(sc) 'scan the file, get all cells of CellName

    That line scans the "Active" model, which is not what you want if using a "work dgn" (OpenDesignFileForProgram).
    You would need to explicitly scan the Model within the work dgn and not the Active model.
    Also, since the work dgn is not "Active" or visible, it renders a number of other items useless.
    Such as redraw, hilite, etc.

    Also out of curiosity, what is the purpose of appending seperate XData to each component of the cell?

    -G-

  • Mr. Jon Summers,

    I actually tried the ActiveModelReference.Scan(sc) first.  When it didn't work I then resorted to the Microstation Help files which had an example that used the "ActiveModelReference.GraphicalElementCache.Scan(sc)".  Then when I pasted the code into this forum, it was still like that.  Since your posting I've changed it back to "ActiveModelReference.Scan(sc)" and it really doesn't seem to make a difference.  When I load a file and execute the code, it works.  When I either run it through "OpenDesignFileForProgram" or with a "Batch Process" it doesn't.

    Sincerely,

    Christmas May

  • Mr. Gerald Hernandez,

    Your thoughts seem to be exactly what I'm seaching for.  What would my code look like to scan the "work dgn" rather than the "Active model"?  That is basically why I have the line "gObjCell.ReplaceCurrentElement sObjTempElement" although I'm not sure it is required?

    Sincerely,

    Christmas May

  • Active Model or Work DGN?

    You haven't answered my earlier question.

    Are you working in a normal MicroStation session? Your example key-in vba run Main suggests that this is so. If so, you can use ActiveModelReference to refer to a model. In this case OpenDesignFileForProgram adds irrelevant complexity.

    OR

    Are you using a Work DGN, where you used OpenDesignFileForProgram to obtain a reference to a DesignFile? If so, you must activate and use a ModelReference to refer to a model from that design file.

    As usual, a code sample is worth 1,000 words.

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • Mr. Jon Summers,

    This project started off using a Work DGN where a OpenDesignFileForProgram is used to obtain a reference to a designfile.  As previously mentioned the code developed worked well for the first file, but failed on the second, third, .. 101st, 102nd, etc. file.  After thinking for awhile, I decided that it might work if I simply extracted my VBA code to a totally seperate .mvba file and then utilized Microstation's built in "Batch Process" to run it on several files . . . slight performace hit due to loading each file.  Much to my suprise, this behaved exactly the same.  It corrected the first file, but failed to correct the additional 100+ files.

    I don't really care if I use the OpenDesignFileForProgram method or a "Batch Process" method.  I need to assign Xdata to an element, in a cell, in a .DGN file that is currently not open.  It doesn't seem like it would take more than 20 lines of code or so?  Microstation acts like I'm not writing/saving the file once the Xdata is associated with the element.

    Sincerely,

    Christmas May

     

  • Unknown said:
    I decided that it might work if I simply extracted my VBA code to a totally separate .mvba file and then utilized Microstation's built in "Batch Process" to run it on several files  … slight performace hit due to loading each file.

    If you want to modify data in a file — whether a DGN file or a TXT file or an XLS file — you have to open that file. There isn't a 'performance hit'. Opening a file is something you just have to do if you want to modify it.

    From what you've posted I think OpenDesignFileForProgram is a red herring: it's a distraction and you don't need it.

    Use the OpenDesignFile method to open each DGN file that you want to modify. You can run your macro from a batch processor, or iterate the DGN files from within VBA. That's a matter of programming convenience.

    Dim fileList() As String
     ' Get files from somewhere
    fileList =  ...
    Dim file As String
    For Each file In fileList
       OpenDesignFile file
       ProcessFile
    Next file

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions