Still cant get GetObject(strDwgName) to work - Fatal error

Still cant get GetObject(strDwgName) to work - Fatal error

Anonymous
Not applicable
323 Views
7 Replies
Message 1 of 8

Still cant get GetObject(strDwgName) to work - Fatal error

Anonymous
Not applicable
any help appreciated, I still cant get it right. Calling the following function with a valid drawing name, if acad is running but dwg is not open, it opens the dwg (after requiring a response to save Drawingx) If I then close the dwg it opened I get 'FATAL ERROR: 'Unhandled Access Violation Reading 0x0000 Exception at 6c5dc1h and acad crashes A2k2 win2k vb6 standard exe project existing function: Public Function GetAcad(Optional sDwgName As String, Optional AcVisible As Boolean = True) As AcadApplication Dim oAcadApp As AcadApplication Dim oAcadDoc As AcadDocument Dim i As Integer: i = 0 On Error Resume Next If Not IsEmpty(sDwgName) Then Set oAcadDoc = GetObject(sDwgName) If Not oAcadDoc Is Nothing Then Set oAcadApp = oAcadDoc.Application End If If Not oAcadApp Is Nothing Then If oAcadApp.Documents.Count > 1 Then oAcadApp.ActiveDocument = oAcadDoc End If End If Else Set oAcadApp = GetObject(, "AutoCAD.Application") If Err Then Err.Clear Restart: Set oAcadApp = CreateObject("AutoCAD.Application") If Err.Number = 91 Then Err.Clear If i = 3 Then Exit Function Else GoTo Restart i = i + 1 End If Else Err.Clear End If End If End If oAcadApp.Visible = AcVisible Set GetAcad = oAcadApp End Function tia Mark
0 Likes
324 Views
7 Replies
Replies (7)
Message 2 of 8

Anonymous
Not applicable
Why don't you use the standard method of getting the app object? Then use your str arg with Documents.Add. "Mark Propst" wrote in message news:4058d478$1_1@newsprd01... > any help appreciated, I still cant get it right. > Calling the following function with a valid drawing name, if acad is running > but dwg is not open, it opens the dwg (after requiring a response to save > Drawingx) > If I then close the dwg it opened I get 'FATAL ERROR: > 'Unhandled Access Violation Reading 0x0000 Exception at 6c5dc1h > and acad crashes > A2k2 win2k vb6 standard exe project > > > existing function: > Public Function GetAcad(Optional sDwgName As String, Optional AcVisible As > Boolean = True) As AcadApplication > Dim oAcadApp As AcadApplication > Dim oAcadDoc As AcadDocument > Dim i As Integer: i = 0 > > On Error Resume Next > If Not IsEmpty(sDwgName) Then > Set oAcadDoc = GetObject(sDwgName) > If Not oAcadDoc Is Nothing Then > Set oAcadApp = oAcadDoc.Application > End If > > If Not oAcadApp Is Nothing Then > If oAcadApp.Documents.Count > 1 Then > oAcadApp.ActiveDocument = oAcadDoc > End If > End If > Else > Set oAcadApp = GetObject(, "AutoCAD.Application") > If Err Then > Err.Clear > Restart: > Set oAcadApp = CreateObject("AutoCAD.Application") > > If Err.Number = 91 Then > Err.Clear > If i = 3 Then > Exit Function > Else > GoTo Restart > i = i + 1 > End If > Else > Err.Clear > End If > End If > > End If > > oAcadApp.Visible = AcVisible > Set GetAcad = oAcadApp > End Function > > tia > Mark > >
0 Likes
Message 3 of 8

