Avatar billede koden12 Nybegynder
22. maj 2004 - 01:25 Der 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.

VH
Koden12
Avatar billede hrc Mester
22. maj 2004 - 08:06 #1
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.
Avatar billede koden12 Nybegynder
22. maj 2004 - 12:12 #2
Det er nogle fine løsninger du har anvist men jeg må indrømme
at jeg ikke har viden nok til at gennemfører (Lave) det.

VH
koden12
Avatar billede hrc Mester
23. maj 2004 - 00:36 #3
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 TfrmMain.btnSaveTextClick(Sender: TObject);

  procedure WriteStrToStream(aStream : TStream; const aString : string);
  begin
    aStream.WriteBuffer(pchar(aString)^,length(aString) + 1);
  end;

  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);

    end; // with
  finally
    DataStream.Free;
    ADOTable.Post; // Afslut skrivning
  end; // try
end;


// 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.
Avatar billede koden12 Nybegynder
23. maj 2004 - 10:16 #4
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..

VH
Koden12
Avatar billede koden12 Nybegynder
23. maj 2004 - 11:05 #5
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;

/// Mangler det ikke noget her ??? der er end;

var
  DataStream : TStream;
  Size, FontStyle : integer;
// her ikke kopieret mere

Skal eData udnævnes et eller andet sted ?

VH
koden12
Avatar billede hrc Mester
23. maj 2004 - 13:47 #6
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.
Avatar billede hrc Mester
23. maj 2004 - 13:48 #7
Hvad er cds-filer?
Avatar billede koden12 Nybegynder
23. maj 2004 - 14:52 #8
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..

VH
koden12
Avatar billede koden12 Nybegynder
23. maj 2004 - 15:28 #9
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
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester