Visual Basic code to create a G-Code

Visual Basic code to create a G-Code

Thomas_Savage
Advisor Advisor
5,896 Views
8 Replies
Message 1 of 9

Visual Basic code to create a G-Code

Thomas_Savage
Advisor
Advisor

Hello,

 

I am asking here for a work colleague. He uses AutoCAD 2008.

 

We use G-coder. And he uses AutoCAD to design his models. In sheet metal.

 

He then flat patterns the sheet metal parts.

 

Then he places all the tools round the part, as a block.

 

He then selects each tool, and manually types in the x and y coordinates, and angle in to G-Coder.

 

If we select all the tools, and type list, it brings up all the x and y coordinates, and the angle. Of all the tools.

 

Does anyone have a code which could extract all the x and y coordinates, and angles to create a G-Code. So they don't have to be typed manually?

 

It is for a Amada Punch.

 

Any help much appreciated.

 

Thomas.



Thomas Savage

Design Engineer


0 Likes
5,897 Views
8 Replies
Replies (8)
Message 2 of 9

norman.yuan
Mentor
Mentor
Accepted solution

Based on your short description, I assume what you want is to collect the coordinates of certain blocks ("tools"), possibly the blocks' insertion point.

 

It should be rather simple to do, if the block name is known. 

 

Here is sample code that shows target block's position, assuming the blocks are in ModelSpace

 

Dim ent as AcadEntity

Dim blk As BlockReference

 

For Each ent in ThisDrawing.ModelSpace

    If TypeOf ent Is AcadBlockReference Then

        Set blk=ent

        If UCase(blk.EffectiveName)="MYTOOL" Then

            MsgBox "MYTOOL:" & VbCrlf & _

                "X: " & blk.InsertionPoint(0) & VbCrLf & _

                "Y: " & blk.InsertionPoint(1) & VbCrLf & _

                "Angle: " & blk.Rotation * 2.0 * 3.1415926

        End If

    End If

Next

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 9

Thomas_Savage
Advisor
Advisor

Hello @norman.yuan

 

Thank you so much for your reply.

 

Yes i want to collect coordinates of the blocks insertion point. Which i can use to create a G - Code for my punch.

 

The Blocks are in model space.

 

I have attached a model, with the blocks (Tools) around it. The tools are green.

 

Would it be possible to apply the rule for me? As i don't have a clue how to create the rule.

 

I use Inventor, and can create rules in Inventor. But this is totally different. So don' know how to do it.

 

I do not use AutoCAD a lot. So do not know what i am doing.

 

Also will the code collect all the tool insertion points? And how will the insertion points (x,y and z coordinates) be shown, in word or notepad?

 

Thank you very much! Your help is much appreciated.

 

Thomas.



Thomas Savage

Design Engineer


0 Likes
Message 4 of 9

norman.yuan
Mentor
Mentor
Accepted solution

OK, I wrote some VBA code as following:

 

a class, called "clsBlock"

 

Option Explicit

Public X As Double
Public Y As Double
Public Z As Double
Public Angle As Double
Public BlockName As String

Public Function OutputText()

    Dim txt As String
    txt = "Block Name: " & BlockName & vbTab & _
        Format(X, "#####0.000") & vbTab & _
        Format(Y, "#####0.000") & vbTab & _
        Format(Z, "#####0.000") & vbTab & _
        Format(Angle, "##0.0")
        
     OutputText = txt

End Function

 Then a module that does the work:

 

Option Explicit

Private mBlockData As Variant

Public Sub DoWork()

    mBlockData = CollectBlockData()
    ExportBlockData mBlockData

End Sub

Private Function CollectBlockData() As Variant

    Dim data() As clsBlock
    
    Dim i As Integer
    Dim ent As AcadEntity
    Dim blk As AcadBlockReference
    
    For Each ent In ThisDrawing.ModelSpace
        If TypeOf ent Is AcadBlockReference Then
            Set blk = ent
            If IsTargetBlock(blk.EffectiveName) Then
            
                ReDim Preserve data(i)
                Set data(i) = New clsBlock
                data(i).X = blk.InsertionPoint(0)
                data(i).Y = blk.InsertionPoint(1)
                data(i).Z = blk.InsertionPoint(2)
                data(i).Angle = blk.Rotation * (180# / 3.1415926)
                data(i).BlockName = blk.EffectiveName
                
                i = i + 1
            End If
        End If
    Next
    
    CollectBlockData = data

End Function

Private Function IsTargetBlock(blkName As String) As Boolean
    
    If UCase(blkName) = "110 X 10" Or UCase(blkName) = "10" Then
        IsTargetBlock = True
    Else
        IsTargetBlock = False
    End If
End Function

Private Sub ExportBlockData(blkData As Variant)
    
    Dim fileNum As Integer
    fileNum = FreeFile
    
    Dim blk As clsBlock
    Dim i As Integer
    Dim txt As String
    
    Open "C:\Temp\ToolPosition.txt" For Output As #fileNum
    
    For i = 0 To UBound(blkData)
        Set blk = blkData(i)
        Write #fileNum, blk.OutputText
    Next
    
    Close #fileNum
    
End Sub

From the code you can see:

 

1. The code searches ModelSpace for 2 blocks with hard-coded block name ("110 x 10" and "10").

 

2. It export the obtained block data (coordinates, rotation angle and block name) to a text file with hard-coded location (C:\Temp\ToolPosition.txt).

 

Attached is the runable VBA project.

 

Hope this gives you a start basis you can build on to further improve it, such as let user choose which block name is targeted, where the text output file should be located (or export the data into Excel sheet...)

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 9

Thomas_Savage
Advisor
Advisor

Hello,

 

Thank you for taking the time to do that. Really appreciate it. This will make my job 10 times easier!

 

I placed the code in the VBA editor, and run the macro. But it came up with an error. Which i have attached as a screenshot.

 

And attached my .dwg so you can see.

 

I downloaded the attached runable VBA project, which i think is also placed in the VBA editor in AutoCAD.

 

I think i could place what blocks are targeted, and change where the text output file should be located.

 

I am just struggling a bit because AutoCAD VBA editor is different to iLogic in Inventor.

 

Hope you can help me get the code running?

 

Thanks you soo much again,

 

Thomas.

 

 

 

 

AutoCAD Code.png



Thomas Savage

Design Engineer


0 Likes
Message 6 of 9

norman.yuan
Mentor
Mentor
Accepted solution

The picture you attached scared me :-(. That was not VBA code would look like, if the *.dvb file can ever be opened in AutoCAD's VBA editor. Are you sure you unzipped the file and loaded the "ExtractBlockData.dvb" into AutoCAD? if the *.dvb file is loaded correctly, the AutoCAD VBA Editor should look like the picture below:

 

BlkDataExtractVBA.png

 

 

Anyway, since all the code is in my previous post, you can simply do this:

 

1. In AutoCAD, type command "VBAIDE" to get into VBA editor;

2. In the toolbar, select the second dropdown button and select "Class Module", to create a class, name it as "clsBlock". Then copy the code from my previous post into the class' code window;

3. Click the dropdown toolbar button and select "Module" to create a module, and copy corresponding code from my previous post into its code windows.

4. Click menu "Debug->Compile xxxx" to compile the code to make sure no error.

5. Click the "Save" button on toolbar to the the VBA project.

 

Now you are ready to run the code.

 

Hopefully this will get you going.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 7 of 9

Thomas_Savage
Advisor
Advisor
Accepted solution

Hello,

 

Got it to work!!!

 

Thank you so much for your help. Very much appreciated. And thank you for the steps. I did not call the class module: clsBlock.

 

I just had to make a few new folders where the text would save to. And now it works fine.

 

My colleague is amazed at what it does, and he was typing all the manually!

 

Thank you again,

 

Thomas.



Thomas Savage

Design Engineer


0 Likes
Message 8 of 9

Anonymous
Not applicable
Accepted solution

class based solutions are always a fine thing to see

 

besides, I'd throw in the following thoughts

 

1)  function IsTargetBlock() can be simplified to

Private Function IsTargetBlock(blkName As String) As Boolean
    IsTargetBlock = blkName = "110 x 10" Or blkName = "10"
End Function

2) you could directly feed ExportBlockData() with CollectBlockData()

ExportBlockData CollectBlockData() 

   thus eliminating both 

Private mBlockData As Variant

   and

mBlockData = CollectBlockData()

3) clsBlock class OutputText() method can be simplified to

Public Function OutputText()
     OutputText = "Block Name: " & BlockName & vbTab & _
                   Format(X, "#####0.000") & vbTab & _
                   Format(Y, "#####0.000") & vbTab & _
                   Format(Z, "#####0.000") & vbTab & _
                   Format(Angle, "##0.0")
End Function

4) in ExportBlockData()

   4.1) you should check for blkData to be not empty before iterating though it

If UBound(blkData) = -1 Then Exit Sub

  4.2) no need for 

Dim txt As String

  4.3)  you could avoid blk As clsBlock helper variable and directly go:

 Dim i As Integer
For i = 0 To UBound(blkData)
Write #fileNum, blkData(i).OutputText
Next

         or you could use a Variant iterator (instead of i as Integer😞

    Dim clsBlk As Variant
    For Each clsBlk In blkData
        Write #fileNum, clsBlk.OutputText
    Next

 

Finally an alternative SelectionSet approach could be used to:

- avoid iterating through each ModelSpace entity and check for both proper type and name

- iterate trough the SelectionSet already filled with properly typed (i.e. AcadBlockReference) objects and avoid the Set blk = ent casting

 

To adopt such an approach you should:

 

 a) add a new function to collect block references in a SelectionSet object, like the following GetBlockReferences() one:

Function GetBlockReferences(ssetObj As AcadSelectionSet) As Boolean
    Dim gpCode(0 To 4) As Integer
    Dim dataValue(0 To 4) As Variant
    
    gpCode(0) = 0:     dataValue(0) = "INSERT"
    gpCode(1) = -4:     dataValue(1) = "<OR"
    gpCode(2) = 2:     dataValue(2) = "110 X 10"
    gpCode(3) = 2:     dataValue(3) = "10"
    gpCode(4) = -4:     dataValue(4) = "OR>"
    
    On Error Resume Next
    With ThisDrawing
        Set ssetObj = .SelectionSets.Item("blcksRefs")
        On Error GoTo 0
        If ssetObj Is Nothing Then Set ssetObj = .SelectionSets.Add("blcksRefs")
    End With
    
    With ssetObj
        .Clear
        .Select acSelectionSetAll, , , gpCode, dataValue
        GetBlockReferences = .Count > 0
    End With
End Function

b) erase IsTargetBlock() function, no more needed since the SelectionSet filtering criteria are doing the type/name filtering job on all ModelSpace entities

 

c) modify CollectBlockData() function to exploit GetBlockReferences() function as follows:

Private Function CollectBlockData() As Variant
    Dim ssetBlckRefs As AcadSelectionSet
    
    If GetBlockReferences(ssetBlckRefs) Then
        ReDim data(ssetBlckRefs.Count - 1) As Variant
        Dim i As Integer
        Dim blk As AcadBlockReference
        For Each blk In ssetBlckRefs
            With blk
                Set data(i) = New clsBlock
                data(i).X = .InsertionPoint(0)
                data(i).Y = .InsertionPoint(1)
                data(i).Z = .InsertionPoint(2)
                data(i).Angle = .Rotation * (180# / 3.1415926)
                data(i).BlockName = .EffectiveName
                i = i + 1
            End With
        Next
        CollectBlockData = data
    End If
End Function

 

 

 

 

Message 9 of 9

Thomas_Savage
Advisor
Advisor

Hello @Anonymous

 

Thank you for the information.

 

It helps me understand the code more.

 

There is some tweaking i want to do to the code.

 

So i might be commenting on here again in a few days, if i can't get the results i want.

 

Thank you. 

 

Thomas.

 



Thomas Savage

Design Engineer


0 Likes