/
YakuninAV
/
Convertors
Обзор
Документация
Войти
/
YakuninAV
/
Convertors
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Core/DBDExcelReaderMSs.pas
759 строк
26 KB
YakuninAV
begin with gitflick
31 июл 2026, 15:21
31 июл 2026, 15:21
1dc0fc6
Код
Авторство
О чём код?
unit DBDExcelReaderMSs; {$I mormot.defines.inc} interface uses SysUtils, Classes, ComObj, ActiveX, Variants, Windows, Messages, OleServer, Excel2000, mormot.core.base, mormot.core.variants, mormot.core.os, mormot.core.unicode, mormot.core.text, mormot.core.search, DBDIntfs; type TDBDExcelReaderMS = class(TDBDBaseExcelReader) strict private XL: TExcelApplication; WB: TExcelWorkbook; WS: TExcelWorksheet; ReadyXL: Boolean; ReadyWB: Boolean; procedure OpenXL; procedure CloseXL; procedure GetUsedRange; public /// Название активной рабочей таблицы function GetWorkSheetName: string; override; /// function GetCellAsCurrency(const aRow, aCol: Integer): Currency; override; /// function GetCellAsDate(const aRow, aCol: Integer): TDate; override; /// function GetCellAsDateTime(const aRow, aCol: Integer): TDateTime; override; /// function GetCellAsFloat(const aRow, aCol: Integer): Double; override; /// function GetCellAsInteger(const aRow, aCol: Integer): Integer; override; /// function GetCellAsText(const aRow, aCol: Integer): string; override; /// function GetCellAsTime(const aRow, aCol: Integer): TTime; override; /// Взять значение из ячейки (тип Variant) function GetCellAsVariant(const aRow, aCol: Integer): Variant; /// Взять формулу из ячейки function GetCellFormula(const aRow, aCol: Integer): string; /// Получить номер последней колонки текущего листа function LastCol: Integer; override; /// Получить номер последней строки, содержащей информацию function LastRow: Integer; override; /// констркутор constructor Create(FileName: TFileName; const aNotifier: IDBDNotifierV1 = nil); /// деструктор destructor Destroy; override; /// Закрыть рабочую книгу procedure Close; override; /// Получить список листов в книге function GetOpenedWorksheetNames: string; override; /// Список названий открытых книг function GetOpenedWorkbookNames: string; override; /// Открыть Excel файл function OpenWorkBook(const aFileName: TFilename): Integer; override; /// Открыть (сделать текущим) лист по индексу. Функция возвращает имя листа или пусто function OpenWorkSheet(const aIndex: Integer): string; overload; override; /// Найти и открыть (сделать текущим) лист по названию. Функция возваращает индекс листа или <=0 function OpenWorkSheet(const aWorkSheetName: string): Integer; overload; override; end; TDBDExcelReaderOLE = class(TDBDBaseExcelReader) strict private MyExcel: OleVariant; CurrentWB: OleVariant; CurrentWS: OleVariant; ReadyXL: Boolean; ReadyWB: Boolean; private function isValidGet(const aRow, aCol: Integer): Boolean; inline; public /// Проверить наличие установленного в системе MSExcel class function CheckExcelInstall: Boolean; /// Проверить запущен ли Excel function CheckExcelRun: Boolean; /// Запустить Excel function RunExcel(DisableAlerts:Boolean=True; Visible: Boolean=False): Boolean; /// Название активной рабочей таблицы function GetWorkSheetName: string; override; /// Получить значение из ячейки (тип Currency) function GetCellAsCurrency(const aRow, aCol: Integer): Currency; override; /// Получить значение из ячейки (тип TDate) function GetCellAsDate(const aRow, aCol: Integer): TDate; override; /// Получить значение из ячейки (тип TDateTime) function GetCellAsDateTime(const aRow, aCol: Integer): TDateTime; override; /// Получить значение из ячейки (тип Double) function GetCellAsFloat(const aRow, aCol: Integer): Double; override; /// Получить значение из ячейки (тип Integer) function GetCellAsInteger(const aRow, aCol: Integer): Integer; override; /// Получить значение из ячейки (тип String) function GetCellAsText(const aRow, aCol: Integer): string; override; /// Получить значение из ячейки (тип TTime) function GetCellAsTime(const aRow, aCol: Integer): TTime; override; /// Получить значение из ячейки (тип Variant) function GetCellAsVariant(const aRow, aCol: Integer): Variant; /// Взять формулу из ячейки function GetCellFormula(const aRow, aCol: Integer): string; override; /// Получить номер последней колонки текущего листа function LastCol: Integer; override; /// Получить номер последней строки, содержащей информацию function LastRow: Integer; override; /// констркутор constructor Create(FileName: TFileName; const aNotifier: IDBDNotifierV1 = nil); /// деструктор destructor Destroy; override; /// Закрыть рабочую книгу procedure Close; override; /// Получить список листов в книге function GetOpenedWorksheetNames: string; override; /// Список названий открытых книг function GetOpenedWorkbookNames: string; override; /// Открыть Excel файл function OpenWorkBook(const aFileName: TFilename): Integer; override; /// Открыть (сделать текущим) лист по индексу. Функция возвращает имя листа или пусто function OpenWorkSheet(const aIndex: Integer): string; overload; override; /// Найти и открыть (сделать текущим) лист по названию. Функция возваращает индекс листа или <=0 function OpenWorkSheet(const aWorkSheetName: string): Integer; overload; override; end; /// Функция переводит номер колонки в символьный адрес function RowColToAddr(const aCol: Integer): string; implementation resourcestring rsEInvalidSheetIndex = 'Задан неверный индекс для WorkBooks. Активация листа прервана'; rsEInvalidSheetActivate = 'Активация листа завершена с ошибкой'; rsEInvalidBookNotOpen = 'Книга ещё не открыта'; rsEInvaidFileName = 'Имя файла не может быть пустым'; rsEInvaidExcelConnection = 'Ошибка подключения к MS Excel'; rsEExcelNotFound = 'Приложение MS Excel не установлено на этом компьютере'; rsInvalidWorkSheetName = 'Название рабочего листа не может быть пустым'; const ExcelApp = 'Excel.Application'; lcid = LOCALE_USER_DEFAULT; function RowColToAddr(const aCol: Integer): string; const abc: array[0..25] of char =('A','B','C','D','E','F','G','H','I','J', 'K','L','M','N','O','P','Q','R','S','T', 'U','V','W','X','Y','Z'); var i: Integer; begin if aCol<1 then raise EConvertError.Create('Номер колонки должен быть >0') else if aCol<=26 then Result := abc[aCol-1] else if aCol<=26*26 then begin Result := abc[aCol div 26] + abc[aCol mod 26]; end else if aCol<=26*26*26 then begin Result := abc[aCol mod 26]; i := aCol div 26; Result := abc[i div 26] + abc[i mod 26] + Result; end else raise EConvertError.Create('Номер колонки должен быть меньше 17576'); end; { TDBDExcelReaderMS } procedure TDBDExcelReaderMS.Close; begin // закрыть книгу без сохранения внесенных в нее изменений WB.Close(0); // xlDontSaveChanges // закрыть все книги без сохранения изменений // XL.DisplayAlerts[lcid] := False; // отключаем предупреждения // XL.Workbooks.Close(lcid); // закроем все книги ReadyWB:=False; end; procedure TDBDExcelReaderMS.CloseXL; begin WS.Disconnect; WB.Disconnect; XL.UserControl := True; // отдадим управление пользователю XL.Quit; // закрыть Excel XL.Disconnect; end; constructor TDBDExcelReaderMS.Create(FileName: TFileName; const aNotifier: IDBDNotifierV1); begin inherited Create(aNotifier); XL := TExcelApplication.Create(nil); WB := TExcelWorkbook.Create(nil); WS := TExcelWorksheet.Create(nil); ReadyXL := False; ReadyWB:=False; if FileName<>'' then OpenWorkBook(FileName); end; destructor TDBDExcelReaderMS.Destroy; begin CloseXL; FreeAndNil(WS); FreeAndNil(WB); FreeAndNil(XL); inherited; end; function TDBDExcelReaderMS.GetCellAsCurrency(const aRow, aCol: Integer): Currency; var Cell: OleVariant; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Value2; end; end; function TDBDExcelReaderMS.GetCellAsDate(const aRow, aCol: Integer): TDate; var dt: TDateTime; Cell: OleVariant; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); dt := WS.Range[Cell, EmptyParam].Value2; Result := dt; end; end; function TDBDExcelReaderMS.GetCellAsDateTime(const aRow, aCol: Integer): TDateTime; var Cell: OleVariant; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Value2; end; end; function TDBDExcelReaderMS.GetCellAsFloat(const aRow, aCol: Integer): Double; var Cell: OleVariant; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Value2; end; end; function TDBDExcelReaderMS.GetCellAsInteger(const aRow, aCol: Integer): Integer; var Cell: OleVariant; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Value2; end; end; function TDBDExcelReaderMS.GetCellAsText(const aRow, aCol: Integer): string; var Cell: OleVariant; begin if not ReadyWB then begin Result := ''; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Text; end; end; function TDBDExcelReaderMS.GetCellAsTime(const aRow, aCol: Integer): TTime; var dt: TDateTime; Cell: OleVariant; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); dt := WS.Range[Cell, EmptyParam].Value2; Result := dt; end; end; function TDBDExcelReaderMS.GetCellAsVariant(const aRow, aCol: Integer): Variant; var Cell: OleVariant; begin Result := Null; if not ReadyWB then begin if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen) end else if (aRow<1) or (aCol<1) then begin if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, 'Неверный адрес ячейки'); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Value2; end; end; function TDBDExcelReaderMS.GetCellFormula(const aRow, aCol: Integer): string; var Cell: OleVariant; begin if not ReadyWB then begin Result := ''; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin Cell:= xlRCtoA1(aRow,aCol); Result := WS.Range[Cell, EmptyParam].Formula; end; end; function TDBDExcelReaderMS.GetOpenedWorkbookNames: string; var i: Integer; begin Result := ''; if not ReadyXL then Exit; if XL.Workbooks.Count=0 then Exit; Result := XL.Workbooks[1].FullName[lcid]; if XL.Workbooks.Count=1 then Exit; for i := 2 to XL.Workbooks.Count do Result := Result + #13#10 + XL.Workbooks[i].FullName[lcid]; end; function TDBDExcelReaderMS.GetOpenedWorksheetNames: string; var i: Integer; begin Result := ''; if not ReadyWB then Exit; if WB.Worksheets.Count=0 then Exit; Result:= (WB.Worksheets.Item[1] as _Worksheet).Name; if WB.Worksheets.Count=1 then Exit; for i := 2 to WB.Worksheets.Count do Result := Result + #13#10 + (WB.Worksheets.Item[i] as _Worksheet).Name; end; procedure TDBDExcelReaderMS.GetUsedRange; var R: ExcelRange; begin if not ReadyWB then begin FLastCol := 0; FLastRow := 0; end else begin R := WS.UsedRange[lcid]; R := WS.Range['A1', EmptyParam].SpecialCells(xlCellTypeLastCell, EmptyParam); FLastCol := R.Column; FLastRow := R.Row; end; end; function TDBDExcelReaderMS.GetWorkSheetName: string; begin if not ReadyWB then Result := '' else Result := WS.Name; end; function TDBDExcelReaderMS.LastCol: Integer; var R: ExcelRange; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin R := WS.UsedRange[lcid]; R := WS.Range['A1', EmptyParam].SpecialCells(xlCellTypeLastCell, EmptyParam); Result := R.Column; end; end; function TDBDExcelReaderMS.LastRow: Integer; var R: ExcelRange; begin if not ReadyWB then begin Result := 0; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, 0, rsEInvalidBookNotOpen); end else begin R := WS.UsedRange[lcid]; R := WS.Range['A1', EmptyParam].SpecialCells(xlCellTypeLastCell, EmptyParam); Result := R.Row; end; end; function TDBDExcelReaderMS.OpenWorkBook(const aFileName: TFilename): Integer; begin if ReadyWB then Close; if aFileName='' then begin Result:=-1; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -1, rsEInvaidFileName); end else if not FileExists(aFileName) then begin result:=-2; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -2, 'Файл "' + aFileName + '" не найден'); end else try // Open (FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword, IgnoreReadOnlyRecommended, Origin, // Delimiter, Editable, Notify, Converter, AddToMru, Local, CorruptLoad) WB.ConnectTo(XL.Workbooks.Open(aFileName, 2, // UpdateLinks: OleVariant; 2 - never update True, // ReadOnly: OleVariant; EmptyParam, // Format: OleVariant; EmptyParam, // Password: OleVariant; EmptyParam, // WriteResPassword: OleVariant; EmptyParam, // IgnoreReadOnlyRecommended: OleVariant; EmptyParam, // Origin: OleVariant; EmptyParam, // Delimiter: OleVariant; EmptyParam, // Editable: OleVariant; EmptyParam, // Notify: OleVariant; EmptyParam, // Converter: OleVariant; False, // AddToMru: OleVariant; // EmptyParam, // Local: OleVariant; // EmptyParam, // CorruptLoad: OleVariant; lcid)); Result:=0; FCount := WB.Worksheets.Count; ReadyWB:=FCount>0; if ReadyWB then begin Result := FCount; OpenWorkSheet(1); end; except Result:=-3; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -3, 'Исключение при открытии файла "' + aFileName + '"'); end; end; function TDBDExcelReaderMS.OpenWorkSheet(const aIndex: Integer): string; begin if not ReadyWB then begin Result := ''; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -1, rsEInvalidBookNotOpen); end else if aIndex<=0 then begin if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -1, 'Индекс не может быть меньше 1)'); result := ''; end else if WB.Worksheets.Count<aIndex then begin if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -1, 'Неверное значение индекса'); result := ''; end else if aIndex <> FCurrIdx then begin WS.Disconnect; WS.ConnectTo(WB.Worksheets[aIndex] as _Worksheet); Result := WS.Name; GetUsedRange; FCurrIdx := aIndex; end else Result := WS.Name; end; function TDBDExcelReaderMS.OpenWorkSheet(const aWorkSheetName: string): Integer; var i: Integer; begin if not ReadyWB then begin Result := -1; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -1, rsEInvalidBookNotOpen); end else if aWorkSheetName='' then begin Result := -2; if Assigned(FNotifier) then FNotifier.Log(dmkErrorInfo, -2, rsInvalidWorkSheetName); end else begin for i := 1 to WB.Worksheets.Count do begin if (WB.Worksheets[i] as _Worksheet).Name = aWorkSheetName then begin WS.Disconnect; WS.ConnectTo(WB.Worksheets[i] as _Worksheet); Result := i; Exit; end; end; Result := 0; end; end; procedure TDBDExcelReaderMS.OpenXL; begin if not ReadyXL then try XL.ConnectKind := ckNewInstance; XL.Connect; // подключение XL.AutoQuit := False; // по умолчанию это свойство True только в unit ExcelXP XL.Visible[lcid] := True; ReadyXL:= True; XL.ScreenUpdating[lcid] := False; // запретить перерисовку экрана XL.Calculation[lcid] := xlManual; // отменить автоматическую калькуляцию формул // отменить проверку автоматическую ошибок в ячейках (для XP и выше) // with XL.ErrorCheckingOptions do begin // BackgroundChecking := False; // NumberAsText := False; // InconsistentFormula := False; // end; except if Assigned(FNotifier) then FNotifier.Log(dmkCrashInfo, 0, rsEInvaidExcelConnection); ReadyXL:= True; end; end; { TDBDExcelReaderOLE } class function TDBDExcelReaderOLE.CheckExcelInstall: Boolean; var ClassID: TCLSID; begin Result:=CLSIDFromProgID(PWideChar(WideString(ExcelApp)), ClassID) = S_OK; end; function TDBDExcelReaderOLE.CheckExcelRun: Boolean; begin try MyExcel:=GetActiveOleObject(ExcelApp); Result:=True; except Result:=false; end; end; procedure TDBDExcelReaderOLE.Close; begin MyExcel.DisplayAlerts := False; CurrentWB.Close; CurrentWB:=Unassigned; end; constructor TDBDExcelReaderOLE.Create(FileName: TFileName; const aNotifier: IDBDNotifierV1); begin inherited Create(aNotifier); end; destructor TDBDExcelReaderOLE.Destroy; begin if MyExcel.Visible then MyExcel.Visible:=False; MyExcel.Quit; MyExcel:=Unassigned; inherited; end; function TDBDExcelReaderOLE.GetCellAsCurrency(const aRow, aCol: Integer): Currency; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := 0; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате Currency'); end else Result := 0; end; function TDBDExcelReaderOLE.GetCellAsDate(const aRow, aCol: Integer): TDate; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := 0; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате TDate'); end else Result := 0; end; function TDBDExcelReaderOLE.GetCellAsDateTime(const aRow, aCol: Integer): TDateTime; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := 0; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате TDateTime'); end else Result := 0; end; function TDBDExcelReaderOLE.GetCellAsFloat(const aRow, aCol: Integer): Double; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := 0; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате Double'); end else Result := 0; end; function TDBDExcelReaderOLE.GetCellAsInteger(const aRow, aCol: Integer): Integer; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := 0; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате Integer'); end else Result := 0; end; function TDBDExcelReaderOLE.GetCellAsText(const aRow, aCol: Integer): string; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value; except Result := ''; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате string'); end else Result := ''; end; function TDBDExcelReaderOLE.GetCellAsTime(const aRow, aCol: Integer): TTime; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := 0; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате TTime'); end else Result := 0; end; function TDBDExcelReaderOLE.GetCellAsVariant(const aRow, aCol: Integer): Variant; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Value2; except Result := Null; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате Variant'); end else Result := Null; end; function TDBDExcelReaderOLE.GetCellFormula(const aRow, aCol: Integer): string; begin if isValidGet(aRow, aCol) then try Result := CurrentWS.Cells.Item[aRow,aCol].Formula; except Result := ''; Log(dmkErrorInfo, 0, 'Исключение при чтении ячейки (' + IntToStr(aRow) + ',' + IntToStr(aCol)+ ') в формате string'); end else Result := ''; end; function TDBDExcelReaderOLE.GetOpenedWorkbookNames: string; var i,cnt: Integer; begin Result := ''; cnt := MyExcel.Workbooks.Count; if cnt<=0 then Exit; try Result := MyExcel.Workbooks[1].FullName; for i := 2 to cnt do Result := Result + #13#10 + MyExcel.Workbooks[i].FullName; except Result:=''; Log(dmkErrorInfo, 0, 'Исключение при формировании списка открытых книг'); end; end; function TDBDExcelReaderOLE.GetOpenedWorksheetNames: string; var i: Integer; begin Result := ''; if FCount<=0 then Exit; try Result := CurrentWB.Worksheets[1].Name; for i := 2 to FCount do Result := Result + #13#10 + CurrentWB.Worksheets[i].Name; except Result:=''; Log(dmkErrorInfo, 0, 'Исключение при формировании списка листов открытой книги'); end; end; function TDBDExcelReaderOLE.GetWorkSheetName: string; begin try Result := CurrentWS.Name; except result:=''; end; end; function TDBDExcelReaderOLE.isValidGet(const aRow, aCol: Integer): Boolean; begin Result := (not VarIsEmpty(CurrentWS)) and (aRow>=1) and (aCol>=1); end; function TDBDExcelReaderOLE.LastCol: Integer; begin if FLastCol<0 then FLastCol := CurrentWS.Cells.SpecialCells(xlLastCell, EmptyParam).Column; Result := FLastCol; end; function TDBDExcelReaderOLE.LastRow: Integer; begin if FLastRow<0 then FLastRow := CurrentWS.Cells.SpecialCells(xlLastCell, EmptyParam).Row; Result := FLastRow; end; function TDBDExcelReaderOLE.OpenWorkBook(const aFileName: TFilename): Integer; begin FLastCol:=-1; FLastRow:=-1; FCount := -1; FCurrIdx := -1; if (aFileName='') then Result := -1 else if not FileExists(aFileName) then Result := -2 else if not CheckExcelInstall then Result := -3 else begin if (not CheckExcelRun) { and (AutoRun) } then RunExcel; if CheckExcelRun then begin try CurrentWB:=MyExcel.Workbooks.Open[aFileName,0,True]; FCount := CurrentWB.Worksheets.Count; ReadyWB := FCount>0; if ReadyWB then begin Result := FCount; OpenWorkSheet(1); end else Result := -4; except Result := -5; end; end else Result := -6; end; end; function TDBDExcelReaderOLE.OpenWorkSheet(const aIndex: Integer): string; begin if (aIndex>=1) and (aIndex<=FCount) then try CurrentWS := CurrentWB.Worksheets[aIndex]; Result := CurrentWS.Name; FCurrIdx := aIndex; FLastCol := CurrentWS.Cells.SpecialCells(xlLastCell, EmptyParam).Column; FLastRow := CurrentWS.Cells.SpecialCells(xlLastCell, EmptyParam).Row; except Result:=''; end else Result := ''; end; function TDBDExcelReaderOLE.OpenWorkSheet(const aWorkSheetName: string): Integer; var i: Integer; begin Result := 0; try for i := 1 to FCount do if AnsiLowerCase(CurrentWB.Worksheets[i].Name) = AnsiLowerCase(aWorkSheetName) then begin CurrentWB:=CurrentWB.Worksheets[i]; FCurrIdx := i; Result := FCurrIdx; FLastCol := CurrentWS.Cells.SpecialCells(xlLastCell, EmptyParam).Column; FLastRow := CurrentWS.Cells.SpecialCells(xlLastCell, EmptyParam).Row; Break; end; except Result:=-1; end; end; function TDBDExcelReaderOLE.RunExcel(DisableAlerts, Visible: Boolean): Boolean; begin try if CheckExcelInstall then begin MyExcel:=CreateOleObject(ExcelApp); //показывать/не показывать системные сообщения Excel (лучше не показывать) MyExcel.Application.EnableEvents:=DisableAlerts; MyExcel.Visible:=Visible; Result:=True; end else begin // MessageBox(0, rsEExcelNotFound, 'Ошибка',MB_OK+MB_ICONERROR); Result:=False; end; except Result:=False; end; end; end.