Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблемы с записью/чтением типизированного файла [D7, XP]


khrenkov ©   (2010-09-20 14:29:00) 

Здравствуйте.

Необходимо, чтобы программа делала следующее (последовательно):
1. при нажатии кнопки ConversBtn обрабатывается выбранный файл *.CSV и его содержимое заносится в массив структур.
2. при нажатии кнопки SaveBtn файл, заполненный массивом структур записывается в файл *.SCDA.
3. при нажатии кнопки OpenBtn должен загружаться выбранный файл *.SCDA и в соответствии с его содержимым должны строиться графики.
Так же необходимо, чтобы п.3 выполнялся "самостоятельно", т.е. чтобы была возможность открыть сохраненный ранее файл *.SCDA.
Проблема:
При запуске приложения и выполнении п. 3 без п.1,2, т.е. при открытии ранее сохраненного файла *.SCDA загружается файл, значения полей структур в котором заполнены "плохими" значениями: нулями, очень маленькими значениями или Nan.
Примечание:
Если запустить приложение и выполнить п.1 и п.2, а в п.3 выбрать тот же файл, что был сохранен в п.2(предположим xxx.SCDA), то все строится и все функционирует.
Если же перезапустить приложение и выполняя п.3 выбрать файл xxx.SCDA, то загружаются некорректные данные.
Предположения:
Либо не правильно пишу в файл
Либо не правильно читаю файл

Кто чем может помочь?

TDataRecord = class(TObject)
 private
   FChan1: Single;
   FChan2: Single;
   FChan3: Single;
   FChan4: Single;
   FChan5: Single;
   FChan6: Single;
   FChan7: Single;
   FDate: Double;
   FDateTime: Double;
   FTime: Double;
 public
   property Chan1: Single read FChan1 write FChan1;
   .........
   property Chan7: Single read FChan7 write FChan7;
   property Date: Double read FDate write FDate;
   property DateTime: Double read FDateTime write FDateTime;
   property Time: Double read FTime write FTime;
   { Public declarations }
 end;

 TDataField = array of TDataRecord;

var
 MainForm: TMainForm;
 DataField1: TDataField;
 Data: TDataField;

implementation

{$R *.dfm}

function TMainForm.ChangeSeparator(var StrTemp: string): string;
begin
 StrTemp := StringReplace(StrTemp, ',', Decimalseparator,[rfReplaceAll]);
 StrTemp := StringReplace(StrTemp, '.', Decimalseparator,[rfReplaceAll]);
end;

function TMainForm.BRKCheck(var StrTemp: string): string;
begin
 if StrTemp = 'BRK' then
   StrTemp := '0';
end;

procedure TMainForm.ChanSwitcherClick(Sender: TObject);
var
 I: Longint;
begin
 ............
end;

procedure TMainForm.ConversBtnClick(Sender: TObject);
var
 OD: TOpenDialog;
 Excel: Variant;
 I, J, DocSize: Longint;
 TempStr: string;
 StopFlag: Boolean;
const
 STRNUMBER: Longint = 20;
 ROWNUMBER: Longint = 9;
