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
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 …
Unknown said:It doesn't work when run via "Batch Process"
Please explain what you mean by "Batch Process".
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) LoopEnd 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.RewriteEnd 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)
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,
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?
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.
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.
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
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".
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]
Visit me at https://communities.bentley.com/communities/other_communities/bentley_innovation/default.aspx
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!
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.