1# SDExcelCtrl
Control COM para Clarion que genera y lee archivos Excel (.xlsx) sin requerir Microsoft Excel instalado.
Implementado en C# (.NET Framework 4.7.2 / x86) usando la biblioteca ClosedXML.
- Crea, abre y guarda archivos
.xlsx - Lee y escribe celdas por rango (
"A1") o por posición (fila, columna) - Formato de número, alineación horizontal/vertical, ajuste de texto
- Ancho de columna y alto de fila
- Fuente: negrita, cursiva, tamaño, nombre, color
- Fondo de celda, bordes granulares (superior/inferior/izquierdo/derecho)
- Administración de hojas (agregar, seleccionar, renombrar)
- 80+ métodos COM con DispId asignados
- No requiere Excel instalado en el servidor ni en el cliente
- Activación RegFree COM (sin registro en el registro de Windows)
- Compatible con el template UltimateCOM de Clarion
| Componente | Versión |
|---|---|
| .NET Framework | 4.7.2 (x86) |
| ClosedXML | 0.97.0 |
| Clarion | 11 o superior |
| SDExcelClass wrapper | Incluido en SDExcelOleCtrl |
Importante: No usar ClosedXML 0.104.x o superior — produce una excepción
TypeInitializationExceptionenSixLabors.Fontsal correr en .NET Framework x86.
| Campo | Valor |
|---|---|
| ProgID | SDExcelCtrl.SDExcelCtrl |
| Class GUID | {5F468519-2E4D-43FA-BD6B-77FD7861D0E1} |
| Interface GUID | {F933A4E7-A35C-4706-A517-EA1F656F1AC1} |
| Assembly GUID | {C5222F73-BDF6-4A76-A313-276C08D208C2} |
Copiar en Clarion\accessory\bin\:
SDExcelCtrl.dll
SDExcelCtrl.manifest
ClosedXML.dll
ClosedXML.Parser.dll
DocumentFormat.OpenXml.dll
DocumentFormat.OpenXml.Framework.dll
ExcelNumberFormat.dll
Irony.dll
Microsoft.Bcl.HashCode.dll
RBush.dll
SixLabors.Fonts.dll
System.Buffers.dll
System.Diagnostics.DiagnosticSource.dll
System.IO.Packaging.dll
System.Memory.dll
System.Numerics.Vectors.dll
System.Runtime.CompilerServices.Unsafe.dll
System.ValueTuple.dll
XLParser.dll
Binding redirect requerido: cada
.EXEnecesita un.exe.configcon redirect deSystem.Numerics.Vectors(oldVersion="0.0.0.0-4.1.4.0" → newVersion="4.1.4.0", publicKeyToken=b03f5f7f11d50a3a).
Copiar en Clarion\accessory\resources\:
SDExcelCtrl.manifest
SDExcelCtrl.header
SDExcelCtrl.SDExcelCtrl.details
SDExcelCtrl.SDExcelCtrl.methods
SDExcelCtrl.SDExcelCtrl.events
El build de Visual Studio copia automáticamente todos estos archivos a
Clarion\dentro del proyecto, listos para distribuir.
MSBuild.exe SDExcelCtrl.csproj -p:Configuration=Release
SDExcel UltimateCOM
SDExcel_Ctrl LONG
SDExcel_Event EQUATE(Event:User + 5500)
SDExcel_Ready BYTE(0)Agregar un control OLE oculto:
OLE,AT(0,0,1,1),USE(?SDExcelOLE),HIDE,TRNSDExcel_Ctrl = ?SDExcelOLE
SDExcel_Ctrl{PROP:Create} = 'SDExcelCtrl.SDExcelCtrl'
SDExcel.SetUCPostEvent(SDExcel_Event)
SDExcel.RegisterEventFunc(SDExcel_Ctrl)OF SDExcel_Event
IF SDExcel.GetEvent()
CASE SDExcel.EventName
OF 'ControlReady'
SDExcel_Ready = True
END
ENDIF SDExcel_Ready
SDExcel_Ctrl{'CreateFile()'}
SDExcel_Ctrl{'AssignByPos(1,1,"Empresa")'}
SDExcel_Ctrl{'AssignByPos(1,2,"Fecha")'}
SDExcel_Ctrl{'SetColumnWidth(20.0)'}
SDExcel_Ctrl{'Save("C:\reportes\informe.xlsx")'}
SDExcel_Ctrl{'Close(0)'}
END| Método | Descripción |
|---|---|
CreateFile() |
Crea un libro nuevo en memoria |
CreateFileAt(fileName) |
Crea un libro y lo guarda en fileName |
OpenFile(fileName) |
Abre un archivo .xlsx existente |
Save(fileName) |
Guarda el libro en fileName |
Close(saveChanges) |
Cierra el libro; saveChanges=1 guarda antes de cerrar |
| Método | Descripción |
|---|---|
Select(range) |
Selecciona celda o rango por nombre ("A1", "A1:C5") |
SelectByPos(row, column) |
Selecciona celda por fila y columna numérica |
SelectRow(row) |
Selecciona fila activa |
SelectColumn(column) |
Selecciona columna por letra ("A", "BC") |
SelectColumnByNumber(column) |
Selecciona columna por número |
| Método | Descripción |
|---|---|
Assign(contents) |
Escribe en la celda activa (cursor no se mueve) |
AssignByRange(range, contents) |
Escribe por rango — mueve el cursor a esa celda |
AssignByPos(row, column, contents) |
Escribe por posición — mueve el cursor a esa celda |
AssignWithFormat(contents, format) |
Escribe y aplica formato en una llamada |
AssignWithFormatByRange(range, contents, format) |
Por rango — mueve el cursor |
AssignWithFormatByPos(row, column, contents, format) |
Por posición — mueve el cursor |
Los métodos ByRange y ByPos actualizan
_activeRow/_activeColumn, lo que permite llamar aSetFontSize,SetBold, etc. inmediatamente después sin unSelectexplícito.
| Método | Retorna | Descripción |
|---|---|---|
Read() |
STRING |
Lee la celda activa |
ReadByRange(cell) |
STRING |
Lee una celda por rango ("C5") |
ReadByPos(row, column) |
STRING |
Lee una celda por posición numérica |
| Método | Descripción |
|---|---|
SetNumberFormat(format) |
Aplica formato a la celda activa |
SetNumberFormatByRange(range, format) |
Aplica formato a un rango |
SetNumberFormatByPos(row, column, format) |
Aplica formato por posición |
Ejemplos de format: "#,##0.00", "dd/mm/yyyy", "@" (texto).
Valores: 1 = Izquierda · 2 = Centro · 3 = Derecha
| Método | Descripción |
|---|---|
SetHAlignment(alignment) |
Aplica en la celda activa |
SetHAlignmentByRange(range, alignment) |
Aplica en un rango |
SetHAlignmentByPos(row, column, alignment) |
Aplica por posición |
Valores: 1 = Arriba · 2 = Centro · 3 = Abajo
| Método | Descripción |
|---|---|
SetVAlignment(alignment) |
Aplica en la celda activa |
SetVAlignmentByRange(range, alignment) |
Aplica en un rango |
SetVAlignmentByPos(row, column, alignment) |
Aplica por posición |
| Método | Descripción |
|---|---|
MergeCells() |
Combina el rango seleccionado con Select("A1:C1") |
MergeCellsByRange(range) |
Combina el rango indicado |
wrapText: 1 = activo · 0 = desactivado
| Método | Descripción |
|---|---|
SetWrapText(wrapText) |
Aplica en la celda activa |
SetWrapTextByRange(range, wrapText) |
Aplica en un rango |
SetWrapTextByPos(row, column, wrapText) |
Aplica por posición |
| Método | Descripción |
|---|---|
SetColumnWidth(width) |
Ancho de la columna activa |
SetColumnWidthByName(column, width) |
Ancho por letra de columna |
SetColumnWidthByNumber(column, width) |
Ancho por número de columna |
| Método | Descripción |
|---|---|
SetRowHeight(height) |
Alto de la fila activa |
SetRowHeightByNumber(row, height) |
Alto por número de fila |
| Método | Descripción |
|---|---|
SetBold(bold) / ByRange / ByPos |
Negrita (1=sí, 0=no) |
SetItalic(italic) / ByRange / ByPos |
Cursiva |
SetFontSize(size) / ByRange / ByPos |
Tamaño en puntos (entero) |
SetFontName(name) / ByRange / ByPos |
Nombre de fuente |
SetFontColor(color) / ByRange / ByPos |
Color en formato "#RRGGBB" |
| Método | Descripción |
|---|---|
SetBgColor(color) / ByRange / ByPos |
Color de fondo "#RRGGBB" |
SetBorder(style) |
Los 4 lados — estilos: 0=ninguno 1=fino 2=medio 3=grueso |
SetTopBorder / SetBottomBorder / SetLeftBorder / SetRightBorder |
Lado individual |
SetBorderByRange / SetOutsideBorderByRange / SetInsideBorderByRange |
Rango completo |
SetTopBorderByRange / SetBottomBorderByRange |
Borde superior/inferior del rango |
| Método | Retorna | Descripción |
|---|---|---|
AddSheet(count) |
— | Agrega count hojas al libro |
SelectSheet(sheet) |
— | Selecciona hoja por índice (base 1) |
SelectSheetByName(name) |
— | Selecciona hoja por nombre |
GetSheetCount() |
SHORT |
Cantidad total de hojas |
GetSheetIndex() |
LONG |
Índice de la hoja activa |
GetSheetIndexByName(name) |
LONG |
Índice de una hoja por nombre |
GetSheetName() |
STRING |
Nombre de la hoja activa |
GetSheetNameByIndex(sheet) |
STRING |
Nombre de una hoja por índice |
SetSheetName(sheet, name) |
— | Renombra una hoja por índice |
| Método | Descripción |
|---|---|
About() |
Muestra un diálogo con la versión del control |
SDExcelCtrl es un reemplazo de MSExcel5 / MSOffice5 para sistemas que no tienen Excel instalado:
| Softmasters | SDExcelCtrl |
|---|---|
MSExcel5.Assign('A1', 'valor') |
SDExcel_Ctrl{'AssignByRange(""A1"",""valor"")'} |
MSExcel5.Save('archivo.xlsx') |
SDExcel_Ctrl{'Save(""archivo.xlsx"")'} |
MSExcel5.Close(0) |
SDExcel_Ctrl{'Close(0)'} |
Después de actualizar
SDExcelClass.incoSDExcelClass.clw, siempre usar Build → Build All (recompilación completa) en el IDE Clarion — nunca Build incremental.
Clarion mantiene la VMT (Virtual Method Table) de la clase por módulo. Si se agregan, eliminan o reordenan métodos en el INC y el proyecto se compila en forma incremental, los módulos que llaman a SDExcel quedan con una VMT desactualizada. El resultado es GPF en tiempo de ejecución: las llamadas a métodos aterrizan en la función equivocada, con parámetros de stack incorrectos.
Regla: cambio en INC/CLW → ConvertToAnsi.ps1 → Build All en cada app Clarion que use SDExcelClass.
- RegFree COM: La activación no requiere registro en el registry de Windows. El runtime encuentra el componente mediante
SDExcelCtrl.manifest, que debe estar junto aSDExcelCtrl.dllen el directorio del ejecutable host (el.exede Clarion). - CPCS / procedimientos de impresión: En procedimientos CPCS el
Event:OpenWindowes bloqueado porIF CPCSPaused; CYCLE.. La inicialización debe realizarse enTakeEvento directamente en elCODEsection después deOPEN(ProgressWindow). - Valores como texto:
AssignByPosy similares almacenan todos los valores comostring. AplicarSetNumberFormatsi se necesita que Excel reconozca el valor como número o fecha.
Distribuido bajo licencia MIT. Ver archivo LICENSE.