Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
Простите меня дорогие форумчане!!! Тема очень сильно избитая но я не смог решить свою проблему. Поэтому прошу помощи у Вас.

Моя проблема заключается в том что я нашел компонент NativeExcel в RAD Studio XE8. Меня все устраивало. Отличная библиотека.
Но оказалось что при выгрузке моего запроса в xlsx символы Unicode например стрелочки кубы и т.д. экспортировались некорректно и файл становится битым. На просторах интернета нашел что у данного компонента есть проблема с выгрузкой unicode кодировки.

Прошу Вас помочь в решении данной проблемы. Возможно ссылкой на компонент для выгрузки запроса. Построчное добавление или вставкой массива в шаблон очень не хочется.
Построчное исполнение подвисает программу а при выгрузке 100 тыс строк это критично.
Также при моей реализации кода с OLE нельзя было пользоваться EXCEL параллельно.

Очень прошу не говорить о платных библиотеках. И если можно то с ссылкой на то чтобы загрузить и применить в собственных проектах не коммерческие использование.
11 сен 19, 18:56    [21968832]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48141

Если Вы не в состоянии ни проводить выгрузку в фоновом потоке, ни стартовать для неё
отдельный COM-сервер, то и формирование XML (которым, собственно, является xlsx) Вам не по
плечу. Выгружайте в .CSV, Ёксель его понимает.

Posted via ActualForum NNTP Server 1.5

11 сен 19, 19:00    [21968837]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 4028
автор
100 тыс строк

Большие объемы через OLE лучше не грузить, очень медленно. Если нет стороннего компонента, то можно формировать CSV-файл (TStringList.DelimetedText в помощь) и уже его открывать/подключать в экселе.

автор
подвисает программу а при выгрузке 100 тыс строк это критично

Если нельзя/сложно делать выгрузку в потоке, то есть простое решение -- вызов Application.ProcessMessages между записью в цикле (программа обработает всю очередь виндовых сообщений словно ничего и не зависло, заодно можно где-нибудь прогресс-бар обновить, чтобы показать процент выполнения).
11 сен 19, 19:47    [21968868]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
rgreat
Member

Откуда:
Сообщений: 5211
JaDi
автор
100 тыс строк
Большие объемы через OLE лучше не грузить, очень медленно.

Фигня. Вгружается мгновенно, если вгружать весь массив данных как массив 1-м запросом.
11 сен 19, 20:16    [21968881]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
Csv удобен для выгрузки одного ответа когда ты говоришь 3-10 отчётов то расеологаешь их на разных листах excel и ты красавчик. Нет ли бесплатного компанента? Если нет то из своего опыта подскажите какой путь более прост в изучении и достаточно эффективен для решения моей задачи.
OLE ещё не нравится ибо после ввода кода везде подчеркивание и красные как я понимаю компилятор ругается. Но исполняет. Понимаю что это для профессионала не страшно но для отладки мне бредокодеру удобнее видеть ошибки в отладчике.
11 сен 19, 22:06    [21968935]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
Application.ProcessMessages я использую в приложении. В принципе потоки начал разбирать для того чтобы приложение не зависело в момент исполнения множественных действий с данными получаемых из БД но освоить excel я надеялся проще поэтому искал компонент. Все мои предыдущие приложения этим мне и не нравились выгрузка это код больше чем рабочий код на обработку информации.
11 сен 19, 22:13    [21968947]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
ёёёёё
Member

Откуда:
Сообщений: 701
vector0001
Csv удобен для выгрузки одного ответа когда ты говоришь 3-10 отчётов то расеологаешь их на разных листах excel и ты красавчик. Нет ли бесплатного компанента? ...

Для чего? Для выгрузки в CSV?
11 сен 19, 22:21    [21968955]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
asutp2
Member

Откуда: Тюмень
Сообщений: 540
vector0001,

есть прекрасная библиотека XLSReadWriteII. Да, она платная, зато полностью решает твою проблему. Плюс если будешь генерировать xlsx в отдельных потоках, а не в основном потоке приложения, то вообще все будет быстро делаться и ничего тормозить не будет.

Но если ты принципиальный противних платных компонент, то твой выбор - csv.
11 сен 19, 22:40    [21968973]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 4028
rgreat
Фигня. Вгружается мгновенно, если вгружать весь массив данных как массив 1-м запросом.

