Lately I have been writing a lot of selection and list programs, and one that I have written was for engineers to list out valves, control valves, and equipment for projects to be able to send them out for quoting and design purposes. One issue that I ran into was being able to get the DataGridView to print each line that is entered into the grid. But, I was able to find a bit of code and with a few modifications of my own...I was able to get it to print all lines entered into the grid, and also allow the programmer to change location of the grid on the printdocument file.
So, below is the code for the datagridview:
Dim mRow As Integer = 0
Dim newpage As Boolean = True
Private Sub PrintDocument1_PrintPage(sender As System.Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim tmpSize As New SizeF()
Dim tmpFont As Font
For i As Integer = 0 To DataGridView1.Columns.Count()
tmpFont = DataGridView1.ColumnHeadersDefaultCellStyle.Font
If tmpFont Is Nothing Then
tmpFont = DataGridView1.DefaultCellStyle.Font
End If
For j As Integer = 0 To DataGridView1.Rows.Count - 1
tmpFont = DataGridView1.Rows(j).DefaultCellStyle.Font
If tmpFont Is Nothing Then
tmpFont = DataGridView1.DefaultCellStyle.Font
End If
Next
Next
Dim cellsPerRow As New List(Of Integer)
Dim rowHeight As Integer = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(0).Height
Dim cellWidths(DataGridView1.Columns.Count - 1) As Integer
Dim rowWidths As New List(Of Integer)
Dim cellCounter As Integer = 0
With DataGridView1
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment =
StringAlignment.Center
fmt.Trimming =
StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top + 120
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If (newpage) Then
e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, .Font,
Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h =
Math.Max(h, rc.Height)
Next
newpage =
False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages =
True
mRow -= 1
newpage =
True
Exit Sub
End If
Loop
mRow = 0
End With
End Sub
So, the bit of code that is highlighted in yellow is where you can control the vertical location of the grid on the printdocument. Also if you want to change the location of the grid horizontally then; three lines below "dim y" there is the code line for the "dim x as single" you can change the value of that to change the horizontal location of the grid.
Happy Coding!
Wednesday, December 5, 2012
Wednesday, November 28, 2012
Dim extension lines set to center linetype...
So, I asked one of the guys that I work with about macros that he would want in AutoCAD to make things easier. And one of the things that he said would be nice is if you could write a macro that would change the extension line of the placed dimension to center linetype.
I had never heard of this being used, but I took the task on. What I found is that there are two ways to do this.
The first way is:
*^c^c-dimstyle;r;;_dimlinear;
Now the dimstyle that is used has the extension lines set to center linetype.
Now the other way to do this is:
*^c^cdimltex1;center;dimltec2;center;_dimlinear;-dimstyle;r;standard;
This just overrides the standard style to make the extension lines center linetype and then at the end we restore the original standard dimstyle.
So, if this is something that you do then. Hopefully this is something that helps you.
I had never heard of this being used, but I took the task on. What I found is that there are two ways to do this.
The first way is:
*^c^c-dimstyle;r;
Now the dimstyle that is used has the extension lines set to center linetype.
Now the other way to do this is:
*^c^cdimltex1;center;dimltec2;center;_dimlinear;-dimstyle;r;standard;
This just overrides the standard style to make the extension lines center linetype and then at the end we restore the original standard dimstyle.
So, if this is something that you do then. Hopefully this is something that helps you.
Tuesday, November 27, 2012
Letter automation...explained a little...
*^C^C_text;\;$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)$(if,$(>=,$(getvar,userr1),15),$(nth,$(getvar,userr4), Q, R, S, T, U, V, W, X),)$(if,$(>=,$(getvar,userr1),23),$(nth,$(getvar,userr5), Y, Z, AA, AB, AC, AD, AE, AF),);setvar;userr1;$M=$(+,$(getvar,USERR1),$(getvar,USERR2));setvar;userr3;
$M=$(+,$(getvar,USERR3),$(getvar,USERR2));
userr4;$M=$(+,$(getvar,USERR4),$(getvar,USERR2));
userr5;$M=$(+,$(getvar,USERR5),$(getvar,USERR2));
SETVAR;USERR3;\SETVAR;USERR4;\SETVAR;USERR5;\
So, above is the code that I had posted earlier for a somewhat automated lettering macro.
Now, I am going to explain how it works. First, we know that you start with the text command and go through all the prompts for it.
Then we work our way into the diesel portion of the macro...so, when developing this I found out that when using the "nth" function by itself you were limited to 7 arguments within the function.
Hence, why I embedded the "nth" function within multiple if statements.
Let's dissect these if statements a little:
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
so, in this first "if statement" I am telling it to evaluate the value of userr1.
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
If a value of 7 or less is returned then it moves on to this nth function where i am again calling for the value of userr1.
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
you will find a recurring theme throughout these if statements that we are evaluating the value of userr1...here we are looking to see if the value of userr1 is greater than or equal to 8.
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
If it returns a value of 8 or greater then it will move on to the next nth statement where we call for the value of userr3.
And this process repeats 2 more times with userr4, and userr5. One thing that you should notice is that the value to be returned from userr1 increase by a value of 8 with each "if statement".
Now that we are done with the if statements we can move on to the easier portions of the macro...how the values of the userr variables increase with each repetition of the command.
setvar;userr1;$M=$(+,$(getvar,USERR1),$(getvar,USERR2))
This code will be repeated four times...you will just have to copy and paste and then replace userr1 with userr3, userr4 or userr5.
And then the prompting for user input of the userr variables finishes out the macro.
Hope that this helped to clarify the process of the macro.
$M=$(+,$(getvar,USERR3),$(getvar,USERR2));
userr4;$M=$(+,$(getvar,USERR4),$(getvar,USERR2));
userr5;$M=$(+,$(getvar,USERR5),$(getvar,USERR2));
SETVAR;USERR3;\SETVAR;USERR4;\SETVAR;USERR5;\
So, above is the code that I had posted earlier for a somewhat automated lettering macro.
Now, I am going to explain how it works. First, we know that you start with the text command and go through all the prompts for it.
Then we work our way into the diesel portion of the macro...so, when developing this I found out that when using the "nth" function by itself you were limited to 7 arguments within the function.
Hence, why I embedded the "nth" function within multiple if statements.
Let's dissect these if statements a little:
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
so, in this first "if statement" I am telling it to evaluate the value of userr1.
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
If a value of 7 or less is returned then it moves on to this nth function where i am again calling for the value of userr1.
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
you will find a recurring theme throughout these if statements that we are evaluating the value of userr1...here we are looking to see if the value of userr1 is greater than or equal to 8.
$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)
If it returns a value of 8 or greater then it will move on to the next nth statement where we call for the value of userr3.
And this process repeats 2 more times with userr4, and userr5. One thing that you should notice is that the value to be returned from userr1 increase by a value of 8 with each "if statement".
Now that we are done with the if statements we can move on to the easier portions of the macro...how the values of the userr variables increase with each repetition of the command.
setvar;userr1;$M=$(+,$(getvar,USERR1),$(getvar,USERR2))
This code will be repeated four times...you will just have to copy and paste and then replace userr1 with userr3, userr4 or userr5.
And then the prompting for user input of the userr variables finishes out the macro.
Hope that this helped to clarify the process of the macro.
Somewhat automated lettering...(diesel macro)
I built this macro this morning upon a challenge issued to me yesterday.
To those who would like some way to automate lettering in AutoCAD LT...here is a Diesel Macro for LT that will allow you to atleast automate up to "AF":
*^C^C_text;\;$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)$(if,$(>=,$(getvar,userr1),15),$(nth,$(getvar,userr4), Q, R, S, T, U, V, W, X),)$(if,$(>=,$(getvar,userr1),23),$(nth,$(getvar,userr5), Y, Z, AA, AB, AC, AD, AE, AF),);setvar;userr1;$M=$(+,$(getvar,USERR1),$(getvar,USERR2));setvar;userr3;
$M=$(+,$(getvar,USERR3),$(getvar,USERR2));
userr4;$M=$(+,$(getvar,USERR4),$(getvar,USERR2));
userr5;$M=$(+,$(getvar,USERR5),$(getvar,USERR2));
SETVAR;USERR3;\SETVAR;USERR4;\SETVAR;USERR5;\
This macro requires more input on the users part than the number automation, but it works for a small amount of lettering.
Before you run the command for the first time you need to make sure that your userr1 is set to a value of 0, and that your userr2 is set to a value of 1 (which is for the incrementing).
When you run the command and you place the first letter; you will notice that it prompts you for the userr3, userr4, and userr5 values...just enter through these for now because you won't mess with them until a little further on.
Now, one thing that you need to keep in mind is the letters that are associated with which userr variable:
To those who would like some way to automate lettering in AutoCAD LT...here is a Diesel Macro for LT that will allow you to atleast automate up to "AF":
*^C^C_text;\;$m=$(if, $(<=,$(getvar,userr1),7),$(nth,$(getvar,userr1), A, B, C, D, E, F, G, H),$(if,$(>=,$(getvar,userr1),8),$(nth,$(getvar,userr3), I, J, K, L, M, N, O, P)),)$(if,$(>=,$(getvar,userr1),15),$(nth,$(getvar,userr4), Q, R, S, T, U, V, W, X),)$(if,$(>=,$(getvar,userr1),23),$(nth,$(getvar,userr5), Y, Z, AA, AB, AC, AD, AE, AF),);setvar;userr1;$M=$(+,$(getvar,USERR1),$(getvar,USERR2));setvar;userr3;
$M=$(+,$(getvar,USERR3),$(getvar,USERR2));
userr4;$M=$(+,$(getvar,USERR4),$(getvar,USERR2));
userr5;$M=$(+,$(getvar,USERR5),$(getvar,USERR2));
SETVAR;USERR3;\SETVAR;USERR4;\SETVAR;USERR5;\
This macro requires more input on the users part than the number automation, but it works for a small amount of lettering.
Before you run the command for the first time you need to make sure that your userr1 is set to a value of 0, and that your userr2 is set to a value of 1 (which is for the incrementing).
When you run the command and you place the first letter; you will notice that it prompts you for the userr3, userr4, and userr5 values...just enter through these for now because you won't mess with them until a little further on.
Now, one thing that you need to keep in mind is the letters that are associated with which userr variable:
userr1 - starts at A and ends with H
userr3 - starts at I and ends with P
userr4 - starts at Q and ends with X
userr5 - starts at Y and ends with AF
knowing this will help with understanding when to change variable values as you keep going up the alphabet. So, for example, once you place an "H"; when the prompt for userr3 appears change it to a value of 0. Once this is done you don't have to edit it anymore; you can just keep hitting enter through the variables until the end of that letter set on the userr variable.
On another note:
If you are a AutoCAD non-Lt user then the text command is a little different for you.
Instead of:
*^c^c_text;\;
You will have this:
*^c^c_text;\;;
And then if you want to add justification to it (for example...middle center justification)
*^c^c_text;j;mc;\;;
If anyone uses this macro and has issues please comment and let us know what changes you had to make to the macro.
Thank you for reading this post!
Monday, November 26, 2012
3 line date stamp...
Here is a quick and easy way to insert a textblock with username, date, and time.
^C^C_text;\;BY: $m=$(GETVAR,LOGINNAME);;;Date: $m=$(edtime,$(getvar,date),MO"/"dd"/"yy);;;Time: $m=$(edtime,$(getvar,date),HH:MMam/pm);
Yet again, this is another code for the AutoCAD LT users out there, but also works on Full version AutoCAD. The only difference for the non-LT users is that the beginning of the code is going to be as follows:
^c^c_text;j;mc;\;0;BY: $m=$(GETVAR,LOGINNAME);;;Date: $m=$(edtime,$(getvar,date),MO"/"dd"/"yy);;;Time: $m=$(edtime,$(getvar,date),HH:MMam/pm);
And then your finished product will be:
p.s. you won't have the line under the date...that is just my crosshair that got in the way...
^C^C_text;\;BY: $m=$(GETVAR,LOGINNAME);;;Date: $m=$(edtime,$(getvar,date),MO"/"dd"/"yy);;;Time: $m=$(edtime,$(getvar,date),HH:MMam/pm);
Yet again, this is another code for the AutoCAD LT users out there, but also works on Full version AutoCAD. The only difference for the non-LT users is that the beginning of the code is going to be as follows:
^c^c_text;j;mc;\;0;BY: $m=$(GETVAR,LOGINNAME);;;Date: $m=$(edtime,$(getvar,date),MO"/"dd"/"yy);;;Time: $m=$(edtime,$(getvar,date),HH:MMam/pm);
And then your finished product will be:
p.s. you won't have the line under the date...that is just my crosshair that got in the way...
Autocad macro...calling coordinate points on blocks
One thing that always comes up when creating P&ID's is; "how can you make it simplier to insert blocks and not have to take the time to do all the trimming of the lines once the block is in?"
I was actually able to create a couple of ways that allowed AutoCAD LT users and full version AutoCAD users to be able to do this. I have posted the LT version with the diesel macro, but today I am going to go over the lisp routine route.
Below you will see today's code that we are going to go over:
*^c^cattdia;0;^c^c_.insert;CHECK;\;1;\;;^C(setq edata (entget (setq en (entlast))));^c^cbreak;\f;(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));^c^cattdia;1;^c
Okay...let's dive into this.
It isn't as overwhelming as it looks...it is actually quite simple.
So, first we are calling the attdia command and setting it to 0. We are doing this so that the 2 attributes that are attached to the block won't show up with a dialog prompt box.
Next we start the insert command and in this example we are inserting a check valve.
CHECK;\;1;\;; - the forward slash is to prompt for user input and this is for the insertion point.
CHECK;\;1;\;; - here we are telling it what scale the block is going to be inserted at.
CHECK;\;1;\;; - This is to set the rotation of the block...another user input prompt.
CHECK;\;1;\;; - and these last two semicolons are to enter through the 2 attributes that are attached to
the block.
Next, we will be going into the routine that recalls the block and calls for the point locations.
^C(setq edata (entget (setq en (entlast)))) - here we are telling AutoCAD to look up the last block that was inserted.
Now we call on the break command with the fence option.
^c^cbreak;\f;
Now comes the fun part of calling for the attribute points.
(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));^c^cattdia;1;
For both points the code is the same, so once you type it once you will be able to copy and paste for the second point, and you can see that by the semicolon that has been made bold and underlined to help you see it.
But here is the code:
(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)))
the first (setq) grouping is calling for the bp1 attribute in the check valve block, and then the second (setq) grouping is what returns the coordinate values of the attribute, and then establishes the first point.
Now all you got to do is add a semicolon and then copy and paste the code for the second point and then end it with a semicolon and you are done.
Happy Trimming...
I was actually able to create a couple of ways that allowed AutoCAD LT users and full version AutoCAD users to be able to do this. I have posted the LT version with the diesel macro, but today I am going to go over the lisp routine route.
Below you will see today's code that we are going to go over:
*^c^cattdia;0;^c^c_.insert;CHECK;\;1;\;;^C(setq edata (entget (setq en (entlast))));^c^cbreak;\f;(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));^c^cattdia;1;^c
Okay...let's dive into this.
It isn't as overwhelming as it looks...it is actually quite simple.
So, first we are calling the attdia command and setting it to 0. We are doing this so that the 2 attributes that are attached to the block won't show up with a dialog prompt box.
Next we start the insert command and in this example we are inserting a check valve.
CHECK;\;1;\;; - the forward slash is to prompt for user input and this is for the insertion point.
CHECK;\;1;\;; - here we are telling it what scale the block is going to be inserted at.
CHECK;\;1;\;; - This is to set the rotation of the block...another user input prompt.
CHECK;\;1;\;; - and these last two semicolons are to enter through the 2 attributes that are attached to
the block.
Next, we will be going into the routine that recalls the block and calls for the point locations.
^C(setq edata (entget (setq en (entlast)))) - here we are telling AutoCAD to look up the last block that was inserted.
Now we call on the break command with the fence option.
^c^cbreak;\f;
Now comes the fun part of calling for the attribute points.
(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)));^c^cattdia;1;
For both points the code is the same, so once you type it once you will be able to copy and paste for the second point, and you can see that by the semicolon that has been made bold and underlined to help you see it.
But here is the code:
(setq edata (entget (entnext (cdr (assoc -1 edata)))))(setq ip1 (cdr (assoc 10 edata)))
the first (setq) grouping is calling for the bp1 attribute in the check valve block, and then the second (setq) grouping is what returns the coordinate values of the attribute, and then establishes the first point.
Now all you got to do is add a semicolon and then copy and paste the code for the second point and then end it with a semicolon and you are done.
Happy Trimming...
Thursday, November 22, 2012
Setting environment variables...
When setting environment variables there are different ways of setting them depending on whether you are using full version AutoCAD or AutoCAD LT. To set an environment variable in AutoCAD you use the command...USERSx. X represents numbers 1-5. With AutoCAD LT you have to use...setenv. There are different environment variables when using this command. A couple of them are StrPrefix, and StrSuffix. You can use these with the diesel macros from the last couple posts for automated numbering.
Subscribe to:
Posts (Atom)

