在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

用Delphi編寫數據報存儲控件

用Delphi編寫數據報存儲控件

更新時間:2022-05-09 文章作者:未知 信息來源:網絡 閱讀次數:

一、概述
在用Delphi編寫數據庫程序時,經常涉及到數據的導入和導出操作,如:將大型數據庫中的數據存儲為便攜文件,以便于出外閱讀;將存儲在文件中的數據信息,導入到另外的數據庫中;而且,通過將數據庫中的數據存儲為數據文件,更便于程序內部和程序間交換數據,避免通過內存交換數據的煩瑣步驟,例如在筆者編寫的通用報表程序中即以該控件作為數據信息傳遞的載體。
二、基本思路
作為數據報存儲控件,應能夠存儲和讀入數據集的基本信息(如:字段名,字段的顯示名稱,字段的數據類型,記錄數,字段數,指定記錄指定字段的當前值等),應能夠提供較好的封裝特性,以便于使用。
基于此,筆者利用Delphi5.0面向對象的特點,設計開發了數據報存儲控件。
三、實現方法
編寫如下代碼單元:
unit IbDbFile;
interface
Uses Windows, SysUtils, Classes, Forms, Db, DbTables, Dialogs;
Const
Flag = '數據報-吉星軟件工作室';
Type
TDsException = Class(Exception);
TIbStorage = class(TComponent)
private
FRptTitle: string; //存儲數據報說明
FPageHead: string; //頁頭說明
FPageFoot: string; //爺腳說明
FFieldNames: TStrings; //字段名表
FStreamIndex: TStrings; //字段索引
FStream: TStream; //存儲字段內容的流
FFieldCount: Integer; //字段數
FRecordCount: Integer; //記錄數
FOpenFlag: Boolean; //流是否創建標志
protected
procedure Reset; //復位---清空流的內容
procedure SaveHead(ADataSet: TDataSet; Fp: TStream); //存儲報表頭信息
procedure LoadTableToStream(ADataSet: TDataSet); //存儲記錄數據
procedure IndexFields(ADataSet: TDataSet); //將數據集的字段名保存到列表中
procedure GetHead(Fp: TFileStream); //保存報表頭信息
procedure GetIndex(Fp: TFileStream); //建立記錄流索引
procedure GetFieldNames(Fp: TFileStream); //從流中讀入字段名表
function GetFieldName(AIndex: Integer): string; //取得字段名稱
function GetFieldDataType(AIndex: Integer): TFieldType;
function GetDisplayLabel(AIndex: Integer): string; //取得字段顯示名稱
procedure SaveFieldToStream(AStream: TStream; AField: TField); //將字段存入流中
function GetFieldValue(ARecordNo, FieldNo: Integer): string; //字段的內容
public
Constructor Create(AOwner: TComponent);
Destructor Destroy; override;
procedure Open; //創建流以準備存儲數據
procedure SaveToFile(ADataSet: TDataSet; AFileName: string); //存儲方法
procedure LoadFromFile(AFileName: string); //裝入數據
procedure FieldStream(ARecordNo, FieldNo: Integer; var AStream: TStream);
property FieldNames[Index: Integer]: string read GetFieldName; //字段名
property FieldDataTypes[Index: Integer]: TFieldType read GetFieldDataType;
property FieldDisplayLabels[Index: Integer]: string read GetDisplayLabel;
property Fields[RecNo, FieldIndex: Integer]: string read GetFieldValue;
//property FieldStreams[RecNo, FieldIndex: Integer]: TStream read GetFieldStream;
property RecordCount: Integer read FRecordCount write FRecordCount;
property FieldCount: Integer read FFieldCount write FFieldCount;
published
property RptTitle: string read FRptTitle write FRptTitle;
property PageHead: string read FPageHead write FPageHead;
property PageFoot: string read FPageFoot write FPageFoot;
end;

function ReadAChar(AStream: TStream): Char;
function ReadAStr(AStream: TStream): string;
function ReadBStr(AStream: TStream; Size: Integer): string;
function ReadAInteger(AStream: TStream): Integer;
procedure WriteAStr(AStream: TStream; AStr: string);
procedure WriteBStr(AStream: TStream; AStr: string);
procedure WriteAInteger(AStream: TStream; AInteger: Integer);

procedure Register;
implementation

procedure Register;
begin
RegisterComponents('Data Access', [TIbStorage]);
end;

function ReadAChar(AStream: TStream): Char;
Var
AChar: Char;
begin
AStream.Read(AChar, 1);
Result := AChar;
end;

function ReadAStr(AStream: TStream): string;
var
Str: String;
C : Char;
begin
Str := '';
C := ReadAChar(AStream);
While C <> #0 do
begin
Str := Str + C;
C := ReadAChar(AStream);
end;
Result := Str;
end;

function ReadBStr(AStream: TStream; Size: Integer): string;
var
Str: String;
C : Char;
I : Integer;
begin
Str := '';
For I := 1 to Size do
begin
C := ReadAChar(AStream);
Str := Str + C;
end;
Result := Str;
end;

function ReadAInteger(AStream: TStream): Integer;
var
Str: String;
C : Char;
begin
Result := MaxInt;
Str := '';
C := ReadAChar(AStream);
While C <> #0 do
begin
Str := Str + C;
C := ReadAChar(AStream);
end;
try
Result := StrToInt(Str);
except
Application.MessageBox(' 當前字符串無法轉換為整數!', '錯誤',
Mb_Ok + Mb_IconError);
end;
end;


procedure WriteAStr(AStream: TStream; AStr: string);
begin
AStream.Write(Pointer(AStr)^, Length(AStr) + 1);
end;

procedure WriteBStr(AStream: TStream; AStr: string);
begin
AStream.Write(Pointer(AStr)^, Length(AStr));
end;

procedure WriteAInteger(AStream: TStream; AInteger: Integer);
var
S : string;
begin
S := IntToStr(AInteger);
WriteAstr(AStream, S);
end;

Constructor TIbStorage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FOpenFlag := False; //確定流是否創建的標志
end;

Destructor TIbStorage.Destroy;
begin
if FOpenFlag then
begin
FStream.Free;
FStreamIndex.Free;
FFieldNames.Free;
end;
inherited Destroy;
end;

procedure TIbStorage.Open;
begin
FOpenFlag := True;
FStream := TMemoryStream.Create;
FStreamIndex := TStringList.Create;
FFieldNames := TStringList.Create;
Reset;
end;

procedure TIbStorage.Reset; //復位
begin
if FOpenFlag then
begin
FFieldNames.Clear;
FStreamIndex.Clear;
FStream.Size := 0;
FRptTitle := '';
FPageHead := '';
FPageFoot := '';
FFieldCount := 0;
FRecordCount := 0;
end;
end;

//-------保存數據部分
procedure TIbStorage.SaveToFile(ADataSet: TDataSet; AFileName: string);
var
Fp: TFileStream;
I : Integer;
Ch: Char;
T1, T2: TDateTime;
Str: string;
begin
if Not FOpenFlag then
begin
showmessage(' 對象沒有打開');
Exit;
end;
try
if FileExists(AFileName) then DeleteFile(AFileName);
Fp := TFileStream.Create(AFileName, fmCreate);
Reset;
SaveHead(ADataSet, Fp); //保存頭部信息---附加說明
IndexFields(ADataSet); //將數據集的字段信息保存到FFieldName
LoadTableToStream(ADataSet); //保存數據集的數據信息
WriteAStr(Fp, FFieldNames.Text); //存儲字段名信息
Ch := '@';
Fp.Write(Ch, 1);
WriteAStr(Fp, FStreamIndex.Text); //存儲字段索引列表
Ch := '@';
Fp.Write(Ch, 1);
Fp.CopyFrom(FStream, 0);
finally
Fp.Free;
end;
end;