Неа, не поможет. Предлагаю записать в эксель через OLE 100к записей по 100 колонок и замерить время. Будет много сюрпризов. Эксель очень тормозной по сравнению с другими методами записи/создания.
11 сен 19, 23:11    [21968996]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1555
Подключитесь через ODBC используя FireDAC
Либо через Microsoft.ACE.OLEDB.12.0 и ADO
11 сен 19, 23:18    [21969000]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
ёёёёё,

Нет я хотел сказать что при выгрузке в csv нельзя сделать много листовой документ и разместить на каждом листе свой ответ
11 сен 19, 23:43    [21969006]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Gator
Member

Откуда: Москва
Сообщений: 14910
vector0001
ёёёёё,

Нет я хотел сказать что при выгрузке в csv нельзя сделать много листовой документ и разместить на каждом листе свой ответ

Можно даже форматирование задавать, как душе угодно и рисовать,
Главное, csv грамотно соорудить.
11 сен 19, 23:54    [21969011]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
ёёёёё
Member

Откуда:
Сообщений: 701
Gator
vector0001
ёёёёё,

Нет я хотел сказать что при выгрузке в csv нельзя сделать много листовой документ и разместить на каждом листе свой ответ

Можно даже форматирование задавать, как душе угодно и рисовать,
Главное, csv грамотно соорудить.

Пример?
12 сен 19, 00:06    [21969019]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Gator
Member

Откуда: Москва
Сообщений: 14910
ёёёёё,

abcdcolorlstartlend
120E7-6trueaacceec12a187
220.1210falsebbddffc187a12
12 сен 19, 00:29    [21969025]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
ёёёёё
Member

Откуда:
Сообщений: 701
Gator
ёёёёё,

abcdcolorlstartlend
120E7-6trueaacceec12a187
220.1210falsebbddffc187a12


Где тут "многолистовой документ и отдельный отчет на каждом листе"?
12 сен 19, 01:07    [21969032]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Василий 2
Member

Откуда:
Сообщений: 700
Если есть исходники, можно попробовать исправить.
Кстати, NativeExcel тоже платный...
12 сен 19, 10:35    [21969194]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Gator
Member

Откуда: Москва
Сообщений: 14910
ёёёёё
Gator
ёёёёё,

abcdcolorlstartlend
120E7-6trueaacceec12a187
220.1210falsebbddffc187a12


Где тут "многолистовой документ и отдельный отчет на каждом листе"?

Кто мешает, например, хранить в базе минимальное эксельное файло с предварительной разметкой, макро и другими приблудами?
Кто мешает заранее наваять для него UNION c разрывом страницы? Типа
select null as DataForPrint,a as a, b as b, c as c ...
union all
select 'same page', a, b, c ... where sheet = 0
union all
select 'same page', a, b, c ... where sheet = 1
union all
select 'same page', a, b, c ... group buy sheet
union all
select 'page break' ,null ,null ,null
12 сен 19, 12:46    [21969344]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
Василий 2,

NativeExcel получен в наследство откуда его взяли не знаю но уверен что не покупали.
Что можно исправить? Проблему выгрузки? Боюсь что не смогу это сделать в виду отсутствия опыта.

Не могу поверить что на просторах интернета нет Подобных компонентов меньшего функционала но того же назначения скорее это все от того что язык постепенно угасает.
12 сен 19, 12:49    [21969352]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48141

vector0001
скорее это все от того что язык постепенно угасает.

Да. Пока на него летят чайники, ничего хорошего ждать не приходится. Выкинь из этой схемы
Дельфи, делай выгрузку непосредственно из экселя, через MS Query.

Posted via ActualForum NNTP Server 1.5

12 сен 19, 12:56    [21969365]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 4028
vector0001
Василий 2,

NativeExcel получен в наследство откуда его взяли не знаю но уверен что не покупали.
Что можно исправить? Проблему выгрузки? Боюсь что не смогу это сделать в виду отсутствия опыта.

Не могу поверить что на просторах интернета нет Подобных компонентов меньшего функционала но того же назначения скорее это все от того что язык постепенно угасает.

Что мешает эти проблемные данные заэкранировать/заменить прежде, чем выгружать? Например, юникодные символы заменить на их ascii аналоги при наличии (а если нет, то выгружать вопросы или заменять на другие обозначения).

А то и просто найти более свежую версию компонентов, где эти проблемы наверняка исправлены.