Anonymous
Not applicable
"Ed Jobe" wrote in message news:4058e945$1_3@newsprd01... > Why don't you use the standard method of getting the app object? Then use > your str arg with Documents.Add. Hi Ed, Thanks for responding. I was trying to benefit from Tony's suggestion from a long while back about using GetObject with the file name rather than the app class in order to retrieve an already open copy of the file if it exists. If I use GetObject on acadapp, then if more than one instance of acad is already running, and any acad instance *other than the first one started* has the target drawing open, the *first* acad started will re-open the dwg in readonly mode and return that document - not the result desired. I've been searching google for a couple years trying to find a way to read the rot to loop though all open sessions but I'm not finding any posts that say they succeeded at doing it. Maybe it's there but I've read thousands of posts and haven't found it....could just be blind by now though! :-) Do you know of a clever way around that problem? I figure if anyone has this one solved it's going to be you! :-) the function I adapted per your suggestion is as follows, maybe i'm not doing something right there. (a2k2 - win2k - vb6 std exe) Public Function GetAcad2(Optional sDwgName As String, Optional AcVisible As Boolean = True) As AcadApplication Dim oAcadApp As AcadApplication Dim oDoc As AcadDocument Dim i As Integer: i = 0 On Error Resume Next Set oAcadApp = GetObject(, "AutoCAD.Application") If Err Then Err.Clear Restart: Set oAcadApp = CreateObject("AutoCAD.Application") If Err.Number = 91 Then Err.Clear If i = 3 Then Exit Function Else GoTo Restart i = i + 1 End If Else Err.Clear End If End If oAcadApp.Visible = AcVisible Dim bDwgOpen As Boolean bDwgOpen = False Dim sJustName As String If Not IsEmpty(sDwgName) Then Dim cf As New cmnFile sJustName = cf.StripPath(sDwgName) For Each oDoc In oAcadApp.Documents Debug.Print oDoc.Name If oDoc.Name = sJustName Then oAcadApp.ActiveDocument = oDoc bDwgOpen = True End If Next End If If bDwgOpen = False Then 'whats the difference between these two??? oAcadApp.Documents.Open sDwgName 'oAcadApp.Documents.Add sDwgName End If Set GetAcad2 = oAcadApp 'still not sure if I'm supposed to clear these internal references 'since the objects already been passed to the calling routine 'or if that will clear the object that was just passed also??? 'Set oDoc = Nothing 'Set oAcadApp = Nothing Set cf = Nothing End Function and the test sub calling it is: Sub main() Dim sDwgName As String sDwgName = "DimensionObjectTest2.dwg" Dim sPath As String sPath = "Z:\0\" Dim sFullName As String sFullName = sPath & sDwgName Dim oAcad As AcadApplication Dim oDoc As AcadDocument On Error Resume Next Set oAcad = GetAcad2(sFullName, True) If Err Then Debug.Print "err" Else Debug.Print "no err" End If Debug.Print "name of returned doc: " & oAcad.ActiveDocument.Name Debug.Print "List of all docs: " For Each oDoc In oAcad.Documents Debug.Print oDoc.Name Next Dim sJustName As String Dim cf As New cmnFile sJustName = cf.StripPath(sDwgName) Debug.Print "Try to get target document: " 'Set oDoc = oAcad.Documents(sDwgName) Set oDoc = oAcad.Documents(sJustName) If Err Then Debug.Print "error getting sdwgname" Else Debug.Print "no error getting sdwgname" 'just to see which drawing is really active Dim aPt(0 To 2) As Double aPt(0) = 0 aPt(1) = 0 aPt(2) = 0 oDoc.ModelSpace.AddCircle aPt, 12 End If Set oDoc = Nothing Set oAcad = Nothing Set cf = Nothing ' End Sub and the print out: err name of returned doc: DimensionObjectTest2.dwg List of all docs: Drawing2.dwg Drawing3.dwg DimensionObjectTest2.dwg Try to get target document: error getting sdwgname the circle ends up in the read only copy in the first instance of acad, not in the originally opened copy which was opened in the second instance of acad. any help greatly appreciated, Mark
0 Likes
Message 4 of 8

