Invalid Tag Elements - Coding query

Morning all,

I've got an excel sheet which I use for managing tag values in my DGN's title blocks. Now all works fine when the tags are valid but for some reason if I work in a file that contains existing invalid tag elements which for some reason are invalid, it causes my excel sheet to stop working. My excel sheet operates by checking for a specific tagset yet these invalid tags are not from my tagset and it would be too much work delete and add valid tags in each file.

I noticed from the object browser that the tag element class has an isvalid property. Is there any way to have my import process (ie scanning target DGN file for tags and populating my spreadsheet with values of specific tags) ignore invalid tags so it will continue to return the tags I am looking for?

Thanks

Parents
  • Unknown said:
    My Excel sheet operates by checking for a specific tagset yet these invalid tags are not from my tagset

    • How are you searching for the tag set?
    • What do you mean by an 'invalid tag'?
    • Can't you simply ignore the tag set containing the invalid tags?

    Note that the IsValid property is a generic property of all graphic elements.  TagElement inherits it from base class Element.

     
    Regards, Jon Summers
    LA Solutions

  • Unknown said:
    How are you searching for the tag set?

    In a specific cell within the excel sheet, the name of the tagset is entered. I appreciate you don't have the full code to work from, the basis for my excel file came from this file within this topic on which you previously assisted with historical queries of mine. I have made quite a few modifications to the original file in both code and GUI of the worksheet but the basis for tag element scanning remains the same.

    Unknown said:
    What do you mean by an 'invalid tag'?

    Its a tag element that you can be no longer edited using the edit tag command, If you click on it the status bar states that it is still a tag element but if you double-click it the message centre states its an invalid tag element. I'm unsure how Tags' break' like this but I do see it quite frequently ever since using V8i.

    This is the error message that displays if comment out the error handler popup that tells me the dgn file has invalid tags.

    Unknown said:
    Can't you simply ignore the tag set containing the invalid tags?

    I don't believe so as I don't see any way to know which tagset the invalid tag comes from. Its almost like the tag has lost its association/link to its parent tagset from which it came from.

    Unknown said:
    Note that the IsValid property is a generic property of all graphic elements.  TagElement inherits it from base class Element.

    Thanks, good to know. I just had a quick look to see if there was anything in the tagelement class that possibly sounded like it could work with the validity of tag elements.


    So because these invalid tag elements exist and I can't exclude them by tagset, I'm thinking something along the lines of  this is the way to proceed:

    • check each tag first for its validity
    • if it's valid, then proceed to the code that checks if its from the target tagset
    • if it's invalid allow the macro move to the next tag element.

    I've tried adding If oTag.IsValid = True Then after the If oTag.IsHidden = False Then line within the ImportTitleBlock tags sub however it hasn't solved the problem.

    Have you any thoughts how to better implement the above or another way that will get round the issue?

    Cheers Jon

  • I don't think I could break them even if I wanted to so how its happening is a mystery. All I can do for now is try to avoid such instances affecting my excel macro.

  • Unknown said:
    I don't think I could break them even if I wanted

    The AddTag method is pretty foolproof.  Since those invalid tags have become orphans, you should be able to reattach tags to those cells that have lost their tags.  Delete the orphaned tags.

     
    Regards, Jon Summers
    LA Solutions

  • The delete tag command has no effect on such instances. I've just tried on the test dgn provided and the tags remain with no change.

    I certainly don't have the time to go and fix all invalid tags that I encounter because:

    a) I may not know where the location of tagset is

    b) you can't easily tell if a tag is valid or invalid (if a drawing contains 100 tag elements and only 1 is invalid, it would be like finding a needle in a haystack to locate the invalid tag through trial and error.

    The issue that they exist isn't a major problem in that the invalid tag still provides visible information on the drawing, the problems are if it needs changed or more importantly that it causes my excel document to fail when importing valid title block tag values. The latter is a major disruption to my workflow and it is this that at this moment I'm more concerned with finding a coding solution to (even though it would be good to happen upon the cause of tags becoming orphans)

    If anyone has any suggestions how to ignore or skip invalid tags in VBA I'd be happy to listen to any suggestions

    Thanks

  • Unknown said:
    The delete tag command has no effect on such instances

    As I wrote, those tags are orphans.  The delete tag command is looking for valid tags attached to a  host element (when you use that command, it deletes not one but all tags attached to a host).  The tags are elements nonetheless, and delete element despatches them to the eternal bit-box.

    Unknown said:
    You can't easily tell if a tag is valid or invalid

    An invalid tag is an orphan; it doesn't have a host.  Its BaseElement property will return Nothing.  A valid tag returns a reference to, in your case, a cell.

    Unknown said:
    It would be like finding a needle in a haystack to locate the invalid tag through trial and error

    Then don't use trial and error.  Use software.

    Unknown said:
    It causes my excel document to fail when importing valid title block tag values. The latter is a major disruption to my workflow

    How are you searching for title block tags?  If you're scanning for tags, then you'll find the invalid tags as well as the valid ones.  Why not scan for cells, filtering on the cell name and property, common to all elements, HasAnyTags? That way you'll find only those cells that have tags, and not any tags that don't have a host.

     
    Regards, Jon Summers
    LA Solutions

  • The worksheet contains a cell that holds the name of the target tagset. The specific tags within the tagset that I want to return the current values are found by using a specific row in the worksheet containing column headers that the tag values for each drawing are populated below e.g. Project No., Drawing Name, Project Title, Scale, Revision etc...

    If the scan finds a cell called Revision that is hosted in my target tagset, its value is displayed in the row and the macro moves to the next cell in the row until the specific range of cells is at the end and the macro close the drawing down and opens the next, repeating to process until all files in the target folder are processed.

    The reason I have not scanned for cells is that the tags are not in a cell, they are just individual tag elements (and associated Point geometry) inserted from file into the correct location.

  • Unknown said:
    The tags are not in a cell

    Tags are never 'in' anything.  They are independent graphic elements.  The relationship between a tag and its host is a dependency.  The key to that dependency is the host element ID.  That element ID tells the tag who it belongs to.

    It's true that you can define a cell that contains tags.  However, when you place such a cell, its tags are extracted and added to the active model as individual elements, with the cell instance as their host.  The tags are no longer in the cell.

    Unknown said:
    The tags are inserted from file into the correct location

    And what's the mechanism to implement that insertion?  There is no CreateTagElement method -- there's an AddTags method that creates instances of TagElements and creates the dependency on the host.

    Unknown said:
    The tags are individual tag elements and associated Point geometry

    What is the 'associated Point geometry'?

     
    Regards, Jon Summers
    LA Solutions

  • I have file where in which I have the tag elements set out in the correct location relative to the coordinate origin and each one moved into position relative to the title block. I reference this into the sheet model and merge it.  The point geometry is a point element that the tags are associated with and it also serves as a guide should one need to reposition the tags if they were ever moved out of position.

    It's true that you can define a cell that contains tags.  However, when you place such a cell, its tags are extracted and added to the active model as individual elements, with the cell instance as their host.  The tags are no longer in the cell.

    I didn't know this so I've just queried the point element that is my tags host and the element information tells me that this is a cell. TBH I've never paid much attention to it and was unaware that it was now a cell; is this due to the dependancy you've explained? As I now know I have a cell to work with I should hopefully be able to implement your suggestion of scanning for cells.

  • Jon,

    I've been reading your article on Finding a Cell using VBA and I am a little confused. Firstly, you provide an example function to find a named cell which looks like exactly what I need, however because my stints at VBA programming are sporadic I'm never fully sure when to use functions let alone implement this into existing code. I am wondering do I :

    1.  use the function as written and call it straight after I open a dgn via OpenDesignFileForProgram (seems logical as its the first thing to do in the DGN)?
    2. or, do I need to use the code within my existing sub procedure ?

    If 1),  how do I use the hasanytags property with the function and then have the remainder of my existing code process the tags within the target cell? (I'm not sure that I can because my understanding is the function returns a true or false result only). If b) do I need to use more than 1 unique instance of ElementScanCriteria because my existing macro uses one instance to scan for msdElementTypeTag?

    Thanks

    1. Scan for cells, a named cell if that suits your situation
    2. For each cell, test whether it HasAnyTags
    3. If the cell has tags, check that it has your tag set
    4. Retrieve the tag array from the cell with Element.GetTags
    5. Update those tags as necessary (rewrite each tag, not the cell)

    I prefer not to scan for msdElementTypeTag.  Because a host typically has multiple tags attached, when you scan for tag elements then your code detects each of N tags and you have to spend extra code figuring out which tag you have caught.

     
    Regards, Jon Summers
    LA Solutions

  • Morning Jon,

    Using your other example for reading Tags as well as finding a cell I've been trying to get the code to perform your actions 1,2 & 4 so that I can get the immediate window to display the tags and their values however excel keeps on crashing. Here is the new code that I've placed in a new module, the existing macro code that deals with populating the spreadsheet has not been included yet. I shall start to implement that once I have your new code working first.

    Dim oCriteria As New ElementScanCriteria
                    Dim oHost As CellElement
    ' Scan for named cell
                    oCriteria.IncludeOnlyCell "Title Tags"
                    oCriteria.ExcludeAllTypes
    ' Scan for normal cells
                    oCriteria.IncludeType msdElementTypeCellHeader
                    Set oEnumerator = myDGN.Models(myModel).Scan(oCriteria)
                    Do While oEnumerator.MoveNext
    'Normal or Shared cell is referenced by oEnumerator.Current
                        Set oHost = oEnumerator.Current
                        
                        If (oHost.HasAnyTags) Then
                            Dim oTags() As TagElement
                            Dim nTags As Integer
                            Dim i As Integer
                            Dim vtValue As Variant
                            oTags = oHost.GetTags()
    'process tag array
                            For i = LBound(oTags) To UBound(oTags)
                                vtValue = oTags(i).Value
                                Debug.Print "Tag [" & CStr(i) & "]" = " & CStr(vtValue)"
                                Next i
                            End If
                        Loop
                    Next

    I've stepped through with the debug tools and it seems to freeze on vtValue = oTags(i).Value and when I hit stop I get an error message stating excel has crashed. Does anything above stand out that would cause excel to crash?

Reply
  • Morning Jon,

    Using your other example for reading Tags as well as finding a cell I've been trying to get the code to perform your actions 1,2 & 4 so that I can get the immediate window to display the tags and their values however excel keeps on crashing. Here is the new code that I've placed in a new module, the existing macro code that deals with populating the spreadsheet has not been included yet. I shall start to implement that once I have your new code working first.

    Dim oCriteria As New ElementScanCriteria
                    Dim oHost As CellElement
    ' Scan for named cell
                    oCriteria.IncludeOnlyCell "Title Tags"
                    oCriteria.ExcludeAllTypes
    ' Scan for normal cells
                    oCriteria.IncludeType msdElementTypeCellHeader
                    Set oEnumerator = myDGN.Models(myModel).Scan(oCriteria)
                    Do While oEnumerator.MoveNext
    'Normal or Shared cell is referenced by oEnumerator.Current
                        Set oHost = oEnumerator.Current
                        
                        If (oHost.HasAnyTags) Then
                            Dim oTags() As TagElement
                            Dim nTags As Integer
                            Dim i As Integer
                            Dim vtValue As Variant
                            oTags = oHost.GetTags()
    'process tag array
                            For i = LBound(oTags) To UBound(oTags)
                                vtValue = oTags(i).Value
                                Debug.Print "Tag [" & CStr(i) & "]" = " & CStr(vtValue)"
                                Next i
                            End If
                        Loop
                    Next

    I've stepped through with the debug tools and it seems to freeze on vtValue = oTags(i).Value and when I hit stop I get an error message stating excel has crashed. Does anything above stand out that would cause excel to crash?

Children
  • Unknown said:
    It seems to freeze on vtValue = oTags(i).Value

    This may be something that neither you nor I can solve.  Someone reported a similar problem using a Variant in Microsoft Access.  It looks like there may be difference between a MicroStation VBA Variant and an Office Variant.  Although the assignment should work, it fails as you have found.

    Try assigning the Variant to a String.  VB/VBA implicitly convert Variant to a String, so the following may work:

    Dim strValue As String

    strValue = oTags(i).Value

     
    Regards, Jon Summers
    LA Solutions

  • I think I read that same issue too. I've made the change from variant to string however the same crash happens as soon as I press F8 move onto the Debug.Print line. I've tested to get the value of any tag in the array using Debug.print oTags(0).value and it crashes again. Could the crash be because the array isn't populated?

    Going back to your article on reading and writing tags, you have the declaration line Dim nTags As Integer in the tag element value extraction & Updating tag value examples yet you do not make use of this variable at any point. Is there line missing that could be the key to the solving the crash?

  • Unknown said:
    Could the crash be because the array isn't populated?

    Yes, of course.  Although you've already tested to find if the element has any tags.  Belt-and-braces programming says you should get the size of the array and proceed only if it's non-zero.

     
    Regards, Jon Summers
    LA Solutions

  • Interrogating the locals window prior to the crash shows that the array has been populated as per the image below.

    So if it is populated, why cant I get the values that can see when I expand each array index?

  • Are there really 11 tags attached to the cell? 

    How many tag definitions are there in your set?

    Is the first member of the array at oTags(0) or oTags(1)?

    Unknown said:
    Why is your variable nTags not used?

    Probably I used that during development to store the count UBound(oTags) - LBound(oTags).  Then it's easy to test for an empty array.  I save spare bits of code such as that until the end of the tax year, then auction them on eBay  8-)

     
    Regards, Jon Summers
    LA Solutions

  • Unknown said:
    Probably I used that during development to store the count UBound(oTags) - LBound(oTags).  Then it's easy to test for an empty array.  I save spare bits of code such as that until the end of the tax year, then auction them on eBay  8-)

    Heh well April will be here soon enough!

    Unknown said:
    Are there really 11 tags attached to the cell?

    How many tag definitions are there in your set?

    Is the first member of the array at oTags(0) or oTags(1)?

    Yeah there most definately is. Below is a screengrab from the seed DGN that the title block tags are arranged in. An you can see there are exactly 11 tag elements and that is also the same number of definitions within the set as well. If I expand oTags(0) in the locals window and scroll down to tagdefinitionname, it says "PROJECT NAME". So the array population seems to be working, what I dont understand is why I can't do anything with it.

  • Further progress to report:

    I have managed to get the code to work on a Windows XP 32 bit machine running Excel 2007 however my Windows 7 Enterprise (64-bit) & Excel 2007 does not work. I have read that Data Execution Prevention (DEP) can affect Excel 2007 macros and our IT dept has been testing various DEP settings without success so I think I can rule that out as the cause of the crash. Seeing as we know the code is working, does anyone have any idea what might cause excel to flake out in Windows 7?

  • Unknown said:
    I have read that Data Execution Prevention (DEP) can affect Excel 2007 macros

    When I open an Office application that contains macros on my Win 7 x64 computer, the app. pops a warning dialog.  It gives me the option to continue with, or without, macros being enabled.  Possibly your corporate IT strategy is to disable macros without offering users an option.

    DEP would not make your macros fail; it would stop them working entirely.  So we must look for some other reason why they don't work on Win 7 x64.

     
    Regards, Jon Summers
    LA Solutions

  • Yeah thats correct I did get the security message the very first time it ran and I ceased that happening again via the macro security settings in the trust centre. Our IT Dept doesn't have any group policy in place to restrict this. The only other result I've found when searching for Macro crashes in excel 2007 was to disable any other COM excel addins, I only have a single Adobe entry and disabling this made no difference. The workstation is brand new so I'm almost out of ideas. This may be a silly question however its still worth asking. You mention that you have Win 7 x64, have you managed to successfully report tags with your example code since you upgraded?

  • Unknown said:
    Have you managed to successfully report tags with your example code since you upgraded to Win 7 x64?

    Yes, but I'm  using only MicroStation VBA and not another application's VBA.

    Here's an example of tag reporting (TextFileWriter.zip).

     
    Regards, Jon Summers
    LA Solutions