TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: GDF on March 18, 2008, 02:33:21 PM
-
Tim (or anyone else can jump in here)
Ever so often when using these routines, it cases AutoCAD to lockup.
Is it because of AcadApplication.Documents.Open function (just quessing)?
I'm using AutoCAD 2008 on Windows XP
But when it does happen, it gets to be annoying. Has anyone else experienced this problem...if so, how to fix it.
I use these two routines hundreds of times a day...so I cannot live without them.
Gary
;;;by Tim Willey
(defun MyNext (/ AcadObj DocCol DirPath DwgList Pos Dwg DwgFile ErrChk Opt)
; Opens/Makes-active next drawing in the directory.
(setq AcadObj (vlax-get-Acad-Object))
(setq DocCol (vla-get-Documents AcadObj))
(setq DirPath (getvar "dwgprefix"))
(setq DwgList (vl-directory-files DirPath "*.dwg" 1))
(setq DwgList (vl-sort DwgList '<))
(setq Pos (vl-position (getvar "dwgname") DwgList))
(if (setq Dwg (nth (1+ Pos) DwgList))
(progn (setq DwgFile (strcat DirPath Dwg))
(setq ErrChk (vl-catch-all-apply 'vla-Item (list DocCol Dwg)))
(if (vl-catch-all-error-p ErrChk)
(progn
(if (and (= (getvar "sdi") 1) (/= (getvar "dbmod") 0))
(progn (initget "Y N")
(setq Opt
(getkword
"\n Drawing has changed. Save changes before exiting drawings? <Y> "))
(if (or (= Opt "Y") (not Opt))
(setq Opt "N")
(setq Opt "Y"))
(vl-cmdf
"_.vbastmt"
(strcat "AcadApplication.Documents.Open \"" DwgFile "\""))
(command Opt))
(vl-cmdf
"_.vbastmt"
(strcat "AcadApplication.Documents.Open \"" DwgFile "\""))))
(command
"_.vbastmt"
(strcat "documents.item \(\"" (vla-get-Name ErrChk) "\"\).activate"))))
;;(alert "\n This is the last drawing in this folder.")
(ARCH:ALERT-I
"MsgBox \"
Open Next Drawing Message
--------------------------------------------------------------------------------------------
You already are in the Last Drawing of this Directory!\"")
)
(princ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;by Tim Willey
(defun MyPrevious (/ AcadObj DocCol DirPath DwgList Pos Dwg DwgFile ErrChk Opt)
; Opens/Makes-active previous drawing in the directory.
(setq AcadObj (vlax-get-Acad-Object))
(setq DocCol (vla-get-Documents AcadObj))
(setq DirPath (getvar "dwgprefix"))
(setq DwgList (vl-directory-files DirPath "*.dwg" 1))
(setq DwgList (vl-sort DwgList '<))
(setq Pos (vl-position (getvar "dwgname") DwgList))
(if (> Pos 0)
(progn (setq Dwg (nth (1- Pos) DwgList))
(setq DwgFile (strcat DirPath Dwg))
(setq ErrChk (vl-catch-all-apply 'vla-Item (list DocCol Dwg)))
(if (vl-catch-all-error-p ErrChk)
(progn
(if (and (= (getvar "sdi") 1) (/= (getvar "dbmod") 0))
(progn (initget "Y N")
(setq Opt
(getkword
"\n Drawing has changed. Save changes before exiting drawings? <Y> "))
(if (or (= Opt "Y") (not Opt))
(setq Opt "N")
(setq Opt "Y"))
(vl-cmdf
"_.vbastmt"
(strcat "AcadApplication.Documents.Open \"" DwgFile "\""))
(command Opt))
(vl-cmdf
"_.vbastmt"
(strcat "AcadApplication.Documents.Open \"" DwgFile "\""))))
(command
"_.vbastmt"
(strcat "documents.item \(\"" (vla-get-Name ErrChk) "\"\).activate"))))
;;(alert "\n This is the first drawing in this folder.")
(ARCH:ALERT-I
"MsgBox \"
Open Next Drawing Message
--------------------------------------------------------------------------------------------
You already are in the First Drawing of this Directory!\"")
)
(princ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
I have never had a problem with them Gary. I will take a look when I get a moment, but then again I use '06 on a regular basis, so I might not see a problem. I guess I might be able to run some tests on '08, as I do have it installed. Let you know what I find out.
-
I have never had a problem with them Gary. I will take a look when I get a moment, but then again I use '06 on a regular basis, so I might not see a problem. I guess I might be able to run some tests on '08, as I do have it installed. Let you know what I find out.
Thanks Tim. Like I said, it only happens once in a while...always when I'm in a rush.
Gary
-
What are you opening? And what do you have open already?
I'm just trying to narrow it down a little, as maybe it's a memory issue with loading a lot of 3d objects, and xrefs. I just opened about ~30 drawings, going next and previous, and didn't see anything happen. Mine had some xrefs, but nothing 3d and nothing too intense.
-
What are you opening? And what do you have open already?
I'm just trying to narrow it down a little, as maybe it's a memory issue with loading a lot of 3d objects, and xrefs. I just opened about ~30 drawings, going next and previous, and didn't see anything happen. Mine had some xrefs, but nothing 3d and nothing too intense.
Small to medium size unit plans...say eight files within a directory. 98% of the time the routine runs smoothly.
I checked outside and it is raining......nay that couldn't be it.
Sometimes I get this problem with Peter Jamtgaard's close drawings routine (a routine that closes all drawings selected within a dialog box).
This could be a netwok problem. Anyway thanks for checking it out for me. Others in our office have had the same problem with it locking up AutoCAD.
Like I said, I cannot work without this routine. Everyone here in the office uses it also.
Thanks again Tim.
-
I wonder if it is because it is using a VBA statement. I'm not sure, but that would be my guess. Maybe I'll see if I can do it in C#, so that the problem won't exist, and it will be a fun little project. :-D
-
Gary: What types of Reactors are you running? There was a bug that got fixed - can't remember when - vlr-notification:
(vlr-notification myreactorObject 'active-document-only)
My command reactors caused havoc when opening / closing drawings until I set the above.
jb
-
Gary: What types of Reactors are you running? There was a bug that got fixed - can't remember when - vlr-notification:
(vlr-notification myreactorObject 'active-document-only)
My command reactors caused havoc when opening / closing drawings until I set the above.
jb
Never knew about that one James. Thanks.
-
Gary,
Here is the C# code, and the dll file within the attached zip file. I tested it in '08, and it seems to be working fine. Let me know if you run into any problems. The command names are the same once it's loaded, MyNext & MyPrevious.
If you want them to auto load within Acad, you can see this post by Glenn (http://www.theswamp.org/index.php?topic=16184.msg196725#msg196725) that explains how to set that up.
/*
* Created by SharpDevelop.
* User: Tim Willey
* Date: 3/18/2008
* Time: 4:17 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
[assembly: CommandClass (typeof (Test.OpenNextPrevious))]
namespace Test
{
/// <summary>
/// Description of OpenNextPrevious.
/// </summary>
class MyStringCompare {
public MyStringCompare () {}
public static int Compare (object obj1, object obj2) {
string str1 = (string)obj1, str2 = (string)obj2;
int i1 = 0,
i2 = 0,
CompareResult,
l1 = str1.Length,
l2 = str2.Length,
tempI1,
tempI2;
string s1, s2;
bool b1, b2;
while (true) {
b1 = Char.IsDigit(str1, i1);
b2 = Char.IsDigit(str2, i2);
if ( !b1 && b2 )
return -1;
if ( b1 && !b2 )
return 1;
if (b1 && b2) {
FindLastDigit(str1, ref i1, out s1);
FindLastDigit(str2, ref i2, out s2);
tempI1 = Convert.ToInt32(s1);
tempI2 = Convert.ToInt32(s2);
if ( tempI1.Equals(tempI2) )
CompareResult = 0;
else if (tempI1 < tempI2)
CompareResult = -1;
else
CompareResult = 1;
if ( !CompareResult.Equals(0) )
return CompareResult;
}
else {
FindLastLetter(str1, ref i1, out s1);
FindLastLetter(str2, ref i2, out s2);
CompareResult = string.Compare(s1, s2);
if ( !CompareResult.Equals(0) )
return CompareResult;
}
if (l1 <= i1) {
if (l2 <= i2) {
return 0;
}
else {
return -1;
}
}
if (l2 <= i2) {
if (l1 < i1) {
return 0;
}
else {
return 1;
}
}
}
}
private static void FindLastLetter (string MainStr, ref int i, out string OutStr) {
int StartPos = i;
int StrLen = MainStr.Length;
++i;
while ( i < StrLen && !Char.IsDigit(MainStr, i) )
++i;
OutStr = MainStr.Substring(StartPos, i - StartPos);
}
private static void FindLastDigit (string MainStr, ref int i, out string OutStr) {
int StartPos = i;
int StrLen = MainStr.Length;
++i;
while ( i < StrLen && Char.IsDigit(MainStr, i) )
++i;
OutStr = MainStr.Substring(StartPos, i - StartPos);
}
}
public class OpenNextPrevious
{
[CommandMethod("MyNext", CommandFlags.Session)]
public void OpenNext()
{
OpenDrawing(1);
}
[CommandMethod("MyPrevious", CommandFlags.Session)]
public void OpenPrevious()
{
OpenDrawing(-1);
}
public void OpenDrawing (int ToOpen) {
Document Doc = null;
DocumentCollection DocCol = AcadApp.DocumentManager;
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
string FullPath = DwgPath + DwgName;
string[] DwgList = Directory.GetFiles(DwgPath, "*.dwg");
Array.Sort(DwgList, new MyStringCompare1());
int cNum = Array.IndexOf(DwgList, FullPath);
if ( ToOpen.Equals(1) ) {
if ( cNum.Equals(DwgList.Length - 1) ) {
MessageBox.Show("Already at the last drawing in the folder.", "Not really an error.");
return;
}
}
else {
if ( cNum.Equals(0) ) {
MessageBox.Show("Already at the first drawing in the folder.", "Not really an error.");
return;
}
}
string Path = DwgList[cNum + ToOpen];
foreach (Document doc in DocCol) {
if (string.Compare(Path, doc.Name, true).Equals(0)) {
Doc = doc;
break;
}
}
if (Doc != null)
DocCol.MdiActiveDocument = Doc;
else
DocCol.Open(Path, false);
}
public class MyStringCompare1 : IComparer {
public MyStringCompare1 () {}
public int Compare (object x, object y) {
return MyStringCompare.Compare( x,y );
}
}
}
}
-
James
Yes I have a lot of running reactors, will have to go thru them.
Tim
Thanks for the update.
Gary,
Here is the C# code, and the dll file within the attached zip file. I tested it in '08, and it seems to be working fine. Let me know if you run into any problems. The command names are the same once it's loaded, MyNext & MyPrevious.
If you want them to auto load within Acad, you can see this post by Glenn (http://www.theswamp.org/index.php?topic=16184.msg196725#msg196725) that explains how to set that up.
I think I'm over my head. Is the following below the reg file I need to make? I renamed your test.dll to NextPrev17.dll.
My command names would be "N2" for "MyNext" and "P2" for "MyPrevious".
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17]
"DESCRIPTION"="Next Previous Drawing in the Directory"
"LOADCTRLS"=dword:00000004
"LOADER"="V:\\ARCH\\Support\\V17\\NextPrev17.dll"
"MANAGED"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Commands]
"M2"="MyNext"
"P2"="MyPrevious"
Gary
-
That looks like what I have, except
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Commands]
"M2"="MyNext"
"P2"="MyPrevious"
Won't work. I just tried it. You have to have the values be the same on both sides (not sure why). But once you do that you can change the pgp file to
M2, *MyNext
P2, *MyPrevious
and it will work.
-
Tim
Can't get it to work. The commands are unknown: "mynext" and "myprevious".
Gary
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17]
"DESCRIPTION"="Next Previous Drawing in the Directory"
"LOADCTRLS"=dword:00000004
"LOADER"="V:\\ARCH\\Support\\V18\\NextPrev17.dll"
"MANAGED"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Commands]
"MyNext"="MyNext"
"MyPrevious"="MyPrevious"
-
Try changing the LOADCTRLS to 12 instead of 4. Mine is set to 12. Not sure why I changed mine, so I didn't want to lead you astray earlier.
You may also have to add the Groups folder under the NextPrev17 folder. Also you would add one string entry with both values being the same. Mine are MyCommands, but I'm sure you can call it whatever you want.
-
Try changing the LOADCTRLS to 12 instead of 4. Mine is set to 12. Not sure why I changed mine, so I didn't want to lead you astray earlier.
You may also have to add the Groups folder under the NextPrev17 folder. Also you would add one string entry with both values being the same. Mine are MyCommands, but I'm sure you can call it whatever you want.
Tim
Made the changes and still get unkown command.
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Groups]
"MYCommands"="MYCommands"
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17]
"DESCRIPTION"="Next Previous Drawing in the Directory"
"LOADCTRLS"=dword:00000012
"LOADER"="V:\\ARCH\\Support\\V18\\NextPrev17.dll"
"MANAGED"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Commands]
"MyNext"="MyNext"
"MyPrevious"="MyPrevious"
Gary
-
Did you exit and reenter Acad? Have you tried to just netload it and use the commands?
Are you using a netword path? If so you might want to read the post after the one I linked to before. .Net files act differently from local and network drives.
Here is what mine looks like. I exported it to a text file.
Key Name: HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R16.2\ACAD-4007:409\Applications\MyAcadCommands
Class Name: <NO CLASS>
Last Write Time: 5/15/2007 - 3:26 PM
Value 0
Name: DESCRIPTION
Type: REG_SZ
Data: My dotNet applications.
Value 1
Name: LOADCTRLS
Type: REG_DWORD
Data: 0xc
Value 2
Name: MANAGED
Type: REG_DWORD
Data: 0x1
Value 3
Name: LOADER
Type: REG_SZ
Data: C:\MyCustom\Dll\3MAutoCAD.dll
Key Name: HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R16.2\ACAD-4007:409\Applications\MyAcadCommands\Commands
Class Name: <NO CLASS>
Last Write Time: 3/19/2008 - 12:11 PM
Value 0
Name: MyXrefManager
Type: REG_SZ
Data: MyXrefManager
Value 1
Name: NewRev
Type: REG_SZ
Data: NewRev
Value 2
Name: MatchRevisions
Type: REG_SZ
Data: MatchRevisions
Value 3
Name: UpdateRevCloud
Type: REG_SZ
Data: UpdateRevCloud
Value 4
Name: MyBPlot
Type: REG_SZ
Data: MyBPlot
Value 5
Name: CopyXrefLayerProps
Type: REG_SZ
Data: CopyXrefLayerProps
Value 6
Name: MyAttPalette
Type: REG_SZ
Data: MyAttPalette
Value 7
Name: XrefCheck
Type: REG_SZ
Data: XrefCheck
Value 8
Name: NewUpdTitleBlock
Type: REG_SZ
Data: NewUpdTitleBlock
Value 9
Name: FilterForEnglishWord
Type: REG_SZ
Data: FilterForEnglishWord
Value 10
Name: UpdateMiddleTitleLine
Type: REG_SZ
Data: UpdateMiddleTitleLine
Key Name: HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R16.2\ACAD-4007:409\Applications\MyAcadCommands\Groups
Class Name: <NO CLASS>
Last Write Time: 5/15/2007 - 3:26 PM
Value 0
Name: MyCommands
Type: REG_SZ
Data: MyCommands
-
Tim
Work just fine on a local drive. Still can't get it to work off of the server drive.
Man your routine is fast. LOVE IT.
This now works:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Groups]
"Support"="Support"
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17]
"DESCRIPTION"="Next Previous Drawing in the Directory"
"LOADCTRLS"=dword:00000004
"LOADER"="C:\\Arch_Custom\\Support\\NextPrev17.dll"
"MANAGED"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\NextPrev17\Commands]
"MyNext"="MyNext"
"MyPrevious"="MyPrevious"
Gary
-
I don't use network drives for any programs, as I'm the only one using them.
Glad you like Gary.
If I find out anything helpful about network drives and .Net I will let you know.
-
I don't use network drives for any programs, as I'm the only one using them.
Glad you like Gary.
If I find out anything helpful about network drives and .Net I will let you know.
Tim
So far no problems, works perfectly.
Have you fiqured out why a network location will not work?
Also would it be possible to close the last drawing while proceeding to the next...similar to the way the old lisp routine worked?
Only want two drawing open at any one time.
Gary
-
I don't use network drives for any programs, as I'm the only one using them.
Glad you like Gary.
If I find out anything helpful about network drives and .Net I will let you know.
Tim
So far no problems, works perfectly.
Have you fiqured out why a network location will not work?
Also would it be possible to close the last drawing while proceeding to the next...similar to the way the old lisp routine worked?
Only want two drawing open at any one time.
Gary
The network issue is on of security. By default network .Net programs are not trusted. To fix it you have to give the network drive (or folders within) a higher trust level. Some say not the best. The other way is to strongly name the dll. I've see some pages on how to do this, but it will be different per site, so your whole site would have one number, and my another, so I'm not sure how you would want to do it off the network.
As far as closing the drawing it's called in, I don't think that would be a problem at all. Would you want it to prompt you to save if needs be? Or just discard the changes? I might be able to get to this today to test.
One work around is to copy the .Net dll to all work stations. Then define a lisp routine with the same name as the two functions within the dll. Within the lisp routines call netload to load the dll. Since commands defined within dll have a higher priority than lisp routines, the lisp routines will only work once per session. I think there was a post about this in the .Net forum, and it works here.
Edit: Found thread about lisp. (http://www.theswamp.org/index.php?topic=14689.0)
-
Tim
As far as closing the drawing it's called in, I don't think that would be a problem at all. Would you want it to prompt you to save if needs be? Or just discard the changes? I might be able to get to this today to test.
No prompt needed, if we make any changes we would save them before using the "next" or "previous" commands. This way we would only have a max of two drawings open at a time.
As far as having the dll on the network, we can live with it on the local drive, down loaded to each workstation.
As much as we use this routine, it has been a great time saver. The old lisp routine was just too prone to crashing.
Thanks for all of your hard work and supporting the swamp.
Gary
-
Here is the quick and dirty way. I'll do some more research to figure out a better way.
You're welcome. As far as theSwamp goes, I'm just happy to have a place where I can learn, and in turn help out others.
/*
* Created by SharpDevelop.
* User: Tim Willey
* Date: 3/18/2008
* Time: 4:17 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
[assembly: CommandClass (typeof (Test.OpenNextPrevious))]
namespace Test
{
/// <summary>
/// Description of OpenNextPrevious.
/// </summary>
class MyStringCompare {
public MyStringCompare () {}
public static int Compare (object obj1, object obj2) {
string str1 = (string)obj1, str2 = (string)obj2;
int i1 = 0,
i2 = 0,
CompareResult,
l1 = str1.Length,
l2 = str2.Length,
tempI1,
tempI2;
string s1, s2;
bool b1, b2;
while (true) {
b1 = Char.IsDigit(str1, i1);
b2 = Char.IsDigit(str2, i2);
if ( !b1 && b2 )
return -1;
if ( b1 && !b2 )
return 1;
if (b1 && b2) {
FindLastDigit(str1, ref i1, out s1);
FindLastDigit(str2, ref i2, out s2);
tempI1 = Convert.ToInt32(s1);
tempI2 = Convert.ToInt32(s2);
if ( tempI1.Equals(tempI2) )
CompareResult = 0;
else if (tempI1 < tempI2)
CompareResult = -1;
else
CompareResult = 1;
if ( !CompareResult.Equals(0) )
return CompareResult;
}
else {
FindLastLetter(str1, ref i1, out s1);
FindLastLetter(str2, ref i2, out s2);
CompareResult = string.Compare(s1, s2);
if ( !CompareResult.Equals(0) )
return CompareResult;
}
if (l1 <= i1) {
if (l2 <= i2) {
return 0;
}
else {
return -1;
}
}
if (l2 <= i2) {
if (l1 < i1) {
return 0;
}
else {
return 1;
}
}
}
}
private static void FindLastLetter (string MainStr, ref int i, out string OutStr) {
int StartPos = i;
int StrLen = MainStr.Length;
++i;
while ( i < StrLen && !Char.IsDigit(MainStr, i) )
++i;
OutStr = MainStr.Substring(StartPos, i - StartPos);
}
private static void FindLastDigit (string MainStr, ref int i, out string OutStr) {
int StartPos = i;
int StrLen = MainStr.Length;
++i;
while ( i < StrLen && Char.IsDigit(MainStr, i) )
++i;
OutStr = MainStr.Substring(StartPos, i - StartPos);
}
}
public class OpenNextPrevious
{
[CommandMethod("MyNext", CommandFlags.Session)]
public void OpenNext()
{
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
Document Doc = AcadApp.DocumentManager.MdiActiveDocument;
Doc.CloseAndDiscard();
OpenDrawing(1, DwgPath, DwgName);
}
[CommandMethod("MyPrevious", CommandFlags.Session)]
public void OpenPrevious()
{
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
Document Doc = AcadApp.DocumentManager.MdiActiveDocument;
Doc.CloseAndDiscard();
OpenDrawing(-1, DwgPath, DwgName);
}
public void OpenDrawing (int ToOpen, string DwgPath, string DwgName) {
Document Doc = null;
DocumentCollection DocCol = AcadApp.DocumentManager;
//string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
//string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
string FullPath = DwgPath + DwgName;
string[] DwgList = Directory.GetFiles(DwgPath, "*.dwg");
Array.Sort(DwgList, new MyStringCompare1());
int cNum = Array.IndexOf(DwgList, FullPath);
if ( ToOpen.Equals(1) ) {
if ( cNum.Equals(DwgList.Length - 1) ) {
MessageBox.Show("Already at the last drawing in the folder.", "Not really an error.");
return;
}
}
else {
if ( cNum.Equals(0) ) {
MessageBox.Show("Already at the first drawing in the folder.", "Not really an error.");
return;
}
}
string Path = DwgList[cNum + ToOpen];
foreach (Document doc in DocCol) {
if (string.Compare(Path, doc.Name, true).Equals(0)) {
Doc = doc;
break;
}
}
if (Doc != null)
DocCol.MdiActiveDocument = Doc;
else
DocCol.Open(Path, false);
}
public class MyStringCompare1 : IComparer {
public MyStringCompare1 () {}
public int Compare (object x, object y) {
return MyStringCompare.Compare( x,y );
}
}
}
}
-
AWESOME
-
AWESOME
:-)
-
Tim
I know this is an old subject. I just noticed that the routine next and previous is case sensitive in opening the next drawing in a folder.
For example:
A7.01
A7.02
a7.03
A7.04
The routine would skip over the lowercase a7.03
Can this be easily fixed? Or do I need to rename my drawing to always be uppercase first letters.
Gary
-
It might be an easy fix, I don't know really. If I have time I'll look at the sorting function, and see what is happening.
-
It might be an easy fix, I don't know really. If I have time I'll look at the sorting function, and see what is happening.
Thanks
-
Was a really simple fix. Edited one line in the sort function to ignore case, and then recompile.
Edit: Forgot to mention that I added two other functions, so now you can close the current drawing when switching to the next/previous drawing.
/*
* Created by SharpDevelop.
* User: Tim Willey
* Date: 3/18/2008
* Time: 4:17 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
[assembly: CommandClass (typeof (Test.OpenNextPrevious))]
namespace Test
{
/// <summary>
/// Description of OpenNextPrevious.
/// </summary>
class MyStringCompare {
public MyStringCompare () {}
public static int Compare (object obj1, object obj2) {
string str1 = (string)obj1, str2 = (string)obj2;
int i1 = 0,
i2 = 0,
CompareResult,
l1 = str1.Length,
l2 = str2.Length,
tempI1,
tempI2;
string s1, s2;
bool b1, b2;
while (true) {
b1 = Char.IsDigit(str1, i1);
b2 = Char.IsDigit(str2, i2);
if ( !b1 && b2 )
return -1;
if ( b1 && !b2 )
return 1;
if (b1 && b2) {
FindLastDigit(str1, ref i1, out s1);
FindLastDigit(str2, ref i2, out s2);
tempI1 = Convert.ToInt32(s1);
tempI2 = Convert.ToInt32(s2);
if ( tempI1.Equals(tempI2) )
CompareResult = 0;
else if (tempI1 < tempI2)
CompareResult = -1;
else
CompareResult = 1;
if ( !CompareResult.Equals(0) )
return CompareResult;
}
else {
FindLastLetter(str1, ref i1, out s1);
FindLastLetter(str2, ref i2, out s2);
[color=red]CompareResult = string.Compare(s1, s2, true);[/color]
if ( !CompareResult.Equals(0) )
return CompareResult;
}
if (l1 <= i1) {
if (l2 <= i2) {
return 0;
}
else {
return -1;
}
}
if (l2 <= i2) {
if (l1 < i1) {
return 0;
}
else {
return 1;
}
}
}
}
private static void FindLastLetter (string MainStr, ref int i, out string OutStr) {
int StartPos = i;
int StrLen = MainStr.Length;
++i;
while ( i < StrLen && !Char.IsDigit(MainStr, i) )
++i;
OutStr = MainStr.Substring(StartPos, i - StartPos);
}
private static void FindLastDigit (string MainStr, ref int i, out string OutStr) {
int StartPos = i;
int StrLen = MainStr.Length;
++i;
while ( i < StrLen && Char.IsDigit(MainStr, i) )
++i;
OutStr = MainStr.Substring(StartPos, i - StartPos);
}
}
public class OpenNextPrevious
{
[CommandMethod("MyNext", CommandFlags.Session)]
public void OpenNext()
{
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
OpenDrawing(1, DwgPath, DwgName, false);
}
[CommandMethod("MyNextAndCloseCurrent", CommandFlags.Session)]
public void OpenNextAndCloseCurrent()
{
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
//AcadApp.DocumentManager.MdiActiveDocument.CloseAndDiscard();
OpenDrawing(1, DwgPath, DwgName, true);
}
[CommandMethod("MyPrevious", CommandFlags.Session)]
public void OpenPrevious()
{
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
OpenDrawing(-1, DwgPath, DwgName, false);
}
[CommandMethod("MyPreviousAndCloseCurrent", CommandFlags.Session)]
public void OpenPreviousAndCloseCurrent()
{
string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
//AcadApp.DocumentManager.MdiActiveDocument.CloseAndDiscard();
OpenDrawing(-1, DwgPath, DwgName, true);
}
public void OpenDrawing (int ToOpen, string DwgPath, string DwgName, bool CloseCurrent) {
Document Doc = null;
DocumentCollection DocCol = AcadApp.DocumentManager;
//string DwgPath = AcadApp.GetSystemVariable("DwgPrefix") as string;
//string DwgName = AcadApp.GetSystemVariable("DwgName") as string;
string FullPath = DwgPath + DwgName;
string[] DwgList = Directory.GetFiles(DwgPath, "*.dwg");
MyStringCompare1 msc1 = new MyStringCompare1();
Array.Sort(DwgList, msc1);
int cNum = Array.IndexOf(DwgList, FullPath);
if ( ToOpen.Equals(1) ) {
if ( cNum.Equals(DwgList.Length - 1) ) {
MessageBox.Show("Already at the last drawing in the folder.", "Not really an error.");
return;
}
}
else {
if ( cNum.Equals(0) ) {
MessageBox.Show("Already at the first drawing in the folder.", "Not really an error.");
return;
}
}
if ( CloseCurrent )
AcadApp.DocumentManager.MdiActiveDocument.CloseAndDiscard();
string Path = DwgList[cNum + ToOpen];
foreach (Document doc in DocCol) {
if (string.Compare(Path, doc.Name, true).Equals(0)) {
Doc = doc;
break;
}
}
if (Doc != null)
DocCol.MdiActiveDocument = Doc;
else
DocCol.Open(Path, false);
}
}
}
-
Thanks Tim
Is this one compatable for all versions? Just to be sure I renamed it to NextPrev18.dll
The last one I used this to load it: NextPrev18.reg
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R18.0\ACAD-8001:409\Applications\NextPrev18\Groups]
"Support"="Support"
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R18.0\ACAD-8001:409\Applications\NextPrev18]
"DESCRIPTION"="Next Previous Drawing in the Directory"
"LOADCTRLS"=dword:00000004
"LOADER"="C:\\Arch_Custom\\Support\\NextPrev18.dll"
"MANAGED"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Autodesk\AutoCAD\R18.0\ACAD-8001:409\Applications\NextPrev18\Commands]
"MyNext"="MyNext"
"MyPrevious"="MyPrevious"
Works great Tim, thanks again.
-
It should be, as I don't think there is anything specific to any version. Just know that it will not save the current drawing if you use one of the new commands.