Delphi와 Excel의 긴밀한 접촉 [Wang Anpeng ([email protected]) 2002/4/14] 뛰어난 RAD로서 Delphi의 강력한 데이터베이스 기능은 가장 중요한 기능 중 하나이지만 작동하기 어려운 QuickReport 컨트롤은 종종 데이터베이스 보고 요구 사항을 충족합니다. 보고서가 매우 복잡하거나 형식 변경에 유연성이 필요한 경우 Excel을 보고서 서버로 사용하는 것이 좋습니다. Delphi 버전 5부터 제공되는 Excel 구성 요소는 OLE 자동화 기술 적용을 크게 단순화합니다. 그러나 누락된 도움말 파일은 항상 Delphi의 가장 큰 비판을 받아 왔으며 이 새로운 구성 요소도 예외는 아닙니다. Excel의 개체 모델은 트리와 같은 계층 구조입니다. 루트는 응용 프로그램 자체입니다. WorkBook은 루트 개체의 속성 개체입니다. 이 문서에서 주로 설명하는 데이터 교환에 사용되는 WorkSheet는 워크북의 속성 개체입니다. 자세한 내용은 MSOffice.Excel VBA 도움말 파일을 참조하세요. 델파이에서 엑셀을 제어하려면 먼저 서버 프로그램과 연결을 하고, 워크북을 연 뒤, 대상 워크시트와 데이터를 교환하고, 마지막으로 연결을 끊어야 한다. Excel 통합 문서 열기 우리의 예는 TStringGrid(물론 일부 데이터를 채워야 함)와 두 개의 버튼이 있는 기본 폼으로 시작합니다. 제어판의 서버 탭에서 TExcelapplication 컨트롤을 끌어서 폼에 배치합니다. 먼저 ConnectKind를 ckRunningOrNew로 설정합니다. 즉, 실행 중인 Excel 인스턴스가 감지되면 연결을 설정하고 그렇지 않으면 Excel을 시작합니다. 또한 프로그램이 실행되자마자 서버 프로그램과 연결되도록 하려면 AutoConnect 속성을 True로 설정하면 됩니다. Excel과의 연결을 설정하는 데 필요한 것은 Excel 입니다. 서버 탭에 여러 다른 Excel 컨트롤이 있다는 것을 눈치챘을 것입니다. 이러한 컨트롤은 ConnectTo 메서드를 통해 이전 Excel에 연결될 수 있습니다. Excel .ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel .ActiveSheet as _Worksheet); ExcelWorksheet2.ConnectTo(Excel .Worksheets.Item['Sheet2'] _Worksheet); ConnectTo 메서드를 사용하기 전에 해당 통합 문서나 워크시트를 열어야 한다는 점에 유의해야 합니다. 또한 이러한 컨트롤은 대부분의 경우 추가적인 편의성을 제공하지 않으므로 TExcelApplication을 하나만 사용하는 것이 가장 좋습니다. Excel 서버와의 연결이 설정되면 새 통합 문서를 만들 수 있습니다. var wkBook : LCID : Integer; ... LCID := GetUserDefaultLCID() := Excel.Workbooks.Add(EmptyParam, LCID); 함수 첫 번째 매개변수는 새 통합 문서에 사용되는 템플릿을 정의하는 데 사용됩니다. xlWBATChart, xlWBATExcel4IntlMacroSheet, xlWBATExcel4MacroSheet 또는 xlWBATWorksheet 상수이거나 기존 xls 파일의 이름일 수 있습니다. 여기서 EmptyParam은 Variants 단위 및 정의된 변수입니다. 이는 기본 범용 템플릿을 사용하여 새 통합 문서를 만드는 것을 의미합니다. 기존 xls 문서를 여는 경우 열려는 파일 이름을 Open 함수의 첫 번째 매개 변수로 전달해야 합니다. wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam , EmptyParam,EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,LCID); 다음 문은 _WorkSheet 변수를 사용하여 현재 활성 셀을 나타내는 모든 데이터 작업을 수행한다는 점을 알아야 합니다. 워크시트 이름을 알고 있는 경우 색인 번호를 워크시트 이름으로 바꿀 수 있습니다: wkSheet:=wkBook.Sheets[1] as _WorkSheet; 데이터 교환을 완료한 후 통합 문서를 저장해야 합니다: Excel.ActiveWorkBook.SaveAs ('MyOutput', EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam, 빈 매개변수, 빈 매개 변수, LCID); 또는: Excel.ActiveWorkBook.Save(LCID); 마지막으로 통합 문서를 닫고 Excel과의 연결을 끊습니다. wkBook.Close(True, SaveAsName, 빈 매개 변수, LCID) //Excel.Quit; ; 여기서 Close 메소드에는 저장 기능이 포함되어 있습니다. 첫 번째 매개변수는 통합 문서를 닫기 전에 수정 사항을 저장할지 여부를 나타내며, 세 번째 매개변수는 여러 작성자가 문서를 처리하는 데 사용됩니다. 두 번째 줄에서는 Excel을 종료할지 묻습니다. 워크시트와 데이터 교환 입력 데이터는 활성 워크시트의 특정 셀 또는 범위에서 수행되며 범위는 모두 워크시트의 개체 속성입니다. 셀은 셀의 집합으로, 특정 위치를 지정하지 않으면 전체 워크시트의 모든 셀을 나타낼 수 있지만 일반적으로 특정 셀을 참조하는 데 사용됩니다. 왼쪽 상단에 있는 셀 A1은 가장 최근 셀을 나타냅니다. Item은 VBA에서 Cells의 기본 속성이므로 생략할 수 있지만 Delphi에서는 이러한 편리함이 없습니다. 셀에 값을 할당하려면 해당 Value 속성을 참조해야 합니다. 이 속성은 당연히 Variant 변수입니다(예: wkSheet.Cells.Item[1, 1].Value := 'Address Book';). 물론 셀에 값을 지정할 수도 있습니다. var AFormula:String; …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; 위 방법은 매우 직접적이고 간단하지만 속도가 매우 느리고 대규모 보고서에는 적합하지 않습니다. 그러면 모든 데이터를 순차적으로 엑셀로 전송할 수 있나요? Range를 사용할 수 있습니다. 이 개체는 마우스로 드래그할 때 일반적으로 직사각형 영역을 나타냅니다. 예를 들어 Range[ 'C3 ','J42']. 여기에는 작은 문제가 있습니다. 데이터가 26열을 초과하거나(예: 100열이 있음) 대상 영역 범위를 즉시 결정해야 하는 경우 문자 이름을 사용하여 셀을 표시하는 것이 더 번거롭기 때문입니다. "C3"은 셀의 레이블이므로 Range[Cells.Item[1,1], Cells.Item[100,100]]과 같은 셀을 사용할 수도 있습니다. Range의 값은 배열이어야 한다고 생각할 수 있지만 Delphi에서 Array를 사용하여 값을 할당하면 안 됩니다! Delphi에서 Excel 개체의 값은 항상 Variant 유형이라는 점을 기억하십시오. var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //여기서 100*100 동적 배열을 생성합니다... // 여기에 wkSheet do Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas;를 사용하여 요소를 배열합니다. 여기서는 워크시트와 Range 모두 Cells 속성을 가지고 있다는 점에 유의해야 합니다. 또한 Range는 방향성이 있습니다. VarArrayCreate로 생성된 1차원 배열은 단일 행 Range에만 할당할 수 있습니다. 단일 열 Range에 대한 값을 정의하려면 2차원 배열을 사용해야 합니다. 예: Datas:=VarArrayCreate([1,100,1 ,1], varVariant); //100*1 동적 배열을 생성합니다. 그런데 Cells.Item[]은 실제로 Range 개체를 반환합니다. 워크시트에서 데이터를 검색하는 것은 기본적으로 데이터 쓰기의 역과정입니다. 주의해야 할 것은 워크시트의 데이터 범위를 결정하는 방법입니다. var ir, ic : Integer …… wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam; ).활성화 ; ir := Excel.ActiveCell.Row ic := Excel.ActiveCell.Column; 여기서는 데이터가 포함된 마지막 셀을 얻기 위해 특수 셀 함수인 SpecialCells가 교묘하게 사용되었습니다. 데이터 편집 다음은 데이터 편집의 두 가지 예입니다. var DestRange: OleVariant; start DestRange := Excel.Range['C1', 'D4']; Excel.Range['A1', 'B4'].Copy(DestRange); Copy 함수에 빈 매개 변수를 전달하면 이 영역의 데이터가 클립보드에 복사되고 나중에 Paste 메서드를 사용하여 다른 위치에 붙여넣을 수 있습니다. var WS: _Worksheet …… Excel.Range['A1', 'B4'].Copy(EmptyParam); //워크시트의 데이터를 클립보드에 복사 WS := Excel.Activesheet as _Worksheet WS; .Range['C1', 'D4'].Select WS.Paste(EmptyParam, EmptyParam, lcid); //클립보드의 내용을 새 워크시트에 붙여넣습니다. 서식 설정 Excel의 강력한 서식 기능 때문에 보고서 서버로 선택합니다. 먼저 "주소록"이라는 제목의 셀을 병합하여 중앙에 표시한 다음 글꼴을 굵게 표시된 18포인트 "공식 스크립트"로 변경합니다. wkSheet.Range['A1','D1'],Font do start Merge(True ); //셀 병합 수평 정렬:= xlCenter; 이름:='official script'; 셀 내용이 길면 내용의 일부가 표시되지 않습니다. 일반적인 방법은 선택한 영역의 오른쪽 가장자리를 두 번 클릭하여 각 열의 너비가 내용의 길이에 자동으로 맞춰지도록 하는 것입니다. Delphi에서는 AutoFit 메서드를 통해 적응형 열 너비와 행 높이를 얻을 수도 있습니다. 이 메서드는 전체 행과 전체 열에만 사용할 수 있습니다. 그렇지 않으면 OLE 메서드 실행 거부 오류가 표시됩니다. wkSheet.Columns.EntireColumn.AutoFit; 중국 스타일 보고서에는 일반적으로 상단 및 하단 캡이 있는 테이블 줄이 필요하며 테두리 컬렉션 속성을 사용할 수 있습니다. VBA의 컬렉션 개체에는 일반적으로 Delphi에서 생략할 수 없는 기본 Item 속성이 있다는 점에 유의해야 합니다. Weight 속성은 테이블 선의 두께를 정의하는 데 사용됩니다. Aname.RefersToRange를 사용하면 Borders do start HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium; Item[xlEdgeTop].Weight:=xlMedium; .무게: =xl얇음; item[xlInsideVertical].Weight:=xlThin; end; 페이지 설정 및 인쇄 페이지 설정은 워크시트의 PageSetUp 개체 속성을 통해 설정됩니다. Excel VBA에는 40개 이상의 용지 상수가 사전 설정되어 있습니다. 일부 프린터는 일부 용지 유형만 지원합니다. Orientation 속성은 인쇄 방향을 제어하는 데 사용되며, 가로 방향 상수 = 2는 가로 인쇄를 나타냅니다. 부울 속성 CenterHorizontally 및 CenterVertically는 인쇄된 내용이 가로 및 세로 가운데에 배치되는지 여부를 결정하는 데 사용됩니다. wkSheet.PageSetUp do start PaperSize:=xlPaperA4; //용지 유형 A4 PRintTitleRows := 'A1:D1'; //이 행/페이지 반복 LeftMargin:=18; //0.25" Left Margin RightMargin:=18; // 0.25"는 프린터마다 다릅니다. TopMargin:=36; //0.5" BottomMargin:=36; //0.5" CenterHorizontally:=True; Orientation:=1; //가로 인쇄(가로)=2, portrait=1 end; 보고서를 인쇄하려면 워크시트의 PrintOut 메서드를 호출할 수 있습니다. VBA에서 정의한 이 메서드는 총 8개의 선택적 매개변수. 처음 두 개는 시작 및 끝 페이지와 세 번째 형식으로 인쇄할 사본 수를 지정하는 데 사용됩니다. 그러나 Delphi에서는 끝에 LCID 매개변수가 추가되고, EmptyParam이 추가됩니다. 이 매개변수에는 사용할 수 없습니다. 마찬가지로 인쇄 미리 보기 메서드 PrintPreview에는 VBA에는 매개 변수가 없지만 Delphi에서 호출할 때는 두 개의 매개 변수가 필요합니다. // wkBook.PrintPreview(True,LCID); //미리보기용 wkSheet.PrintOut(EmptyParam,EmptyParam,1,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,LCID); 더 복잡할수록 더 나은 접근 방식은 특정 테이블 범위의 이름을 지정한 다음 이름으로 참조하는 것입니다. Names는 이 작업을 수행할 수 있는 Add 메서드가 있는 WorkBook의 컬렉션 개체 속성입니다. Var Aname : Excel2000.Name …… Aname := wkBook.Names.Add('주소록','=Sheet1!$A$3:$D$7', EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam, 빈Param,EmptyParam); Add 함수의 첫 번째 매개변수는 정의된 이름이고, 두 번째 매개변수는 이름이 나타내는 셀 범위입니다. 범위 이름의 유형은 한정자를 사용해야 합니다. 유형 라이브러리(D4)를 사용하는 경우 한정자는 Excel_TLB입니다. 또한 명명된 범위는 절대 참조를 사용해야 합니다. 즉, "$" 기호를 추가해야 합니다. 범위에 이름을 지정하면 해당 이름으로 참조할 수 있습니다. 다음 코드 줄은 주소록 내용을 굵게 표시합니다. AName.RefersToRange.Font.Bold:=True; 그러나 가장 놀라운 점은 동적으로 수행할 수 있다는 것입니다. Delphi에서 Excel 매크로 프로그램을 수정해보세요! 다음 코드는 통합 문서를 닫을 때 마지막 액세스 시간을 기록하는 매크로를 생성합니다. var LineNo: CM: CodeModule; sDate:String; start CM := WkBook.VBProject.VBComponents.Item( 'ThisWorkbook'). Codemodule; LineNo := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='마지막 액세스 날짜:'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+''"'); 매크로 이전 사용 섹션에 VBIDE2000 단위를 추가합니다. 유형 라이브러리가 사용되는 경우 해당 단위는 VBIDE_TLB입니다. 이 코드의 핵심은 CodeModule 개체입니다. 안타깝게도 Excel VBA 도움말 문서에는 이 개체에 대한 흔적이 없으므로 MSDN만 검색할 수 있습니다. Delphi4 및 이전 버전 Delphi4에서는 TExcelApplication 개체를 제공하지 않으며, OLE 자동화 기술을 사용하려면 형식 라이브러리를 도입해야 합니다. Excel97의 형식 라이브러리는 Excel8.olb입니다. 이 두 가지 방법의 주요 차이점은 서버 프로그램과의 연결을 설정하는 방법입니다. 다음은 형식 라이브러리를 통해 Excel을 제어하는 프로그램 프레임워크입니다. Windows, ComObj, ActiveX, Excel_TLB를 사용합니다. var Excel: LCID; ; 알 수 없음:I알 수 없음; 결과: HResult; 시작 LCID:= LOCALE_USER_DEFAULT; 결과:= GetActiveObject(CLASS_Application, nil, 알 수 없음); //실행 중인 프로그램 인스턴스 캡처 시도 if (Result = MK_E_UNAVAILABLE) then Excel := CoApplication.Create //새 프로그램 인스턴스 시작 else start {GetActiveObject 메서드 호출 중 오류 확인} OleCheck(Result); (Unknown.QueryInterface(_Application, Excel)); end …… //데이터 처리 수행 Excel.Visible[LCID] := True; // Excel.DisplayAlerts[LCID] := False; // 프롬프트 대화 상자 표시 Excel.Quit; 예외 처리 메커니즘에는 복잡한 OLE 검사가 필요하므로 여기서는 사용되지 않습니다. 비용 제외 부분의 실행 속도입니다. 함께 제공되는 CoApplication 함수와 델파이 버전에 따라 생성된 일부 상수 이름이 다를 수 있으므로 해당 유형 라이브러리를 확인해야 합니다. Quit 메서드를 호출하기 전에 프로그램에서 생성된 모든 통합 문서 및 워크시트 변수를 해제해야 합니다. 그렇지 않으면 Excel이 메모리에 상주하여 실행될 수 있습니다(Ctrl+Alt+Del을 눌러 볼 수 있음). 프로그램 인스턴스를 캡처하기 위해 GetActiveObject를 호출하는 데 작은 문제가 있습니다. Excel이 최소화된 실행 상태인 경우 프로그램의 메인 프레임만 표시되고 사용자 영역은 표시되지 않을 수 있습니다. 또한 형식 라이브러리를 도입하지 않으려는 경우 지연 바인딩을 사용할 수도 있지만 훨씬 느립니다. 다음 예제에서는 Excel 응용 프로그램을 나타내는 Variant 변수를 선언합니다. var Excel: Variant; ... try Excel := GetActiveOleObject('Excel.Application'); Except Excel := CreateOleObject('Excel.Application'); .Visible := 참; 지연 바인딩을 사용할 때 컴파일러는 호출된 Excel 개체 메서드를 확인하지 않고 이러한 작업을 실행 중에 완료하도록 서버 프로그램에 맡깁니다. 이러한 방식으로 VBA에서 설정한 많은 수(종종 12개 이상)가 기본 매개 변수로 설정됩니다. 작동하므로 이 방법에는 예상치 못한 이점이 있습니다. 코드는 간결합니다. var WBk, WS, SheetName: OleVariant ..... WBk := Excel.WorkBooks.Open('C:/Test.xls; ') ;WS := WBk.Worksheets.Item['SheetName']; WS.Activate; …… WBk.Close(SaveChanges := True); Excel.Quit; , 그냥 직접 수행할 수 있습니다. const xlWBATWorksheet = -4167 …… XLApp.Workbooks.Add(xlWBatWorkSheet); 마지막으로 Excel을 닫은 후 변수를 해제하는 것을 잊지 마십시오. Excel := Unsigned; 다음은 Delphi6+MSOffice2000에 전달된 이 기사의 예제에 사용된 소스 코드입니다. 단위 Unit1; 인터페이스는 Windows, 메시지, SysUtils, 변형, 그래픽, 컨트롤, 양식, 대화 상자, OleServer, Excel2000, 그리드, StdCtrls를 사용합니다. type TForm1 = class(TForm) Button1: TButton: TStringGrid; 절차 FormActivate(Sender: TObject); Button1Click(발신자: TObject); 프로시저 OpenExl; 프로시저 NameSheet; 프로시저 Printit; ; 구현 {$R *.dfm}은 VBIDE2000을 사용합니다. var ir,ic:Integer; wkSheet:_WorkSheet; wkBook:_WorkBook; 행[1].CommaText:='장삼, 남, 25,010-33775566'; 행[2].CommaText:='이시, 남, 47,012-6574906'; 행[3].CommaText:='금요일, 여자 ,18,061-7557381'; Rows[4].CommaText:='Sun Tao, 여성, 31,3324559'; end; 절차 TForm1.OpenExl; 시작 LCID:=GetUserDefaultLCID(); , LCID); wkSheet:=wkBook.Sheets[1] _WorkSheet 종료; TForm1.Write2Xls; var Datas:Variant; start ir:=StringGrid1.ColCount; Datas:=varArrayCreate([1,ir,1,ic],varVariant) :=1 - ir do for j:=1 - ic do Datas[i,j]:=StringGrid1.Cells[j-1,i-1]; wkSheet를 사용하여 Activate(LCID)를 시작합니다. Cells.Item[1,1].Value:='주소록'; .Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; // Excel.Visible[LCID]:=True; 데이터:=할당되지 않음; 프로시저 TForm1.Retrieve; i,j:Integer; 시작 Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).ir:=Excel.ActiveCell.Row; =Excel.ActiveCell.Column; Datas:=Range[Cells.Item[1,1],Cells.Item[ir,ic]].Value; StringGrid1 시작 ColCount:=ir; ScrollBars:=ssBoth; ir-1 do for j:=0 to ic-1 do Cells[j,i]:=Datas[i+1,j+1] end; Datas:=UnAssigned; end; const SaveAsName='test.xls'; Excel.Quit; 이름 시트 시작; AName:=wkBook.Names.Add('주소록','=Sheet1!$A$3:$D$7',EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam) end; .AddFormula; var AFormula:문자열; AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; 절차 TForm1.Formats; Font do start Merge(True); //셀 병합 수평 정렬:= xlCenter; 이름:='official script'; FontStyle:=Bold; wkSheet.Columns.EntireColumn.AutoFit; Aname.RefersToRange를 사용하면 수평 정렬:= xlRight; Item[xlEdgeTop].Weight:=xlMedium; Item[xlInsideHorizontal].=xlThin; item[xlInsideVertical].=xlThin; end; 프로시저 TFOrm1.AddMacro; CM: CodeModule:String; VBComponents.Item('ThisWorkbook').Codemodule LineNo; := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='마지막 액세스 날짜:'+DateToStr(Date()) CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+'"'); 절차 TForm1.Printit 시작 wkSheet.PageSetUp PaperSize:=xlPaperA4; //용지 유형 A4 PrintTitleRows := 'A1:D1'; //이 행/페이지 반복 LeftMargin:=18; //0.25" Left Margin RightMargin:=18; //0.25"는 프린터마다 다릅니다. 위쪽 여백:=36; //0.5" 아래쪽 여백:=36; //0.5" 가로 중심:=True; 방향:=1; //가로=2, 세로=1 end; wkSheet.PrintOut(EmptyParam,EmptyParam,1,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,LCID) end; ; OpenExl을 사용해 보십시오. AddFormula; NameSheet; AddMacro; end; end; Excel과의 긴밀한 관계 [Wang [email protected]] 뛰어난 RAD 기능 가장 중요한 기능 중 하나이지만 작동하기 어려운 QuickReport 컨트롤은 데이터베이스 보고서의 요구 사항을 충족하지 못하는 경우가 많습니다. 보고서가 매우 복잡하거나 형식 변경에 유연성이 필요한 경우 Excel을 보고서 서버로 사용하는 것이 좋습니다. Delphi 버전 5부터 제공되는 Excel 구성 요소는 OLE 자동화 기술 적용을 크게 단순화합니다. 그러나 누락된 도움말 파일은 항상 Delphi의 가장 큰 비판을 받아 왔으며 이 새로운 구성 요소도 예외는 아닙니다. Excel의 개체 모델은 트리와 같은 계층 구조입니다. 루트는 응용 프로그램 자체입니다. WorkBook은 루트 개체의 속성 개체입니다. 이 문서에서 주로 설명하는 데이터 교환에 사용되는 WorkSheet는 워크북의 속성 개체입니다. 자세한 내용은 MSOffice.Excel VBA 도움말 파일을 참조하세요. 델파이에서 엑셀을 제어하려면 먼저 서버 프로그램과 연결을 하고, 워크북을 연 뒤, 대상 워크시트와 데이터를 교환하고, 마지막으로 연결을 끊어야 한다. Excel 통합 문서 열기 우리의 예제는 TStringGrid(물론 일부 데이터를 채워야 함)와 두 개의 버튼이 있는 기본 폼으로 시작합니다. 제어판의 서버 탭에서 TExcelApplication 컨트롤을 끌어서 폼에 배치합니다. 먼저 ConnectKind를 ckRunningOrNew로 설정합니다. 즉, 실행 중인 Excel 인스턴스가 감지되면 연결을 설정하고 그렇지 않으면 Excel을 시작합니다. 또한 프로그램이 실행되자마자 서버 프로그램과 연결되도록 하려면 AutoConnect 속성을 True로 설정하면 됩니다. Excel과의 연결을 설정하는 데 필요한 것은 Excel 입니다. 서버 탭에 여러 다른 Excel 컨트롤이 있다는 것을 눈치챘을 것입니다. 이러한 컨트롤은 ConnectTo 메서드를 통해 이전 Excel에 연결될 수 있습니다. Excel .ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel .ActiveSheet as _Worksheet); ExcelWorksheet2.ConnectTo(Excel .Worksheets.Item['Sheet2'] _Worksheet); ConnectTo 메서드를 사용하기 전에 해당 통합 문서나 워크시트를 열어야 한다는 점에 유의해야 합니다. 또한 이러한 컨트롤은 대부분의 경우 추가적인 편의성을 제공하지 않으므로 TExcelApplication을 하나만 사용하는 것이 가장 좋습니다. Excel 서버와의 연결이 설정되면 새 통합 문서를 만들 수 있습니다. var wkBook : LCID : Integer; ... LCID := GetUserDefaultLCID() := Excel.Workbooks.Add(EmptyParam, LCID); 함수 첫 번째 매개변수는 새 통합 문서에 사용되는 템플릿을 정의하는 데 사용됩니다. xlWBATChart, xlWBATExcel4IntlMacroSheet, xlWBATExcel4MacroSheet 또는 xlWBATWorksheet 상수이거나 기존 xls 파일의 이름일 수 있습니다. 여기서 빈 매개변수는 Variants 단위 및 정의된 변수입니다. 이는 기본 범용 템플릿을 사용하여 새 통합 문서를 만드는 것을 의미합니다. 기존 xls 문서를 여는 경우 열려는 파일 이름을 Open 함수의 첫 번째 매개 변수로 전달해야 합니다. wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam , EmptyParam,EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,LCID); 다음 문은 _WorkSheet 변수를 사용하여 현재 활성 셀을 나타내는 모든 데이터 작업을 수행한다는 점을 알아야 합니다. 워크시트 이름을 알고 있는 경우 색인 번호를 워크시트 이름으로 바꿀 수 있습니다: wkSheet:=wkBook.Sheets[1] as _WorkSheet; 데이터 교환을 완료한 후 통합 문서를 저장해야 합니다: Excel.ActiveWorkBook.SaveAs ('MyOutput', EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam, 빈 매개변수, 빈 매개 변수, LCID); 또는: Excel.ActiveWorkBook.Save(LCID); 마지막으로 통합 문서를 닫고 Excel과의 연결을 끊습니다. wkBook.Close(True, SaveAsName, 빈 매개 변수, LCID) //Excel.Quit; ; 여기서 Close 메소드에는 저장 기능이 포함되어 있습니다. 첫 번째 매개변수는 통합 문서를 닫기 전에 수정 사항을 저장할지 여부를 나타내며, 세 번째 매개변수는 여러 작성자가 문서를 처리하는 데 사용됩니다. 두 번째 줄에서는 Excel을 종료할지 묻습니다. 워크시트와 데이터 교환 입력 데이터는 활성 워크시트의 특정 셀 또는 범위에서 수행되며 범위는 모두 워크시트의 개체 속성입니다. 셀은 셀의 집합으로, 특정 위치를 지정하지 않으면 전체 워크시트의 모든 셀을 나타낼 수 있지만 일반적으로 특정 셀을 참조하는 데 사용됩니다. 왼쪽 상단에 있는 셀 A1은 가장 최근 셀을 나타냅니다. Item은 VBA에서 Cells의 기본 속성이므로 생략할 수 있지만 Delphi에서는 이러한 편리함이 없습니다. 셀에 값을 할당하려면 해당 Value 속성을 참조해야 합니다. 이 속성은 당연히 Variant 변수입니다(예: wkSheet.Cells.Item[1, 1].Value := 'Address Book';). 물론 셀에 값을 지정할 수도 있습니다. var AFormula:String; …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; 위 방법은 매우 직접적이고 간단하지만 속도가 매우 느리고 대규모 보고서에는 적합하지 않습니다. 그러면 모든 데이터를 순차적으로 엑셀로 전송할 수 있나요? Range를 사용할 수 있습니다. 이 개체는 마우스로 드래그할 때 일반적으로 직사각형 영역을 나타냅니다. 예를 들어 Range[ 'C3 ','J42']. 여기에는 작은 문제가 있습니다. 데이터가 26열을 초과하거나(예: 100열이 있음) 대상 영역 범위를 즉시 결정해야 하는 경우 문자 이름을 사용하여 셀을 표시하는 것이 더 번거롭기 때문입니다. "C3"은 셀의 레이블이므로 Range[Cells.Item[1,1], Cells.Item[100,100]]과 같은 셀을 사용할 수도 있습니다. Range의 값은 배열이어야 한다고 생각할 수 있지만 Delphi에서 Array를 사용하여 값을 할당하면 안 됩니다! Delphi에서 Excel 개체의 값은 항상 Variant 유형이라는 점을 기억하십시오. var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //여기서 100*100 동적 배열을 생성합니다... // 여기에 wkSheet do Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas;를 사용하여 요소를 배열합니다. 여기서는 워크시트와 Range 모두 Cells 속성을 가지고 있다는 점에 유의해야 합니다. 또한 Range는 방향성이 있습니다. VarArrayCreate로 생성된 1차원 배열은 단일 행 Range에만 할당할 수 있습니다. 단일 열 Range에 대한 값을 정의하려면 2차원 배열을 사용해야 합니다. 예: Datas:=VarArrayCreate([1,100,1 ,1], varVariant); //100*1 동적 배열을 생성합니다. 그런데 Cells.Item[]은 실제로 Range 개체를 반환합니다. 워크시트에서 데이터를 검색하는 것은 기본적으로 데이터 쓰기의 역과정입니다. 주의해야 할 것은 워크시트의 데이터 범위를 결정하는 방법입니다. var ir, ic : Integer …… wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam; ).활성화 ; ir := Excel.ActiveCell.Row ic := Excel.ActiveCell.Column; 여기서는 데이터가 포함된 마지막 셀을 얻기 위해 특수 셀 함수인 SpecialCells가 교묘하게 사용되었습니다. 데이터 편집 다음은 데이터 편집의 두 가지 예입니다. var DestRange: OleVariant; start DestRange := Excel.Range['C1', 'D4']; Excel.Range['A1', 'B4'].Copy(DestRange); Copy 함수에 빈 매개 변수를 전달하면 이 영역의 데이터가 클립보드에 복사되고 나중에 Paste 메서드를 사용하여 다른 위치에 붙여넣을 수 있습니다. var WS: _Worksheet …… Excel.Range['A1', 'B4'].Copy(EmptyParam); //워크시트의 데이터를 클립보드에 복사 WS := Excel.Activesheet as _Worksheet WS; .Range['C1', 'D4'].Select WS.Paste(EmptyParam, EmptyParam, lcid); //클립보드의 내용을 새 워크시트에 붙여넣습니다. 서식 설정 Excel의 강력한 서식 기능 때문에 보고서 서버로 선택합니다. 먼저 "주소록"이라는 제목의 셀을 병합하여 중앙에 표시한 다음 글꼴을 굵게 표시된 18포인트 "공식 스크립트"로 변경합니다. wkSheet.Range['A1','D1'],Font do start Merge(True ); //셀 병합 수평 정렬:= xlCenter; 이름:='official script'; 셀 내용이 길면 내용의 일부가 표시되지 않습니다. 일반적인 방법은 선택한 영역의 오른쪽 가장자리를 두 번 클릭하여 각 열의 너비가 내용의 길이에 맞게 자동으로 조정되는 것입니다. Delphi에서는 AutoFit 메서드를 통해 적응형 열 너비와 행 높이를 얻을 수도 있습니다. 이 메서드는 전체 행과 전체 열에만 사용할 수 있습니다. 그렇지 않으면 OLE 메서드 실행 거부 오류가 표시됩니다. wkSheet.Columns.EntireColumn.AutoFit; 중국 스타일 보고서에는 일반적으로 상단 및 하단 캡이 있는 테이블 줄이 필요하며 테두리 컬렉션 속성을 사용할 수 있습니다. VBA의 컬렉션 개체에는 일반적으로 Delphi에서 생략할 수 없는 기본 Item 속성이 있다는 점에 유의해야 합니다. Weight 속성은 테이블 선의 두께를 정의하는 데 사용됩니다. Aname.RefersToRange를 사용하면 Borders do start HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium; Item[xlEdgeTop].Weight:=xlMedium; .무게: =xl얇음; item[xlInsideVertical].Weight:=xlThin; end; 페이지 설정 및 인쇄 페이지 설정은 워크시트의 PageSetUp 개체 속성을 통해 설정됩니다. Excel VBA에는 40개 이상의 용지 상수가 사전 설정되어 있습니다. 일부 프린터는 일부 용지 유형만 지원합니다. Orientation 속성은 인쇄 방향을 제어하는 데 사용되며, 가로 방향 상수 = 2는 가로 인쇄를 나타냅니다. 부울 속성 CenterHorizontally 및 CenterVertically는 인쇄된 내용이 가로 및 세로 가운데에 배치되는지 여부를 결정하는 데 사용됩니다. with wkSheet.PageSetUp do start PaperSize:=xlPaperA4; //용지 유형 A4 PrintTitleRows := 'A1:D1'; //이 행/페이지 반복 LeftMargin:=18; //0.25" Left Margin RightMargin:=18; // 0.25"는 프린터마다 다릅니다. TopMargin:=36; //0.5" BottomMargin:=36; CenterHorizontally:=True; Orientation:=1; //가로 인쇄(가로)=2, portrait=1 end; 보고서를 인쇄하려면 VBA에서 정의한 이 메서드를 호출하면 됩니다. 선택적 매개변수인 처음 2개는 시작 페이지와 끝 페이지, 세 번째 형식으로 인쇄할 매수를 지정하는 데 사용됩니다. 그러나 델파이에서는 마지막에 LCID 매개변수가 추가되며 이 매개변수에는 EmptyParam을 사용할 수 없습니다. . 마찬가지로 인쇄 미리 보기 메서드 PrintPreview에는 VBA에는 매개 변수가 없지만 Delphi에서 호출할 때는 두 개의 매개 변수가 필요합니다. // wksheet.printout (true, lcid); 더 복잡하고 더 나은 접근 방식은 특정 테이블 범위를 지정 한 다음 이름으로 참조하는 것입니다. 이름은 통합 문서의 컬렉션 객체 속성으로,이 작업을 수행 할 수있는 추가 방법이 있습니다. var aname : excel2000.name;…… aname : = wkbook.names.add ( '주소록', '= A $ 3 : $ d $ 7', emptyparam, emptyparam, emptyparam, emptyparam, emptyparam, emptyparam. emptyparam, emptyparam); ADD 함수의 첫 번째 매개 변수는 정의 된 이름이고 두 번째 매개 변수는 이름으로 표시되는 셀 범위입니다. 범위 이름의 유형은 유형 라이브러리 (D4)를 사용하는 경우 예선은 Excel_TLB입니다. 또한 명명 된 범위는 절대 참조를 사용해야합니다. 즉, "$"기호를 추가해야합니다. 범위를 지정하면 다음 이름으로 주소록 내용을 굵게 표시 할 수 있습니다. 그러나 가장 놀라운 것은 동적으로 할 수 있습니다. 델파이에서 Excel 매크로 프로그램을 수정하십시오! 다음 코드는 통합 문서에 대한 매크로를 생성합니다. CodemOdule; Lineno : = cm.createeventProc ( 'beforeclose', 'Workbook'); sdate : '마지막 액세스 날짜 :'+dateToStr (date ()); 매크로는 이전 용도 섹션에 단위를 추가합니다. 이 코드의 핵심은 CodemoDule 객체입니다. 불행히도 Excel VBA 도움말 문서에는이 객체의 흔적이 없으므로 MSDN 만 검색 할 수 있습니다. Delphi4 및 이전 버전 Delphi4는 TexcelApplication 객체를 제공하지 않으며 Excel97의 유형 라이브러리를 사용하려면 유형 라이브러리를 도입해야합니다. 이 두 가지 방법의 주요 차이점은 서버 프로그램과의 연결을 설정하는 방법입니다 미지의 결과; 미지); / /excel (unkne.queryinterface (_application, excel)); true; excel.displayalerts [lcid]. 비용은 제외 부품의 실행 속도입니다. 첨부 된 기능 공동 및 다른 Delphi 버전으로 생성 된 일부 상수 이름은 다를 수 있으므로 해당 유형 라이브러리를 확인해야합니다. Quit 메소드를 호출하기 전에 프로그램에서 생성 된 모든 통합 문서 및 워크 시트 변수를 릴리스하십시오. 그렇지 않으면 Excel이 메모리에 상주하고 실행할 수 있습니다 (CTRL+Alt+DEL을 눌러 볼 수 있습니다). Excel이 최소화 된 실행 상태 인 경우 GetActiveObject를 호출하는 데 작은 문제가 있습니다. 또한 유형 라이브러리를 소개하지 않으려면 Lagging Binding을 사용할 수도 있지만 훨씬 느립니다. 다음 예는 Excel Application을 나타내는 변형 변수를 선언합니다. variant; .Visible : = true; Lagging Binding을 사용하는 경우 컴파일러는 호출 된 Excel 객체 메소드를 확인하지 않지만 이러한 방식으로 이러한 방식으로 이런 방식으로이 작업을 수행하여 VBA가 설정 한 많은 기본 매개 변수가 있습니다. 이 방법은 예상치 못한 이점을 가지고 있습니다. 코드는 간결합니다 : var wbk, ws, sheetname : ..... wbk : = excel.works.open ( 'c : /test.xls '); ws : wbk.worksheets.item [ 'sheetname']… , 당신은 직접 할 수 있습니다 : const xlwbatworksheet = -4167; 마지막으로, Excel을 닫은 후 변수를 해제하는 것을 잊지 마십시오. 단위 1; 인터넷, 메시지, sysutils, 변형, 클래스, 그래픽, 컨트롤, 양식, Oleserver, Excel2000, stdctrls (tform) 버튼; 절차 formactivate (발신자 : Tobject); Buttle1 구현 {$ r *.dfm} vbide2000을 사용합니다. wksheet : _workseet : wkbook; 행 [1] .commatext : 'Zhang San, 남성, 25,010-33775566' , 18,061-7557381 '; ROWS [4] , LCID); tform1. var variant; : = 1은 j : = 1에서 IC를 수행합니다 DataS [i, j] : stringgrid1.cells [J-1]; .item [3,1], 셀. item [ir+2, ic]. DataS : varment; = Excel.ActiveCell.Column; DataS : range [1,1], 셀 IR-1은 j : = 0 ~ IC-1 DO 세포 [j, i]에 대해 수행한다 [i+1, j+1]; DATION은 끝이 없다. namesheet; 시작 aname : = wkbook.names.add ( '주소록', '= pheate1! $ 3 : $ d $ 7', emptyparam, emptyparam, emptyparam, emptyparam, emptyparam); .addformula; var aformula : String; aformula : '= range.'; 글꼴은 합병을 시작합니다 (true). FontStyle : wksheet.column.Aname.referstorange; 항목 : xlthin. vbcomponents.item ( 'thisworkbook'). Codemodule; : = cm.createeventproc ( 'beforeclose', 'Workbook'); "+sdate+'"'); papersize : = xlpapera4; TopMargin : = 36; //0.5 "Bottommargin : = 36; 중심; 오리엔테이션 : // landscape = 2, wksheet.printout (emptyparam, emptyparam, emptyparam, emptyparam, lcid); 시작 Openexl; NAMESHEET;