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

Parents
  • 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-

Reply
  • 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-

Children
  • 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

  • Okay so back to the question at hand.

    I have two files named File1.dgn and File2.dgn.  Both files have a cell named "ABC" which contains a line and a circle.  I want a macro that will assign the following xdata to the line:

    .SetXData "Reference1", "L1"

    and

    .SetXData "Reference1", "C1"

    to the circle.  I want to be able to run this code via a "batch process".

    Sincerely,

    Christmas May

  • Here is a quick attempt at solving this issue.

    Demo app:

    This application will add xdata on to a line and an ellipse that are in a cell named simplecell.  The process can then be driven from the MicroStation batch processor.  The zip file contains:

    1.        Adddata.bprc – the batch process control file, this file can be built from the MicroStation user interface

    2.        Addxdata.txt – the commands to run, this file will load and run the VBA module

    3.        Newsgroupdemo.mvba – the vba macro that will loop through all models in a file and look for a cell and add xdata to lines and ellipses. For demo only…

    4.        Celllibrary.dgn – a cell library with one cell that has an ellipse and line

    5.        File1, file2.dgn – two sample files that have already processed models.

    Steps to run and test:

    1.        Open the file file1.dgn remove the current elements.

    2.        Attach the cell library celllibrary.dgn to the file and place the cell from the library.

    3.        Repeat for file 2

    4.        Edit the addxdata.bprc file to point to your locations of the file1 and file2 dgn files.

    5.        Edit the addxdata.bprc file to set the cmdfilename to the fully qualified locatioin to the addxdata.txt file.

    6.        Place the newsgroup.mvba file to a location on the default VBA search path.

    7.        Run msbatch batchprocess “fully qualified path to the addxdata.bprc file”

    8.        Open the file(s) in MicroStation to check the xdata on the elements.

    HTH,

    mark anderson [Bentley]

    batchupdatexdata.zip
  • Gentlemen,

    Thanks for all of your input on this subject.  As I've said throughout this thread my codes seemed to work on a file by file basis, but not as a batch process.  I did "pretty much" as Mr. Anderson directed me to above.  His code exhibited the exact same behavior as mine always has.  The code worked for individual files, but not as a "batch process".  Turns out my programming capability IS adequate, however, my knowledge of Microstation is NOT.  Bentley software is new to me and I obviously didn’t understand the nuances of “Batch Process”.

    Turns out I needed to pay closer attention to his "6.  Place the newsgroup.mvba file to a location on the default VBA search path."  As it turns out none of my batch processes for this Xdata topic have ever executed.  In fact if you totally delete the .mvba files the “batch process” still appears to "run".  I expected a more noticeable error message box.  However, I now see a whole slew of errors in the Microstation message center about not being able to load projects.

    The only other favor I would like to have is for someone to modify Mr. Anderson’s code to utilize the “OpenDesignFileForProgram” method rather than the “Batch Process” method?

    I have lots of code to write and if I need any assistance I will start a new thread and look forward to your future comments and/or suggestions.  Thanks to all of you so VERY MUCH!

    Sincerely,

    Christmas May

  • Since we are writing this for you ...  How do you want to get the list of files into the application.  Should the application run in MicroStation or outside of MicroStation (a COM based exe written in VB or VB.NET).  

    Rgds,

    marka

  • Ok I added a sub for processing outside of the current design file.  you just need to give it the path that you want to process.  

    HTH,

    mark anderson [Bentley]

    batchupdatexdata.zip