22. maj 2004 - 01:25Der er
8 kommentarer og 1 løsning
Tekst som forbliver tekst
Jeg har en access database som gennem ADO har et tekst felt. Det hedder teksten. Jeg sætter en DBedit på og skriver noget i databasen gennem DBedit , og jeg laver teksten om til Time new roman 14, fed gennem dialogboksen. Men når jeg gemmer teksten laver den alle felter om til den skrift tybe og jeg ville gerne at jeg kunne have fx time new roman i den ene og coureu new (eller hvad det hedder i den næste , når jeg trykker en ny frem i min database. Kan det på nogen måde lade sig gøre at den beholder den tekst tybe jeg har valgt.
Hvis du bare gemmer teksten i tabellen så følger formatteringen ikke med. Det må du gemme særskilt i tilhørende felter, eks. tilføje felterne: FontName, FontSize, FontAttr
Alternativt kan du gemme det hele i et OLEObjekt-felt -> dvs. at du gemmer en binær klump data hvor du har specificeret, at det er Courier New, pkt 14, bold, eksempelvis:
CourierNew#0$000E$0001The quick brown fox jumps over the lazy dogs#0
#0 indikerer at det er en nul-terminator, $xxxx angiver en 4-byte størrelse.
Her gemmes font navn, størrelse 14, bold, tekst, og data mu du parse og sætte når du indlæser feltet igen. Jeg kan ikke se andre måder (men det er der sikkert). Måske findes der en "lav dette til Rich Text"-funktion som kan gøre det for dig - man kan være heldig.
Den første er lige ud af landevejen. Du skal gemme følgende: Fontnavn, størrelse, attribut og tekst. Du opretter alle fire felter i en tabel og gemmer det for hver linie du indsætter. Ulempen er at det ikke ser særlig smart ud ;-)
Den anden... I Access bruges OLE-Objektet som lagerplads for binære data, altså ting der ikke umiddelbart kan placeres på nogen af de andre felttyper. Du behøver ikke lave det sådan som jeg viste dig, men BLOB (Binary Large Object B???)-data skal streames og så er det naturligt at gøre det på den måde. Desuden er det ikke spild af plads og der er ikke nogen begrænsning på strenglængden.
Alternativt kan du gemme data i en record og så streame den til feltet.
Lægger lige et eksempel der blev noget mere besværligt end jeg havde regnet med. Skriver og læser til en tabel bestående af kolonnerne ID(sutoinc), Name(komponentens navn) og Data(Ole-Object):
procedure WriteIntToStream(aStream : TStream; const aInt : integer; const aSize : integer = -1); begin if aSize = -1 then aStream.WriteBuffer(aInt,sizeof(integer)) else aStream.WriteBuffer(aInt,aSize); end;
var DataStream : TStream; Size, FontStyle : integer; begin ADOTable.Insert; DataStream := ADOTable.CreateBlobStream(ADOTableData,bmWrite); try with eData do begin // Find samlet data størrelse Size := length(Font.Name) + 1 + sizeof(integer) + sizeof(integer) + sizeof(TColor) + length(Text) + 1;
// Ikke muligt for mig at gemme Font.Style direkte, øv! FontStyle := 0; if fsBold in Font.Style then FontStyle := $1; if fsItalic in Font.Style then FontStyle := FontStyle or $2; if fsUnderline in Font.Style then FontStyle := FontStyle or $4; if fsStrikeOut in Font.Style then FontStyle := FontStyle or $8;
// Gem komponentens navn ADOTableName.AsString := eData.Name; // Peger på FieldByName('Name');
// Gem alle data i 'Data'-feltet WriteIntToStream(DataStream,Size); WriteStrToStream(DataStream,Font.Name); WriteIntToStream(DataStream,Font.Size); WriteIntToStream(DataStream,FontStyle); WriteIntToStream(DataStream,Font.Color,sizeof(TColor)); WriteStrToStream(DataStream,Text);
// Indlæser pågældende record procedure TfrmMain.btnReadTextClick(Sender: TObject); var base, pc : pchar; DataStream : TStream; Size, FontStyle : integer; begin if ADOTable.Eof then exit;
DataStream := ADOTable.CreateBlobStream(ADOTableData,bmRead); try with eData do begin DataStream.Read(Size,sizeof(integer)); // Læs størrelse
GetMem(base,Size); // Allokér hukommelse til data try DataStream.ReadBuffer(base^,Size); // Indlæs data
pc := base; // Parse data Font.Name := pc; // Da fontens navn er nul-termineret er den direkte pc := StrEnd(pc) + 1; Spring videre til næste data Font.Size := integer(pc^); pc := pc + sizeof(integer); // osv, osv FontStyle := integer(pc^); pc := pc + sizeof(integer); Font.Color := TColor(pc^); pc := pc + sizeof(TColor); Text := pc; // Resten af base er teksten i feltet finally FreeMem(base); end;
// Sæt font.style Font.Style := []; if FontStyle and $1 = $1 then Font.Style := Font.Style + [fsBold]; if FontStyle and $2 = $2 then Font.Style := Font.Style + [fsItalic]; if FontStyle and $4 = $4 then Font.Style := Font.Style + [fsUnderline]; if FontStyle and $8 = $8 then Font.Style := Font.Style + [fsStrikeOut]; end; // with finally DataStream.Free; end; // try end;
Jeg ved at det er blevet lidt langhåret, men jeg håber at du kan lære lidt deraf alligevel. Ovenstående eksempel har en lille bug et eller andet sted - hvis man fjerner farve-feltet, så kører det.
WAW , jeg havde opgivet den. Der kan man bare se : ) Mange tak, den skal der rodes med.. Pyt med farve, det betyder ikke så meget. **** Noget andet :
I går lavede jeg nogle test med cds filer som database. Det er nemt nok...(det vidste jeg ikke ) Men size 50 er det 50 tegn eller ? Så der opstod jo nogle ? , men det høre under noget andet så hvor er det godt at det her forum findes..
Næ, det skulle jeg da ikke mene - det er en indlejret procedure der kun kendes i "SkrivTilStream" proceduren. Jeg tæller et "begin" og et "end", så det skulle stemme.
eData skal rigtignok defineres et sted. Det er en TEdit og sådan nogle giver jeg altid et navn med e (for Edit) foran. Er aldrig kommet i vanen med at lave kode hvor komponenterne hedder Edit1, Button1, 2 osv.
Dobbelt klik på TClientDataSet komponenten. Du får nu et lille vindue frem hvor i man kan definere databasens felter. Det gøres ved at højre-klikke og vælge "New Field".
*** Tja , det er der man laver cds databasefilerne, som jeg testede af. Jeg ved ikke hvad det er for nogle filer. Men det virker.. De bruges hele tiden i de demoer der kommer med fx Delphi. Jeg har tit tænkt og spurgt her hvordan og med hvad de laves.. men ingen har svaret på det.. Men Hemmeligheden ? : ) ses ovenfor
Jeg er jo ikke så go, så du må være tålmodig.. se nu bare jeg vidste ingengang at man bare ? kunne lave en ny begin og end i den samme... Ikke at jeg ikke har prøvet det... jo da... men det gik galt.. : ) Nå så må jeg lære de BLOB og/eller stremes at kende nu.. Dem har jeg heller aldrig kunnet.. Men jeg ser dem hele tiden hos den gode delphi folk..
Det ligger langt ud over mine evner.. Det køre slet ikke.. Den kan ikke finde ADOTable1 ?? inde i procduren..
[Fatal Error] tekst.dpr(5): Could not compile used unit 'Unit1.pas' [Error] Unit1.pas(102): Statement expected but end of file found [Error] Unit1.pas(75): Operator not applicable to this operand type [Error] Unit1.pas(73): Operator not applicable to this operand type [Error] Unit1.pas(61): Undeclared identifier: 'ADOTable1'
Ellers tak..
VH koden12
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.