Estrecho contacto entre Delphi y Excel [Wang Anpeng ([email protected]) 14/4/2002] Como excelente RAD, la poderosa función de base de datos de Delphi es una de sus características más importantes, pero el control QuickReport, difícil de operar, a menudo no puede. Satisfacer las necesidades de informes de bases de datos. Si su informe es muy complejo o requiere flexibilidad en los cambios de formato, utilizar Excel como servidor de informes es una buena opción. El componente Excel proporcionado por Delphi a partir de la versión 5 simplifica enormemente la aplicación de la tecnología de automatización OLE. Sin embargo, los archivos de ayuda que faltan siempre han sido el aspecto más criticado de Delphi, y estos nuevos componentes no son una excepción. Este artículo intenta presentar esto con más detalle. El modelo de objetos de Excel es una estructura jerárquica en forma de árbol. La raíz es la aplicación en sí. El libro de trabajo es el objeto de atributo del objeto raíz. La hoja de trabajo utilizada para el intercambio de datos que se analiza principalmente en este artículo es el objeto de atributo del libro de trabajo. Para obtener más información, consulte el archivo de ayuda de MSOffice Excel VBA. Para controlar Excel en Delphi, primero debe establecer una conexión con el programa del servidor, abrir el libro, luego intercambiar datos con la hoja de trabajo de destino y finalmente desconectarse. Abra el libro de Excel. Nuestro ejemplo comienza con un formulario principal con un TStringGrid (por supuesto, es necesario completar algunos datos) y dos botones. Arrastre un control de aplicación TExce desde la pestaña Servidores del panel de control y colóquelo en el formulario. Primero, configure ConnectKind en ckRunningOrNew, lo que significa que si se puede detectar la instancia de Excel en ejecución, establezca contacto con ella; de lo contrario, inicie Excel. Además, si desea que el programa establezca contacto con el programa del servidor tan pronto como se ejecute, puede establecer la propiedad AutoConnect en True. Todo lo que se necesita para establecer contacto con Excel es una declaración: Excel Connect. Quizás haya notado que hay varios otros controles de Excel en la pestaña Servidores. Estos controles se pueden vincular al Excel anterior mediante el método ConnectTo: ExcelWorkbook1.ConnectTo(. Excel ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel. ActiveSheet como _Worksheet2.ConnectTo(Excel. Worksheets.Item['Sheet2']); _Worksheet); Cabe señalar que el libro de trabajo u hoja de trabajo correspondiente debe abrirse antes de usar el método ConnectTo. Además, estos controles no brindarán comodidad adicional en la mayoría de los casos, por lo que es mejor usar solo una TExcelApplication. Una vez que se establece el contacto con el servidor de Excel, se puede crear un nuevo libro: var wkBook: _WorkBook: Integer; ... LCID:= GetUserDefaultLCID(); función El primer parámetro se utiliza para definir la plantilla utilizada para el nuevo libro. Puede utilizar xlWBATChart, xlWBATExcel4IntlMacroSheet. Constante xlWBATExcel4MacroSheet o xlWBATWorksheet, o puede ser el nombre de un archivo xls existente. El EmptyParam aquí es la unidad Variantes y la variable definida, lo que significa usar la plantilla universal predeterminada para crear un nuevo libro. Si abre un documento xls existente, debe pasar el nombre del archivo que se abrirá como primer parámetro a la función Abrir: wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam , Param Vacío, Param Vacío, Param Vacío, Param Vacío, EmptyParam,EmptyParam,LCID); Debe saber que todas las operaciones de datos son principalmente para la hoja de trabajo activa. La siguiente declaración utiliza una variable _WorkSheet para representar la celda activa actual. Si conoce el nombre de la hoja de trabajo, el número de índice se puede reemplazar por el nombre de la hoja de trabajo: wkSheet:=wkBook.Sheets[1] as _WorkSheet Después de completar el intercambio de datos, debe guardar el libro de trabajo: Excel.ActiveWorkBook.SaveAs; ('MiSalida', VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, EmptyParam, EmptyParam, LCID); o: Excel.ActiveWorkBook.Save(LCID); Finalmente, cierre el libro y desconéctese de Excel: wkBook.Close(True, SaveAsName, EmptyParam, LCID); ; El método Cerrar aquí contiene la función de guardar. El primer parámetro indica si se deben guardar las modificaciones antes de cerrar el libro. El segundo parámetro proporciona el nombre del archivo que se guardará. El tercer parámetro se utiliza para que varios autores procesen la situación. La segunda línea solicita finalizar Excel. Intercambio de datos con la hoja de trabajo Los datos de entrada se realizan en una determinada celda o rango de la hoja de trabajo activa. Tanto el rango como las celdas son propiedades de objeto de la hoja de trabajo. Celdas es una colección de celdas si no se especifica una ubicación específica, puede representar todas las celdas de la hoja de trabajo completa. Sin embargo, generalmente se usa para hacer referencia a una celda específica. Por ejemplo, WS.Cells.Item[1,1]. representa la celda más reciente. Celda A1 en la esquina superior izquierda. Tenga en cuenta que Elemento es la propiedad predeterminada de Celdas en VBA y se puede omitir, pero no existe tal conveniencia en Delphi. Para asignar un valor a una celda, debe consultar su propiedad Valor. No hace falta decir que esta propiedad es una variable Variante, por ejemplo: wkSheet.Cells.Item[1, 1].Value := 'Libreta de direcciones'; Por supuesto, también puede asignar un valor a una celda. Especifique la fórmula: var AFormula:String …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; El método anterior es muy directo y simple, pero es muy lento y no es adecuado para informes grandes. Entonces, ¿se pueden transferir todos los datos a Excel en secuencia? Podemos usar Rango. Este objeto representa un área en la hoja de trabajo. A medida que lo arrastramos con el mouse, generalmente es un área rectangular. Simplemente proporcione las posiciones de las celdas de la esquina superior izquierda y la esquina inferior derecha, como Rango ['C3. ','J42']. Aquí hay un pequeño problema, porque si los datos exceden las 26 columnas (por ejemplo, hay 100 columnas) o si el rango objetivo debe determinarse sobre la marcha, es más problemático usar nombres de caracteres para marcar las celdas. Recuerde que dado que "C3" es la etiqueta de la celda, por supuesto también podemos usar Celdas, como Rango[Cells.Item[1,1], Cells.Item[100,100]]. Es concebible que el valor de Range sea una matriz, ¡pero no debes usar Array en Delphi para asignarle un valor! Recuerda que en Delphi el valor de un objeto de Excel siempre es de tipo Variante. var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //Crea una matriz dinámica de 100*100… //Asigna valores al elementos de matriz aquí con wkSheet do Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; Cabe señalar que tanto la hoja de trabajo como el Rango tienen la propiedad Celdas. Para mayor claridad, aquí se utiliza la declaración with. Además, el Rango es direccional. Una matriz unidimensional creada con VarArrayCreate solo se puede asignar a un Rango de una sola fila. Si desea definir un valor para un Rango de una sola columna, debe usar una matriz bidimensional, por ejemplo. ejemplo: Datas:=VarArrayCreate([1,100,1 ,1], varVariant); //Crea una matriz dinámica de 100*1. Por cierto, Cells.Item[] en realidad devuelve un objeto Range. Recuperar datos de la hoja de trabajo es básicamente el proceso inverso de escribir datos. A lo que se debe prestar atención es a cómo determinar el rango de datos de la hoja de trabajo: var ir, ic: Integer …… wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam; ).Activar; ir := Excel.ActiveCell.Row; ic := Excel.ActiveCell.Columna; La función de celda especial SpecialCells se utiliza inteligentemente aquí para obtener la última celda que contiene datos. Edición de datos A continuación se muestran dos ejemplos de edición de datos. var DestRange: OleVariant; comenzar DestRange := Excel.Range['C1', 'D4']; Excel.Range['A1', 'B4'].Copy(DestRange); Si pasa un parámetro vacío a la función Copiar, los datos de esta área se copian al portapapeles y se pueden pegar en otras ubicaciones utilizando el método Pegar más adelante. var WS: _Worksheet; …… Excel.Range['A1', 'B4'].Copy(EmptyParam); //Copiar datos en una hoja de trabajo al portapapeles WS := Excel.Activesheet como _Worksheet; .Rango['C1', 'D4'].Seleccione; WS.Paste(EmptyParam, EmptyParam, lcid); //Pegue el contenido del portapapeles en una nueva hoja de trabajo. Configuración de formato Elija Excel como servidor de informes principalmente por sus poderosas capacidades de formato. Primero fusionamos las celdas con el título "Libreta de direcciones" y las mostramos en el centro, y luego cambiamos la fuente a "script oficial" de 18 puntos en negrita: con wkSheet.Range['A1','D1'],Font comenzar Merge(True); //Fusionar celdas HorizontalAlignment:= xlCenter; Si el contenido de la celda es largo, parte del contenido no se mostrará. El método habitual es hacer doble clic en el borde derecho del área seleccionada para que el ancho de cada columna se adapte automáticamente a la longitud del contenido. En Delphi, el ancho de columna y la altura de fila adaptables también se pueden lograr mediante el método AutoFit. Cabe señalar que este método solo se puede usar para toda la fila y toda la columna; de lo contrario, se generará un error de negativa a ejecutar el método OLE: wkSheet.Columns.EntireColumn.AutoFit; los informes de estilo chino generalmente requieren líneas de tabla con límites superiores e inferiores, y puede usar el atributo de colección Borders. Cabe señalar que los objetos de colección en VBA generalmente tienen una propiedad Item predeterminada, que no se puede omitir en Delphi. La propiedad Peso se utiliza para definir el grosor de las líneas de la tabla: con Aname.RefersToRange,Borders comienzan HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium Item[xlEdgeTop].Weight:=xl Item[xlInsideHorizontal] .Peso: =xlDelgado; item[xlInsideVertical].Weight:=xlThin; la configuración de página y la configuración de impresión de página se configuran a través de la propiedad del objeto PageSetUp de la hoja de trabajo. Hay más de 40 constantes de papel preestablecidas en Excel VBA. Cabe señalar que algunas impresoras sólo admiten algunos de los tipos de papel. El atributo Orientación se utiliza para controlar la dirección de impresión, y el paisaje constante = 2 indica impresión horizontal. Las propiedades booleanas CenterHorizontally y CenterVertically se utilizan para determinar si el contenido impreso está centrado horizontal y verticalmente. con wkSheet.PageSetUp comience PaperSize:=xlPaperA4; //Tipo de papel A4 PRintTitleRows := 'A1:D1'; //Repita esta fila/página LeftMargin:=18; //0.25" Left Margin RightMargin:=18; // 0,25" variará entre impresoras TopMargin:=36; //0,5" BottomMargin:=36; //0.5" CenterHorizontally:=True; Orientation:=1; //Impresión horizontal (horizontal)=2, vertical=1 end; Para imprimir un informe, puede llamar al método PrintOut de la hoja de trabajo. Este método definido por VBA tiene 8 parámetros opcionales, los dos primeros se usan para especificar las páginas inicial y final, y el número de copias que se imprimirán en el tercer formato. Sin embargo, en Delphi, se agrega un parámetro LCID al final y no se puede usar EmptyParam. para este parámetro. De manera similar, el método de vista previa de impresión PrintPreview no tiene parámetros en VBA, pero requiere dos parámetros cuando se llama en Delphi. // wkBook.PrintPreview(True,LCID); //para obtener una vista previa wkSheet.PrintOut(EmptyParam,EmptyParam,1, EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,LCID) Si el formato del informe es. Más complejo. Un mejor enfoque es nombrar rangos de tablas específicos y luego hacer referencia a ellos por su nombre. Names es una propiedad de objeto de colección de WorkBook, que tiene un método Add que puede realizar este trabajo. Var Aname: Excel2000.Name; …… Aname:= wkBook.Names.Add('Libreta de direcciones','=Sheet1!$A$3:$D$7', VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, ParamVaciado,ParamVaciado); El primer parámetro de la función Agregar es el nombre definido y el segundo parámetro es el rango de celdas representado por el nombre. Cabe señalar que el tipo del nombre del rango debe usar un calificador. Si se usa una biblioteca de tipos (D4), el calificador es Excel_TLB. Además, el rango nombrado debe usar una referencia absoluta, es decir, agregar el símbolo "$". Una vez que nombre un rango, puede hacer referencia a él con ese nombre. La siguiente línea de código hace que el contenido de la libreta de direcciones aparezca en negrita: AName.RefersToRange.Font.Bold:=True Pero quizás lo más sorprendente es que puede hacerlo dinámicamente. ¡Modifique los programas de macros de Excel en Delphi! El siguiente código crea una macro para nuestro libro de trabajo que registra la hora del último acceso al cerrar el libro: var LineNo: integer; CM: CodeModule:String; comenzar CM := WkBook.VBProject.VBComponents.Item( 'ThisWorkbook'). Módulo de código; LineNo:= CM.CreateEventProc('BeforeClose', 'Libro de trabajo'); SDate:='Última fecha de acceso:'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+''"'); la macro Agregue una unidad a la sección de usos anterior: VBIDE2000 Si se utiliza una biblioteca de tipos, la unidad correspondiente es VBIDE_TLB. La clave de este código es el objeto CodeModule Desafortunadamente, no hay rastro de este objeto en el documento de ayuda de Excel VBA, por lo que solo podemos buscar en MSDN. Delphi4 y versiones anteriores Delphi4 no proporcionan el objeto TExcelApplication y es necesario introducir una biblioteca de tipos para utilizar la tecnología de automatización OLE. La biblioteca de tipos de Excel97 es Excel8.olb. La principal diferencia entre estos dos métodos es el método para establecer una conexión con el programa del servidor. El siguiente es el marco del programa para controlar Excel a través de la biblioteca de tipos: utiliza Windows, ComObj, ActiveX, Excel_TLB: _Application: entero; ; Desconocido: IDesconocido Resultado: HResultado; comenzar LCID: = LOCALE_USER_DEFAULT Resultado: = GetActiveObject (CLASS_Application, nulo; Desconocido); //Intenta capturar la instancia del programa en ejecución si (Resultado = MK_E_UNAVAILABLE) luego Excel := CoApplication.Create //Inicia una nueva instancia del programa; de lo contrario, comienza {Verificar errores durante la llamada al método GetActiveObject} OleCheck(Resultado); (Unknown.QueryInterface(_Application, Excel)); fin …… //Realizar procesamiento de datos Excel.Visible[LCID] := True; // Excel.DisplayAlerts[LCID] := False; //Mostrar el cuadro de diálogo Excel.Quit La estructura habitual try...except no se utiliza aquí porque el mecanismo de manejo de excepciones requiere comprobaciones OLE complejas; el costo La velocidad de ejecución de la parte excepto. Cabe señalar que la función CoApplication que la acompaña y algunos nombres constantes generados por diferentes versiones de Delphi pueden ser diferentes, por lo que debe verificar la biblioteca de tipos correspondiente. Antes de llamar al método Quit, asegúrese de liberar todas las variables de libros y hojas de cálculo creadas en el programa; de lo contrario, Excel puede residir en la memoria y ejecutarse (puede presionar Ctrl+Alt+Supr para ver). Hay un pequeño problema al llamar a GetActiveObject para capturar la instancia del programa. Si Excel está en un estado de ejecución minimizado, es posible que solo se muestre el marco principal del programa y el área del usuario no sea visible. Además, si no desea introducir una biblioteca de tipos, también puede utilizar el enlace retrasado, pero es mucho más lento. El siguiente ejemplo declara una variable Variant para representar la aplicación de Excel: var Excel: Variant; ... intente Excel := GetActiveOleObject('Excel.Application'); excepto Excel := CreateOleObject('Excel.Application'); .Visible := Verdadero; Cuando se utiliza el enlace retrasado, el compilador no verifica el método del objeto de Excel llamado, sino que deja estas tareas al programa del servidor para que las complete durante la ejecución. De esta manera, una gran cantidad de parámetros predeterminados establecidos por VBA (a menudo más de una docena). se utilizan como deberían funcionar, por lo que este método tiene un beneficio inesperado: el código es conciso: var WBk, WS, SheetName: OleVariant; ..... WBk := Excel.WorkBooks.Open('C:/Test. xls');WS := WBk.Worksheets.Item['SheetName']; WS.Activate; …… WBk.Close(SaveChanges := True); Además de ejecutarse lentamente, si desea utilizar constantes definidas en la biblioteca de tipos; , solo puedes hacerlo tú mismo: const xlWBATWorksheet = -4167 …… XLApp.Workbooks.Add(xlWBatWorkSheet); Finalmente, no olvide liberar las variables después de cerrar Excel: Excel := Unassigned; el siguiente es el código fuente utilizado en el ejemplo de este artículo, pasado bajo Delphi6+MSOffice2000. unidad Unidad1; la interfaz utiliza Windows, Mensajes, SysUtils, Variantes, Clases, Gráficos, Controles, Formularios, Diálogos, OleServer, Excel2000, Cuadrículas, StdCtrls tipo TForm1 = clase(TForm) Botón1: TButton1: TStringGrid Excel: TExcelApplication; procedimiento FormActivate(Remitente: TObject procedimiento); Button1Click (Remitente: TObject); procedimiento privado {Declaraciones privadas} Write2Xls; procedimiento OpenExl; procedimiento AddFormula; procedimiento NameSheet; TForm1; ; la implementación {$R *.dfm} usa VBIDE2000; hoja de trabajo:_Hoja de trabajo; LCID:Entero; libro de trabajo:_Libro de trabajo; Rows[1].CommaText:='Zhang San, hombre, 25,010-33775566'; Rows[2].CommaText:='Li Si, hombre, 47,012-6574906'; Rows[3].CommaText:='Viernes, mujer ,18,061-7557381'; Filas[4].CommaText:='Sun Tao, mujer, 31,3324559'; final; procedimiento TForm1.OpenExl; comience con Excel LCID:=GetUserDefaultLCID(); , LCID); wkSheet:=wkBook.Sheets[1] como fin del procedimiento; TForm1.Write2Xls; var Datos:Variante; i,j:Integer; comenzar ir:=StringGrid1.RowCount; ic:=StringGrid1.ColCount; :=1 para hacer para j:=1 para hacer Datas[i,j]:=StringGrid1.Cells[j-1,i-1]; con wkSheet comience Activate(LCID); Cells.Item[1,1].Value:='Libro de direcciones'; .Item[3,1],cells.Item[ir+2,ic]].Valor:=Datos; // Excel.Visible[LCID]:=True; Datos:=Sin asignar; finalizar; procedimiento TForm1.Retrieve; var Datas:Variant; i,j:Integer; comenzar con wkSheet Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).Activar; =Excel.ActiveCell.Columna; Datas:=Range[Cells.Item[1,1],Cells.Item[ir,ic]].Value; con StringGrid1 comienza ColCount:=ic RowCount:=ir; a ir-1 hacer para j:=0 a ic-1 hacer Celdas[j,i]:=Datos[i+1,j+1]; Datos:=Sin asignar; finalizar; procedimiento TForm1.CloseExl; const SaveAsName='test.xls'; comenzar wkBook.Close(True,SaveAsName,EmptyParam,LCID); Hoja de nombre; comenzar AName:=wkBook.Names.Add('Libreta de direcciones','=Sheet1!$A$3:$D$7',EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam end; .AddFormula; var AFormula:Cadena comenzar; AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Valor:=AFormula; procedimiento TForm1.Formats; comenzar con wkSheet.Range['A1','D1'] Fuente comienza Merge(True); //Fusionar celdas HorizontalAlignment:= xlCenter Tamaño:=18 Nombre:='script oficial'; FontStyle:=Bold; wkSheet.Columns.EntireColumn.AutoFit; con Aname.RefersToRange, los bordes comienzan con HorizontalAlignment:= xlRight;Peso:=xlMedio; Artículo[xlInsideHorizontal].Peso:=xlThin; elemento[xlInsideVertical].Peso:=xlThin; fin; procedimiento TFOrm1.AddMacro; entero; sDate:String; VBComponents.Item('ThisWorkbook').Codemodule; := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='Última fecha de acceso:'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+'"'); fin; el procedimiento TForm1.Printit comienza con wkSheet.PageSetUp. PaperSize:=xlPaperA4; //Tipo de papel A4 PrintTitleRows := 'A1:D1'; //Repetir esta fila/página LeftMargin:=18; //0.25" Left Margin RightMargin:=18; //0.25" variará entre impresoras TopMargin:=36; //0.5" BottomMargin:=36; //0.5" CenterHorizontally:=True; Orientación:=1; //Paisaje=2, retrato=1 fin; wkSheet.PrintOut(EmptyParam,EmptyParam,1, EmptyParam,EmptyParam,EmptyParam,EmptyParam,LCID fin; ; comience a probar OpenExl; Write2xls; NameSheet; PrintIt; AddMacro; finalmente CloseExl final; fin de Delphi, potente base de datos. Una de sus características más importantes, pero el control QuickReport, difícil de operar, a menudo no puede satisfacer las necesidades de los informes de la base de datos. Si su informe es muy complejo o requiere flexibilidad en los cambios de formato, utilizar Excel como servidor de informes es una buena opción. El componente Excel proporcionado por Delphi a partir de la versión 5 simplifica enormemente la aplicación de la tecnología de automatización OLE. Sin embargo, los archivos de ayuda que faltan siempre han sido el aspecto más criticado de Delphi, y estos nuevos componentes no son una excepción. Este artículo intenta presentar esto con más detalle. El modelo de objetos de Excel es una estructura jerárquica en forma de árbol. La raíz es la aplicación en sí. El libro de trabajo es el objeto de atributo del objeto raíz. La hoja de trabajo utilizada para el intercambio de datos que se analiza principalmente en este artículo es el objeto de atributo del libro de trabajo. Para obtener más información, consulte el archivo de ayuda de MSOffice Excel VBA. Para controlar Excel en Delphi, primero debe establecer una conexión con el programa del servidor, abrir el libro, luego intercambiar datos con la hoja de trabajo de destino y finalmente desconectarse. Abra el libro de Excel. Nuestro ejemplo comienza con un formulario principal con un TStringGrid (por supuesto, es necesario completar algunos datos) y dos botones. Arrastre un control TExcelApplication desde la pestaña Servidores del panel de control y colóquelo en el formulario. Primero, configure ConnectKind en ckRunningOrNew, lo que significa que si se puede detectar la instancia de Excel en ejecución, establezca contacto con ella; de lo contrario, inicie Excel. Además, si desea que el programa establezca contacto con el programa del servidor tan pronto como se ejecute, puede establecer la propiedad AutoConnect en True. Todo lo que se necesita para establecer contacto con Excel es una declaración: Excel Connect. Quizás haya notado que hay varios otros controles de Excel en la pestaña Servidores. Estos controles se pueden vincular al Excel anterior mediante el método ConnectTo: ExcelWorkbook1.ConnectTo(. Excel ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel. ActiveSheet como _Worksheet2.ConnectTo(Excel. Worksheets.Item['Sheet2']); _Worksheet); Cabe señalar que el libro de trabajo u hoja de trabajo correspondiente debe abrirse antes de usar el método ConnectTo. Además, estos controles no brindarán comodidad adicional en la mayoría de los casos, por lo que es mejor usar solo una TExcelApplication. Una vez que se establece el contacto con el servidor de Excel, se puede crear un nuevo libro: var wkBook: _WorkBook: Integer; ... LCID:= GetUserDefaultLCID(); función El primer parámetro se utiliza para definir la plantilla utilizada para el nuevo libro. Puede utilizar xlWBATChart, xlWBATExcel4IntlMacroSheet. Constante xlWBATExcel4MacroSheet o xlWBATWorksheet, o puede ser el nombre de un archivo xls existente. El EmptyParam aquí es la unidad Variantes y la variable definida, lo que significa usar la plantilla universal predeterminada para crear un nuevo libro. Si abre un documento xls existente, debe pasar el nombre del archivo que se abrirá como primer parámetro a la función Abrir: wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam , Param Vacío, Param Vacío, Param Vacío, Param Vacío, EmptyParam,EmptyParam,LCID); Debe saber que todas las operaciones de datos son principalmente para la hoja de trabajo activa. La siguiente declaración utiliza una variable _WorkSheet para representar la celda activa actual. Si conoce el nombre de la hoja de trabajo, el número de índice se puede reemplazar por el nombre de la hoja de trabajo: wkSheet:=wkBook.Sheets[1] as _WorkSheet Después de completar el intercambio de datos, debe guardar el libro de trabajo: Excel.ActiveWorkBook.SaveAs; ('MiSalida', VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, VacíoParam, EmptyParam, EmptyParam, LCID); o: Excel.ActiveWorkBook.Save(LCID); Finalmente, cierre el libro y desconéctese de Excel: wkBook.Close(True, SaveAsName, EmptyParam, LCID); ; El método Cerrar aquí contiene la función de guardar. El primer parámetro indica si se deben guardar las modificaciones antes de cerrar el libro. El segundo parámetro proporciona el nombre del archivo que se guardará. El tercer parámetro se utiliza para que varios autores procesen la situación. La segunda línea solicita finalizar Excel. Intercambio de datos con la hoja de trabajo Los datos de entrada se realizan en una determinada celda o rango de la hoja de trabajo activa. Tanto el rango como las celdas son propiedades de objeto de la hoja de trabajo. Celdas es una colección de celdas si no se especifica una ubicación específica, puede representar todas las celdas de la hoja de trabajo completa. Sin embargo, generalmente se usa para hacer referencia a una celda específica. Por ejemplo, WS.Cells.Item[1,1]. representa la celda más reciente. Celda A1 en la esquina superior izquierda. Tenga en cuenta que Elemento es la propiedad predeterminada de Celdas en VBA y se puede omitir, pero no existe tal conveniencia en Delphi. Para asignar un valor a una celda, debe consultar su propiedad Valor. No hace falta decir que esta propiedad es una variable Variante, por ejemplo: wkSheet.Cells.Item[1, 1].Value := 'Libreta de direcciones'; Por supuesto, también puede asignar un valor a una celda. Especifique la fórmula: var AFormula:String …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; El método anterior es muy directo y simple, pero es muy lento y no es adecuado para informes grandes. Entonces, ¿se pueden transferir todos los datos a Excel en secuencia? Podemos usar Rango. Este objeto representa un área en la hoja de trabajo. A medida que lo arrastramos con el mouse, generalmente es un área rectangular. Simplemente proporcione las posiciones de las celdas de la esquina superior izquierda y la esquina inferior derecha, como Rango ['C3. ','J42']. Aquí hay un pequeño problema, porque si los datos exceden las 26 columnas (por ejemplo, hay 100 columnas) o si el rango objetivo debe determinarse sobre la marcha, es más problemático usar nombres de caracteres para marcar las celdas. Recuerde que dado que "C3" es la etiqueta de la celda, por supuesto también podemos usar Celdas, como Rango[Cells.Item[1,1], Cells.Item[100,100]]. Es concebible que el valor de Range sea una matriz, ¡pero no debes usar Array en Delphi para asignarle un valor! Recuerda que en Delphi el valor de un objeto de Excel siempre es de tipo Variante. var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //Crea una matriz dinámica de 100*100… //Asigna valores al elementos de matriz aquí con wkSheet do Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; Cabe señalar que tanto la hoja de trabajo como el Rango tienen la propiedad Celdas. Para mayor claridad, aquí se utiliza la declaración with. Además, el Rango es direccional. Una matriz unidimensional creada con VarArrayCreate solo se puede asignar a un Rango de una sola fila. Si desea definir un valor para un Rango de una sola columna, debe usar una matriz bidimensional, por ejemplo. ejemplo: Datas:=VarArrayCreate([1,100,1 ,1], varVariant); //Crea una matriz dinámica de 100*1. Por cierto, Cells.Item[] en realidad devuelve un objeto Range. Recuperar datos de la hoja de trabajo es básicamente el proceso inverso de escribir datos. A lo que se debe prestar atención es a cómo determinar el rango de datos de la hoja de trabajo: var ir, ic: Integer …… wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam; ).Activar; ir := Excel.ActiveCell.Row; ic := Excel.ActiveCell.Columna; La función de celda especial SpecialCells se utiliza inteligentemente aquí para obtener la última celda que contiene datos. Edición de datos A continuación se muestran dos ejemplos de edición de datos. var DestRange: OleVariant; comenzar DestRange := Excel.Range['C1', 'D4']; Excel.Range['A1', 'B4'].Copy(DestRange); Si pasa un parámetro vacío a la función Copiar, los datos de esta área se copian al portapapeles y se pueden pegar en otras ubicaciones utilizando el método Pegar más adelante. var WS: _Worksheet; …… Excel.Range['A1', 'B4'].Copy(EmptyParam); //Copiar datos en una hoja de trabajo al portapapeles WS := Excel.Activesheet como _Worksheet; .Rango['C1', 'D4'].Seleccione; WS.Paste(EmptyParam, EmptyParam, lcid); //Pegue el contenido del portapapeles en una nueva hoja de trabajo. Configuración de formato Elija Excel como servidor de informes principalmente por sus poderosas capacidades de formato. Primero fusionamos las celdas con el título "Libreta de direcciones" y las mostramos en el centro, y luego cambiamos la fuente a "script oficial" de 18 puntos en negrita: con wkSheet.Range['A1','D1'],Font comenzar Merge(True); //Fusionar celdas HorizontalAlignment:= xlCenter; Si el contenido de la celda es largo, parte del contenido no se mostrará. El método habitual es hacer doble clic en el borde derecho del área seleccionada para que el ancho de cada columna se adapte automáticamente a la longitud del contenido. En Delphi, el ancho de columna y la altura de fila adaptables también se pueden lograr mediante el método AutoFit. Cabe señalar que este método solo se puede usar para toda la fila y toda la columna; de lo contrario, se generará un error de negativa a ejecutar el método OLE: wkSheet.Columns.EntireColumn.AutoFit; los informes de estilo chino generalmente requieren líneas de tabla con límites superiores e inferiores, y puede usar la propiedad de colección Borders. Cabe señalar que los objetos de colección en VBA generalmente tienen una propiedad Item predeterminada, que no se puede omitir en Delphi. La propiedad Peso se utiliza para definir el grosor de las líneas de la tabla: con Aname.RefersToRange,Borders comienzan HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium Item[xlEdgeTop].Weight:=xl Item[xlInsideHorizontal] .Peso: =xlDelgado; item[xlInsideVertical].Weight:=xlThin; la configuración de página y la configuración de impresión de página se configuran a través de la propiedad del objeto PageSetUp de la hoja de trabajo. Hay más de 40 constantes de papel preestablecidas en Excel VBA. Cabe señalar que algunas impresoras sólo admiten algunos de los tipos de papel. El atributo Orientación se utiliza para controlar la dirección de impresión, y el paisaje constante = 2 indica impresión horizontal. Las propiedades booleanas CenterHorizontally y CenterVertically se utilizan para determinar si el contenido impreso está centrado horizontal y verticalmente. con wkSheet.PageSetUp comience PaperSize:=xlPaperA4; //Tipo de papel A4 PrintTitleRows := 'A1:D1'; //Repita esta fila/página LeftMargin:=18; //0.25" Left Margin RightMargin:=18; // 0,25" variará entre impresoras TopMargin:=36; //0,5" BottomMargin:=36; //0,5" CenterHorizontally:=True; Orientation:=1; //Impresión horizontal (paisaje)=2, vertical=1 end; Para imprimir un informe, puede llamar al método PrintOut de la hoja de trabajo. Parámetros opcionales, los dos primeros se utilizan para especificar las páginas inicial y final y el número de copias impresas en el tercer formato. Sin embargo, en Delphi, se agrega un parámetro LCID al final y VacuumParam no se puede utilizar para este parámetro. De manera similar, el método de vista previa de impresión PrintPreview no tiene parámetros en VBA, pero requiere dos parámetros cuando se llama en Delphi. // wkbook.printpreview (true, lcid); Más complejo, un mejor enfoque es nombrar rangos de tabla específicos y luego hacerlas referirlos por su nombre. Names es una propiedad de objeto de colección de Workbook, que tiene un método ADD que puede hacer este trabajo. Var aname: Excel2000.name; SewyParam, vacío); El primer parámetro de la función ADD es el nombre definido, y el segundo parámetro es el rango de celda representado por el nombre. Cabe señalar que el tipo de nombre de rango debe usar un calificador. Además, el rango nombrado debe usar referencia absoluta, es decir, agregar el símbolo "$". Una vez que nombra un rango, puede hacer referencia a ese nombre. ¡Modifique los programas macro de Excel en Delphi! El siguiente código crea una macro para nuestro libro de trabajo que registra el último tiempo de acceso al cerrar el libro: VAR Lineno: Integer; CodeModule; Sdate: = 'Última fecha de acceso:'+dataToStr (date ()); La macro agregue una unidad a la sección de usos anteriores: VBIDE2000. La clave de este código es el objeto CodeModule. Delphi4 y versiones anteriores Delphi4 no proporcionan el objeto Texcelapplication, y se debe introducir una biblioteca de tipos para usar la tecnología de automatización OLE. La principal diferencia entre estos dos métodos es el método para establecer una conexión con el programa del servidor. ; Desconocido); (Desconocido.QueryInterface (_Application, Excel)); Verdadero; El costo de la velocidad de ejecución de la parte excepto. Cabe señalar que la coplelación de la función acompañante y algunos nombres constantes generados por diferentes versiones de Delphi pueden ser diferentes, por lo que debe verificar la biblioteca de tipos correspondiente. Antes de llamar al método de dejar de fumar, asegúrese de lanzar todas las variables de libros y hojas de trabajo creadas en el programa, de lo contrario, Excel puede residir en la memoria y ejecutar (puede presionar Ctrl+Alt+del para ver). Todavía hay un pequeño problema para llamar a la instancia del programa de captura GetActiveObject. Además, si no desea introducir la biblioteca de tipos, también puede usar el método para rezagar la unión, pero la velocidad es mucho más lenta. El siguiente ejemplo muestra una variable variable para representar aplicaciones de Excel: Varxcel: Variant; : = verdadero; Al usar la vinculación de retraso, el compilador no verifica el método de objeto de Excel llamado, y entrega estas tareas al programa del servidor y lo completa durante la ejecución, de modo que una gran cantidad de parámetros predeterminados (más de una docena) establecerán por VBA. jugado. ); : = Wbk.works.item ['SheetName']; . XLAPP.WORKBOOKS.Add (xlwbatworksheet); Finalmente, no se olvide de liberar la variable después de apagar Excel: Excel: = Unassigned; Unidad de la unidad1; ; Button1Clectione Implementación {$ r *.dfm} usa VBIDE2000; wksheet: _worksheet; Filas [1] .commatext: = 'zhang san, hombre, 25,010-33775566'; Filas [4]. Hojas [1] como hojas de trabajo; TForm1.write2xls; a ic hacer DataS [i, j]: = stringGrid1.Cells [J-1, I-1]; [Células .Item [3,1], Cells.Item [IR+2, IC]]. Datas: = Unasignado; .columna; DataS: = Range [Cells.Item [1,1], Cells.Item [IR, IC]]. : = 0 a IC-1 do Cells [J, I]: = DataS [i+1, j+1]; DataS: = Aname: = wkbook.names.Add ('Libro de direcciones', '= Hoja! ADDFORMULA; Aformula: = '= rand ()'; xlcenter; Fontstyle: = Bold; Elemento [XlinsideHorizTal]. . : = Cm.CreateEventProc ('BeforecLose', 'Libro de trabajo'); Comience con wksheet.pagesetup Do Comen Papersize: = xlpaperA4; : = 36; Orientación: = 1; ; Nam.