procedure TIbStorage.SaveHead(ADataSet: TDataSet; Fp: TStream);
Var
I : Integer;
Ch: Char;
begin
if Not ADataSet.Active then ADataSet.Active := True;
WriteAStr(Fp, Flag);
WriteAStr(Fp, FRptTitle);
WriteAStr(Fp, FPageHead);
WriteAStr(Fp, FPageFoot);
FFieldCount := ADataSet.Fields.Count;
FRecordCount := ADataSet.RecordCount;
WriteAStr(Fp, IntToStr(ADataSet.Fields.Count));
WriteAStr(Fp, IntToStr(ADataSet.RecordCount));
Ch := '@';
Fp.Write(Ch, 1);
end;

procedure TIbStorage.IndexFields(ADataSet: TDataSet);
var
I : Integer;
AField: TField;
begin
For I := 0 to ADataSet.Fields.Count - 1 do
begin
AField := ADataSet.Fields[I];
//不用FFieldNames.Values[AField.FieldName] := AField.DisplayLabel;是考慮效率
FFieldNames.Add(AField.FieldName + '=' + AField.DisplayLabel);
FFieldNames.Add(AField.FieldName + 'DataType=' + IntToStr(Ord(AField.DataType)));
end;
end;

procedure TIbStorage.LoadTableToStream(ADataSet: TDataSet);
var
No: Integer;
I, J, Size: Integer;
Tmp, Id, Str : string; //id=string(RecNO) + string(FieldNo)
Len: Integer;
Ch : Char;
BlobStream: TBlobStream;
begin
if Not FOpenFlag then
begin
showmessage(' 對象沒有打開');
Exit;
end;
try
ADataSet.DisableControls;
ADataSet.First;
No := 0;
FStreamIndex.Clear;
FStream.Size := 0;
While Not ADataSet.Eof do
begin
No := No + 1;
For J := 0 to ADataSet.Fields.Count - 1 do
begin
Id := Inttostr(NO) + '_' + IntToStr(J);
//建立流的位置的索引, 索引指向: Size#0Content
FStreamIndex.Add(Id + '=' + IntToStr(FStream.Position));
//存儲字段信息到流中
SaveFieldToStream(FStream, ADataSet.Fields[J]);
end;
ADataSet.Next;
end;
finally
ADataSet.EnableControls;
end;
end;

//如果一個字段的當前內容為空或者BlobSize<=0,則只寫入字段大小為0, 不寫入內容
procedure TIbStorage.SaveFieldToStream(AStream: TStream; AField: TField);
var
Size: Integer;
Ch: Char;
XF: TStream;
Str: string;
begin
if AField.IsBlob then
begin
//如何把一個TBlobField字段的內容存儲為流
Xf := TBlobStream.Create(TBlobField(AField), bmread);
try
if Xf.Size > 0 then
begin
Size := Xf.Size;
WriteAInteger(AStream, Size);
AStream.CopyFrom(Xf, Xf.Size);
end
else
WriteAInteger(AStream, 0);
finally
XF.Free;
end;
end
else
begin
Str := AField.AsString;
Size := Length(Str);
WriteAInteger(AStream, Size);
if Size <> 0 then
AStream.Write(Pointer(Str)^, Size);
//WriteAstr(AStream, Str);
end;
Ch := '@';
AStream.Write(Ch, 1);
end;

//------------Load Data
procedure TIbStorage.LoadFromFile(AFileName: string);
var
Fp: TFileStream;
Check: string;
begin
Reset;
try
if Not FileExists(AFileName) then
begin
showmessage(' 文件不存在:' + AFileName);
Exit;
end;
Fp := TFileStream.Create(AFileName, fmOpenRead);
Check := ReadAStr(Fp);
if Check <> Flag then
begin
Application.MessageBox(' 非法文件格式', '錯誤', Mb_Ok + Mb_IconError);
Exit;
end;
GetHead(Fp);
GetFieldNames(Fp);
GetIndex(Fp);
FStream.CopyFrom(Fp, Fp.Size-Fp.Position);
finally
Fp.Free;
end;
end;

