CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - ReplaceDialog - użycie

ReplaceDialog - użycie

dział ogólny

ReplaceDialog - użycie

Postprzez Pitek » wtorek, 26 października 2010, 21:22

Witam!
Mam pytanie jak użyć komponent ReplaceDialog w odniesieniu do zawartości tabeli komponentu StringGrid ?
Przykład : Mam tabelę np. 10 na 10 a w niej w różnych komórkach tekst : "super tabela". chciałbym za pomocą komponentu ReplaceDialog zamienić ten tekst na np. "super extra tabela". Nie mam za bardzo pojęcia jak ustawić chociażby zakres wyszukiwanego tekstu lub wielkość uwzględnianych liter.
Nigdy wcześniej tego nie robiłem czy jest to trudne i wymaga z mojej strony ogromniej ilości kodu ?

Pozdrawiam pitek3010

P.S. CB udało mi się zrobić te podpowiedzi xD
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez polymorphism » środa, 27 października 2010, 11:09

Jeśli chodzi o porównywanie stringów bez uwzględniania wielkości znaków, masz do tego metodę AnsiString::AnsiCompareIC.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Cyfrowy Baron » środa, 27 października 2010, 12:29

Autor postu zdaje się raczej sądzić, iż komponent TReplaceDialog udostępnia jakieś funkcje umożliwiające proste, bezwysiłkowe zamienianie tekstu. Tak jednak nie jest. Ten komponent udostępnia tylko okienko dialogowe z kilkoma zmiennymi i zdarzeniami. Wykorzystując zdarzenie OnReplace można oczywiście zmienić tekst w komórkach tabeli, ale ten komponent jest zasadniczo przystosowany do obiektów typu TMemo i TRichEdit, co nie oznacza, że wystarczy je podpiąć pod tego obiekty, a komponent zrobi resztę.

Podaję tutaj prosty przykład zamiany tekstu z uwzględnianiem opcji wielkości liter. Przykład działa prawidłowo, ale może wymagać dopracowania lub zmian, gdyż wyszukiwanie zawsze odbywa się tutaj od początku do końca tabeli, a nie od wybranej komórki. Gdy wyszukiwanie dojdzie do końca zaczyna się od początku, o ile zostanie wciśnięty przycisk Zamień:

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 ReplaceDialog1->Execute();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ReplaceDialog1Replace(TObject *Sender)
{
 static int col = -1, row = 0;

 bool next = true;
 while(next)
 {
  if(col < 9)
  {
   ++col;
  }
  else
  {
   col = 0;
   ++row;

   if(row > 9) row = 0;
  }

  int compare;
  if( ReplaceDialog1->Options.Contains(frMatchCase) )
   compare = CompareStr( StringGrid1->Cells[col][row], ReplaceDialog1->FindText);

  if( !ReplaceDialog1->Options.Contains(frMatchCase) )
   compare = CompareText(StringGrid1->Cells[col][row], ReplaceDialog1->FindText);

  if( compare == 0 )
  {
   StringGrid1->Cells[col][row] = ReplaceDialog1->ReplaceText;

   StringGrid1->Col = col;
   StringGrid1->Row = row;
   next = false;
  }
  else
  {
   next  = true;
   if(col >= 9 && row >= 9)
   {
    col = 0;
    row = 0;
    return;
   }
  }
 }
}
//---------------------------------------------------------------------------




P.S. CB udało mi się zrobić te podpowiedzi xD


Myślałem nad tym i dałoby się to zrobić za pomocą dwóch list jednej w pamięci, jednej wizualnej i pętli, ale to się nie sprawdzi przy dużej liczbie rekordów. Powinieneś opisać ten problem w oddzielnym wątku. Ten jeden raz zrobię to za Ciebie, być może ktoś będzie miał pomysł jak to zrobić.

Chodzi o zrobienie czegoś podobnego jak podpowiedzi w edytorze środowiska C++builder:

podpowiedz.png


Rzecz w tym, żeby zrobić coś podobnego dla tabeli typu TStringGrid. Zrobienie samego mechanizmu podpowiedzi nie jest problemem, więc kwestia tego, czy to będzie tabela czy inny obiekt jest tutaj nieistotna. Istotne jest to jak wyszukiwać tekst w trakcie pisania.

Mam dajmy na to obiekt typu TEdit - Edit1, mam też listę typu TStringList - ARecords zawierającą rekordy, oraz drugą listę typu TListBox - BResult pustą. Chodzi o to by podczas wpisywania tekstu w Edit1 program szukał na liście ARecords rekordu, którego tekst zaczyna się na litery wpisane już w Edit1, np:

Lista ARecords zawiera wpisy:

