Having Difficulty With IsDone Method of OdRecords in Object Data Code

Discussion in 'AutoCAD' started by matt_1ca, Feb 4, 2005.

  1. matt_1ca

    matt_1ca Guest

    I have created a routine to make a non-existing table and populate it with
    data from text entities I create from insertion point coordinates I get from
    a text file.

    I was able to do the process above and attach records to said created acadObjects
    and everything seems to be looking good. As a check I go look into each of those
    objects and go Map/object data/edit object data and I see the table I created
    populated by the data I pushed for each one of those texts that I created.

    Next I tried to retrieve information from those attached texts and put them in
    an array using code below but everytime I test it with " If Not odRcs.IsDone "
    as shown below or "If odRcs.IsDone=true" it does not flag me for any error at all
    instead it goes merrily on its way saying it does not have any data i.e. it is
    done -- I looped through my dataset with more than 100 text and not even one of
    it seems to have data using the if test I did above. :


    For Each entA In sel
    Set aoj = ThisDrawing.ObjectIdToObject(entA.ObjectID)
    blnGotRcs = odTb.GetODRecords.init(aoj, True, False)
    Set odRcs = odTb.GetODRecords

    If Not odRcs.IsDone Then
    For intCnt = 0 To odRcs.Record.Count - 1
    Set odRc = odRcs.Record(intCnt)
    'whatever is in the grid will be take from external database
    If UCase(Trim(odRc("PointNumber").Value)) = UCase(Trim(strKeyValue)) Then
    ReDim varReturn(4)
    varReturn(0) = UCase(Trim(odRc("pointnumber").Value))
    varReturn(1) = UCase(Trim(odRc("xcoordinate").Value))
    varReturn(2) = UCase(Trim(odRc("ycoordinate").Value))
    varReturn(3) = UCase(Trim(odRc("zelevation").Value))
    varReturn(4) = UCase(Trim(odRc("description").Value))
    varReturn(5) = UCase(Trim(odRc("csvfilename").Value))
    End If
    Next intCnt

    End If

    Next entA


    So I checked and double checked that all my odRecords objects are all set to nothing
    after I am done using it. But even that did not solve the problem.
    I tried to look back at how I created the attachment and see if there
    was any error generated at all.

    blnAbleToAttach = odRc.AttachTo(aoj.ObjectID)

    And the returned blnAbleToAttach is TRUE so even in the other function that attaches the
    data it does not report any error at all.

    Because cannot find anything obviously wrong next is I started thinking maybe I need
    an equivalent of recordset.update in ADO so I experimented adding
    blnUpdatedOdRcs = odRcs.Update(odRc) into my code that tries to attach data to objects:

    For intCtrr = LBound(varRecords) To UBound(varRecords)
    odRc.Item(intCtrr).Value = varRecords(intCtrr)
    Next intCtrr
    blnUpdatedOdRcs = odRcs.Update(odRc)
    blnAbleToAttach = odRc.AttachTo(aoj.ObjectID)

    But it gave me a new error something like "update of odRecords object failed"
    Next I tried :

    For intCtrr = LBound(varRecords) To UBound(varRecords)
    odRc.Item(intCtrr).Value = varRecords(intCtrr)
    blnUpdatedOdRcs = odRcs.Update(odRc)
    Next intCtrr
    blnAbleToAttach = odRc.AttachTo(aoj.ObjectID)

    Still the same problem "update of odRecords object failed", and it looks like I am just
    going around in circle. Please help me what is it that I am not doing right?

    I gratefully appreciate all the help you can give me on this

    Thanks,
    Matt
     
    matt_1ca, Feb 4, 2005
    #1
  2. matt_1ca

    Norman Yuan Guest

    I do not have enough time to read through your code, but the error sound
    svery similar to one of my experience with AcadMAP VBA. I posted question to
    AcadMAP Developer NG last October. Since I cannot find my post there any
    more, I put it here, not sure it helps or not. If I get time later, I may
    look into your code more carefully.

    Message begins here:

    I run into a rather weird problem when attaching object data to acad entity.
    Actually the problem is setting record value when the field type is
    "Character" (Text).

    See following code:

    Dim rd As ODRecord
    Set rd = MyODTable.CreateRecord

    rd.Item(0)=0 'Numeric type
    rd.Item(1)="" 'Text type. Pay attention to this field in code below

    rd.AttachTo ent.ObjectID

    Above code works OK. Now see following code:

    Dim rd As ODRecord
    Set rd = MyODTable.CreateRecord

    Dim strVar as String '''In VB/VBA strVar is initialized to "", right?

    rd.Item(0)=0 'Numeric type
    rd.Item(1)=strVar 'This line cause "Automation error" and crash Acad.

    rd.AttachTo ent.ObjectID

    However, following code works as the first snippet

    Dim rd As ODRecord
    Set rd = MyODTable.CreateRecord

    Dim strVar as String
    strVar="" '''Explicitly set the string variable to ""

    rd.Item(0)=0 'Numeric type
    rd.Item(1)=strVar 'This line cause "Automation error" and crash Acad.

    rd.AttachTo ent.ObjectID

    I have been doing VB/VBA many years and alway assume Dim strVar make strVar
    a 0 length string. obviously, AcadMap does not take that assumption. I'd
    think it is AcadMap's fault that when its developer implement Map's COM
    interface, there is some that does not handle string the same way as
    expected in VB/VBA. Any though on this?

    As for my project, I have no way to around this except for make sure all
    string variables, being passed to Map object data table, must be assigned a
    value explicitly.


    Message ends here.
     
    Norman Yuan, Feb 4, 2005
    #2
  3. matt_1ca

    LochDhu Guest

    Matt,

    You're close - I think it's GetODRecords.init and where you call it from.

    Try This.

    Change this:

    To this:
    I would wrap it up like this:

    If odRcs.Init(aoj, False, False) = True Then 'You have at least one
    record...
    Do Until odRcs.IsDone'loop over records - an object can have
    multiple!
    Set odRc = odRcs.Record
    'do your IF stuff....
    odRcs.Next
    Loop
    End If


    Notice I am using False for OpenMode because you are not updating or
    removing a record. And, there is an issue using True and having multiple
    records attached to an object.

    I think that will work for you.

    Good Luck,

    Scott
     
    LochDhu, Feb 4, 2005
    #3
  4. matt_1ca

    matt_1ca Guest

    In my case, I never take any chances, I make it a practice to always have an Init routine which does nothing but initialize variables I will be using not just for strings but for integers and longs as well, so I do not think I will run into that problem you mentioned of crashing because of passing an uninitialized string.

    The problem I am having is that of not being able to to make the program see that there is record in the attached records to all my Acadobject.

    I can see visually that the data is attached when I do a manual map\object data\edit attached object.

    But when I try to do it using code like in the code I showed and actually test odrecords if there is data using odrecords.isdone it cannot seem to see that there is indeed data already -- always returning TRUE on the very first time odrecords.isdone is called. I go to my odrecords and do an Add Watch but when I expand the variable from the watch window -- it shows that it is empty indeed -- which only confirms what odrecords.isdone is saying.

    Setting odrecords to nothing does not solve the problem so it is something else that I am not doing right. No error is generated so that I am left without a clue what is happening.

    Since all these AcadObjects and attached data I have are things I created using code, I have a feeling it might have something to do with a need to implement an odRecords.update when I assign value to my ODrecord just like it is done in ADO and DAO ( but I am not totally sure -- because I have not even seen anybody using update method and there is no example ), but then again maybe it is or maybe something else. Somekind of a technique I have not discovered yet. Any thoughts on this?
     
    matt_1ca, Feb 4, 2005
    #4
  5. matt_1ca

    matt_1ca Guest

    Thank you for your response:
    I did exactly what you said I interchanged calls, I called
    set odRcs = odTb.GetODRecords before calling
    blnGotRcs=odTb.GetODRecords.init(aoj,False,False)

    Next I cleared all my breakpoints and retained only one breakpoint which I placed at :
    Do Until odRcs.IsDone 'loop over records

    It stops there exactly the first time it tries to run the loop cycles and what I noticed is that it never returns a false.

    I check the textstring property of each entity that is being processed at every cycle of the loop and they are indeed the text entities that has object data attached to them which I created using code.

    I checked the blnGotRcs variable and it says True -- so I shoud have at least one record.

    Next I tried to find out if this behaviour is consistent throughout the whole loop

    I did a debug.print enta.textstring & " " & cstr( blnGotRcs) & " " & cstr(odRcs.Isdone)

    right after:
    If odRcs.Init(aoj, False, False) = True
    and just before Do Until odRcs.IsDone

    which just results in a debug.print of all 100 text I created having blnGotRcs consistently as True but never entering the loop even once because its odRcs.IsDone is also consistently True.

    So I am truly grateful I know the right sequencing for GetODRecords however the same problem I had before was not solved.
     
    matt_1ca, Feb 4, 2005
    #5
  6. matt_1ca

    matt_1ca Guest

    Hello Scott,

    Something new I found out -- I am not too sure about what is causing it though. Well, here it goes -- from that last response -- I mentioned about a debug.print that I was using to see what was happening -- well, I added to that debug.print cstr(odRcs.OwnerDbId) & " " & cstr(odRcs.Rewind) at the exact location as I had the
    debug.print before and what it showed was that the OwnerDbId was consistently 0 as well.

    Matt
     
    matt_1ca, Feb 4, 2005
    #6
  7. matt_1ca

    matt_1ca Guest

    I am simulating line by line and comparing, I looked at everything and they all seem normal I looked at the values of the following variables so I know that I am in the right track

    1. Check the value of name property of the variable holding for object data table from which I call the .odrecords method from -- the name is correct.

    2. I check the value returned by a call to odtable.getodrecords.init and the value returned is true thus success.

    3. I check the value returned when I do odRecord.attachTo and again the value returned is true which indicates success.

    4. I check the value of all the fields of the OdRecord I am calling the AttachTo method from. And again all the values are correct as compared to the drawing text I created through the program I described at the top of this thread.

    I have to say that everything looks normal and yet I know, I am missing out on a key technique -- otherwise my code should be working by now.

    There has got to be a way -- there is always a way.

    The only thing I am not really sure of is the value I am passing to attachTo method of ODrecord. From all the materials I have gathered they seem to be declaring the stuff from which they are calling objectID as AcadEntity, thus in effect AcadEntity.objectId whereas on my part it is declared as AcadObject.objectId -- and the only reason why I am refusing to alter my code to follow what is written in the materials I have is that I strongly believe that the two are one and the same -- I have not experimented on it -- but I think they ought to be one and the same -- or are they?
     
    matt_1ca, Feb 5, 2005
    #7
  8. matt_1ca

    matt_1ca Guest

    Well you can drop that theory about differences between AcadEntity.ObjectId and AcadObject.ObjectID, because I changed all the arguments passed from AcadObject to AcadEntity just so I can conform to the materials i.e. examples I have here in front of me. And well, what resulted after I made the transistion is the exact same problem I had originally so back to base one.

    From that experiment I have concluded that there seems to be indeed no difference between an argument passed as AcadObject.ObjectId and AcadEntity.ObjectId -- at least the functionality resulting seems to be identical -- and so practically the only difference between the two is their spelling. But they seem to be referring to the same animal.
     
    matt_1ca, Feb 5, 2005
    #8
  9. matt_1ca

    matt_1ca Guest

    I do not know why nobody is answering? Any suggestion -- welcome
     
    matt_1ca, Feb 5, 2005
    #9
  10. Have you tried the Autodesk MAP customization newsgroup?
     
    Tony Tanzillo, Feb 5, 2005
    #10
  11. odRcs is the collection of recordsets
    I don't think it has a IsDone property
    You should iterate it using it's count property

    Each of the recordsets inside the collection
    do have an IsDone property, which should
    be true if it's the last record in the recordset
    But of course it can be done using the count
    property also, as you are doing.
     
    Jorge Jimenez, Feb 5, 2005
    #11
  12. matt_1ca

    matt_1ca Guest

    Hello Jorge

    Thanks for your response, and you are right in saying that I should iterate through the count property. I used to try doing it using some other way -- but this is really the only way -- so you are perfectly correct.

    You also made mention of Isdone, well, you need to trust me in this one -- odRecords really has an Isdone property.

    Matt
     
    matt_1ca, Feb 6, 2005
    #12
  13. matt_1ca

    matt_1ca Guest

    Hello Tony,

    Thanks for your response,

    About the discussion group you mentioned -- let me browse what kind of stuff they have there. In the meantime I will continue trying to solve the problem -- I trust there are AutoCAD gurus navigating even this discussion group -- for one I have seen with my own eyes a question being answered by no less than the world famous (book author) , Joe Suptin himself -- so who knows maybe someone in this group might be able give me an answer.

    Matt
     
    matt_1ca, Feb 6, 2005
    #13
  14. I don't think the record collection has an IsDone property.
    It's just a collection not a recordset!
     
    Jorge Jimenez, Feb 6, 2005
    #14
  15. matt_1ca

    matt_1ca Guest

    The observation that ODrecords is a collection is a correct observation.

    Additionally, a click in the object browser will let us observe important things.

    Matt
     
    matt_1ca, Feb 6, 2005
    #15
  16. matt_1ca

    LochDhu Guest


    That's still incorrect:

    Set odRcs = odTb.GetODRecords
    blnGotRcs = odRcs.GetODRecords.init(aoj, False, False)
    ..
    I am not using GetODRecords with odTb on the second line - rather, I'm using
    it with odRcs.

    Set odRcs = odTb.GetODRecords > Gets all Records associated with that
    particular table.

    blnGotRcs = odRcs.GetODRecords.init(aoj, False, False) > Gets the records
    from that particular table associated with that particular object - aoj.
    Returns true if records found.

    Scott
     
    LochDhu, Feb 6, 2005
    #16
  17. matt_1ca

    matt_1ca Guest

    I have tried the piece of code you sent doing the second GetODRecords call from odRcs instead of from odTb but I am being stopped by a

    Run-time error '438'
    Object doesn't support this property or method

    So the next thing I did was go to my object browser -- there seems to be no GetODRecords method for odRecords it says the method is only for odTable and odTables. My reference is set to AutoDesk Map 2004.

    I am doing a Set amP = odoC2.Application.GetInterfaceObject("autocadmap.application.2")
    because Set amP = odoC2.Application.GetInterfaceObject("autocadmap.application") is giving me an error too.

    Matt
     
    matt_1ca, Feb 6, 2005
    #17
  18. matt_1ca

    matt_1ca Guest

    Although I am being stopped by an error saying that method GetODRecords does not exist for odRecords -- and Object Browser confirming it -- I refuse to believe it -- I firmly trust your code should work perfect.

    i.e. blnGotRcs = odRcs.GetODRecords.init(aoj, False, False)

    The reason why I am saying that is I have cross referenced your code against all of the sample codes I have from different independent peoples -- and indeed they are all saying the exact same thing -- i.e. odRcs ought to have that GetODRecord method. And yet why oh why is this happening to me? Please help me, am I the only one on this planet experiencing it -- or has someone seen it too?

    Thank you so much for all the kind help you can give

    Matt
     
    matt_1ca, Feb 7, 2005
    #18
  19. matt_1ca

    matt_1ca Guest

    Cheers !!!!!!!! Please erase everything I have said about odRcs should have GetODRecords method --- I found out today one minute ago that as usual the Object Browser is correct, i.e. the GeODRecords method is not a method of odRcs -- it is a method only of ODtables and ODtable. Well at least that is my initial conclusion the reason is as stated below:

    What I did was this:
    Instead of the code below,
    blnGotRcs = odRcs.GetODRecords.init(aoj, False, False)
    I changed it to:
    blnGotRcs = odRcs.init(aoj, False, False)

    Well I am really not 100% sure yet if will work all the way -- but it quickly got rid of the IsDone problem I mentioned at least for 11 of the 300 entities I created. It is too early to make conclusions -- I am still being stopped by a few glitches in my code by I will let this thread know how it goes -- so that someone who will be in the same shoes as I am in right now in the future can reference this thread and not have hit so many walls I just did :)
     
    matt_1ca, Feb 7, 2005
    #19
  20. matt_1ca

    matt_1ca Guest

    Cheers, everyone! Roll out the barrel -- The beer is on me!

    blnGotRcs = odRcs.init(aoj, False, False)

    that is the silver bullet that slayed the dragon alright.
    I jumped for joy the moment everything worked out as I designed --

    Thanks to all who responded to my request for help.

    Especial thanks to Scott, Man you are really the one who brought the answer within reach -- you are the greatest ! I owe you one :)

    Matt
     
    matt_1ca, Feb 7, 2005
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.