P.S. Надеюсь, что используется выгрузка в xlsx-формат, а не в нативный xls, у которого куча глюков и подобных косяков как раз (помнится, когда-то у DevExpress выгрузка в xls аналогично ломалась и портила файл при определенных данных).
12 сен 19, 13:21    [21969399]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 4028
Еще был пару лет назад случай с XLSX-файлами -- туда из сторонней программы попадали левые названия полей (совпадающие с системными) и эксель не хотел открываться. Приходилось xlsx-архив распаковывать, править проблемные xml-данные и пересобирать. Возможно, тут тоже такой лайфхак поможет, если других вариантов не будет.
12 сен 19, 13:26    [21969410]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
Gator
Member

Откуда: Москва
Сообщений: 14910
Dimitry Sibiryakov
vector0001
скорее это все от того что язык постепенно угасает.

Да. Пока на него летят чайники, ничего хорошего ждать не приходится. Выкинь из этой схемы
Дельфи, делай выгрузку непосредственно из экселя, через MS Query.

+Много
Нахрен дельфи с квери и екселями? Пусть идёт ящики сколачивать для картотек позапрошлого века!
12 сен 19, 13:32    [21969424]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1555
Чем доступ через ODBC не подходит?
Если просто выгрузить данные без разукрашивания ячеек? К тому же и сам Excel не нужен...
12 сен 19, 13:34    [21969429]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
Полез к компонент NativeExcel нашел процедуру отвечающую за выгрузку. На скине видно как он видит текст
могу выслать всю процедуру если это поможет делу. Я так понимаю необходимо исправить момент выгрузки преобразования и перекомпилировать данный компонент.

К сообщению приложен файл. Размер - 84Kb
12 сен 19, 13:45    [21969444]     Ответить | Цитировать Сообщить модератору
 Re: Выгрузка SQL запроса в xlsx без использования OLE на Delphi XE8  [new]
vector0001
Member

Откуда:
Сообщений: 40
vector0001,

+
procedure TDataset2Excel.ExportDetail;
Var
   i, rowindex: integer;
   row : integer;
   FieldType: TFieldType;
   Field: TField;
   Cell: IXLSRange;
   DValue: TDateTime;
   {$ifndef D2009}
   sValue: AnsiString;
   {$endif}
   h,m,s,ms: word;
   CurPos : TBookmark;
   //SheetRowIndex: integer;
   aLineStyle:  LongWord; 
   aLineWeight: LongWord; 

   lFirstRow: integer;
   TopBorderExist: boolean;

  function DelphiDateFormatToExcelDateFormat(Format: string): string;
  var
    i: integer;
  begin
    Result := Format;
    for i := 1 to Length(Format) do
      case Format[i] of
        'n' { Minutes }: Result[i] := 'm';
        'z' { Milisec }: Result[i] := '0';
      end;

    Result := StringReplace(Result, 'ampm', 'AM/PM', [rfReplaceAll,rfIgnoreCase]);
    Result := StringReplace(Result, 'a/p',  'AM/PM', [rfReplaceAll,rfIgnoreCase]);
  end;
  
  function DelphiNumericFormatToExcelNumericFormat(Format: string): string;
  begin
    Result := Format;
    Result := StringReplace(Result, 'S', '\S', [rfReplaceAll]);
    Result := StringReplace(Result, 's', '\s', [rfReplaceAll]);
  end;

begin
  FDataset.DisableControls;
  CurPos := FDataset.GetBookmark;
  FDataset.First;
try
  SetupGroupStorage;
  FWorksheet.Outline.SummaryRow := xlAbove;

  row := 1 + FRowOffset + FRowsPerHeader;
  lFirstRow := row;
  rowindex := 0;
  //SheetRowIndex := 0;

  while not(DataSet.Eof) do begin
     Inc(rowindex);
     Inc(FSheetRowIndex);
     FFieldsExported := 0;

     ProcessGroups(row);

     for i := 1 to FFieldsCount do begin

       if VisibleFieldsOnly and Not(FDataset.Fields[i - 1].Visible) then Continue;

       Inc(FFieldsExported);

       if FClearGroupFields and FGroupStorage.Enabled then begin
          if FGroupStorage.IsGroupField(FDataSet.Fields[i - 1].FieldName) then begin
             Continue;
          end;
       end;
       
       Field := FDataSet.Fields[i - 1]; 
       FieldType := Field.DataType;
       Cell := FWorksheet.Cells.Item[row, FFieldsExported + FColOffset];

       if FieldType = ftString then begin
          {$ifdef D2009}
          Cell.Value := Field.DisplayText;
          {$else} 
          sValue := Field.DisplayText ;
          Cell.Value := StringToWideString(sValue, DetailFont.Charset);
          {$endif} 
       {$IFNDEF D45}
       end else if (FieldType = ftFMTBcd) and (not Field.IsNull) then begin // Jordi
          Cell.Value := Field.AsFloat;
       end else if (FieldType = ftTimeStamp) then begin
          Cell.Value := Field.AsDateTime;
       {$ENDIF}
       end else begin
          Cell.Value := Field.AsVariant;
       end;

       //font
       if not(foFont in DisableFormat) then begin
           SetCellFont(DetailFont, Cell);
       end;

       //borders
       if not(foBorders in DisableFormat) then begin

           TopBorderExist := (Cell.Borders[xlEdgeTop].LineStyle <> xlLineStyleNone);

           if DetailBorderStyle <> BorderStyleNone then begin
              aLineStyle  := xlLineStyleNone;
              aLineWeight := xlThin; 
              case DetailBorderStyle of
                 BorderStyleSingleHair: begin
                                          aLineStyle  := xlContinuous;
                                          aLineWeight := xlHairline; 
                                        end;
                 BorderStyleSingleThick:begin
                                          aLineStyle  := xlContinuous;
                                          aLineWeight := xlThick; 
                                        end;
                 BorderStyleSingleThin:begin
                                          aLineStyle  := xlContinuous;
                                          aLineWeight := xlThin; 
                                        end;
                 BorderStyleDouble:begin
                                          aLineStyle  := xlDouble;
                                          aLineWeight := xlThick; 
                                        end;
              end;

              Cell.Borders[xlEdgeBottom].LineStyle := aLineStyle;
              Cell.Borders[xlEdgeLeft].LineStyle   := aLineStyle;
              Cell.Borders[xlEdgeRight].LineStyle  := aLineStyle;

              if aLineStyle <> xlLineStyleNone then begin
                 Cell.Borders[xlEdgeBottom].Weight := aLineWeight;
                 Cell.Borders[xlEdgeLeft].Weight   := aLineWeight;
                 Cell.Borders[xlEdgeRight].Weight  := aLineWeight;
              end;

              if Not(TopBorderExist) then begin
                  Cell.Borders[xlEdgeTop].LineStyle := aLineStyle;
                  if aLineStyle <> xlLineStyleNone then begin
                      Cell.Borders[xlEdgeTop].Weight := aLineWeight;
                  end;
              end;

           end;

           if DetailBorderColor <> clNone then begin
               Cell.Borders[xlEdgeBottom].Color := ColorToRGB(DetailBorderColor);
               Cell.Borders[xlEdgeLeft].Color   := ColorToRGB(DetailBorderColor);
               Cell.Borders[xlEdgeRight].Color  := ColorToRGB(DetailBorderColor);
               if Not(TopBorderExist) then 
                  Cell.Borders[xlEdgeTop].Color  := ColorToRGB(DetailBorderColor);
           end;

       end;

       //numberformat
       if not(foNumberFormat in DisableFormat) then begin
           
           case FieldType of

              ftDate: if TDateField(Field).DisplayFormat <> '' then begin
                         Cell.NumberFormat := DelphiDateFormatToExcelDateFormat(TDateField(Field).DisplayFormat);
                      end else begin
                         Cell.NumberFormat := DelphiDateFormatToExcelDateFormat({$IFDEF D2011}FormatSettings.{$ENDIF}ShortDateFormat); // 'dd.mm.yyyy';
                      end;

              ftTime: if TTimeField(Field).DisplayFormat <> '' then begin
                         Cell.NumberFormat := DelphiDateFormatToExcelDateFormat(TTimeField(Field).DisplayFormat);
                      end else begin
                         Cell.NumberFormat := DelphiDateFormatToExcelDateFormat({$IFDEF D2011}FormatSettings.{$ENDIF}ShortTimeFormat); // 'hh:mm:ss';
                      end;


              ftDateTime:
                      if TDateTimeField(Field).DisplayFormat <> '' then begin
                         Cell.NumberFormat := DelphiDateFormatToExcelDateFormat(TDateTimeField(Field).DisplayFormat);
                      end else begin
                         //bug modified by Michael Tien Jan 09, 2006
                         DValue := Field.asDateTime;
                         DecodeTime(DValue, h, m, s, ms);
                         if (h + m + s + ms) > 0 then
                            Cell.NumberFormat := DelphiDateFormatToExcelDateFormat({$IFDEF D2011}FormatSettings.{$ENDIF}ShortDateFormat + ' ' + {$IFDEF D2011}FormatSettings.{$ENDIF}ShortTimeFormat) // 'dd.mm.yyyy hh:mm:ss'
                         else
                            Cell.NumberFormat := DelphiDateFormatToExcelDateFormat({$IFDEF D2011}FormatSettings.{$ENDIF}ShortDateFormat); //'dd.mm.yyyy'
                      end;

              ftCurrency:
                      if TCurrencyField(Field).DisplayFormat <> '' then begin
                         Cell.NumberFormat := TCurrencyField(Field).DisplayFormat;
                      end else begin
                         Cell.NumberFormat := '#,##0.00';
                      end;

              ftInteger,
              ftSmallint,
              ftWord,
              ftFloat,
              ftBCD,
              {$IFNDEF D45}
              ftFMTBcd,
              {$ENDIF}
              ftLargeint:
                      if TNumericField(Field).DisplayFormat <> '' then begin
                         Cell.NumberFormat := DelphiNumericFormatToExcelNumericFormat(TNumericField(Field).DisplayFormat);
                      end;

              ftBoolean: {$ifdef D2009}
                         Cell.Value := Field.Text;
                         {$else}
                         Cell.Value := StringToWideString(Field.Text, DetailFont.Charset);
                         {$endif} 
           end;
       end;

       //alignment
       if not (foAlignment in DisableFormat) then begin
          case Field.Alignment of
             taCenter:       Cell.HorizontalAlignment := xlHAlignCenter;
             taLeftJustify:  Cell.HorizontalAlignment := xlHAlignLeft;
             taRightJustify: Cell.HorizontalAlignment := xlHAlignRight;
          end;
       end;

