Проблема в экспорте Csv.

отредактировано 16:43 Раздел: FastReport 4.0
Здравствуйте!
Я пишу про экспорт в csv файл, но возможно, такая проблема есть и в других экспортах.
Опишу свою ситуацию: В компоненте frxCSVExport1 у меня значение свойств frxCSVExport1.OverwritePrompt:= True; frxCSVExport1.OpenAfterExport:= True; При сохранении файла у меня в проекте уже присваивается название файла по умолчанию, и как правило, пользователи это имя и используют.
Это работает. Только есть одно "НО". Если по каким то причинам экспортный файл уже открыт и пользователь пытается снова экспортировать данные в этот же файл, то после сообщения-диалога о том, что файл уже существует, хотите его перезаписать, отвечаем да, на этом всё заканчивается (никакой подсветки на открытом файле, никакого сообщения не происходит на то, что файл не получается перезаписать, так как он открыт). Пользователь думает, что всё прошло гладко, а на самом деле, данные в файле, остаются старыми - безо всякого предупреждения-сообщения об этом.
Это вполне частая ситуация у пользователей, к сожалению. Так что эту проблему как то надо решить.
Может в более свежей версии эта проблема устранена? Или возможно, кто то подскажет как разрешить эту ситуацию, может кто сталкивался и решил эту проблему уже?
Очень надеюсь на быстрый ответ.
Заранее благодарна,
Надежда

Комментарии

  • отредактировано 16:43
    3 способа проверить, открыт ли файл. Используйте один из них. И лучше для вашего случая - удалять файл вручную до экспорта.
    procedure TForm5.Button1Click(Sender: TObject);
    // True - файл уже открыт. Иначе - False.
      function IsOpen(const aFileName: String): Boolean;
      var
        Hf: Integer;
      begin
        // Существует ли файл.
        Result := FileExists(aFileName);
        // Если файл не существует, значит он не открыт. Выходим.
        if not Result then
          Exit;
        // Проверяем, открыт ли уже файл. Для этого пытаемся открыть файл
        // в режиме неразделяемого доступа.
        Hf := FileOpen(aFileName, fmOpenReadWrite or fmShareExclusive);
        Result := Hf = -1;
        if not Result then
          FileClose(Hf);
      end;
    
    begin
      if IsOpen(filename) then
        ShowMessage('открыт')
      else
        ShowMessage('не открыт');
    end;
    
    procedure TForm5.Button2Click(Sender: TObject);
    // True - файл уже открыт. Иначе - False.
      function IsOpen2(const aFileName: String): Boolean;
      var
        Fs: TFileStream;
      begin
        // Существует ли файл.
        Result := FileExists(aFileName);
        // Если файл не существует, значит он не открыт. Выходим.
        if not Result then
          Exit;
        // Проверяем, открыт ли уже файл. Для этого пытаемся открыть файл
        // в режиме неразделяемого доступа.
        Result := False;
        Fs := nil;
        try
          Fs := TFileStream.Create(aFileName, fmOpenReadWrite, fmShareExclusive);
        except
          Result := True;
        end;
        Fs.Free;
      end;
    
    begin
      if IsOpen2(filename) then
        ShowMessage('открыт')
      else
        ShowMessage('не открыт');
    end;
    
    procedure TForm5.Button3Click(Sender: TObject);
    var
      hFile: THandle;
    begin
      hFile := CreateFile(PChar(filename), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
      if (hFile = INVALID_HANDLE_VALUE) and (GetLastError = ERROR_SHARING_VIOLATION) then
        ShowMessage('открыт')
      else
      begin
        CloseHandle(hFile);
        ShowMessage('не открыт');
      end;
    end;
    
  • отредактировано 16:43
    Nightmareterrible написал: »
    3 способа проверить, открыт ли файл. Используйте один из них. И лучше для вашего случая - удалять файл вручную до экспорта.
    Большое спасибо за ответ и за код! Судя по вашему совету, выходит, что в исходниках фастрепорта это до сих пор не включено, да? И если так, то вопрос в том, значит мне не обойтись от собственного вмешательства в изменение исходников фастрепорта? Значит мне надо найти файл исходников, куда этот код добавить, перекомпилировать фаст репорт и потом сносить фастрепорт в делфи и переустанавливать заново. Правильно я поняла?
    Уж очень не люблю это дело. И даже не потому, что затраты времени на переустановку, хотя и это тоже. Но гравным образом, после изменения исходников надо всегда помнить при любом обновлении продукта, что код надо опять править. Было бы здорово, если проблемы устраняли разработчики самого фастрепорта.
  • отредактировано 16:43
    Возможно, это не проблема Фастрепорта, т.к. это просто не поддерживается системой FastReport. Задача - сформировать правильно отчёт, а не включать расширенные менеджеры файлов. Такие вещи нужно предусматривать самостоятельно.
    Для этого у каждого экспорта, которые вы кидаете на форму, существует обработчик onBeginExport. В нём-то и нужно делать проверку на открытый файл.
    Исходники чужого компонента менять нельзя - иначе вы столкнётесь рано или поздно с проблемой совместимости, когда скачаете новую версию компонента. И если это будет через пару лет, то вам потребуется огромное количество времени чтобы только понять, почему что-то работает не так. Исходники лучше использовать, чтобы посмотреть "как оно работает" и решить проблему малой кровью.
  • отредактировано 16:43
    Nightmareterrible написал: »
    Для этого у каждого экспорта, которые вы кидаете на форму, существует обработчик onBeginExport. В нём-то и нужно делать проверку на открытый файл.
    Исходники чужого компонента менять нельзя - иначе вы столкнётесь рано или поздно с проблемой совместимости, когда скачаете новую версию компонента. И если это будет через пару лет, то вам потребуется огромное количество времени чтобы только понять, почему что-то работает не так. Исходники лучше использовать, чтобы посмотреть "как оно работает" и решить проблему малой кровью.
    Большое спасибо за совет использовать обработчик onBeginExport. Я попробую! А насчет изменения исходников - полностью с вами согласна! :-)
  • отредактировано 16:43
    Nightmareterrible написал: »
    Для этого у каждого экспорта, которые вы кидаете на форму, существует обработчик onBeginExport
    Упссс. Я поспешила радоваться :) У копонента экспорта TfrxCSVExport вообще нет никих событий (Events). А что, у вас есть onBeginExport на этом компоненте???? Может у вас новее версия фастрепорта 4??? (у меня 4.7.178)
  • Stalker4Stalker4 123
    отредактировано 16:43
    Nadya_rus написал: »
    Упссс. Я поспешила радоваться :) У копонента экспорта TfrxCSVExport вообще нет никих событий (Events). А что, у вас есть onBeginExport на этом компоненте???? Может у вас новее версия фастрепорта 4??? (у меня 4.7.178)
    Вообще то последняя версия FR4 это 4.15. Там у TfrxCSVExport есть событие OnBeginExport.
  • отредактировано 16:43
    Можно и по-другому, если не хотите качать новую версию. На событие frxReport1.onPreview повесьте код:
    procedure TDataModule5.frxReport1Preview(Sender: TObject);
    var
      i, j, m_pdf, m_html, m_xls, m_rtf: integer;
    begin
      m_pdf := 0;
      m_html := 0;
      m_xls := 0;
      m_rtf := 0;
      TfrxPreviewForm(TfrxReport(Sender).PreviewForm).PdfB.OnClick := frxReportPDFExport;
      for i := 0 to frxExportFilters.Count - 1 do
      begin
        if TfrxCustomExportFilter(frxExportFilters[i].Filter).ClassName = 'TfrxPDFExport' then
          m_pdf := i
        else if TfrxCustomExportFilter(frxExportFilters[i].Filter)
          .ClassName = 'TfrxHTMLExport' then
          m_html := i
        else if TfrxCustomExportFilter(frxExportFilters[i].Filter)
          .ClassName = 'TfrxXLSExport' then
          m_xls := i
        else if TfrxCustomExportFilter(frxExportFilters[i].Filter)
          .ClassName = 'TfrxRTFExport' then
          m_rtf := i;
      end;
      TfrxPreviewForm(TfrxReport(Sender).PreviewForm).ExportPopup.Items[m_pdf].OnClick :=
        frxReportPDFExport;
      TfrxPreviewForm(TfrxReport(Sender).PreviewForm).ExportPopup.Items[m_html].OnClick :=
        frxReportHTMLExport;
      TfrxPreviewForm(TfrxReport(Sender).PreviewForm).ExportPopup.Items[m_xls].OnClick :=
        frxReportXLSExport;
      TfrxPreviewForm(TfrxReport(Sender).PreviewForm).ExportPopup.Items[m_rtf].OnClick :=
        frxReportRTFExport;
    end;
    

    Я думаю, комментарии к коду излишни. Код работает уже больше года - ни разу не было сбоев.
  • отредактировано 16:43
    Nightmareterrible написал: »
    Можно и по-другому, если не хотите качать новую версию. На событие frxReport1.onPreview повесьте код:
    procedure TDataModule5.frxReport1Preview(Sender: TObject);
    var
      i, j, m_pdf, m_html, m_xls, m_rtf: integer;
    begin
      ...
      TfrxPreviewForm(TfrxReport(Sender).PreviewForm).PdfB.OnClick := frxReportPDFExport;
      for i := 0 to frxExportFilters.Count - 1 do
      begin
    ...
      end;
    end;
    
    Какой юнит надо прописать в uses, чтоб компилился этот код? Сейчас не признает TfrxPreviewForm, frxExportFilters если я пытаюсь вставить ваш код в свой проект.
    Заранее Спасибо.
  • отредактировано 16:43
    frxPreview, frxDsgnIntf, frxExportXLS, frxExportPDF, frxExportHTML, frxExportRTF

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.