Anonymous
Not applicable
Mark, I think this exerpt from vb help is the key to your problem. "If the pathname argument is omitted, GetObject returns a currently active object of the specified type." You're probably thinking that if no dwg with that name is open, then it would error. The behavior to get the currently active type is only available if you leave the path blank. In my test, with acad not open, it opened acad and then the dwg. It works like ShellExecuteEx. I don't see a way (at least with this function) to test if the dwg is already open. If it opens read-only, you could assume that it was. :-) -- ---- Ed ---- "Mark Propst" wrote in message news:4058fcf8_3@newsprd01... > > "Ed Jobe" wrote in message > news:4058e945$1_3@newsprd01... > > Why don't you use the standard method of getting the app object? Then use > > your str arg with Documents.Add. > > Hi Ed, > Thanks for responding. > > I was trying to benefit from Tony's suggestion from a long while back about > using GetObject with the file name rather than the app class in order to > retrieve an already open copy of the file if it exists. > If I use GetObject on acadapp, then if more than one instance of acad is > already running, and any acad instance *other than the first one started* > has the target drawing open, the *first* acad started will re-open the dwg > in readonly mode and return that document - not the result desired. I've > been searching google for a couple years trying to find a way to read the > rot to loop though all open sessions but I'm not finding any posts that say > they succeeded at doing it. Maybe it's there but I've read thousands of > posts and haven't found it....could just be blind by now though! > :-) > > Do you know of a clever way around that problem? > I figure if anyone has this one solved it's going to be you! > :-) > > the function I adapted per your suggestion is as follows, maybe i'm not > doing something right there. > (a2k2 - win2k - vb6 std exe) > > Public Function GetAcad2(Optional sDwgName As String, Optional AcVisible As > Boolean = True) As AcadApplication > Dim oAcadApp As AcadApplication > Dim oDoc As AcadDocument > Dim i As Integer: i = 0 > > On Error Resume Next > Set oAcadApp = GetObject(, "AutoCAD.Application") > If Err Then > Err.Clear > Restart: > Set oAcadApp = CreateObject("AutoCAD.Application") > > If Err.Number = 91 Then > Err.Clear > If i = 3 Then > Exit Function > Else > GoTo Restart > i = i + 1 > End If > Else > Err.Clear > End If > > End If > > oAcadApp.Visible = AcVisible > Dim bDwgOpen As Boolean > bDwgOpen = False > Dim sJustName As String > > If Not IsEmpty(sDwgName) Then > Dim cf As New cmnFile > sJustName = cf.StripPath(sDwgName) > > For Each oDoc In oAcadApp.Documents > Debug.Print oDoc.Name > If oDoc.Name = sJustName Then > oAcadApp.ActiveDocument = oDoc > bDwgOpen = True > End If > Next > End If > > If bDwgOpen = False Then > 'whats the difference between these two??? > oAcadApp.Documents.Open sDwgName > 'oAcadApp.Documents.Add sDwgName > End If > > > Set GetAcad2 = oAcadApp > > 'still not sure if I'm supposed to clear these internal references > 'since the objects already been passed to the calling routine > 'or if that will clear the object that was just passed also??? > 'Set oDoc = Nothing > 'Set oAcadApp = Nothing > > Set cf = Nothing > > End Function > > and the test sub calling it is: > Sub main() > Dim sDwgName As String > sDwgName = "DimensionObjectTest2.dwg" > Dim sPath As String > sPath = "Z:\0\" > Dim sFullName As String > sFullName = sPath & sDwgName > > Dim oAcad As AcadApplication > Dim oDoc As AcadDocument > > On Error Resume Next > Set oAcad = GetAcad2(sFullName, True) > If Err Then > Debug.Print "err" > Else > Debug.Print "no err" > End If > Debug.Print "name of returned doc: " & oAcad.ActiveDocument.Name > Debug.Print "List of all docs: " > For Each oDoc In oAcad.Documents > Debug.Print oDoc.Name > Next > Dim sJustName As String > Dim cf As New cmnFile > sJustName = cf.StripPath(sDwgName) > > Debug.Print "Try to get target document: " > 'Set oDoc = oAcad.Documents(sDwgName) > Set oDoc = oAcad.Documents(sJustName) > If Err Then > Debug.Print "error getting sdwgname" > Else > Debug.Print "no error getting sdwgname" > 'just to see which drawing is really active > Dim aPt(0 To 2) As Double > aPt(0) = 0 > aPt(1) = 0 > aPt(2) = 0 > oDoc.ModelSpace.AddCircle aPt, 12 > End If > > Set oDoc = Nothing > Set oAcad = Nothing > Set cf = Nothing ' > > End Sub > > > > and the print out: > err > name of returned doc: DimensionObjectTest2.dwg > List of all docs: > Drawing2.dwg > Drawing3.dwg > DimensionObjectTest2.dwg > Try to get target document: > error getting sdwgname > > the circle ends up in the read only copy in the first instance of acad, not > in the originally opened copy which was opened in the second instance of > acad. > > any help greatly appreciated, > Mark > >
0 Likes
Message 5 of 8