procedure TIbStorage.GetHead(Fp: TFileStream);
begin
FRptTitle := ReadAStr(Fp);
FPageHead := ReadAstr(Fp);
FPageFoot := ReadAstr(Fp);
FFieldCount := ReadAInteger(Fp);
FRecordCount := ReadAInteger(Fp);
if ReadAChar(Fp) <> '@' then showmessage('GetHead File Error');
end;

procedure TIbStorage.GetFieldNames(Fp: TFileStream);
var
Ch: Char;
Str: string;
begin
Str := '';
Str := ReadAStr(Fp);
FFieldNames.CommaText := Str;
Ch := ReadAChar(Fp);
if Ch <> '@' then Showmessage('When get fieldnames Error');
end;

procedure TIbStorage.GetIndex(Fp: TFileStream);
var
Ch: Char;
Str: string;
begin
Str := '';
Str := ReadAStr(Fp);
FStreamIndex.CommaText := Str;
Ch := ReadAChar(Fp);
if Ch <> '@' then Showmessage('When Get Field Position Index Error');
end;

//---------Read Field's Value Part
function TIbStorage.GetFieldValue(ARecordNo, FieldNo: Integer): string;
var
Id, T : string;
Pos: Integer;
Len, I : Integer;
Er: Boolean;
begin
Result := '';
Er := False;
if ARecordNo > FRecordCount then
Er := true; //ARecordNo := FRecordCount;
if ARecordNo < 1 then
Er := True; // ARecordNo := 1;
if FieldNo >= FFieldCount then
Er := True; // FieldNo := FFieldCount - 1;
if FieldNo < 0 then
Er := True; //FieldNo := 0;
if Er then
begin
Showmessage('記錄號或者字段標號越界');
Exit;
end;
if FFieldCount = 0 then Exit;
Id := Inttostr(ARecordNO) + '_' + IntToStr(FieldNo);
Pos := StrToInt(FStreamIndex.Values[Id]);
FStream.Position := Pos;
//取得字段內容的長度
Len := ReadAInteger(FStream);
if Len > 0 then
Result := ReadBStr(FStream, Len);
if ReadAChar(FStream) <> '@' then
Showmessage('When Read Field, Find Save Format Error');
end;

procedure TIbStorage.FieldStream(ARecordNo, FieldNo: Integer; var AStream: TStream);
var
Id, T : string;
Pos: Integer;
Len, I : Integer;
Er: Boolean;
begin
Er := False;
if ARecordNo > FRecordCount then
Er := true; //ARecordNo := FRecordCount;
if ARecordNo < 1 then
Er := True; // ARecordNo := 1;
if FieldNo >= FFieldCount then
Er := True; // FieldNo := FFieldCount - 1;
if FieldNo < 0 then
Er := True; //FieldNo := 0;
if Er then
begin
TDsException.Create('GetFieldValue函數索引下標越界');
Exit;
end;
if FFieldCount = 0 then Exit;
Id := Inttostr(ARecordNO) + IntToStr(FieldNo);
Pos := StrToInt(FStreamIndex.Values[Id]);
FStream.Position := Pos;
Len := ReadAInteger(FStream);
AStream.CopyFrom(FStream, Len);
end;

function TIbStorage.GetFieldName(AIndex: Integer): string; //取得字段名稱
begin
//存儲的字段和數據類型各占一半
if ((AIndex < 0) or (AIndex >= FFieldNames.Count div 2)) then
Application.MessageBox(' 取字段名索引越界', '程序 錯誤',
Mb_Ok + Mb_IconError)
else
Result := FFieldNames.Names[AIndex*2];
end;

