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.RewriteEnd Sub
Please help,
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
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