Da ich hier kein Delphi habe, hab ich's gerade mal schnell mit VBA und dann in LinqPad (C#) probiert:
Code:
var appType = Type.GetTypeFromProgID("Excel.Application");
dynamic excelApp = Activator.CreateInstance(appType);
var workBook = excelApp.Workbooks.Open(@"jadajada\Excel-Controls Test.xlsx");
var msoTextBox = 12;
var msOLEControlObject = 19;
var activeSheet = workBook.ActiveSheet;
Func<string, string> cleanCellAddress =
cellAddress => cellAddress != null
? cellAddress.Replace("$", "")
: null;
var shapes = (from dynamic shape in (IEnumerable)activeSheet.Shapes
where shape.Type == msoTextBox
|| (shape.Type == msOLEControlObject && shape.OLEFormat.progID.Contains("TextBox"))
select new
{
Name = (string)shape.Name,
TopLeftCell = cleanCellAddress(shape.TopLeftCell.Address as string),
BottomRightCell = cleanCellAddress(shape.BottomRightCell.Address as string),
AllCells = (from dynamic cell in (IEnumerable)excelApp.Range(shape.TopLeftCell, shape.BottomRightCell).Cells
select cleanCellAddress(cell.Address as string)).ToList()
}).ToList();
Dynamic entpricht Delphi's OleVariant.
Die Funktionen, die man so freizügig in VBA nutzen kann, kann man einfach direkt auf dass Excel.Application-Objekt anwenden. (Ich nutze in dem Beispiel die Range-Funktion)
Wenn ihr Textboxes haben wollt, dann könnt ihr nicht auf den Namen gehen, den kann man ändern!
Es gibt einen Type bei den Shapes, der kann 12 sein (TextBox) oder 19 (Ein
OLE Control das eine Textbox darstellt).
Wenn 19, dann muss man die ProgId prüfen, ob es auch eine TextBox ist.
Falls BottomRightCell erst in späteren Excel-Version dazukam, kann man halt nur Links-oben nutzen...