//       if not(foAlignment in DisableFormat) then begin
//           if FieldType in [ftDate, ftTime, ftDateTime] then
//                 Cell.HorizontalAlignment := xlHAlignLeft;
//       end;

       if Assigned(FAfterDetailCell) then FAfterDetailCell(Self, Cell, rowindex, i - 1, Field);
     end;

     if Assigned(FAfterDetailRow) and (FFieldsExported > 0) then
        FAfterDetailRow(Self, FWorksheet.RCRange[ row, FColOffset + 1,
                                                  row, FFieldsExported + FColOffset], rowindex);

     FDataset.Next;
     Inc(row);

     //pagebreak
     if (row > FRowsPerSheet) and not(FDataSet.Eof) then begin
        //FAfterDetail
       if Assigned(FAfterDetail) and 
          (FFieldsExported > 0)     and 
          ((row - 1) > (FRowsPerHeader + FRowOffset)) then
          FAfterDetail(Self, FWorksheet.RCRange[FRowsPerHeader + FRowOffset + 1,
                                                FColOffset + 1,
                                                row - 1, 
                                                FFieldsExported + FColOffset]);
       if Assigned(FAfterExport) and
          (FFieldsExported > 0)     and 
          ((row - 1 - FRowOffset) > 0) then
          FAfterExport(Self, FWorksheet.RCRange[ FRowOffset + 1,
                                                 FColOffset + 1,
                                                 row - 1, 
                                                 FFieldsExported + FColOffset]);


        CreateWorksheet;
        ExportHeaders;
        row := FRowsPerHeader + 1 + FRowOffset;
        lFirstRow := row;
        CloseGroups();
        //SheetRowIndex := 0;
     end;

   end;
//   FRowsCount := SheetRowIndex;
   FRowsCount := row - lFirstRow;

   if Assigned(FAfterDetail) and
      (FFieldsExported > 0)     and 
      ((row - 1) > (FRowsPerHeader + FRowOffset)) then
      FAfterDetail(Self, FWorksheet.RCRange[FRowsPerHeader + FRowOffset + 1,
                                            FColOffset + 1,
                                            row - 1, 
                                            FFieldsExported + FColOffset]);
finally                                         
   FDataset.GotoBookmark(CurPos);
   FDataset.EnableControls;
   FDataset.FreeBookmark(CurPos);
end;

end;


Модератор: Пользуйтесь тегом (кнопкой) SRC для оформления кода, пожалуйста.
12 сен 19, 13:47    [21969448]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить