Hi
I'm looking for help on the question detailed above where my purpose is to delete a certain SharedCellDefinition (I failed at writing a VBA snippet for this so resorted to the CadInputQueue instead), then attach a new cell library (the code firstly searches for a string to get the location of the cell library) and, lastly, replace all cells which used the previous cell definition with ones from the attached library.
I figured the way to replace the cells was to get a scan going which would find the SharedCellDefinition that I wanted to change them to, and then enumerate through all the cells I wanted to use (replace the cell defintion) but this seems to have not worked.
This is slightly more problematic as my code does not give me any errors when I run, and when I try the key-ins (even the ".SendCommand "delete scdefs KPR"" line does not seem to achieve the desired result as part of the macro), etc, by hand, the same actions result in exactly the process I want to happen, so I am slightly unsure what's going wrong. I'm hoping it is as simple as me missing out a "Redraw"/"Rewrite" from where there should be one.
Thoughts on what's going wrong?
Anyways, here's the code (I was trying to use the SyntaxHighlighted but it seems I failed in that as well -- did I need to manually highlight it there? I copied it in and chose "VB" in the options but this text editor doesn't show any changes to what I input).
Sub Main() With CadInputQueue .SendCommand "delete scdefs KPR" CommandState.StartDefaultCommand ' Back to a standard state End With Dim alcCells As String alcCells = Share.GetCells AttachCellLibrary alcCells If IsCellLibraryAttached Then ' Proceed ' We now need to replace the KPR cells with those from the imported library: ' All cells in the level KP_R need to be then replaced with the new imported "KPR" cell ' After that, the replaced cells need to be scaled down to half the size they are at. Call ReplaceCells(lvlKPR, "KPR") Else: Exit Sub End If End Sub Private Sub ReplaceCells(levelName As String, replacingElement As String) Dim oReplacer As SharedCellDefinitionElement Dim replaceScanCriteria As ElementScanCriteria Set replaceScanCriteria = New ElementScanCriteria replaceScanCriteria.ExcludeAllTypes replaceScanCriteria.IncludeType msdElementTypeSharedCellDefinition Dim replEnum As ElementEnumerator Set replEnum = ActiveModelReference.Scan(replaceScanCriteria) Do While replEnum.MoveNext If replEnum.Current.IsSharedCellDefinitionElement Then Dim tempSCE As SharedCellDefinitionElement Set tempSCE = replEnum.Current If tempSCE.Name = replacingElement Then Set oReplacer = tempSCE Exit Do End If End If Loop ' Set up corresponding level object Dim oLevel As Level Set oLevel = ActiveDesignFile.Levels(levelName) ' Set up scan criteria Dim oScanCriteria As ElementScanCriteria Set oScanCriteria = New ElementScanCriteria oScanCriteria.ExcludeAllLevels oScanCriteria.ExcludeAllTypes oScanCriteria.IncludeLevel oLevel oScanCriteria.IncludeType msdElementTypeLineString Dim oEnumerator As ElementEnumerator Set oEnumerator = ActiveModelReference.Scan(oScanCriteria) Dim oElement As Element Do While oEnumerator.MoveNext Set oElement = oEnumerator.Current If oElement.IsCellElement Then Dim eleCell As CellElement Set eleCell = oElement eleCell.ReplaceCurrentElement oReplacer eleCell.Redraw eleCell.Rewrite Else: MsgBox "This element is not suitable for this action." End If Loop End Sub
Hi Koit,
I did not think too much about your code, because in my opinion there is a problem in your original assumption.
I never have not thought too much how shared cells replacement works, but I guess it's not as simple as graphic cells replacement.
Unknown said:I failed at writing a VBA snippet for this so resorted to the CadInputQueue instead
Based on MicroStation VBA help file the key-in syntax is: DELETE SCDEFS <ALL | ANONYMOUS | NAMED>. Based on what information you use the key-in delete scdefs KPR?
Unknown said:my purpose is to delete a certain SharedCellDefinition ... then attach a new cell library (the code firstly searches for a string to get the location of the cell library) and, lastly, replace all cells which used the previous cell definition with ones from the attached library.
How do you want to delete Shared Cell Definition element (step 1) if there are the shared cells instances and to replace the instances later (step 3)? It cannot work. The I have not tried do it using VBA or MDL code, but I am pretty sure the Shared Cell Defintion can be removed only if there are no instances linked to it the definition. It's what a compress option "SC_NAMED" and the key-in DELETE SCDEFS ALL do.
Unknown said: and when I try the key-ins (even the ".SendCommand "delete scdefs KPR"" line does not seem to achieve the desired result
What is your desired result using this key-in? The key-in itself is wrongly used I guess and it's not clear why you want to delete the shared cell definition element in the situation it's still used by some shared cells.
Unknown said:I was trying to use the SyntaxHighlighted but it seems I failed in that as well
SyntaxHighlighter tool works fine. Did you set in the tool that your code is VB code? Otherwise the code is usually not highlighted because identified as a normel text.
Unknown said:Thoughts on what's going wrong?
Well ... see my comments. But I am thinking it your first wrong step is why you don't use MicroStation cell replacement tool that works I guess fine and can be easily used to replace all instances of one shared cell by another shared cell definition. The only requirement is the cells have to have the same name.
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Unknown said:Seems to be alright though.
Unfortunately it's not. But it shoud be possible to edit your existing post and to change the highlighter setting for the posted code.
Unknown said:I found no reference to the cell replacement tool in the Microstation v8 VBA Help
I did not write about VBA tool, but about MicroStation tool that is designed to replace both types of cells in different modes. It can be simply used by key-in, which in general I don't recommend (to use key-ins in VBA or MDL code), but in this situation it can be efficient workaround how to use existing complex functionality.
Unknown said:I'm still curious by the ReplaceCurrentElement bit though.
It's probably the method I recommend to start with. I don't know if it's possible, but if this method is able to replace SharedCellDefinition element and don't break existing connection to existing SharedCell elements (shared cells instances), it should be simple solution of your requirement.
Thanks Jan, got it now. Seems I had to delete the original code and re-copy it. Looks better though!
I see re the cell replacer tool.
How about the supposition that we ignore the bit in my code where I try to delete as a SharedCellDefinition -- as you pointed out, it's both wrong and unnecessary. However, even without that, and looking specifically into the bit here (the method for replacing cells).
Then when we consider the functionality of the ReplaceCurrentElement which you suggested I use, the function above should achieve the intended purpose. It is my understanding that I need to "find"/"retrieve" the SharedCellDefinition first before I can use it as a replacement element, which I thought this code would do. However, there is no apparent result for the above method. And note, here we are already talking about replacing CellElements/SharedCellElements and not their definitions.
What do you think?
Cheers
Koit
Private Sub ReplaceCells(levelName As String, replacingElement As String) Dim oReplacer As SharedCellDefinitionElement Dim replaceScanCriteria As ElementScanCriteria Set replaceScanCriteria = New ElementScanCriteria replaceScanCriteria.ExcludeAllTypes replaceScanCriteria.IncludeType msdElementTypeSharedCellDefinition Dim replEnum As ElementEnumerator Set replEnum = ActiveModelReference.Scan(replaceScanCriteria) Do While replEnum.MoveNext If replEnum.Current.IsSharedCellDefinitionElement Then Dim tempSCE As SharedCellDefinitionElement Set tempSCE = replEnum.Current If tempSCE.Name = replacingElement Then Set oReplacer = tempSCE Exit Do End If End If Loop ' Set up corresponding level object Dim oLevel As Level Set oLevel = ActiveDesignFile.Levels(levelName) ' Set up scan criteria Dim oScanCriteria As ElementScanCriteria Set oScanCriteria = New ElementScanCriteria oScanCriteria.ExcludeAllLevels oScanCriteria.ExcludeAllTypes oScanCriteria.IncludeLevel oLevel oScanCriteria.IncludeType msdElementTypeLineString Dim oEnumerator As ElementEnumerator Set oEnumerator = ActiveModelReference.Scan(oScanCriteria) Dim oElement As Element Do While oEnumerator.MoveNext Set oElement = oEnumerator.Current If oElement.IsCellElement Then Dim eleCell As CellElement Set eleCell = oElement eleCell.ReplaceCurrentElement oReplacer eleCell.Redraw eleCell.Rewrite Else: MsgBox "This element is not suitable for this action." End If Loop End Sub
Unknown said:What do you think?
Well ... nothing. This discussion is very theoretical. You have not provided any testing case and my feeling is that even basic requirements are not clearly defined. To discuss a code without having test case and exact report what is (not) working seems to me like time wasting.
In my opinion you should at first clearly define what do you want to achieve and what requirements and condition exist, using other words "What the replacement means to you?" E.g. is there any mslink, user data or other data attached to your shared cell? To replace the cell and to maintain this extra data is substantially more complex than to work with plain cells. Also, does replacement has to maintain element id or the original element can be deleted and a new one placed?