Anonymous
Not applicable
Hi Ed, Thanks for staying with me on this. I apologize if I'm just beating a dead horse here. It seems to me that this would be a very normal and usual thing that everyone would need to be able to do...but since I'm the only one beating my head on this wall I guess that shows just how really ABnormal I am!!! :-) (but then we already knew that eh?) I'm may not have explained what I want to accomplish clearly enough. It also may be that I'm trying to do something that is not possible. Furthermore, it is probably not absolutely necessary to do what I want either since I'm just writing routines that I will use and I can then work around their limitations and work in a controlled environment, eg: not call this function when a running instance of acad exists with the target drawing open if more that one acad is running and if the open target drawing is not in the first session started. No big deal really, I just thought that if there were a way, then a generic getacad function should utilize it....I didn't realize it was going to be such a headache! |:-\ <----(flattened head from banging on desk) (If this app were for the open market I would think it would have to have a more robust method of acquiring a specific drawing whether or not it was open and whether or not multiple instances of acad were running and whether or not the open dwg was in the first instance of acad to have been started during that editing session. So I assumed the power houses here would already know how to do this, but maybe...........) As it stands, if the drawing is open in the first instance, or if there's only one instance, or if the drawing is not open in any instance, or if there are no instances of acad running then it will work as desired. However if the sdwg is open, and there are more than one acad running, and the open sDwg is not in the first acad started(AcadInstance1), then it does not work....in the sense that instead of returning the open sDwg (in AcadInstance1+x), AcadInstance1 opens a read only copy of sDwg and returns that document object. Is it clear what I'm trying to do? Is it just not possible? Or am I just being dense? "Ed Jobe" wrote in message news:405a3b20$1_2@newsprd01... > Mark, I think this exerpt from vb help is the key to your problem. > "If the pathname argument is omitted, GetObject returns a currently active > object of the specified type." I'm well familiar with that section (believe me, I've read the help files many many times on this and many many hours on google) but I don't see that this is the key to my problem. Maybe I'm not understanding something correctly. (oooh now that would be different! lol) That statement to me means that if I call GetObject(, AcadApplication) then that will return a running instance of acad if one exists, (otherwise it will raise an error.) so far so good....but not what I'm trying to acomplish.... > You're probably thinking that if no dwg with that name is open, then it > would error. hmmm...don't understand where you got that idea.... no, if I call GetObject(sDwg), and acadInstance1 is running, and sDwg is not open, it doesn't error, acadInstance1 opens the dwg. - that part is fine If I call GetObject(sDwg), and acadInstance1 is running, and sdwg is open in that instance, it returns the sdwg. - that part is fine If I call GetObject(sDwg), and there is no acad session running, it opens acad and opens the dwg - that part is fine If I call GetObject(sDwg), and multiple AcadInstances(1 to 1+X) are running, and sdwg is open in AcadInstance(>1), AcadInstance1 opens sdwg as ReadOnly and that is the document object returned. - *that is the problem I'm trying to solve.* > The behavior to get the currently active type is only available > if you leave the path blank. hmmm.....that doesn't seem to be the case or I don't understand that statement. If one or more acad is running (currently active type) and I call GetObject(sDwg), the first instance of acad will open sDwg and return the document object. Oh, maybe that's what you mean...instead of returning the class application it returns the class document...is that what you mean??? but that's no problem cause you then just get the application object from the document object (as you know) so I'm not sure what that statement refers to exactly... > In my test, with acad not open, it opened acad > and then the dwg. Right, that part works fine! If the dwg is not open or acad is not open, no problem. If the dwg is not open and acad is open, also no problem If acad is open (more than one) and the dwg is also open and the dwg is not in acadInstance(1)...***problem*** >It works like ShellExecuteEx. I don't see a way (at least > with this function) to test if the dwg is already open. *That's* the key to my problem (as I see it). I was hoping you had an answer for how to do that.(obviously not with *this* function since it's not working in that case...but with some *other* function or some addition or change to this function!) As I see it, this is what I want to be able to do, but dont' know how: Check all running instances of acad (as if there were a collection of running instances) On Error Resume Next For Each RunningAcad in RunningAcads Set oDoc = RunningAcad.Documents.Item(sDwg) If Not Err Then ...sDwg is open....Use(RunningAcad) Exit For End if Next RunningAcad That's what I'm trying to do and cant find a way to. Is there a way with some Api call??? >If it opens > read-only, you could assume that it was. :-) Yes, but then there's no way to get the document object that is *not* read only...so thats the problem. GetObject will only return RunningInstance#1....how to access RunningInstance1+x is what I'm looking for... Do you know a solution to that problem? or am I trying to do the impossible.? Again, Thank you very much for your thoughts and ideas. You are always an invaluable treasure house of knowlege and insight and I appreciate you taking your time with my trifling questions! Hope I'm not being too much of a pest!...well, yeah I know I *am*...but I hope your forbearance and infinite patience will overlook that fact :-) Mark
0 Likes
Message 6 of 8

Anonymous
Not applicable
Yes its clear what you are trying to do, I was merely pointing out that GetObject can't accomplish that. However, maybe you are trying to do more than you need to. I can't think of any commercial app that does that. Wouldn't the user know if they already have the dwg open? Its not always possible or advisable to code for every contingency. As a programmer, you usually have to make some assumptions about the environment you work in. That determines the way your program works, and then the users learn your program. For example, I have one Acess app I use, where the user selects text from acad wiring schedules to import into a table for printing wiring tags. Rather than try and figure out all the possibilities of drawing combinations, I just have the user open the one they need first. Its still the same amount of steps for the user, but the code logic is much simpler. See here: On Error Resume Next 'If acad is open, assume the active drawing is the one they need. Set acad = GetObject(, "AutoCAD.Application") If Err <> 0 Then Set acad = CreateObject("AutoCAD.Application") acad.Visible = True AppActivate acad.Caption 'User needs to navigate to the right drawing. acad.ActiveDocument.Utility.Prompt "Open the drawing file first and then re-execute this command!" Exit Sub End If They quickly learn that they need the right drawing open before they run the command. -- ---- Ed ---- "Mark Propst" wrote in message news:405a5136_3@newsprd01... > Hi Ed, > Thanks for staying with me on this. I apologize if I'm just beating a dead > horse here. > It seems to me that this would be a very normal and usual thing that > everyone would need to be able to do...but since I'm the only one beating my > head on this wall I guess that shows just how really ABnormal I am!!! > :-) > (but then we already knew that eh?) > > I'm may not have explained what I want to accomplish clearly enough. > It also may be that I'm trying to do something that is not possible. > Furthermore, it is probably not absolutely necessary to do what I want > either since I'm just writing routines that I will use and I can then work > around their limitations and work in a controlled environment, eg: not call > this function when a running instance of acad exists with the target drawing > open if more that one acad is running and if the open target drawing is not > in the first session started. No big deal really, I just thought that if > there were a way, then a generic getacad function should utilize it....I > didn't realize it was going to be such a headache! > |:-\ <----(flattened head from banging on desk) > > (If this app were for the open market I would think it would have to have a > more robust method of acquiring a specific drawing whether or not it was > open and whether or not multiple instances of acad were running and whether > or not the open dwg was in the first instance of acad to have been started > during that editing session. So I assumed the power houses here would > already know how to do this, but maybe...........) > > As it stands, if the drawing is open in the first instance, or if there's > only one instance, or if the drawing is not open in any instance, or if > there are no instances of acad running then it will work as desired. > However if the sdwg is open, and there are more than one acad running, and > the open sDwg is not in the first acad started(AcadInstance1), then it does > not work....in the sense that instead of returning the open sDwg (in > AcadInstance1+x), AcadInstance1 opens a read only copy of sDwg and returns > that document object. > > Is it clear what I'm trying to do? > Is it just not possible? > Or am I just being dense? > > > "Ed Jobe" wrote in message > news:405a3b20$1_2@newsprd01... > > Mark, I think this exerpt from vb help is the key to your problem. > > "If the pathname argument is omitted, GetObject returns a currently active > > object of the specified type." > > I'm well familiar with that section (believe me, I've read the help files > many many times on this and many many hours on google) but I don't see that > this is the key to my problem. > Maybe I'm not understanding something correctly. (oooh now that would be > different! lol) > That statement to me means that if I call GetObject(, AcadApplication) then > that will return a running instance of acad if one exists, (otherwise it > will raise an error.) > so far so good....but not what I'm trying to acomplish.... > > > You're probably thinking that if no dwg with that name is open, then it > > would error. > > hmmm...don't understand where you got that idea.... > no, if I call GetObject(sDwg), and acadInstance1 is running, and sDwg is not > open, it doesn't error, acadInstance1 opens the dwg. - that part is fine > > If I call GetObject(sDwg), and acadInstance1 is running, and sdwg is open in > that instance, it returns the sdwg. - that part is fine > > If I call GetObject(sDwg), and there is no acad session running, it opens > acad and opens the dwg - that part is fine > > If I call GetObject(sDwg), and multiple AcadInstances(1 to 1+X) are running, > and sdwg is open in AcadInstance(>1), AcadInstance1 opens sdwg as ReadOnly > and that is the document object returned. - *that is the problem I'm trying > to solve.* > > > The behavior to get the currently active type is only available > > if you leave the path blank. > > hmmm.....that doesn't seem to be the case or I don't understand that > statement. > If one or more acad is running (currently active type) and I call > GetObject(sDwg), the first instance of acad will open sDwg and return the > document object. > Oh, maybe that's what you mean...instead of returning the class application > it returns the class document...is that what you mean??? but that's no > problem cause you then just get the application object from the document > object (as you know) so I'm not sure what that statement refers to > exactly... > > > > In my test, with acad not open, it opened acad > > and then the dwg. > > Right, that part works fine! > If the dwg is not open or acad is not open, no problem. > If the dwg is not open and acad is open, also no problem > If acad is open (more than one) and the dwg is also open and the dwg is not > in acadInstance(1)...***problem*** > > >It works like ShellExecuteEx. I don't see a way (at least > > with this function) to test if the dwg is already open. > > *That's* the key to my problem (as I see it). I was hoping you had an > answer for how to do that.(obviously not with *this* function since it's not > working in that case...but with some *other* function or some addition or > change to this function!) > > As I see it, this is what I want to be able to do, but dont' know how: > Check all running instances of acad (as if there were a collection of > running instances) > > On Error Resume Next > For Each RunningAcad in RunningAcads > Set oDoc = RunningAcad.Documents.Item(sDwg) > If Not Err Then > ...sDwg is open....Use(RunningAcad) > Exit For > End if > Next RunningAcad > > That's what I'm trying to do and cant find a way to. > Is there a way with some Api call??? > > >If it opens > > read-only, you could assume that it was. :-) > > Yes, but then there's no way to get the document object that is *not* read > only...so thats the problem. GetObject will only return > RunningInstance#1....how to access RunningInstance1+x is what I'm looking > for... > > Do you know a solution to that problem? or am I trying to do the > impossible.? > > Again, Thank you very much for your thoughts and ideas. You are always an > invaluable treasure house of knowlege and insight and I appreciate you > taking your time with my trifling questions! Hope I'm not being too much of > a pest!...well, yeah I know I *am*...but I hope your forbearance and > infinite patience will overlook that fact > :-) > > Mark > >
0 Likes
Message 7 of 8

Anonymous
Not applicable
Thanks Ed, Yeah, I'm always trying to make the simple difficult! That's what I needed to confirm, that I wasn't just missing something simple... I'll now go get some putty and ducttape and start working on that dent in the wall! :-) Mark "Ed Jobe" wrote in message news:405b2063$1_1@newsprd01... However, maybe you are trying to do more > than you need to. I can't think of any commercial app that does that. > Wouldn't the user know if they already have the dwg open? duh! :-) thanks again for your patience
0 Likes
Message 8 of 8

Anonymous
Not applicable
Yeah, we've all done that...get so involved solving a problem, that you forget what he goal was. :-) -- ---- Ed ---- "Mark Propst" wrote in message news:405b3892$1_2@newsprd01... > Thanks Ed, > Yeah, I'm always trying to make the simple difficult! > That's what I needed to confirm, that I wasn't just missing something > simple... > I'll now go get some putty and ducttape and start working on that dent in > the wall! > :-) > Mark > > "Ed Jobe" wrote in message > news:405b2063$1_1@newsprd01... > > However, maybe you are trying to do more > > than you need to. I can't think of any commercial app that does that. > > Wouldn't the user know if they already have the dwg open? > > duh! :-) > > thanks again for your patience > >
0 Likes