Avatar billede lukej Nybegynder
17. april 2003 - 16:28 Der er 4 kommentarer og
1 løsning

søgefunktion - record

HEj

jeg har lavet et program hvor man kan skrive ind hvilke numre man har på sine cd'er. Oplysningerne bliver gemt i en record. Det er oplysninger om tittel, kunstner, album og længde m.m.
Problemet ligger i at den kun søger på et ord der ligner 100%, i stedet for at se mellem fingre med om det er stort begyndelses bogstav osv. Hvordan ændrer man det?? Så den er lige glad med om det er store eller små bogstaver????
Avatar billede cooljay2000 Nybegynder
17. april 2003 - 16:32 #1
Vis os lidt af din kode (din record og din søge-kode) - så skal du få et kvalificeret svar!
Avatar billede lukej Nybegynder
17. april 2003 - 16:50 #2
unit Sog;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus;

type

TMusik=record
  Slettet:boolean;
  Kunstner, Tittel, Album, Langde:string[50];
end;
  TFSog=class(TForm)


    MainMenu1: TMainMenu;
    Indskriv1: TMenuItem;
    Luk1: TMenuItem;
    Hent1: TMenuItem;
    Sgeside1: TMenuItem;
    ListBox: TListBox;

    EdSog: TEdit;

    CheckBoxKunstner: TCheckBox;
    CheckBoxTittel: TCheckBox;
    CheckBoxLangde: TCheckBox;
    CheckBoxAlbum: TCheckBox;

    BtSog: TButton;
    procedure Luk1Click(Sender: TObject);
    procedure BtSogClick(Sender: TObject);
    procedure Sgeside1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FSog: TFSog;
  MusikFil: file of TMusik;
  Musik:TMusik;
  MusikAktuel:TMusik;
  PosIFil: integer;
  Slettet:boolean;

implementation

uses indskriv;

{$R *.dfm}

procedure TFSog.Luk1Click(Sender: TObject);
begin
        close;

end;


procedure TFSog.BtSogClick(Sender: TObject);
begin
if CheckBoxKunstner.Checked=true then

begin
AssignFile(MusikFil, 'Musik.qz');
Reset(MusikFil);
While not eof(MusikFil) do
    begin
      Read(MusikFil,MusikAktuel);
        if not MusikAktuel.slettet then
        if Pos(EdSog.Text, MusikAktuel.Kunstner)>0 then
      begin
      ListBox.Items.Add(MusikAktuel.Kunstner +' '+' '+
      MusikAktuel.Tittel +' '+' '+ MusikAktuel.Album+' '+' '+MusikAktuel.Langde);
      end;
                          end;
    end;

if CheckBoxTittel.Checked=true then
begin
AssignFile(MusikFil, 'Musik.qz');
Reset(MusikFil);
While not eof(MusikFil) do
    begin
      Read(MusikFil,MusikAktuel);
        if not MusikAktuel.slettet then
        if Pos(EdSog.Text, MusikAktuel.Tittel)>0 then
      begin
      ListBox.Items.Add(MusikAktuel.Kunstner +' '+' '+
      MusikAktuel.Tittel +' '+' '+ MusikAktuel.Album+' '+' '+MusikAktuel.Langde);
      end;
                          end;
    end;

    if CheckBoxAlbum.Checked=true then
begin
AssignFile(MusikFil, 'Musik.qz');
Reset(MusikFil);
While not eof(MusikFil) do
    begin
      Read(MusikFil,MusikAktuel);
        if not MusikAktuel.slettet then
        if Pos(EdSog.Text, MusikAktuel.Album)>0 then
      begin
      ListBox.Items.Add(MusikAktuel.Kunstner +' '+' '+
      MusikAktuel.Tittel +' '+' '+ MusikAktuel.Album+' '+' '+MusikAktuel.Langde);
      end;
                          end;
    end;

    if CheckBoxLangde.Checked=true then
begin
AssignFile(MusikFil, 'Musik.qz');
Reset(MusikFil);
While not eof(MusikFil) do
    begin
      Read(MusikFil,MusikAktuel);
        if not MusikAktuel.slettet then
        if Pos(EdSog.Text, MusikAktuel.Langde)>0 then
      begin
      ListBox.Items.Add(MusikAktuel.Kunstner +' '+' '+
      MusikAktuel.Tittel +' '+' '+ MusikAktuel.Album+' '+' '+MusikAktuel.Langde);
      end;
                          end;
    end;
end;





Dette er så koden Jeg ønsker ikke at få rettet i koden, men en stump kode der er til at sidde índ i den originale kode....
Avatar billede cooljay2000 Nybegynder
17. april 2003 - 17:08 #3
du bruger Pos til at søge med, hvilket begrænser dine muligheder meget. Bl.a. er der problemet med Upper/lower-case.

Hvis dit problem kun drejer sig om upper/lower-case så sammenlign 2 'uppercase'ede strenge - pos(Uppercase(string1),Uppercase(string2))

Hvis du der i mod gerne vil en masse andre ting - f.eks. kunne søge på '*llica*' så brug regular expressions. Har selv brugt denne her: http://anso.virtualave.net/delphi_stuff.htm
Avatar billede athlon-pascal Juniormester
18. april 2003 - 20:10 #4
Kig på følgende, en simpel funktion der også lader dig søge på '*llica*' og '?llica*' og den slags:

unit Wildcard;

interface

uses
  SysUtils;

function WildcardMatch(const source, pattern: String): Boolean;
function WildcardMatchIC(const source, pattern: String): Boolean;
function WildcardMatchEx(const source, pattern: String; const ic: Boolean): Boolean;

implementation

function WildcardMatchEx(const source, pattern: String; const ic: Boolean): Boolean;
begin
  { perform a wildcard match, either case-sensitive or case-insensitive,
    depending on the ic flag. }
  if ic = True then
    result := WildcardMatchIC(source, pattern)
  else
    result := WildcardMatch(source, pattern);
end;

function WildcardMatchIC(const source, pattern: String): Boolean;
begin
  { perform a case insensitive wildcard match by converting the pattern
    and source strings to uppercase. }
  result := WildcardMatch(UpperCase(source), UpperCase(pattern));
end;

function WildcardMatch(const source, pattern: String): Boolean;
var
  pSource: Array [0..255] of Char;
  pPattern: Array [0..255] of Char;

  function MatchPattern(element, pattern: PChar): Boolean;

    function IsPatternWild(pattern: PChar): Boolean;
    begin
      Result := StrScan(pattern,'*') <> nil;
      if not Result then Result := StrScan(pattern,'?') <> nil;
    end;

  begin
    if 0 = StrComp(pattern,'*') then
      Result := True
    else if (element^ = Chr(0)) and (pattern^ <> Chr(0)) then
      Result := False
    else if element^ = Chr(0) then
      Result := True
    else begin
      case pattern^ of
      '*': if MatchPattern(element,@pattern[1]) then
            Result := True
          else
            Result := MatchPattern(@element[1],pattern);
      '?': Result := MatchPattern(@element[1],@pattern[1]);

      else
        if element^ = pattern^ then
          Result := MatchPattern(@element[1],@pattern[1])
        else
          Result := False;
      end;
    end;
  end;

begin
  StrPCopy(pSource,source);
  StrPCopy(pPattern,pattern);
  Result := MatchPattern(pSource,pPattern);
end;

end.

Ref.: http://www.eksperten.dk/spm/285290
Avatar billede jensfudge Nybegynder
23. april 2003 - 11:12 #5
Personligt ville jeg have det hele gemt i en tabelstruktur i stedet:
Ved at benytte TClientDataset er du ovre alle BDE problemer osv, de er perfekte til det du er ved at lave. I det følgende eksempel åbner jeg en tabel jeg har benyttet til billedeID'er, forkortet og modificeret til dette eksempel...

Procedure Tdm.OpenPictureID;
var
fileNm : String;
begin
  fileNm := sPath+'PictureID.cds';
  cdsPictureID.FileName := filenm;
  if not FileExists(filenm) then
  begin
    with cdsPictureID do
    begin
      with FieldDefs.AddFieldDef do
      begin
        DataType := ftInteger;
        Name := 'NEXTVAL';
      end;
      with FieldDefs.AddFieldDef do
      begin
        DataType := ftString;
        Name := 'Location';
      end;

      CreateDataSet;
    end;
  end;
  cdsPictureID.Open;
end;


Ved at benytte denne har du muligheden for at kalde .locate på dit dataset, hvor én af parametrene er insensitive....

Desuden: Et dataset.locate kald søger iøvrigt binært fremfor sekventielt, så du får lidt hastighed med i købet.

/Jens
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