2010-07-21 9 views
2

J'ai un attribut appelé HistoryText dans un objet qui est stocké sous forme de chaîne. Je souhaite afficher toutes les lignes d'une grille. Je devrais pouvoir supprimer et éditer des rangées dans la grille. Le format est le suivant:Liste de chaînes avec délimiteur en tant que chaîne?

16.5.2003-$-12:09-$-anna-$-Organization created 
2.6.2005-$-13:03-$-jimmy-$-Organization edited 
19.12.2005-$-13:33-$-madeleine-$-Organization edited 

Donc, chaque ligne ont 4 champs, date, heure, utilisateur, et un message avec une chaîne de delimiter comme '- $ -. En tant que délimiteur, une chaîne et non un caractère ne peut pas être affecté à la propriété délimiteur de listes de chaînes.

J'ai une routine pour extraire la chaîne à un StringList:

procedure ParseDelimited(const aStringList: TStringList; const aOrgList, aDelimiter: string); 
var 
    vDelimiterPos : integer; 
    vPartialStr : string; 
    vRemaingTxt : string; 
    vDelimiterLength : integer; 
begin 
    vDelimiterLength := Length(aDelimiter); 

    if (AnsiRightStr(aOrgList, Length(aDelimiter)) = aDelimiter) then 
    vRemaingTxt := aOrgList 
    else 
    vRemaingTxt := aOrgList + aDelimiter; 

    aStringList.BeginUpdate; 
    aStringList.Clear; 
    try 
    while Length(vRemaingTxt) > 0 do 
    begin 
     vDelimiterPos := Pos(aDelimiter, vRemaingTxt); 
     vPartialStr := Copy(vRemaingTxt,0,vDelimiterPos-1); 
     aStringList.Add(vPartialStr); 
     vRemaingTxt := Copy(vRemaingTxt,vDelimiterPos+vDelimiterLength,MaxInt); 
    end; 
    finally 
    aStringList.EndUpdate; 
    end; 
end; 

et il semble fonctionner très bien. Mon problème consiste à synchroniser les modifications dans StringList à la propriété String d'origine? Il y a tellement de données historiques avec ce délimiteur donc je ne pense pas que le changer en TChar est une option réaliste.

Mise à jour: Une clarification. Je pense que je peux réussir à convertir la chaîne en StringList avec la méthode ci-dessus. Puis l'afficher dans la grille ne devrait pas être si difficile. Le problème vient lorsque je veux convertir le TStringList à la propriété String originale wih '- $ -' comme délimiteur. Je ne peux pas faire HistoryText: = myStringList.Delimitedtext par exemple.

Deuxième mise à jour: Je l'ai résolu. Vous avez tous obtenu un +1 pour des réponses rapides et essayant vraiment d'aider. En résumé, comment je l'ai fait.

Lire à partir Historytext:

MyStringList.Text := Historytext; 

Maintenant, chaque rangée ont 3 délimiteurs de « - $ - » et chaque ligne est séparée par un saut de ligne comme d'habitude.

  • Dans une boucle, analysez la liste des chaînes et affichez-la dans la grille. Je ne me soucie plus de MyStringList.
  • Permet à l'utilisateur de supprimer et d'éditer des lignes dans la grille.
  • Une fois terminé, effectuez une boucle par ligne et par colonne dans la grille et créez une nouvelle chaîne avec le même format que l'original.
  • Affectez cette chaîne à HistoryText.

shift donc mise au point de StringList au réseau a facilité :)

+0

Quelle est votre vraie question? Vous mentionnez vouloir afficher dans une grille et que la procédure de liste de chaînes "semble bien fonctionner". "Synchroniser les changements" est également un peu large. De quoi avez-vous besoin? Se – Tobiasopdenbrouw

+0

ma mise à jour :) –

+0

Ma solution ne fonctionne (en D2007 +) dans les deux sens - et est beaucoup plus courte. –

Répondre

2

coup sauvage dans l'obscurité (il est pas très clair ce que vous demandez):

travail à travers les rangées de la grille :

  • pour chaque ligne:
    • affecter une chaîne vide à une chaîne temporaire var
    • Pour chaque colonne ajouter une ligne/valeur de colonne plus votre delimiter à chaîne temporaire var
    • supprimer dernier délimiteur de chaîne temporaire var (si elle est non vide)
    • ajouter chaîne temporaire var à StringList
  • Ecrire la propriété texte stringlist à votre HistoryText

const 
    Delimiter = '-$-'; 
var 
    row: Integer; 
    col: Integer; 
    SL: TStringList; 
    rowString: string; 
begin 
    SL := TStringList.Create; 
    try 
    for row := 0 to StringGrid1.RowCount - 1 do begin 
     rowString := ''; 
     for col := 0 to StringGrid1.ColCount - 1 do begin 
     rowString := StringGrid1.Cells[col, row] + Delimiter; 
     end; 
     if rowString <> '' then begin 
     rowString := Copy(rowString, 1, Length(rowString) - Length(Delimiter)); 
     end; 
     SL.Add(rowString); 
    end; 
    HistoryText := SL.Text; 
    finally 
    SL.Free; 
    end; 
end; 

En utilisant la solution de Uwe de la propriété LineBreak de TStrings:

var 
    row: Integer; 
    col: Integer; 
    SLRows: TStringList; 
    SLCols: TStringlist; 
begin 
    SLRows := TStringList.Create; 
    try 
    SLCols := TStringList.Create; 
    try 
     SLCols.LineBreak := '-$-'; 
     for row := 0 to StringGrid1.RowCount - 1 do begin 
     SLCols.Clear; 
     for col := 0 to StringGrid1.ColCount - 1 do begin 
      SLCols.Add(StringGrid1.Cells[col, row]); 
     end; 
     SLRows.Add(SLCols.Text); 
     end; 
     HistoryText := SLRows.Text; 
    finally 
     SLCols.Free; 
    end; 
    finally 
    SLRows.Free; 
    end; 
end; 
5

Au lieu de délimiteur (char) et DelimitedText, vous pouvez également utiliser LineBreak (une chaîne) et texte:

lst := TStringList.Create; 
try 
    lst.LineBreak := '-$-'; 
    lst.Text := '16.5.2003-$-12:09-$-anna-$-Organization created'; 
    Memo1.Lines := lst; // or whatever you do with it 
finally 
    lst.Free; 
end; 

Ans cela fonctionne même l'inverse.

+0

Hey qui est un bon. Savez-vous quand (quelle version Delphi) a été introduite? –

+0

D7

+0

Désolé mais je ne comprends pas. Chaque ligne de la propriété de chaîne est délimitée par un retour chariot + saut de ligne. Alors La chaîne est réelle: 16.5.2003 - $ - 12:09 - $ - anna - $ - Organisation créée # D # A 2.6.2005 - $ - 13:03 - $ - jimmy - $ - Organisation modifiée # D # A 19.12.2005 - $ - 13:33 - $ - madeleine - $ - Organisation modifiée # D # A LST: = TStringList.Create; essayez lst.LineBreak: = '- $ -'; lst.Text: = // myObject.HistoryText Utilisez la liste dans la grille par exemple enfin lst.Free; fin; Est-ce que c'est ce que vous voulez dire? –

Questions connexes