Table SetAutoScale & SetAutoScale2

Table SetAutoScale & SetAutoScale2

grobnik
Collaborator Collaborator
2,475 Views
3 Replies
Message 1 of 4

Table SetAutoScale & SetAutoScale2

grobnik
Collaborator
Collaborator

Dear all, I need support for an issue with table.
I have a table composed by 70 rows and 12 columns, Rows height and columns width has been settled before as preliminary, when table being inserted in the drawing. 
The scope is to fit the column size to cell contents, with a fixed row height.
Of course I don't know, before writing data into the table's cell, if the contents length will be higher than the columns width, so when table will be drawn and updated I would like to adapt the columns width to cell contents.
I tried to apply the below code but nothing is changing, I tried after writing the cells contents and before writing the cells contents but result it's the same: if cell's contents it's higher than columns width I have the contents carriage return results. See image below.
I Tried also to use the Autoscale2 method but I do not understand how to use nContent parameter, due to it's required as long type variable instead a text as table data cells required.

For i = 2 To .Rows - 1
For j = 0 To .Columns - 1
Actable.SetAutoScale i, j, False 'or True
Next j
Next i

Please somebody could help me ?

0 Likes
2,476 Views
3 Replies
Replies (3)
Message 2 of 4

ambrosl
Autodesk
Autodesk

Each cell can contain multiple pieces of content, the first piece content in a cell has an index of 0.  So the third parameter of SetAutoScale2 is usually assigned a value of 0.  The following is an example that should set the AutoScale value to True for each cell in all table objects located in Model space.

 

  Dim acTable As AcadTable
  Dim acEnt As AcadEntity
  
  ' Step through all entities in Model space
  For Each acEnt In ThisDrawing.ModelSpace
    ' Check to see if the entity is a Table
    If acEnt.ObjectName = "AcDbTable" Then
      Set acTable = acEnt
      
      Dim nRow As Integer, nCol As Integer
      nRow = 0
      
      ' Step through each row in the table
      Do While acTable.Rows > nRow
        nCol = 0
        
        ' Step through each column
        Do While acTable.Columns > nCol
          ' Set the AutoScale value for each cell based on the content in
          ' index 0, the first content in each cell
          acTable.SetAutoScale2 nRow, nCol, 0, True

          nCol = nCol + 1
        Loop
        
        nRow = nRow + 1
      Loop
    End If
  Next acEnt


Lee Ambrosius
Senior Principal Content Experience Designer
For additional help, check out the AutoCAD Developer Documentation
0 Likes
Message 3 of 4

grobnik
Collaborator
Collaborator

Hi Mr. Ambrosl,

thank you for the code in reply to my post, but I have not seen any effect on my table contents.

Probably there is something of wrong in my initial code (here below reported with also your code part inserted).

I'll try to explain below code functionality:

I have a drawing which contains a lot of blocks, each block contain some Attributes, attributes are extracted from blocks and listed in a table inside the drawing. In a first time I was producing an external excel file, without any kind of problem, but each time I made a modification on drawing I have also to update excel file. On the opposite with a table part of drawing I have to update only table data inside the drawing.

 

In this case the main issue, as explained in my initial post, is to adapt the columns width to cell contents.

So, if SetAutoScale2 functionality could be compared with excel column adapting functionality it should work, and can be used for my scope, if not I have to fix manually the columns width after data has been filled.

 

 

 

Sub ProvaTabellaBlocchi()

Dim minp As Variant
Dim maxp As Variant
Dim pt(2) As Double
Dim acTable As AcadTable
Dim zz As Long
pt(0) = 5700#
pt(1) = 1250#

ColNr = 0
Rownr = 2
Set acTable = ThisDrawing.ActiveLayout.Block.AddTable(pt, 70, 12, 5, 60)

'AcTable.SetColumnWidth 2, 95
With acTable
.Layer = "GS - TABLE"
.StyleName = "GLASS SERVICE"
 

.RegenerateTableSuppressed = True
.RecomputeTableBlock False
.TitleSuppressed = False
.HeaderSuppressed = False
.SetTextStyle AcRowType.acTitleRow, "GS - Testo" '<-- change text style name here
.SetTextStyle AcRowType.acHeaderRow, "GS - Testo"
.SetTextStyle AcRowType.acDataRow, "GS - Testo"
.HorzCellMargin = 4 '2
.VertCellMargin = 0.5
Dim i As Double, j As Double
Dim MyCol As New AcadAcCmColor
MyCol.SetRGB 255, 0, 0
.SetText 1, 0, "TAG"
.SetText 1, 1, "LOOP"
.SetText 1, 2, "DESCRIPTION"
.SetText 1, 3, "TAG"
.SetText 1, 4, "LOOP"
.SetText 1, 5, "DESCRIPTION"
.SetText 1, 6, "TAG"
.SetText 1, 7, "LOOP"
.SetText 1, 8, "DESCRIPTION"
.SetText 1, 9, "TAG"
.SetText 1, 10, "LOOP"
.SetText 1, 11, "DESCRIPTION"
'.ColumnWidth
'title
.SetCellTextHeight i, j, 8
.SetCellAlignment i, j, acMiddleCenter
'MyCol.SetRGB 194, 212, 235
'.SetCellBackgroundColor i, j, MyCol
MyCol.SetRGB 255, 0, 0
.SetCellContentColor i, j, MyCol
.SetCellType i, j, acTextCell
.SetText 0, 0, "LOOP REFERENCE & DESCRIPTION"

i = i + 1

'headers
For j = 0 To .Columns - 1

'MyCol.SetRGB 203, 220, 183
'.SetCellBackgroundColor i, j, MyCol
MyCol.SetRGB 255, 0, 0
.SetCellContentColor i, j, MyCol
.SetCellTextHeight i, j, 5
.SetCellAlignment i, j, acMiddleCenter
.SetCellType i, j, acTextCell
Next
'.SetText i, j, "Header" & CStr(j + 1)
j = 0

For i = 2 To .Rows - 1
For j = 0 To .Columns - 1

.SetCellTextHeight i, j, 3
.SetCellAlignment i, j, acMiddleCenter
.SetRowHeight i, 3


If i Mod 2 = 0 Then
MyCol.SetRGB 255, 0, 0
Else
MyCol.SetRGB 255, 0, 0
End If
'.SetCellBackgroundColor i, j, MyCol
'MyCol.SetRGB 0, 76, 0
.SetCellContentColor i, j, MyCol
.SetCellType i, j, acTextCell
Next j
Next i
For i = 2 To .Rows - 1
For j = 0 To .Columns - 1
      .SetAutoScale i, j, False = False
Next j
Next i


'Estrae Blocchi
For Each Entity In ThisDrawing.ModelSpace
          'Set Block = Entity
        If TypeOf Entity Is AcadBlockReference Then
        'If Entity.ObjectName = "AcDbBlockReference" Then

            If Entity.Name = "COMPONENT TAG" Then
                If Entity.HasAttributes = True Then
                    ListaAtt = Entity.GetAttributes
                    'PuntoInser = Entity.InsertionPoint

                     acTable.SetText Rownr, ColNr, ListaAtt(0).TextString
                     acTable.SetText Rownr, ColNr + 1, ListaAtt(1).TextString
                     acTable.SetText Rownr, ColNr + 2, ListaAtt(2).TextString
                     
                     'AcTable.SetAutoScale 2, ColNr, True = True
                     'AcTable.SetAutoScale 2, ColNr + 1, True = True
                     'AcTable.SetAutoScale 2, ColNr + 2, True = True
                    Rownr = Rownr + 1
                    
                    If Rownr >= 70 Then
                        Rownr = 2
                        ColNr = ColNr + 3
                    End If
                    'Entity.Delete
                End If
            End If
        End If
Next Entity



' set color for grid
MyCol.SetRGB 255, 255, 255
.SetGridColor AcGridLineType.acHorzBottom, AcRowType.acTitleRow, MyCol
.SetGridColor AcGridLineType.acHorzInside, AcRowType.acTitleRow, MyCol
.SetGridColor AcGridLineType.acHorzTop, AcRowType.acTitleRow, MyCol
.SetGridColor AcGridLineType.acVertInside, AcRowType.acTitleRow, MyCol
.SetGridColor AcGridLineType.acVertLeft, AcRowType.acTitleRow, MyCol
.SetGridColor AcGridLineType.acVertRight, AcRowType.acTitleRow, MyCol

.SetGridColor AcGridLineType.acHorzBottom, AcRowType.acHeaderRow, MyCol
.SetGridColor AcGridLineType.acHorzInside, AcRowType.acHeaderRow, MyCol
.SetGridColor AcGridLineType.acHorzTop, AcRowType.acHeaderRow, MyCol
.SetGridColor AcGridLineType.acVertInside, AcRowType.acHeaderRow, MyCol
.SetGridColor AcGridLineType.acVertLeft, AcRowType.acHeaderRow, MyCol
.SetGridColor AcGridLineType.acVertRight, AcRowType.acHeaderRow, MyCol

.SetGridColor AcGridLineType.acHorzBottom, AcRowType.acDataRow, MyCol
.SetGridColor AcGridLineType.acHorzInside, AcRowType.acDataRow, MyCol
.SetGridColor AcGridLineType.acHorzTop, AcRowType.acDataRow, MyCol
.SetGridColor AcGridLineType.acVertInside, AcRowType.acDataRow, MyCol
.SetGridColor AcGridLineType.acVertLeft, AcRowType.acDataRow, MyCol
.SetGridColor AcGridLineType.acVertRight, AcRowType.acDataRow, MyCol

'set line weights for grid
.SetGridLineWeight AcGridLineType.acVertLeft, AcRowType.acTitleRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertRight, AcRowType.acTitleRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzTop, AcRowType.acTitleRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzBottom, AcRowType.acHeaderRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzInside, AcRowType.acHeaderRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzTop, AcRowType.acHeaderRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertInside, AcRowType.acHeaderRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertLeft, AcRowType.acHeaderRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertRight, AcRowType.acHeaderRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzBottom, AcRowType.acDataRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzInside, AcRowType.acDataRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acHorzTop, AcRowType.acDataRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertInside, AcRowType.acDataRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertLeft, AcRowType.acDataRow, AcLineWeight.acLnWt000
.SetGridLineWeight AcGridLineType.acVertRight, AcRowType.acDataRow, AcLineWeight.acLnWt000



End With

'Dim acTable As AcadTable
Dim acEnt As AcadEntity
  
  ' Step through all entities in Model space
  'For Each acEnt In ThisDrawing.ModelSpace
    ' Check to see if the entity is a Table
    'If acEnt.ObjectName = "AcDbTable" Then
     ' Set acTable = acEnt
      
      Dim nRow As Integer, nCol As Integer
      nRow = 0
      
      ' Step through each row in the table
      Do While acTable.Rows > nRow
        nCol = 0
        
        ' Step through each column
        Do While acTable.Columns > nCol
          ' Set the AutoScale value for each cell based on the content in
          ' index 0, the first content in each cell
          acTable.SetAutoScale2 nRow, nCol, 0, True

          nCol = nCol + 1
          Debug.Print "nCol "; nCol
        Loop
        
        nRow = nRow + 1
        Debug.Print "nRow "; nRow
      Loop
'    End If
 ' Next acEnt
acTable.RegenerateTableSuppressed = False
acTable.RecomputeTableBlock True
acTable.Update

acTable.GetBoundingBox minp, maxp
ZoomWindow minp, maxp
ZoomScaled 0.9, acZoomScaledRelative
ThisDrawing.SetVariable "LWDISPLAY", 1
Set MyCol = Nothing
  MsgBox "finito"
End Sub

 

0 Likes
Message 4 of 4

ambrosl
Autodesk
Autodesk

Okay... I went back and took a look at a few things, it seems to me that SetAutoScale and SetAutoScale won't work because those functions aren't designed for text content but rather blocks to auto-fit a cell (http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_Table_Ge... Some clarification needs to be made in the ActiveX documentation about which content is affected by AutoScale.

If I am not mistaken, your goal is to increase the width of each column to fit the longest text string.

 

TableCellWrap1.png

TableCellWrap2.png

From what I can tell, there isn't a direct way to tell the table to adjust its column widths automatically using the methods and properties of the AcadTable object. It is possible I missed something though. You can adjust the width of each column based on the longest text string by first calculating the width of each text string in each column using something like the following code. The code sample is what I used to adjust the width and height of the cell in the above images.

 

Sub AdjustColumnWidths()
  Dim acTable As AcadTable
  Dim acEnt As AcadEntity
  Dim sCellTextVal As String
  Dim oMtext As AcadMText
  Dim dMtextWidth As Double
  
  ' Define the insertion point for the mtext object
  Dim insPt(0 To 2) As Double
  insPt(0) = 0: insPt(1) = 0: insPt(2) = 0
          
  ' Create an empty mtext object, this object will be used to get the max width
  ' of the text string in a column later
  Set oMtext = ThisDrawing.ModelSpace.AddMText(insPt, 0, "")
  oMtext.Visible = False
            
  ' Step through all entities in Model space
  For Each acEnt In ThisDrawing.ModelSpace
    ' Check to see if the entity is a Table
    If acEnt.ObjectName = "AcDbTable" Then
      Set acTable = acEnt
      acTable.RegenerateTableSuppressed = True
      
      Dim dColWidth() As Double
      ReDim dColWidth(acTable.Columns)
      
      Dim nRow As Integer, nCol As Integer
      nRow = 0
      
      ' Step through each row in the table
      Do While acTable.Rows > nRow
        nCol = 0
        
        ' Skip the first row, the header
        If nRow > 0 Then
        
          ' Step through each column
          Do While acTable.Columns > nCol
            ' Get the current column width
            If dColWidth(nCol) = 0 Then dColWidth(nCol) = acTable.GetColumnWidth(nCol)
          
            ' Set the MText object based on the text in the cell
            oMtext.TextString = acTable.GetTextString(nRow, nCol, 0)
            oMtext.StyleName = acTable.GetTextStyle2(nRow, nCol, 0)
            oMtext.Height = acTable.GetTextHeight2(nRow, nCol, 0)

            ' Calculate the width of the MText using its boundary box
            Dim vMin, vMax As Variant
            oMtext.GetBoundingBox vMin, vMax

            ' Make sure to include the Margins in the width for the new column
            dMtextWidth = vMax(0) - vMin(0) + _
                          acTable.GetMargin(nRow, nCol, acCellMarginLeft) + _
                          acTable.GetMargin(nRow, nCol, acCellMarginRight)

            ' Is the width of the MText object greater than the current column width?
            If dMtextWidth > dColWidth(nCol) Then dColWidth(nCol) = dMtextWidth
            
'            If dMtextWidth > dColWidth(nCol) Then
'              acTable.SetColumnWidth nCol, dMtextWidth * 1.05
'              dColWidth(nCol) = dMtextWidth * 1.05
'
'              ' Change to match original row height of 3
'              acTable.SetRowHeight nRow, 3
'            End If
            
            nCol = nCol + 1
          Loop
        End If
    
        nRow = nRow + 1
      Loop
      
      ' Change the width of the columsn in the table
      nCol = 0
      Do While acTable.Columns > nCol
        acTable.SetColumnWidth nCol, dColWidth(nCol)

        nCol = nCol + 1
      Loop
      
      ' Reset the height of the data rows that are not equal to 3
      nRow = 2
      Do While acTable.Rows > nRow
        If acTable.GetRowHeight(nRow) <> 3 Then acTable.SetRowHeight nRow, 3

        nRow = nRow + 1
      Loop
      
      ' Recalculate the table
      acTable.RecomputeTableBlock True
      acTable.RegenerateTableSuppressed = False
    End If
  Next acEnt
  
  ' Remove the Mtext object created earlier for calculating the column width
  oMtext.Delete
  Set oMtext = Nothing
End Sub

 



Lee Ambrosius
Senior Principal Content Experience Designer
For additional help, check out the AutoCAD Developer Documentation
0 Likes