Mercedes
Fiat Brava
Fiat Coupe
Fiat Ducato
Polonez



Po wpisaniu do Edit jeden tekstu: Fia program przeszukuje listę ARecords i filtruje wyniki wyświetlane w liście BResult, czyli umieszcza na tej liście wszystkie rekordy zaczynające się na Fia, a więc:


Fiat Brava
Fiat Coupe
Fiat Ducato




Gdy np. w Edit1 znajdzie się tekst Fiat C to na liście BResult zostanie wyświetlony rekord Fiat Coupe.

Zadanie da się zrealizować w prosty sposób: po każdym wpisanym znaku program przegląda listę z rekordami i wpisuje na listę wynikową tylko te pasujące. To proste rozwiązanie, ale w przypadku dużej liczy rekordów będzie powstawać duże opóźnienie.
Szukam innego sposobu.
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez polymorphism » środa, 27 października 2010, 13:03

W sumie prosta sprawa: kontener set (lub map) i jego metoda lower_bound (złożoność logarytmiczna). Dla dużych baz robisz analogicznie, tyle że sam musisz zaimplementować kontener i ewentualnie algorytm lower bound.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Cyfrowy Baron » środa, 27 października 2010, 13:14

A mógłbyś podać jakiś prosty przykład z dwiema listami. Przejrzałem pomoc i lower_bound nie jest chyba tym czego tutaj potrzeba, znalazłem za to metodę key_compare. Nigdy nie stosowałem żadnej, więc muszę się z tym dopiero zapoznać, ale przykład byłby mile widziany.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez polymorphism » środa, 27 października 2010, 13:52

KOD cpp:     UKRYJ  
const char* data[] =
{
        "Mercedes",
        "Fiat Brava",
        "Fiat Coupe",
        "Fiat Ducato",
        "Polonez"
};

set<string> s;

s.insert(data,data + sizeof(data) / sizeof(void*));

string key = "Fia"; //<--- szukane

set<string>::iterator it = s.lower_bound(key);
if(it != s.end())
{
        /* wypisanie wszystkich pozycji zaczynających się od zawartości 'key' */
        do
        {
                cout << *it << '\n';
        }
        while(++it != s.end() &&
                it->size() >= key.size() &&
                equal(key.begin(),key.end(),it->begin()));
}
 

Oczywiście jest to prosty kod, nieuwzględniający paru rzeczy. Można by na przykład użyć upper_bound do określenia górnej granicy zbioru, dzięki czemu nie trzeba by dokonywać porównań przy wyliczaniu wszystkich znalezionych pozycji (teraz ma to złożoność liniową - ble!). Użycie upper_bound wiąże się z koniecznością zmiany przechowywania elementów - teraz, pomimo zapewnienia własnej implementacji funktora porównującego, nie byłbym w stanie określić, który string to key, a który jest elementem listy. Jest to ważne przy wyszukiwaniu górnej granicy na podst. fragmentu tekstu.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Cyfrowy Baron
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Pitek » środa, 27 października 2010, 21:48

Wracając do tematu to dziękuję za przykładowy kod troszkę go "podrasowałem" i w sumie mi wystarcza. Mam tylko pytanie jak rozróżnić kliknięcie przycisku Zamień a Zamień wszystko ?
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Cyfrowy Baron » czwartek, 28 października 2010, 09:21

Mam tylko pytanie jak rozróżnić kliknięcie przycisku Zamień a Zamień wszystko ?


Oczywiście można to rozpoznać tylko w zdarzeniu OnReplace:

KOD cpp:     UKRYJ  
void __fastcall TForm1::ReplaceDialog1Replace(TObject *Sender)
{
 if( ReplaceDialog1->Options.Contains(frReplace) )
   ShowMessage("Wybrano przycisk \"Zamień\"");

 if( ReplaceDialog1->Options.Contains(frReplaceAll) )
    ShowMessage("Wybrano przycisk \"Zamień wszystko\"");
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Cyfrowy Baron » czwartek, 28 października 2010, 11:01

Mam pytanie odnoście kodu polymorphism. Jak przerobić ten kod by działał na typie UnicodeString oraz na liście typu TStrings. obiekt typu TStringGrid oferuje gotową listę typy TStrings zawierającą rekordy w wybranej kolumnie, dzięki temu nie muszę tworzyć nowej listy. Jeżeli trzeba to przepisać na char to robi się problem, gdyż dochodzi czas potrzebny na przepisanie listy. Przypominam, że filtrowanie odbywa się o zawartość tabeli, która może być zmienna, więc nie mogę na sztywno zdefiniować rekordów, lecz muszę pobierać je na bieżąco z tabeli.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Cyfrowy Baron » czwartek, 28 października 2010, 12:15

Kodu polymorphism nie udało mi się zaadoptować na potrzeby programu - problem ze TStrings i UnicodeString, ale częściowo problem rozwiązałem, niestety natknąłem się na poważną przeszkodę - nie można pobrać z edytowanej komórki wprowadzanego tekstu, ponieważ brak jest zdarzenia w rodzaju OnEdit, które występuje np. w obiekcie Edit1. Wymagałoby to połączenia tabeli z obiektem typu TEdit i wpisywania tekstu właśnie w Edit, a potem przepisania tego do komórki. Dodałem wprawdzie kod przechwytujący wciskane przyciski na klawiaturze, ale to nie może działać w pełni poprawnie. Niemniej zamieszczam kod i przykładowy program. Jeżeli wpadnę na jakiś pomysł to wrócę do tego tematu.
Plik nagłówkowy Unit1.h
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TPanel *Panel1;
        TStringGrid *StringGrid1;
        void __fastcall FormShow(TObject *Sender);
        void __fastcall StringGrid1KeyPress(TObject *Sender, wchar_t &Key);
        void __fastcall StringGrid1SelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect);
        void __fastcall StringGrid1Click(TObject *Sender);
        void __fastcall StringGrid1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
private:        // User declarations
        void __fastcall LoadFile(void);

        TPoint SetPos(void);
        TStringList* Filtruj(void) ;

        String editText;

public:         // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


Plik źródłowy Unit1.cpp
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#include <memory>
#include <set>
#include <locale>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
using namespace std;

int ACol, ARow;

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 setlocale(LC_CTYPE, ".ACP");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::LoadFile(void)
{
 String fileName = ExtractFilePath(ParamStr(0)) + "lista.txt";
 auto_ptr<TStringList> Lista (new TStringList());
 Lista->LoadFromFile(fileName);
 int c = 0;

 do
 {
  String tmpValue = Lista->Strings[c];
  int i;
  for(i = 0; i < 4; i++)
  {
   int x = tmpValue.Pos(";");
   StringGrid1->Cells[i + 1][c + 3] = tmpValue.SubString(1, x - 1);
   tmpValue = tmpValue.Delete(1, x);
  }

  StringGrid1->Cells[i][c + 3] = tmpValue;

 }while(++c < Lista->Count);
}
//---------------------------------------------------------------------------
TPoint TForm1::SetPos(void)
{
 TPoint pt;

 for(int col = 0; col <= ACol; col++)
  pt.x = pt.x + StringGrid1->ColWidths[col];

 for(int row = 0; row <= ARow; row++)
  pt.y = pt.y + StringGrid1->RowHeights[row];

 pt.x = pt.x + this->Left + Panel1->Left + StringGrid1->Left;
 pt.y = pt.y + this->Top + Panel1->Top + StringGrid1->Top + 5;

 return pt;
}
//---------------------------------------------------------------------------
TStringList* TForm1::Filtruj(void)
{
 Caption = editText;

 auto_ptr<TStringList> Result (new TStringList);

 for(int x = 0; x < StringGrid1->Cols[ACol]->Count; x++)
 {
  String Value = StringGrid1->Cols[ACol]->Strings[x];
  int p = Value.Pos(editText);
  if(p > 0) Result->Add(Value);
 }

 return Result.release();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
 LoadFile();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1KeyPress(TObject *Sender, wchar_t &Key)
{
 if(Key == VK_ESCAPE)
 {
  FormPopup->Close();
  editText = "";
  return;
 }

 if(isascii((unsigned char)Key)) editText = editText + (String)Key;

 if(Key == VK_DELETE) editText = "";
 if(Key == VK_BACK) editText = editText.Delete(editText.Length() - 2, 1);


 if(!FormPopup->Showing)
 {
  TPoint pt = SetPos();
  FormPopup->SetBounds( pt.x + 10, pt.y, FormPopup->Width, FormPopup->Height);
  FormPopup->Show();

  FormPopup->Height = FormPopup->ListBox1->Height;
  StringGrid1->SetFocus();
 }

 FormPopup->ListBox1->Items->Assign(Filtruj());


 if(FormPopup->ListBox1->Items->Count < 20 &&
    FormPopup->ListBox1->Items->Count > 0)
 {
   FormPopup->ListBox1->Height = FormPopup->ListBox1->ItemHeight *
                                 FormPopup->ListBox1->Items->Count + 4;
   FormPopup->Height = FormPopup->ListBox1->Height;
 }
 else
 {
  FormPopup->ListBox1->Height = 264;
 }

 if(FormPopup->ListBox1->Items->Count == 0) FormPopup->Close();

}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol, int ARow,
          bool &CanSelect)
{
 ::ACol = ACol;
 ::ARow = ARow;
 StringGrid1Click(Sender);
 editText = "";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StringGrid1Click(TObject *Sender)
{
 if(FormPopup->Showing)
 {
  FormPopup->Close();
  editText  = "";
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1MouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
{
  TPoint pt;
  StringGrid1->MouseToCell(X, Y, ::ACol, ::ARow);
}
//---------------------------------------------------------------------------
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez polymorphism » czwartek, 28 października 2010, 12:47

Jak przerobić ten kod by działał na typie UnicodeString oraz na liście typu TStrings. obiekt typu TStringGrid oferuje gotową listę typy TStrings zawierającą rekordy w wybranej kolumnie

Wyszukiwanie lower bound da się zaimplementować dla TStrings, tylko że w przypadku tego algorytmu, jak i innych, opartych na wyszukiwaniu binarnym, zbiór musi być posortowany. Z tego co widzę dane pobierane są z grida, nie są posortowane, więc ta metoda wyszukiwania nie ma tu zastosowania, chyba że wprowadzić indeksy, tak jak to ma miejsce w bazach danych.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Pitek » piątek, 29 października 2010, 23:12

Mam pewien problem. Próbowałem rozwiązać go sam ale jakoś nie wychodzi. Mianowicie kiedy mam w komórce tekst Cyfrowy Baron a tekst którego szukam do zamiany na inny to Cyfrowy nie zamienia go muszę podać całą zawartość komórki. I teraz pytanie, jak zrobić ażeby wyszukiwał każdy tekst a nie tylko całą zawartość komórki ?
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez polymorphism » sobota, 30 października 2010, 19:35

Zamiast porównywać stringi, użyj metody String::Pos.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Pitek
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez Cyfrowy Baron » niedziela, 31 października 2010, 09:11

Rozwijając myśl polymorphism dodam, że należy stworzyć funkcję przeszukującą tekst kontekstowo:

KOD cpp:     UKRYJ  
int CompareContext(String Str1, String Str2, bool MatchCase)
{
  if(MatchCase == false)
  {
    Str1 = Str1.LowerCase();
    Str2 = Str2.LowerCase();
  }

  int x = Str1.Pos(Str2);

  if(x > 0) return 0;

  return 1;
}
//---------------------------------------------------------------------------


Funkcja zwraca wartość typu Integer zamiast boolean, ale to dlatego, że chciałem uczynić ją zgodną z wcześniej prezentowanymi funkcjami CompareStr i CompareText. Funckje CompareContext wykorzystuje się dokładnie tak samo jak tamte:

KOD cpp:     UKRYJ  
  int compare;
  if( ReplaceDialog1->Options.Contains(frMatchCase) )
       compare = CompareContext(StringGrid1->Cells[col][row],
                        ReplaceDialog1->FindText, true);

  if( !ReplaceDialog1->Options.Contains(frMatchCase) )
       compare = CompareContext(StringGrid1->Cells[col][row],
                          ReplaceDialog1->FindText, false);


Gdybyś do tego chciał zamieniać tekst kontekstowo, czyli np. chcesz zamienić wyraz super na extra, a w przeszukiwanej komórce masz np. tekst super tabel, czyli po zamianie kontekstowej powinieneś otrzymać extra tabela. Proponuje stworzenie nowej funkcji, którą nazwę ReplaceContext:

KOD cpp:     UKRYJ  
String ReplaceContext(String Text, String FindText, String ReplaceText)
{
 String Result;
 int x = Text.Pos(FindText);

 Result = Text.Delete(x, FindText.Length());
 Result = Result.Insert(ReplaceText, x);

 return Result;
}
Wywołanie funkcji:

KOD cpp:     UKRYJ  
if( compare == 0 )
  {
   StringGrid1->Cells[col][row] = ReplaceContext(StringGrid1->Cells[col][row],
                                                                            ReplaceDialog1->FindText,
                                                                            ReplaceDialog1->ReplaceText);

   StringGrid1->Col = col;
   StringGrid1->Row = row;
   next = false;
  }

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Pitek
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ReplaceDialog - użycie

Postprzez polymorphism » niedziela, 31 października 2010, 11:45

KOD cpp:     UKRYJ  
int x = Text.Pos(FindText);

 Result = Text.Delete(x, FindText.Length());

A co jeśli w Text nie ma FindText? Według dokumentacji Pos zwróci 0, zatem z Text usuniesz FindText::Length znaków z początku - brakuje warunku.

W sumie może użyć funkcji StringReplace...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 48 gości

cron