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

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

  • 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

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

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

  • Thanks for the example, Jon.

    I had actually successfully implemented the cell filtering code on the title block tags to work in another macro (MicroStation MVBA this time) on Friday so I can see the code works fine in MS, the issue is definately something to do with excel 2007/Windows 7 x64/ combination of both.

    I'm not sure where I go from here with the existing excel project. I'm thinking that I may have to consider starting from scratch with a MicroStation Macro where I should be able to do most of the work but while I think I will be able to get the data (within the array) to populate the excel worksheet (I might need to output the contents to a CSV file then read the CSV within Excel), the grey area that I've not yet fully resolved is how to ensure the amended contents are correctly applied to the correct file. I'm hoping that my existing export excel macro will work fine and that I wont have to export to the CSV and have the MS MVBA read the contents and apply the changes. Have you any ideas that might be a better method to achieve the desired results?

  • Unknown said:
    Have you any ideas that might be a better method to achieve the desired results?

    FlexiTable

    No doubt I'm biassed, but FlexiTable can update tags. It can also hunt through the DGN files in a folder to match the one that you need to updated. It's also compatible with Excel.

    But I suppose you want a VBA solution. The sticking point seems to be an internal difference in Variant between MicroStation VBA and Office VBA. The only solution I can see is that which you propose: pass data between your MicroStation VBA app. and your Excel VBA app. in a neutral format. Because you're not calling a function across a Windows process boundary you avoid the internal compatibility problem. A suitable format is CSV or, for more complex data, XML.

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • Question for you Jon,

    Using your method for getting the tags into an array, how do you use the join function in this instance in order to produce a delimited string? Most examples use a function or have each value of the array specified before using the Join function. Is there is quick way of doing it?

    Thanks

  • Here's what I have and the line in bold is where it throws up an invalid procedure call or argument error.

     While myElemEnum.MoveNext
            Set oCell = myElemEnum.Current
            
            If oCell.IsGraphical Then
                If oCell.HasAnyTags Then
                    
                    Dim mytag() As TagElement
                    Dim i As Integer
                    Dim strValue As String
                    Dim StrMyArray As String
                    Dim oTagSets As TagSets
                    Dim oTagSet As TAGSET
                    Set oTagSets = ActiveDesignFile.TagSets
                    For Each oTagSet In oTagSets
                        If oTagSet.Name = sTagset_Name Then
                            mytag = oCell.GetTags
                            'For i = LBound(mytag) To UBound(mytag)
                            'strValue = mytag(i).Value
                            StrMyArray = Join(mytag, ",")
                                Debug.Print "CStr(StrMyArray)"                           
                                Next i
                            End If
                        Next
                    End If
                End If
                Wend

  • Mismatched Data Types

    Unknown said:

    Dim strJoined As String
    Dim mytag() As TagElement
    strJoined = Join(mytag, ",")

    The VB/VBA Join function expects an array of Strings. It doesn't understand an array of TagElement.

    To do what you want, you must copy the TagElement.Value data to a new String array, then use Join.

    If you do that in MicroStation VBA, it should work. If you are using Excel VBA, then you collide with the Variant problem.

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions