Thank you for an advice.
Using the examples I was able to write the code as shown below but when running a command in AutoCad 2022 it gives me this error (see attachment).
I'm trying to format the table so that it only has header and data rows only with rows height 6.8 and text height 3.5.
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
using Autodesk.AutoCAD.Colors;
namespace LinkToExcel
{
public class Commands
{
[CommandMethod("S2T")]
static public void UpdateTableFromSpreadsheet()
{
var doc =
Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var opt = new PromptEntityOptions("\nSelect table to update");
opt.SetRejectMessage("\nEntity is not a table.");
opt.AddAllowedClass(typeof(Table), false);
var per = ed.GetEntity(opt);
if (per.Status != PromptStatus.OK)
return;
using (var tr = db.TransactionManager.StartTransaction())
{
try
{
var obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
var tb = obj as Table;
// It should always be a table
// but we'll check, just in case
if (tb != null)
{
// The table must be open for write
tb.UpgradeOpen();
// Update data link from the spreadsheet
var dlIds = tb.Cells.GetDataLink();
foreach (ObjectId dlId in dlIds)
{
var dl =
(DataLink)tr.GetObject(dlId, OpenMode.ForWrite);
dl.Update(
UpdateDirection.SourceToData,
UpdateOption.None
);
// And the table from the data link
tb.UpdateDataLink(
UpdateDirection.SourceToData,
UpdateOption.None
);
}
}
tr.Commit();
ed.WriteMessage(
"\nUpdated the table from the spreadsheet."
);
}
catch (Exception ex)
{
ed.WriteMessage(
"\nException: {0}",
ex.Message
);
}
}
}
[CommandMethod("T2S")]
static public void UpdateSpreadsheetFromTable()
{
var doc =
Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var opt =
new PromptEntityOptions(
"\nSelect table with spreadsheet to update"
);
opt.SetRejectMessage(
"\nEntity is not a table."
);
opt.AddAllowedClass(typeof(Table), false);
var per = ed.GetEntity(opt);
if (per.Status != PromptStatus.OK)
return;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
try
{
DBObject obj =
tr.GetObject(per.ObjectId, OpenMode.ForRead);
Table tb = obj as Table;
// It should always be a table
// but we'll check, just in case
if (tb != null)
{
// The table must be open for write
tb.UpgradeOpen();
// Update the data link from the table
tb.UpdateDataLink(
UpdateDirection.DataToSource,
UpdateOption.ForceFullSourceUpdate
);
// And the spreadsheet from the data link
var dlIds = tb.Cells.GetDataLink();
foreach (ObjectId dlId in dlIds)
{
var dl =
(DataLink)tr.GetObject(dlId, OpenMode.ForWrite);
dl.Update(
UpdateDirection.DataToSource,
UpdateOption.ForceFullSourceUpdate
);
}
}
tr.Commit();
ed.WriteMessage(
"\nUpdated the spreadsheet from the table."
);
}
catch (Exception ex)
{
ed.WriteMessage("\nException: {0}", ex.Message);
}
}
}
static public List<string> GetSheetNames(string excelFileName)
{
var listSheets = new List<string>();
var excel = new Excel.Application();
var wbs = excel.Workbooks.Open(excelFileName);
foreach (Excel.Worksheet sheet in wbs.Worksheets)
{
listSheets.Add(sheet.Name);
}
excel.Quit();
return listSheets;
}
[CommandMethod("WELDTABLE")]
static public void TableFromSpreadsheet()
{
const string dlName = "Import table from Excel demo";
var doc =
Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
// Ask the user to select an XLS(X) file
var ofd =
new OpenFileDialog(
"Select Excel spreadsheet to link",
null,
"xls; xlsx",
"ExcelFileToLink",
OpenFileDialog.OpenFileDialogFlags.
DoNotTransferRemoteFiles
);
var dr = ofd.ShowDialog();
if (dr != System.Windows.Forms.DialogResult.OK)
return;
// Display the name of the file and the contained sheets
ed.WriteMessage(
"\nFile selected was \"{0}\". Contains these sheets:",
ofd.Filename
);
// First we get the sheet names
var sheetNames = GetSheetNames(ofd.Filename);
if (sheetNames.Count == 0)
{
ed.WriteMessage(
"\nWorkbook doesn't contain any sheets."
);
return;
}
// And loop through, printing their names
for (int i = 0; i < sheetNames.Count; i++)
{
var name = sheetNames[i];
ed.WriteMessage("\n{0} - {1}", i + 1, name);
}
// Ask the user to select one
var pio = new PromptIntegerOptions("\nSelect a sheet");
pio.AllowNegative = false;
pio.AllowZero = false;
pio.DefaultValue = 1;
pio.UseDefaultValue = true;
pio.LowerLimit = 1;
pio.UpperLimit = sheetNames.Count;
var pir = ed.GetInteger(pio);
if (pir.Status != PromptStatus.OK)
return;
// Ask for the insertion point of the table
var ppr = ed.GetPoint("\nEnter table insertion point");
if (ppr.Status != PromptStatus.OK)
return;
// Remove any Data Link, if one exists already
var dlm = db.DataLinkManager;
var dlId = dlm.GetDataLink(dlName);
if (dlId != ObjectId.Null)
{
dlm.RemoveDataLink(dlId);
}
// Create and add the new Data Link, this time with
// a direction connection to the selected sheet
var dl = new DataLink();
dl.DataAdapterId = "AcExcel";
dl.Name = dlName;
dl.Description = "Excel fun with Through the Interface";
dl.ConnectionString =
ofd.Filename + "!" + sheetNames[pir.Value - 1];
dl.DataLinkOption =
DataLinkOption.PersistCache;
dl.UpdateOption |=
(int)UpdateOption.AllowSourceUpdate;
dlId = dlm.AddDataLink(dl);
using (var tr = doc.TransactionManager.StartTransaction())
{
const string styleName = "weld table style";
ObjectId tsId = ObjectId.Null;
DBDictionary sd =
(DBDictionary)tr.GetObject(
db.TableStyleDictionaryId,
OpenMode.ForRead
);
if (sd.Contains(styleName))
{
tsId = sd.GetAt(styleName);
}
else
{
TableStyle ts = new TableStyle();
ts.SetTextHeight(3.5, (int)RowType.HeaderRow);
ts.SetTextHeight(3.5, (int)RowType.DataRow);
ts.HorizontalCellMargin = 0.5;
ts.VerticalCellMargin = 0.2;
ts.SetColor(
Color.FromColorIndex(ColorMethod.ByAci, 2),
(int)(RowType.HeaderRow));
ts.SetColor(
Color.FromColorIndex(ColorMethod.ByAci, 2),
(int)(RowType.DataRow));
ts.SetGridColor(
Color.FromColorIndex(ColorMethod.ByAci, 2),
(int)GridLineType.AllGridLines,
(int)(RowType.HeaderRow));
ts.SetGridColor(
Color.FromColorIndex(ColorMethod.ByAci, 1),
(int)GridLineType.AllGridLines,
(int)(RowType.DataRow));
tsId = ts.PostTableStyleToDatabase(db, styleName);
tr.AddNewlyCreatedDBObject(ts, true);
}
var bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
// Create our table
var tb = new Table();
tb.Position = ppr.Value;
tb.Cells.SetDataLink(dlId, true);
tb.GenerateLayout();
if (tsId == ObjectId.Null)
tb.TableStyle = db.Tablestyle;
else
tb.TableStyle = tsId;
// Add it to the drawing
var btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForWrite
);
tb.SetColumnWidth(0, 16.5);
tb.SetColumnWidth(1, 14.7);
tb.SetColumnWidth(2, 18.3);
tb.SetColumnWidth(3, 14.7);
tb.SetColumnWidth(4, 18.3);
tb.SetColumnWidth(5, 24.3);
tb.SetColumnWidth(6, 28.5);
tb.SetColumnWidth(7, 14.7);
tb.SetColumnWidth(8, 28.5);
tb.SetColumnWidth(9, 14.7);
tb.SetColumnWidth(10, 17.7);
tb.SetColumnWidth(11, 25.5);
btr.AppendEntity(tb);
tr.AddNewlyCreatedDBObject(tb, true);
tr.Commit();
}
}
}
}