TheSwamp
Code Red => VB(A) => Topic started by: David Hall on July 05, 2005, 11:35:49 AM
-
Ok, we are ready to move ahead and code something useful. I am thinking of a project that draws some lines, making sure that the proper layer is being used, and setting/changing the lineweights as needed to accopmplish this through a dialog box and command line. We will also need some error checking to make sure the user can't crash the whole system.
-
My first thoughts before we code anything are organizational thoughts:
1-What linetypes need to be loaded?
for now we will use Dash and Hidden to get started
2-What layers, if any, need to be created/set current?
I think we need 2 layers to go with our 2 linetypes. White and yellow on a black background works well
3-Ltscale / PsLtscale issues
I think we need to work at a scale of 1 for now b/c part of us are Metric, and the rest are imperial. Starting with 1 makes it easier for concepts to be conveyed. This also gives us some areas to set system var like Psltscale, Dimscale, and Ltscale
4-Do you want this to be dialog driven or command line driven?
Lets code for both
And finally, what does all this do? Lets draw a pline on a layer that uses the correct linetype, lineweight, and pline width.
-
Any ideas on how to get started?
-
When I get some time, I'll put something together
-
This is for everyone that wanted to learn VBA. Im looking for a discussion on what we should do to get started, and what needs to be done to accomplish the task.
-
I believe you already have something in mind, don't you? Why don't you just start it off. I'd think most people wouldn't know where to begin since we're mostly starting off at the edge of the pond and are reluctant to jump in with both feet.
-
Do you want us to pseudo code something, and then expand it from there?
Is that what you want us to do?
-
... most people wouldn't know where to begin since we're mostly starting off at the edge of the pond and are reluctant to jump in with both feet.
<raising hand>....uuuhhh... that'd be me, for one.
CmdrDuh, your suggestions sound good to me. Just something to draw some lines. Simple, sweet, easy...
-
My thoughts are that we need to outline what it is we want our code to do, then we need to figure out what it affects as far as system variables and other settings. Then we can start coding. :)
-
My thoughts are that we need to outline what it is we want our code to do, then we need to figure out what it affects as far as system variables and other settings. Then we can start coding. :)
Exactly!!!
So, what do we want to do?
I have a list of reqirements for a simple project that we can work on. Here (http://www.theswamp.org/phpBB2/viewtopic.php?p=70536#70536)
-
Lets make small modules that we can test, then combine them all into a larger program. Lets start by loading some line types. Dashed and Hidden to get started.
I'll start us off
Public Sub LLine()
End Sub
For those that are coding (read following) along, put this in the ThisDrawing Module of a new project. (For anyone needing help getting a new project started or help locating this, PM me)
What goes between the first and last line I posted? I'll give you a hint. We are going to use a method inside of ThisDrawing to load our linetypes, so ......
Public Sub LLine()
ThisDrawing.
End Sub
If you type that in, and hit the DOT (period) after ThisDrawing, you will get a list of methods we can access. Lets see who can figure out what goes next.
-
Somehow, I'm thinking this
ThisDrawing.Linetypes.Load=("Hidden, Dashed" "acad.lin")
but I'm not getting it quite right. What am I doing wrong?
-
Somehow, I'm thinking this
ThisDrawing.Linetypes.Load=("Hidden, Dashed" "acad.lin")
but I'm not getting it quite right. What am I doing wrong?
Your very close! Enter stage right, Online Help. Now I hate online help as much as the next guy, I prefer books, so i can break the binding in all the right spots. KEY FEATURE is if you highlight what you want to search on and hit F1, it loads the help file. So highlight Linetypes.Load and hit F1
It is going to give you the definition, and to the right is See Example. Click that. it is going to give you and example similiar to this
Sub Example_Load()
' This example attempts to load the linetype "HIDDEN" from
' the acad.lin file. If the linetype already exists, then
' a message is displayed.
Dim linetypeName As String
linetypeName = "HIDDEN"
' Load "HIDDEN" line type from acad.lin file
On Error Resume Next ' trap any load errors
ThisDrawing.Linetypes.Load linetypeName, "acad.lin"
' If the name already exists, then notify user
If Err.Description = "Duplicate record name" Then
MsgBox "A line type named '" & linetypeName & "' already exists.", , "Load Example"
End If
End Sub
-
Something very important about the example is you DO NOT HAVE TO FOLLOW IT exactly.
Notice it took 3 lines to load a linetype in that example
Dim linetypeName As String
linetypeName = "HIDDEN"
ThisDrawing.Linetypes.Load linetypeName, "acad.lin"
The first line is declaring a variable as type String. Our name of the linetype is a string (Duh)
Second line sets the string to a value.
And finally, third line does the work.
It could have been done with one line-ThisDrawing.Linetypes.Load "HIDDEN", "ACAD.LIN"
-
Heh. I did that for Linetypes property, but I do see where I was going wrong. No parens.
-
Heh. I did that for Linetypes property, but I do see where I was going wrong. No parens.
and no = sign needed either
-
That too. I'd like to ask what's next, but I'd like to see the others who want to learn this stuff not fall behind. Are there any questions on how we got to the ThisDrawing module? Beuller?
-
Whats next you ask..... Well, what happens if you run your code twice?
-
It errors because there is no On error resume next or something like that. actually, since I already had those loaded, they errored out in the first place.
-
BTW, Dave, congrats on being able to control this place.
-
BTW, Dave, congrats on being able to control this place.
Thanks, I was a mod at another site for a few years, so I asked Mark if I could mod this forum only. When you posted your example with the code tag backwards, I was like..... eerrrrrggh, that is so frusterating not to be able to fix that. Fortunetly you saw and fixed it.
-
It errors because there is no On error resume next or something like that.
RIGHT! Now a word about On Error Resume Next
Gurus can chime in if you disagree, but this is the worst kind of error checking in my opinion. It does work, and it is better than nothing, but its the lazy way out. Someday, you will have a situation where you need to catch the error and deal with it, and if you use this all the time, it will pass through and you will have no chance to fix the problem.
Now why did the example use it you ask? Well, the people at Autodesk can in no way anticipate what you are going to do, and they know your going to copy and paste, so they put that in so when you run it for the first time, and your just learning VBA, it works. Your linetypes load, your happy, and you move on.
So what is a better way of catching the error? Use Select Case.
example to follow.
-
For the LISPers out there, Select Case works like the COND statement in lisp. From the Help File
Executes one of several groups of statements, depending on the value of an expression.
Syntax
Select Case testexpression
[Case expressionlist-n
[statements-n]] ...
[Case Else
[elsestatements]]
End Select
where the testexpression is what you are testing against. the Case Expression is the match value, and the statements is what to do
so here is an example
Dim A as interger
A=3
Select Case A
Case 1:
Msgbox "A = 1"
Case 2:
Msgbox "A = 2"
Case 3:
Msgbox "A = 3"
Case Else:
Msgbox "A is not in the List"
End Select
Now there is more that would go into our error checking, but does everyone get the idea?
-
I think so.
-
<Not wanting to get left behind>
Yeah, been kinda following this thread, but gotta do a lotta work today too. :(
Will play a little catch-up this evening.
-
<Not wanting to get left behind>
Im not going to cover much more today, as I want everyone who is following along to get a chance to work on this. IF you are so inclined (or bored) this weekend, add an error checking function in our LoadLineType function.
Use the error number, and return a message box to the user saying its already loaded. If any other number comes up, give the user a message box that has the error number and description.
There are good examples in the online help, and in the docs we have already posted in the Course forum. Im avail for PM and email this weekend as well.
-
:) thanks.
-
i have had a family emergency come up and will probably be unavailable this weekend. I will try and check in, but there is no guarentee. See you guys on Monday
-
Sorry to hear that David, see ya Monday.
-
Ill give an update as I can
-
Im back, and things are better than we had first heard. I'll leave it at that so we dont completely HiJack this thread
-
So did anyone think about code over the weekend? Was anyone able to come up with some error checking based on error number using Select Case?
-
Not me, sir. I helped with an eagle scout service project that wiped me out. I never slept so much as I have this past weekend.
-
Had to come back to work to get some rest? Been there and done that.
-
No, the project lasted from 8am to noon. When I got home I went to sleep. Sunday after church, I went to sleep again and no, I didn't fall asleep at church. Trying to keep kids quiet and still will keep you plenty active and awake. Anyway, let's get this back on track:
Get to those error traps. Good idea to introduce them early, Dave.
-
Based on This Post (http://www.theswamp.org/phpBB2/viewtopic.php?p=71290#71290) does anyone have an idea of how we can trap for errors in loading linetypes?
-
OK, so anyone have any ideas?
-
Given the example I posted earlier,
Dim A as interger
A=3
Select Case A
Case 1:
Msgbox "A = 1"
Case 2:
Msgbox "A = 2"
Case 3:
Msgbox "A = 3"
Case Else:
Msgbox "A is not in the List"
End Select
Lets look at what is going on in this code. First I have to create the variable, A, so Dim A as integer.
Im using an integer just as an example. Then Set A=3. So everyone agrees A=3 right? OK, now the
Select Case statement.
Select Case A - which means, evaluate A, and see if it matches any of the choices that follow.
Case 1: - which means Does A=1? No, so go to next case.
Case 2: Does A=2? No, go to next case
Case 3: Does A=3? Yes, so do what follows which is a messagebox that says A=3
Had A not equaled 1, 2, or 3, the Case Else: would have been used as a catch all, w/ a box that said A is not in list.
Now how could we use that logic and trap an error for loading a linetype?
Public Sub LLINE()
On Error GoTo ErrorHandler
. . . . .
End Sub
We start by telling the code to GoTo the ErrorHandler if there is a problem. Following this, we can begin coding our app.
At some point, we put in the error handler
Public Sub LLINE()
On Error GoTo ErrorHandler
ThisDrawing.Linetypes.Load "HIDDEN", "ACAD.LIN"
ThisDrawing.Linetypes.Load "DASHED", "ACAD.LIN"
Exit Sub
ErrorHandler:
. . . . . .
End Sub
OK, so we have told Vb to use the error handler if needed, and we go to our first line, which says load the Hidden linetype.
If the linetype is already loaded, VB will raise an error code, specifially code " -2145386405" which is what we want to trap on.
So,Public Sub LLINE()
On Error GoTo ErrorHandler
ThisDrawing.Linetypes.Load "HIDDEN", "J:\TEP SUPPORT\ACAD.LIN"
ThisDrawing.Linetypes.Load "DASHED", "J:\TEP SUPPORT\ACAD.LIN"
Exit Sub
ErrorHandler:
Select Case Err
Case -2145386405:
Err.Clear
Resume Next
Case Else:
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Select
End Sub
So if Err = -2145386405, Clear the Err and then resume the program with the next line.
Knowing that the error was caused by the linetype already being loaded, we can trap that and move on without the user seeing
an error message.
Was everybody able to generate an error message before? Was the number the same? It should have been, because that is the number for duplicate linetypes
-
Was everybody able to generate an error message before? Was the number the same?
Yes to both.
On the code you posted. I still get the error dialog when I run the program. Or are we supposed to.
-
no, your not supposed to, what code did you type in? the -2145386405 number was the one we were searching for. Can you post your code?
-
I used your code two posts up.
In the dialog I get
run-time error '-2145386405 (8020005b)':
duplicate record name
-
I could have typoed as well hold on
-
in the IDE, go to Tools->Options, General Tab, Error Trapping, Are you set on Break on all errors? Set to Break on UnHandled Errors
-
in the IDE, go to Tools->Options, General Tab, Error Trapping, Are you set on Break on all errors? Set to Break on UnHandled Errors
That worked. :oops:
-
Dont feel bad. That one had me stumped for days when I got started
-
For everyone following along, Were you able to load linetype without errors? If you got an error, was it resolved by switching to Unhandled errors only? We are going to move to Layers next, if no one has questions about loading linetypes.
-
If you are comefortable, move on to Step 2 (http://www.theswamp.org/phpBB2/viewtopic.php?t=5888)
-
For those that are done and want a PDF, here (http://www.theswamp.org/~vbac/Linetype%20Sub.pdf) it is.
-
Sorry for the absence, heavy work load this week.
:( I had to reread your primers on how to
work the blasted IDE. (good stuff btw-thanks)
For some unknown reason, I crashed my 'pooters both here at home and at work. Don't know what it was, but "I'm feeling much better now." :)
Ok, here we go with the ketchup questions, or WILT:
Public Sub LLine()
the "LLine" could be anything I want? Kinda like defun ---?
ThisDrawing
Is this an example of the camel case you mentioned before? Not absolutely necessary from a syntax standpoint but just considered "good form"?
I tried using a "on error resume next", just like you said NOT to and it didn't seem to work. Kept getting an error message "duplicate record name". No code number. Shouldn't this work for such a simple macro?
Woops. Maybe cause i had thisPublic Sub LLINE()
ThisDrawing.Linetypes.Load "HIDDEN", "ACAD.LIN"
ThisDrawing.Linetypes.Load "DASHED", "ACAD.LIN"
On Error Resume Next
End Sub
instead of thisPublic Sub LLINE()
On Error Resume Next
ThisDrawing.Linetypes.Load "HIDDEN", "ACAD.LIN"
ThisDrawing.Linetypes.Load "DASHED", "ACAD.LIN"
End Sub
Tools->Options, General Tab, Error Trapping, Break on UnHandled Errors. <---Should this 'generally' be set as a default in the IDE? Or is that "a question that really doesn't need to be asked" at this point?
I was just saving the macro code in the drawing file itself, and then toggling to acad, & alt+F8, rather than saving the file out to a directory as <filename.dvb> and then appload-ing from acad. What is the difference between these two methods? As far as I can tell, they do the same thing.
Is the first method only available in that specific drawing, and I won't be able to use it from another drawing file? When is one preferred over the other?
Finally, Case Else:
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
I don't understand what this does. I mean, if the macro tries... wait, is this just a "catch all" kinda thing to throw up an error message for any OTHER (ie not error code -2145386405) type of error that may be encountered?
Otherwsie, I seem to have it working. Not sure I really know much more than I did before, but it sure feels like it!
Oh, one other thing. That drop down thingy when you hit the 'dot' is pretty cool... or so it seems at this point.
Thanks for the patience. Moving on to step 2 now. :)
-
Sorry for the absence, heavy work load this week.
Better late than never..
Public Sub LLine()
the "LLine" could be anything I want? Kinda like defun ---?
Yes it could have been Public Sub Bird-Lines()
ThisDrawing
Is this an example of the camel case you mentioned before? Not absolutely necessary from a syntax standpoint but just considered "good form"?
yes and no, In this case, VBA is/will going to fix whatever you type to fit the notation. Where you should be concentrating on is how you want to
name your variables that VBA does not auto handle i.e. strDrawingName for a string for the Drawing name
I tried using a "on error resume next", just like you said NOT to and it didn't seem to work. Kept getting an error message "duplicate record name". No code number. Shouldn't this work for such a simple macro?
Woops. Maybe cause i had thisPublic Sub LLINE()
ThisDrawing.Linetypes.Load "HIDDEN", "ACAD.LIN"
ThisDrawing.Linetypes.Load "DASHED", "ACAD.LIN"
On Error Resume Next
End Sub
instead of thisPublic Sub LLINE()
On Error Resume Next
ThisDrawing.Linetypes.Load "HIDDEN", "ACAD.LIN"
ThisDrawing.Linetypes.Load "DASHED", "ACAD.LIN"
End Sub
Tools->Options, General Tab, Error Trapping, Break on UnHandled Errors. <---Should this 'generally' be set as a default in the IDE?
OK, first, it kept giving you the box b/c we were breaking on ALL errors.
This was a setting I should have had everyone set before. Yes it shold be default, at some point. I know that sounds vauge,(sp) but it depends on
your comfort level. The difference between the 2 settings is 1 breaks on every error(duh) and the other breaks on any un-handled error.
What that means in a nutshell is break if I didnt try to catch it. Does that make sense?
As to the second part of that question, it didn't work in the first ex b/c you raised an error before you told it to resume if an error came up.
thats why it worked in the second ex. You told it to resume, and it did
Finally, Case Else:
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
I don't understand what this does. I mean, if the macro tries... wait, is this just a "catch all" kinda thing to throw up an error message for any OTHER (ie not error code -2145386405) type of error that may be encountered?
Yes, its a catch all
-
Thanks for the feedback. I actually feel like I DID learn something.
What that means in a nutshell is break if I didnt try to catch it. Does that make sense?
Yep.