AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Externer Fehler kurz nach dem öffnen eines OpenDialogs
Thema durchsuchen
Ansicht
Themen-Optionen

Externer Fehler kurz nach dem öffnen eines OpenDialogs

Ein Thema von Andreas L. · begonnen am 28. Sep 2009 · letzter Beitrag vom 28. Sep 2009
Antwort Antwort
Andreas L.
(Gast)

n/a Beiträge
 
#1

Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 15:44
Hi,

ich wollte mit einer simplen Anwendung meinen CSV-Parser testen. Auf der Form befindet sich lediglich ein Button, eine ListView mit 20 Columns und ein OpenDialog. Nachdem öffnen des OpenDialogs dauert es ein wenig (egal ob ich eine Datei auswähle oder nicht), dann kommt
Zitat:
---------------------------
Fehler
---------------------------
Externe Exception EEFFACE.
---------------------------
OK Details >>
---------------------------
. Nach Bestätigung muss ich die IDE abschießen weil überhaupt nichts mehr reagiert.

So rufe ich den OpenDialog auf:
Delphi-Quellcode:
var
  csv: TBcCSVParser;
  i: Integer;
  x: Integer;
begin
  if OpenDialog1.Execute then
  begin
    csv := TBcCSVParser.Create(nil);
    try
      csv.LoadFromFile(OpenDialog1.FileName);
      for i := 0 to csv.DataSets.Count - 1 do
      begin
        with listview1.Items.Add do
        begin
          Caption := '';
          for x := 0 to csv.DataSets[i].Count - 1 do
            SubItems.Add(csv.DataSets[i][x]);
        end;
      end;
    finally
      csv.Free;
    end;
  end;
