VBA AutoCAD Excel

JP -  
 JP -
Hello,

I will explain my problem: I can handle VBA with if statements or select case statements since it's not too complicated, but having never had any VBA training, I'm completely stuck. I was given a formula that allows me to retrieve attribute data from blocks in AutoCAD to Excel.
My problem is the following: if I don't open Excel, it doesn't work.
What I would like is that when I execute this program, my Excel file named "ESSAI.xls" opens. Here is its path: "C:\Users\msi\Documents\ESSAI.xls"

Here is the program:

'Visual BASIC Programming in AutoCAD
Dim AcadDoc As Object, ExcelApp As Object, ExcelSheet As Object

Private Sub Liste_Click()
Dim Collection As Object, Objet As Object
Dim i As Integer
Dim P As Variant, Attributes As Variant, Column As Integer, colonne As Integer

'AcadDoc is a link to the current drawing
Set AcadDoc = GetObject(, "Autocad.application").ActiveDocument
'ExcelApp is a link to the current Excel application
Set ExcelApp = GetObject(, "Excel.application")
'I think it's here where I need to provide
'the path to my Excel file, but I don't know how
'ExcelSheet is a link to the worksheet named Feuil1
Set ExcelSheet = ExcelApp.activeworkbook.sheets("Feuil2")

'Filling in line no. 1 of the Feuil1 sheet with column headers
ExcelSheet.Cells(1, 1) = "ID"
ExcelSheet.Cells(1, 2) = "POIDS_HA"
ExcelSheet.Cells(1, 3) = "POIDS_TS"
ExcelSheet.Cells(1, 4) = "TYPE"

'collection represents all graphical entities contained in the object space
Set Collection = AcadDoc.ModelSpace
i = 2
'For each object in the collection
For Each Objet In Collection
'Filling in Excel, row by row starting from the second
'line of the sheet, indicating the identifier, entity type
'Line, Arc, Circle... etc
ExcelSheet.Cells(i, 4) = Objet.Handle

If Objet.EntityType = 7 Then
Attributes = Objet.GetAttributes
For j = LBound(Attributes) To UBound(Attributes)
Select Case Attributes(j).TagString
Case "POIDS_HA": colonne = 1
Case "POIDS_TS": colonne = 2
Case "TYPE": colonne = 3

End Select
ExcelSheet.Cells(i, colonne) = Attributes(j).TextString
'Attributes = Objet.GetAttributes(j)
i = i + 1
Next j
End If
Next
End Sub

If someone could help me. Thank you in advance

JP
Configuration: Windows Vista / Safari 535.11

1 answer

  1. Yoda
     
    Hello,

    In VBA Editor, Tools menu References check that Microsoft Excel 11.0 Object Library is checked
    Here is your code with some modifications.

    'Visual BASIC Programming in AutoCAD Dim AcadDoc As Object, ExcelApp As Object, ExcelSheet As Excel.Worksheet, ExcelWorkBook As Excel.Workbooks Private Sub Liste_Click() Dim Collection As Object, Objet As Object Dim i As Integer Dim P As Variant, Attributes As Variant, Column As Integer, colonne As Integer 'ExcelApp is a link to the currently running Excel application On Error Resume Next 'Check if Excel is open and if not, open it. Set objExcel = GetObject(, "Excel.Application") If Err.Number > 0 Then Set objExcel = CreateObject("Excel.Application") End If objExcel.Visible = True Set ExcelWorkBook = objExcel.Workbooks.Open("C:\Users\msi\Documents\ESSAI.xls") Set ExcelSheet = objExcel.ActiveWorkbook.Sheets("Feuil2") 'AcadDoc is a link to the current drawing Set AcadDoc = GetObject(, "Autocad.application").ActiveDocument 'Filling in row number 1 of sheet Feuil1 with column headers ExcelSheet.Cells(1, 1) = "ID" ExcelSheet.Cells(1, 2) = "WEIGHT_HA" ExcelSheet.Cells(1, 3) = "WEIGHT_TS" ExcelSheet.Cells(1, 4) = "TYPE" 'collection represents all graphic entities contained in the model space Set Collection = AcadDoc.ModelSpace i = 2 'For each object in the collection For Each Objet In Collection 'Filling in Excel, row by row starting from the second 'line of the sheet, indicating the ID, the type of entity 'Line, Arc, Circle ... etc ExcelSheet.Cells(i, 4) = Objet.Handle If Objet.EntityType = 7 Then Attributes = Objet.GetAttributes For j = LBound(Attributes) To UBound(Attributes) Select Case Attributes(j).TagString Case "WEIGHT_HA": colonne = 1 Case "WEIGHT_TS": colonne = 2 Case "TYPE": colonne = 3 End Select ExcelSheet.Cells(i, colonne) = Attributes(j).TextString 'Attributes = Objet.GetAttributes(j) i = i + 1 Next j End If Next End Sub
    0
    1. jp
       
      Hello

      Thank you, it works

      I have another problem though:
      I have lots of blocks
      but I only want to retrieve the attributes of two blocks named
      Nomenclature and HA_Nomenclature
      Nomenclature has attributes TYPE, TYPE1, REP, NB_HA
      HA_Nomenclature has attributes TYPE1, NB_HA

      My issue is that it shows me an error and it highlights this line

      "ExcelSheet.Cells(i, colonne) = Attributes(j).TextString"

      and I'm stuck. If you know what’s going on, thank you.
      0
    2. Yoda
       
      Hello,
      I believe it's due to the column value. If column=0 then it crashes.
      Also, you are not filtering the blocks. You should process the blocks in separate sheets.

      Here’s what I would use to filter the Nomenclature block

      If Objet.EntityType = 7 And Objet.Name = "Nomenclature" Then Attributes = Objet.GetAttributes For j = 0 To UBound(Attributes) Select Case Attributes(j).TagString Case "TYPE": column = 1 Case "TYPE1": column = 2 Case "REP": column = 3 Case "NB_HA": column = 4 End Select ExcelSheet.Cells(i, column) = Attributes(j).TextString Next j i = i + 1 'move to the next line for the next End If
      0
    3. jp
       
      Thank you
      I haven't tried it yet, I'll keep you posted. However, for my case, I don't see the point of making a sheet for each attribute. So if I'm not mistaken, I should make a select case like below for the blocks and attributes I want.

      If Objet.EntityType = 7 Then
      select case Objet.Name
      case "Nomenclature"
      Attributes = Objet.GetAttributes
      For j = 0 To UBound(Attributes)
      Select Case Attributes(j).TagString
      Case "TYPE": column = 1
      Case "TYPE1": column = 2
      Case "REP": column = 3
      Case "NB_HA": column = 4
      End Select
      ExcelSheet.Cells(i, column) = Attributes(j).TextString
      Next j
      i = i + 1 'move to the next line for the next one
      End If
      Case "HA_Nomenclature"
      Attributes = Objet.GetAttributes
      For j = 0 To UBound(Attributes)
      Select Case Attributes(j).TagString
      Case "TYPE1": column = 1
      Case "NB_HA": column = 2
      End Select
      ExcelSheet.Cells(i, column) = Attributes(j).TextString
      Next j
      i = i + 1 'move to the next line for the next one
      End If

      JP
      0
    4. Yoda
       
      Hello,

      I have already done this program with Autolisp, so from experience, I know that it is necessary to handle the blocks individually. Here’s how I proceed:
      - I ask the user to select (on the screen) the block to be processed
      - I retrieve the name of the block, check that it has attributes, and write the tags on the first line
      - I ask to make a selection of objects (capture, all, ...)
      - in the selection, I extract the attributes of all the blocks that correspond to the chosen block and write their values on the second line and the following lines.

      This is the basic algorithm. You can process all the blocks at once but by sorting them and using a different Excel sheet for each series.

      ;)
      0
    5. JP
       
      Hello

      the program works wonderfully, thank you very much. I did as you told me, one sheet for each attribute. However, I have one last issue; I retrieve the attributes of the block for which I specified the name (here Nomenclature), but I get the "Handles" of all blocks whereas I only want those of Nomenclature blocks.

      .'Visual BASIC Programming in AutoCAD
      Dim AcadDoc As Object, ExcelApp As Object, ExcelSheet As Excel.Worksheet, ExcelWorkBook As Excel.Workbooks
      Private Sub Liste_Click()
      Dim Collection As Object, Objet As Object
      Dim i As Integer
      Dim P As Variant, Attributes As Variant, Column As Integer, colonne As Integer

      'ExcelApp is a link to the current excel application
      On Error Resume Next
      'Check if Excel is open, and if not, open it.
      Set objExcel = GetObject(, "Excel.Application")
      If Err.Number > 0 Then
      Set objExcel = CreateObject("Excel.Application")
      End If
      objExcel.Visible = True

      Set ExcelWorkBook = objExcel.Workbooks.Open("f:\Projet LP CAODAO\Projet 2.0\EXCEL\TESTE.xls")
      Set ExcelSheet = objExcel.ActiveWorkbook.Sheets("Extraction")

      'AcadDoc is a link to the current drawing
      Set AcadDoc = GetObject(, "Autocad.application").ActiveDocument

      'Filling line 1 in the Feuil1 sheet with column headers
      ExcelSheet.Cells(1, 1) = "ID"
      ExcelSheet.Cells(1, 2) = "TYPE"
      ExcelSheet.Cells(1, 3) = "TYPE1"
      ExcelSheet.Cells(1, 4) = "NBRE_ELEMENT"
      ExcelSheet.Cells(1, 5) = "REP"
      ExcelSheet.Cells(1, 6) = "NB_HA"
      ExcelSheet.Cells(1, 7) = "DIAM_HA"
      ExcelSheet.Cells(1, 8) = "LONG_HA"
      ExcelSheet.Cells(1, 9) = "E_HA"

      'collection represents all graphical entities contained in the object space
      Set Collection = AcadDoc.ModelSpace
      i = 2
      'For each object in the collection

      For Each Objet In Collection
      'Filling in excel, row by row starting from the second
      'row of the sheet, indicating the identifier, the type of entity
      If Objet.Name = "Nomenclature" Then
      ExcelSheet.Cells(i, 1) = Objet.GetAttributes.Handle
      If Objet.EntityType = 7 Then
      Attributes = Objet.GetAttributes
      For j = 0 To UBound(Attributes)
      Select Case Attributes(j).TagString
      Case "TYPE": colonne = 2
      Case "TYPE1": colonne = 3
      Case "NBRE_ELEMENT": colonne = 4
      Case "REP": colonne = 5
      Case "NB_HA": colonne = 6
      Case "DIAM_HA": colonne = 7
      Case "LONG_HA": colonne = 8
      Case "E_HA": colonne = 9
      End Select
      ExcelSheet.Cells(i, colonne) = Attributes(j).TextString
      Next j
      i = i + 1 'move to the next line for the next
      End If
      End If
      Next

      End Sub


      Thank you
      0