function TIbStorage.GetFieldDataType(AIndex: Integer): TFieldType; //取得字段名稱
begin
//存儲的字段和數據類型各占一半
if ((AIndex < 0) or (AIndex >= FFieldNames.Count div 2)) then
Application.MessageBox(' 取字段數據類型索引越界', '程序 錯誤',
Mb_Ok + Mb_IconError)
else
Result := TFieldType(StrToInt(FFieldNames.Values[FFieldNames.Names[AIndex*2+1]]));
end;

function TIbStorage.GetDisplayLabel(AIndex: Integer): string; //取得字段顯示名稱
begin
if ((AIndex < 0) or (AIndex >= FFieldNames.Count)) then
Application.MessageBox(' 取字段名索引越界', '程序 錯誤',
Mb_Ok + Mb_IconError)
else
Result := FFieldNames.Values[GetFieldName(AIndex)];
end;

end.
通過測試,該控件對Ttable,Tquery, TaodTable, TadoQuery, TibTable, TibQuery等常用的數據集控件等都能較好的支持,并且具有較好的效率(測試:1100條人事記錄,23個字段存儲為文件約用時2秒鐘)。

四、控件的基本使用方法
1.存儲數據集中的數據到文件
IbStorage1.Open; //創建存儲流
IbStorage1.SaveToFile(AdataSet, Afilename);
2.從文件中讀出數據信息
IbStorage1.Open;
IbStorage1.LoadFromFile(AfileName);
3.對數據報存儲控件中數據的訪問
Value := IbStorage1.Fields[ArecNo, AfieldNo]; //字符串類型
其它略。
五、結束語
通過編寫此數據報存儲控件,較好地解決了數據庫程序中數據的存儲和交換問題,為數據庫程序的開發提供了一種實用的控件。
該控件在Windows98,Delphi5開發環境下調試通過。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 我要看一级黄色大片| 国产一级不卡视频| 国产精品333| 国产伦精品一区二区三区四区视频_| 91制片厂免费观看| 国产四区在线观看| 日本成人在线不卡| 超碰91在线播放| 伊人网在线免费| 国产在线播放观看| 成人一级片网站| 污视频网站观看| 中文字幕日韩综合| 欧美日韩理论片| 日本高清视频免费在线观看| 少妇高潮大叫好爽喷水| 日韩久久久久久久久久久久| 日韩网站在线免费观看| 自拍日韩亚洲一区在线| www日韩视频| 国产精品av免费| 久草视频国产在线| 97视频在线免费播放| 日本肉体xxxx裸体xxx免费| xxx中文字幕| 天天夜碰日日摸日日澡性色av| 国产免费成人在线| 激情成人在线观看| 大肉大捧一进一出好爽视频| 午夜剧场高清版免费观看 | 欧美日韩dvd| 精品视频在线观看一区| av丝袜天堂网| 2018中文字幕第一页| 一级黄色香蕉视频| 高清无码视频直接看| 欧美特级aaa| 欧美一级片免费播放| 午夜宅男在线视频| 精品无码国模私拍视频| 思思久久精品视频| 日韩网址在线观看| www.亚洲视频.com| 黄色三级视频在线播放| 18岁网站在线观看| 一二三级黄色片| 男人天堂成人在线| 国产女教师bbwbbwbbw| 亚洲欧美手机在线| 午夜免费福利在线| 热99这里只有精品| 永久免费在线看片视频| 色综合色综合色综合色综合| 国产午夜福利视频在线观看| 精品视频在线观看一区二区| 男生操女生视频在线观看| 成年人免费大片| 久久美女福利视频| 国产高清精品在线观看| 国产一区二区三区小说| 免费的一级黄色片| 青青视频免费在线| 日本精品福利视频| 热久久最新地址| 欧美大片免费播放| 91视频成人免费| 一本二本三本亚洲码| 最新av在线免费观看| 久久av秘一区二区三区| 99999精品| 欧美少妇在线观看| 国产一线二线三线女| 久久亚洲a v| 日韩 欧美 视频| 免费无码av片在线观看| 可以免费在线看黄的网站| 国产一级片黄色| 一区二区久久精品| 最新av在线免费观看| 日本aa在线观看| 成人黄色片视频| 国产精品一区二区小说| 五月婷婷六月丁香激情| 中文字幕制服丝袜在线| 性一交一乱一伧国产女士spa| 国内少妇毛片视频| 黄色av免费在线播放| 色婷婷一区二区三区在线观看| 色呦呦网站入口| 久久久999视频| 亚洲精品第三页| 拔插拔插海外华人免费| 国产三级三级三级看三级| 国产精品久久久久久久99| 精品国偷自产一区二区三区| 亚洲第一狼人区| 九九热只有这里有精品| 黄色一级二级三级| 91传媒免费视频| 精品视频无码一区二区三区| 亚欧美一区二区三区| heyzo国产| 男人的天堂成人| 丰满少妇在线观看| 又大又硬又爽免费视频| 韩国日本美国免费毛片| 欧美大黑帍在线播放| 天天干在线影院| 国产一区二区网| 天堂av在线中文| 九九热精品在线播放| 男人和女人啪啪网站| www.51色.com| 嫩草av久久伊人妇女超级a| www.九色.com| 在线观看成人免费| 中文字幕亚洲影院| 欧美伦理片在线观看| 看av免费毛片手机播放| 青青青在线观看视频| 久久精品一二三四| 日韩不卡一二三| 中文字幕网av| 天天操天天摸天天爽| 日韩精品一区中文字幕| 国产美女在线一区| 日韩av高清在线看片| 9色视频在线观看| 亚洲小视频在线播放| 亚洲 欧洲 日韩| 小泽玛利亚av在线| 蜜臀av.com| 六月婷婷激情网| 精品国产一区二区三区无码| 国产精品第157页| 国产欧美日韩网站| 波多野结衣乳巨码无在线| 免费无码不卡视频在线观看| 成人免费aaa| xxxx一级片| 999久久久精品视频| 亚洲欧美一区二区三区不卡| 超碰免费在线公开| 无码 制服 丝袜 国产 另类| 亚洲色欲久久久综合网东京热| 岛国大片在线播放| 国产精品久久久久9999小说| 性chinese极品按摩| √天堂资源在线| 成人午夜免费剧场| 久色视频在线播放| 国产一区视频免费观看| 国产一级免费大片| 人人妻人人澡人人爽欧美一区双| 精品无码一区二区三区在线| 亚洲五月天综合| 国产精品久久成人免费观看| 男人添女荫道口女人有什么感觉| 鲁一鲁一鲁一鲁一色| 亚洲视频在线观看一区二区三区| 亚洲一区二区三区观看| 成人午夜免费在线| 中文字幕永久视频| 久久综合亚洲精品| av网站在线不卡| 日本手机在线视频| 性生生活大片免费看视频| 97在线国产视频| 日本77777| 国产天堂在线播放| 六月婷婷激情综合| 蜜桃福利午夜精品一区| 欧美激情视频免费看| 亚洲免费黄色录像| 久久婷婷国产精品| 美女扒开大腿让男人桶| 亚洲一级片免费观看| 国产真人无码作爱视频免费| 屁屁影院ccyy国产第一页| 日韩中文字幕a| 91av俱乐部| 欧美爱爱视频免费看| av 日韩 人妻 黑人 综合 无码| 欧美成人黑人猛交| 亚洲不卡中文字幕无码| 九九久久九九久久| 91香蕉国产线在线观看| 超碰在线播放91| 99视频精品免费| 日批视频在线免费看| 丁香花在线影院观看在线播放 | 99精品视频网站| 永久免费的av网站| 青青草精品视频在线观看| 精品久久一二三| 日本欧美黄色片| 男人操女人免费软件| 国模吧无码一区二区三区| 毛片在线视频播放| 北条麻妃在线观看|