begin
 OD := TOpenDialog.Create(nil);
 try
   OD.Filter := 'Файлы CSV|*.CSV';
   OD.InitialDir := 'C:\Program Files\Borland\Delphi7\Projects\Stove';
   if OD.Execute then
   begin
     DataField1 := nil;
     DocSize := 1;
     StopFlag := true;
     Excel := CreateOleObject('Excel.Application');
     Excel.Workbooks.Open[OD.FileName];
     while StopFlag do
     begin
       TempStr := Excel.Range['A' + IntToStr(DocSize)];
       if TempStr = '' then
       begin
         StopFlag := false;
         DocSize := DocSize - 1;
         Break;
       end;
     Inc(DocSize);
     end;
     SetLength(DataField1,(DocSize div 10));
     try
       for I := 1 to (DocSize div 10) do
       begin
         DataField1[I-1] := TDataRecord.Create;
         for J := 1 to ROWNUMBER do
         begin
           case J of
             1:
               begin
                 TempStr := Excel.Range['A' + IntToStr(I * 10)];
                 ChangeSeparator(TempStr);
                 DataField1[I-1].Date := StrToDate(TempStr);
               end;
             .............
             9:
               begin
                 TempStr := Excel.Range['I' + IntToStr(I * 10)];
                 BRKCheck(TempStr);
                 ChangeSeparator(TempStr);
                 DataField1[I-1].FChan7 := RoundTo(StrToFloat(TempStr),-2);
               end;
           end;
         end;
       end;
     finally
       Excel.ActiveWorkbook.Close;
       Excel.Application.Quit;
       Excel := Unassigned;
     end;
   end;
 finally
   OD.Free;
 end;
end;

procedure TMainForm.SaveBtnClick(Sender: TObject);
var
 SD: TSaveDialog;
 FileName: string;
 FileForWrite: File of TDataRecord;
 I: Longint;
begin
 SD := TSaveDialog.Create(nil);
 try
   SD.Filter := 'Файлы SCDA|*.SCDA';
   SD.InitialDir := 'C:\Program Files\Borland\Delphi7\Projects\Stove';
   if SD.Execute then
   begin
     FileName := Concat(SD.FileName,'.SCDA');
     AssignFile(FileForWrite,FileName);
     Rewrite(FileForWrite);
     for I := 0 to Length(DataField1) - 1 do
       Write(FileForWrite,DataField1[i]);
     CloseFile(FileForWrite);
   end
 finally
   SD.Free;
 end;
end;

procedure TMainForm.OpenBtnClick(Sender: TObject);
var
 DataFile: TDataRecord;
 OD: TOpenDialog;
 FileName: string;
 FileForRead: File of TDataRecord;
 I: Longint;
 Size: Integer;
begin
 Data := nil;
 OD := TOpenDialog.Create(nil);
 try
   OD.Filter := 'Файлы SCDA|*.SCDA';
   OD.InitialDir := 'C:\Program Files\Borland\Delphi7\Projects\Stove';
   if OD.Execute then
   begin
     FileName := OD.FileName;
     AssignFile(FileForRead,FileName);
     Reset(FileForRead);
     Size := FileSize(FileForRead);
     SetLength(Data,Size);
     for I := 0 to Size - 1 do
     begin
       Data[i] := TDataRecord.Create;
       Read(FileForRead,Data[i]);
     end;
     CloseFile(FileForRead);
    // Edit1.Text := FileName;
   end
 finally
   OD.Free;
 end;
end;
end.


khrenkov   (2010-09-20 15:07:00) [1]

Anatoly Podgoretsky, согласен!


khrenkov   (2010-09-20 15:04:00) [2]

MBo, вашу идею понял, спасибо. С записями работает =)


Anatoly Podgoretsky   (2010-09-20 14:59:00) [3]

Вообще то у тебя нет типизированного файла.
TDataRecord это не запись. Хочешь работать с записями, сделай Record


MBo   (2010-09-20 14:47:00) [4]

Рано отправил.
В данном случае не видно причин, кроме формальнойинкапсуляции, по которым данный объект не может быть простой записью (record), а записи сохранять-читать легко.

В общем же случае для объектов надо реализовывать механизм сохранения-восстановления (см. TPersistent, TComponent, DefineProperties)


MBo   (2010-09-20 14:40:00) [5]

Объекты таким образом записывать в файл нельзя - получается, что  в файл пишется значение указателя, адрес объекта. При сохранении-загрузке в одной сессии адреса еще остаются действительными, если не было уничтожения объектов, перезаписи данных областей памяти. При новом запуске даже призрачного шанса на это нет.
Поэтому


Наверх

Титульная страница Поиск, карта сайта Написать письмо