Der Code meines Parsers (wird wohl noch nicht ganz funktionieren, habs das grad sozusagen "from scratch" geschrieben:
Delphi-Quellcode:
unit BCParsers;

interface

uses
  SysUtils, Classes, ContNrs, {BCUtils}, DateUtils, StrUtils;

type
  TBcCSVParser = class;
  TBcCSVDataSets = class;
  TBcCSVDataSet = class;

  TBcCSVParser = class(TComponent)
  private
    FDataSets: TBcCSVDataSets;
    FFieldSeparator: String;
    FFieldDefinition: String;
    FComment: TStrings;
  protected
    procedure SetComment(Value: TStrings);
    procedure SetDataSets(Value: TBcCSVDataSets);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure ParseStrings(Strings: TStrings);
    procedure LoadFromStream(Stream: TStream);
    procedure LoadFromFile(const FileName: String);
    procedure BuildStrings(Strings: TStrings);
    procedure SaveToStream(Stream: TStream);
    procedure SaveToFile(const FileName: String);
    property DataSets: TBcCSVDataSets read FDataSets write SetDataSets;
  published
    property FieldSeparator: String read FFieldSeparator write FFieldSeparator;
    property FieldDefinition: String read FFieldDefinition write FFieldDefinition;
    property Comment: TStrings read FComment write SetComment;
  end;

  TBcCSVDataSets = class(TObjectList)
  protected
    procedure SetItem(Index: Integer; Value: TBcCSVDataSet);
    function GetItem(Index: Integer):TBcCSVDataSet;
  public
    function Add:Integer;
    property Items[Index:Integer]:TBcCSVDataSet read GetItem write SetItem; default;
  end;

  TBcCSVDataSet = class(TStrings);

implementation

{ TBcCSVParser }
constructor TBcCSVParser.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDataSets := TBcCSVDataSets.Create;
  FComment := TStringList.Create;
  FFieldDefinition := '"';
  FFieldSeparator := ';';
end;

destructor TBcCSVParser.Destroy;
begin
  FDataSets.Free;
  FComment.Free;
  inherited Destroy;
end;

procedure TBcCSVParser.SetComment(Value: TStrings);
begin
  FComment.Assign(Value);
end;

procedure TBcCSVParser.SetDataSets(Value: TBcCSVDataSets);
begin
  FDataSets := Value;
end;

procedure TBcCSVParser.ParseStrings(Strings: TStrings);
var
  iLine, CommentPos, DefinitionPos: Integer;
  CurrentDataSet, CurrentValue: String;
begin
  FDataSets.Clear;
  FComment.Clear;

  for iLine := 0 to Strings.Count - 1 do
  begin
    CommentPos := pos('#', Strings[iLine]);
    if CommentPos = 1 then
      Comment.Add(Copy(Strings[iLine], CommentPos + 1, Length(Strings[iLine]) - CommentPos - 1))
    else
    begin
      with DataSets[DataSets.Add] do
      begin
        CurrentDataSet := Strings[iLine];
        while CurrentDataSet <> 'do
        begin
          DefinitionPos := pos(FFieldDefinition, Strings[iLine]);
          if DefinitionPos = 1 then
          begin
            //extract value from field definition
            CurrentValue := Copy(CurrentDataSet, DefinitionPos + 1,
                                 posEx(FFieldDefinition,
                                       CurrentDataSet,
                                       DefinitionPos + 1) - DefinitionPos - 1);

            System.Delete(CurrentDataSet, DefinitionPos,
                   posEx(FFieldDefinition, CurrentDataSet, DefinitionPos + 1) - DefinitionPos);

            //unescape value
            if pos(FFieldDefinition + FFieldDefinition, CurrentValue) > 0 then
              CurrentValue := StringReplace(CurrentValue,
                                            FFieldDefinition + FFieldDefinition,
                                            FFieldDefinition,
                                            [rfReplaceAll, rfIgnoreCase]);
          end
          else
          begin
            //extract value
            CurrentValue := Copy(CurrentDataSet, 1, pos(FFieldSeparator, CurrentDataSet) - 1);
            System.Delete(CurrentDataSet, 1, pos(FFieldSeparator, CurrentDataSet));
          end;
          Add(CurrentValue);
        end;
      end;
    end;
  end;
end;

procedure TBcCSVParser.LoadFromStream(Stream: TStream);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    Data.LoadFromStream(Stream);
    ParseStrings(Data);
  finally
    Data.Free;
  end;
end;

procedure TBcCSVParser.LoadFromFile(const FileName: string);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    Data.LoadFromFile(FileName);
    ParseStrings(Data);
  finally
    Data.Free;
  end;
end;

procedure TBcCSVParser.BuildStrings(Strings: TStrings);
var
  iDataSet, iCommentLine, iValue: Integer;
  CurrentValue, CurrentDataSet: String;
begin
  Strings.Clear;

  //add comment line by line
  for iCommentLine := 0 to Comment.Count - 1 do
    Strings.Add('#' + Comment[iCommentLine]);

  //write datasets
  for iDataSet := 0 to DataSets.Count - 1 do
  begin
    CurrentDataSet := '';
    for iValue := 0 to DataSets[iDataSet].Count - 1 do
    begin
      //prepare current value
      CurrentValue := DataSets[iDataSet][iValue];
      if pos(FFieldSeparator, CurrentValue) > 0 then
      begin
        //escape field definition in value if needed
        if pos(FFieldDefinition, CurrentValue) > 0 then
          CurrentValue := StringReplace(CurrentValue,
                                        FFieldDefinition,
                                        FFieldDefinition + FFieldDefinition,
                                        [rfReplaceAll, rfIgnoreCase]);
        //set field definition
        CurrentValue := FFieldDefinition + CurrentValue + FFieldDefinition;
      end;
      //append value to dataset
      CurrentDataSet := CurrentDataSet + FFieldSeparator + CurrentValue;
    end;
    //add dataset
    Strings.Add(CurrentDataSet);
  end;
end;

procedure TBcCSVParser.SaveToStream(Stream: TStream);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    BuildStrings(Data);
    Data.SaveToStream(Stream);
  finally
    Data.Free;
  end;
end;

procedure TBcCSVParser.SaveToFile(const FileName: string);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    BuildStrings(Data);
    Data.SaveToFile(FileName);
  finally
    Data.Free;
  end;
end;

{ TBcCSVDataSets }
procedure TBcCSVDataSets.SetItem(Index: Integer; Value: TBcCSVDataSet);
begin
  inherited Items[Index] := Value;
end;

function TBcCSVDataSets.GetItem(Index: Integer):TBcCSVDataSet;
begin
  Result := inherited Items[Index] as TBcCSVDataSet;
end;

function TBcCSVDataSets.Add:Integer;
var
  NewDataSet: TBcCSVDataSet;
begin
  NewDataSet := TBcCSVDataSet.Create;
  Result := inherited Add(NewDataSet);
end;
Hier noch eine Test CSV-Datei:
Code:
TEST;TEST2;TEST3
"TEST";"TEST2";"TEST3"
"Te""st";"TE;ST2";TEST3
Kann jemand den Fehler nachvollziehen?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 15:49
Probier mal das:
Delphi-Quellcode:
var
  csv: TBcCSVParser;
  i: Integer;
  x: Integer;
begin
  if OpenDialog1.Execute then
  begin
    ShowMessage(OpenDialog1.Filename);
  end;
end;
Wenn das funktioniert liegt der Fehler wo anders. Funktioniert das nicht, probierst du das nochmal mit einem neuen leeren Projekt aus. Funktioniert das dort auch nicht, stimmt was mit deiner IDE/Compiler nicht.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Andreas L.
(Gast)

n/a Beiträge
 
#3

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 15:54
Ok,
Delphi-Quellcode:
if OpenDialog1.Execute then
  ShowMessage(OpenDialog1.FileName);
geht auch nicht in einem leeren Projekt. Selber Fehler. An was kann das liegen?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 15:58
Ähm, die Komponente OpenDialog1 hast du aber auf deinem Formular liegen oder? Ich frage nur mal zur Sicherheit.

Woran das liegen kann? Kaputte IDE/Compiler Installation?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Andreas L.
(Gast)

n/a Beiträge
 
#5

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 16:09
Zitat von Luckie:
Ähm, die Komponente OpenDialog1 hast du aber auf deinem Formular liegen oder? Ich frage nur mal zur Sicherheit.
Klar

Zitat von Luckie:
Woran das liegen kann? Kaputte IDE/Compiler Installation?
Hatte bisher keine Probleme. Installation ist auch erst 2 Monate alt. Versuche mal eine Reparatur...
  Mit Zitat antworten Zitat
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#6

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 16:37
Mir fällt was auf, worüber ich auch schon mal gestolpert bin:
Delphi-Quellcode:
with listview1.Items.Add do
        begin
Du bekommst ja einen Pointer auf das TListItem zurück. Ich bin nicht sicher, ob das so mit dem with verwendet werden kann. Ich musste da auch mal eine Variable TListItem deklarieren und damit arbeiten. Hatte das für einen Bug in den Tnt-Kompos gehalten.

Versuch' mal den Umweg über eine Variable.

Grüße, Messie
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 16:38
Grundsätzlich ja, aber with ist immer gefährlich ( möglicherweise wird falsches Objekt adressiert)
Markus Kinzler
  Mit Zitat antworten Zitat
Andreas L.
(Gast)

n/a Beiträge
 
#8

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 16:58
Zitat von messie:
Mir fällt was auf, worüber ich auch schon mal gestolpert bin:
Delphi-Quellcode:
with listview1.Items.Add do
        begin
Nö, das funktioniert schon. Verwende ich ständig.

Hab jetzt festgestellt das der Fehler nur aufrtitt wenn ich im OpenDialog am Desktop bin. Und zwar noch bevor die Dateisymbole gelesen werden (sind alles nur weiße Dokumente wie bei unbekannten Dateien). Scheint so als wenn das Symbol einer Verknüpfung nicht ausgelesen werden kann -> Absturz
  Mit Zitat antworten Zitat
Benutzerbild von Ralf Kaiser
Ralf Kaiser

Registriert seit: 21. Mär 2005
Ort: Wuppertal
932 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Externer Fehler kurz nach dem öffnen eines OpenDialogs

  Alt 28. Sep 2009, 17:20
Kontrollier mal, ob bei dir die Debuggeroption "Debug in spawned processes" aktiviert ist. Damit hatte ich auch schonmal Schwierigkeiten wenn eine im Explorer eingeklinkte Shellerweiterung Mist gebaut hat oder auf einen Breakpoint auflief.

In einem solchen Fall kam dann bei mir immer der Debugger mit der CPU-Ansicht hoch sobald der OpenDialog aufging (bei mir allerdings ohne kompletten Absturz - einen Blick in die Debuggeroptinen ist es allemal Wert)
Ralf Kaiser
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz