Newsgroup: it.comp.lang.delphi
Titolo: Maiuscola

Qualcuno sa come si fa a convertire in maiuscolo SOLO la prima lettere di
una stringa?
Grazie per la risposta
Luigi

 una stringa?
CharUpperBuff fa proprio quel che chiedi: basta passargli un pchar che 
contiene la stringa e un intero che specifica quanti caratteri devono 
diventare maiuscoli.

Caro amico,
grazie per la risposta,ma non sono riuscito ad andare in porto.
Mi puoi postare la sintassi del codice,se per esempio ho un DBEdit1 cosa
dovrei scrivere sull'evento OnChange?
Forse
DBEdit1:=CharUpperBuff(DBEdit1,1);
Ho provato comunque in tanti modi ,ma non riesco proprio,
e' da poco che uso Delphi,comunque qualcosa sono riuscito a fare,anzi.
Grazie di nuovo per una eventuale risposta.
Luigi


Intendo comunque convertire in maiuscola la prima lettera e lasciare
minuscole tutte le altre.
Luigi

 minuscole tutte le altre.
Mi pare di capire che vuoi farlo mentre immetti il testo...

 ha scritto nel messaggio
news:uBLD9.12877$3l.3...@twister1.libero.it...


No,dopo che ho immesso il testo e che passo ad un altro controllo...
Grazie
Luigi


 minuscole tutte le altre.
Ho pensato alla seguente implementazione che può essere un buon 
compromesso per quello che (credo) tu intendi fare:
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
   Shift: TShiftState);
var s:string;
     c:char;
begin
  s:=edit1.text;
  if s<> '' then
    begin
     c:=s[1];
     if ord(c) > 96 then
      begin
       c:=chr(ord(c)-32);
       s[1]:=c;
       edit1.Text:=s;
       edit1.SelStart:=length(s);
      end
     else
      edit1.Text:=s;
    end;
end;
Questo codice l'ho scritto per un oggetto TEdit, ma credo vada bene 
anche per un TDBEdit.
Si basa sulla considerazione (alquanto matematica!) che la differenza 
tra l'ordinale di una lettera maiuscola e di una minuscola è sempre di 
32 nella tabella ASCII.
Se il testo dell'edit è vuoto, non c'è ragione perchè facciamo alcuna 
operazione;altrimenti, prendiamo il primo carattere e se non è già 
maiuscolo lo convertiamo. In seguito aggiorniamo il testo dell'edit e 
spostiamo il cursore alla fine del testo stesso (dato che la 
sostituzione lo sposta proprio al primo carattere!).Se invece è già 
maiuscolo lasciamo tutto com'è.
Questa tecnica mette in uppercase sempre e comunque il primo carattere, 
lasciando invariati i rimanenti (siano essi maiuscoli o minuscoli): in 
ogni caso, con delle modifiche si può anche fare in modo che il resto 
del testo sia sempre e comunque minuscolo.
Mi è sembrata una scelta migliore implementare il tutto
nell'evento OnKeyUp dell' edit, dato che un cambiamento del testo nell' 
evento OnChange dava adito ad una alquanto "subdola" ricorsività del codice.

 No,dopo che ho immesso il testo e che passo ad un altro controllo...
Ah ma allora è molto più semplice:
procedure TForm1.Edit1Exit(Sender: TObject);
var s:string;
begin
  s:=edit1.Text;
  CharUpperBuff(pchar(s),1);
  edit1.Text:=s;
end;
L'evento Edit1Exit è scatenato proprio quando si passa ad un altro 
controllo. :)
Anche in questo caso il codice va riadattato (basta sostituire) per il 
DBEdit.


MMM...
Il codice l'ho capito la tua spiegazione proprio no.
Se dovessi leggere la spiegazione non ci capirei niente era tutto logico.
Ciao

 Il codice l'ho capito la tua spiegazione proprio no.
Quale aspetto della spiegazione non hai capito?


Azzo ma ke mi sono fumato...
L'ho riletto ed ho capito tutto... in pratica non l'hai messo on change
perchè sennò scatta ogni volta che cambia la edit mentre nel tuo modo solo
quando uno finisce di scrivere.
Ciao

Ti ringrazio molto,funziona tutto alla meraviglia in entrambi i casi.
Ti chiedo se e' possibile applicare il tutto anche su una DBGrid,dopo
l'uscita da una cella o una colonna.
Grazie di nuovo,sei veramente bravo!
Luigi
"Kernel" <ker...@NOSPAMlacosca.org> ha scritto nel messaggio
news:3MRD9.46336$744.1...@news1.tin.it...


 l'uscita da una cella o una colonna.
Per applicare i cambiamenti dopo l'uscita da una cella o da una colonna, 
  conviene fare così:
Dichiariamo una variabile globale nella sezione "private" che chiamiamo 
"curcell", di tipo TField.
  private
   curcell:tfield;
Implementiamo l'evento OnDataChange del DataSource in questo modo:
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
  curcell:=field;
end;
E l'evento Table1BeforePost così:
procedure TForm1.Table1BeforePost(DataSet: TDataSet);
  var s:string;
begin
  s:= curcell.asstring;
  CharUpperBuff(pchar(s),1);
  table1.edit;
  curcell.AsString:=s;
end;
La scelta di utilizzare questi due eventi per applicare i cambiamenti e 
non un banale evento OnColExit del DbGrid viene dalla considerazione che 
l'evento OnColExit viene scatenato effettivamente solo quando si cambia 
colonna e non quando si cambia riga nel DbGrid.
Nell' evento DataChange del DataSource acquisiamo l'"identità" del campo 
correntemente selezionato per il cambiamento; nell'evento BeforePost 
della Table, che occorre prima che i dati nella tabella vengano 
cambiati, facciamo tutti gli aggiustamenti che vogliamo.
In particolare, prima di assegnare un nuovo valore al campo mettiamo in 
edit la tabella.

if s<>'' then s:=upcase(s[1])+copy(s,2,length(s)-1);
Ciao, Sandro

Grazie per la risposta,
funziona tutto alla meraviglia,ora pero',e non vorrei veramente approfittare
della tua disponibilita',sorge un altro problema,
cioe' la conversione viene applicata a tutti i campi della tabella,io vorrei
invece limitarla solo ad alcuni campi,se per esempio la tabella contiene i
campi A,B,C,D,E vorrei limitare
la conversione in maiuscolo ai campi C e E,inoltre la conversione deve
essere fatta solo se nei campi scelti si digitano per esempio le stringhe
'bologna','roma,e'palermo'
in caso contrario la conversione non deve essere fatta.
Nella mia piccola applicazione ho diverse DBGrid con campi diversi,ma che
hanno come origine dati la stessa tabella.
Come vedi la cosa si complica,e' dieci anni che uso MsAccess e queste cose
erano  facili da fare ,pero' con Delphi devo ricominciare quasi tutto da
capo.
Indipendentemente dalla tua risposta ti ringrazio ancora.
Luigi
"Kernel" <ker...@NOSPAMlacosca.org> ha scritto nel messaggio
news:LH6E9.66503$Yw.31...@news2.tin.it...


 in caso contrario la conversione non deve essere fatta.
Per applicare la conversione alle colonne e ai contenuti che vuoi, credo 
che la seguente implementazione costituisca un buon compromesso:
Innanzitutto dichiariamo, creiamo, riempiamo (e alla chiusura 
dell'applicazione deallochiamo!) una stringlist con le città sui nomi 
delle quali vuoi applicare la conversione, così:
   private
   curcell:tfield;
   citta: tstringlist;
...
procedure TForm1.FormShow(Sender: TObject);
begin
  citta:=tstringlist.Create;
  citta.Text:='roma'+#13#10+'palermo'+#13#10+'messina'; //Aggiungi qui 
tutti i nome delle città che vuoi convertire aggiungendo i caratteri 
#13#10 tra un nome e l'altro, ma NON alla fine :).
  citta.Text:=citta.Text;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  citta.Free;
end;
Poi modifichiamo l'evento OnBeforePost della Table1 nel modo seguente:
procedure TForm1.Table1BeforePost(DataSet: TDataSet);
var s:string;
     i:integer;
begin
  if ((curcell.DisplayLabel = 'A') or (curcell.DisplayLabel = 'B')) and 
    (citta.Indexof(curcell.asstring)<>-1) then
   begin
    s:= curcell.asstring;
    CharUpperBuff(pchar(s),1);
    table1.edit;
    curcell.AsString:=s;
   end;
end;
L'istruzione IF si occupa rispettivamente di controllare che siano 
giuste le colonne nelle quali le modifiche devono essere effettuate e se 
ciò che si è immesso nel campo rientra tra le stringhe sulle quali 
effettuare la conversione.
Per come è adesso, il codice cambia solo le stringhe che corrispondono 
al nome delle città contenute in "citta", qualora esse si trovino nelle 
colonne prescelte per il cambiamento; nel caso volessi convertire le 
stringhe anche se non si trovano nella colonna prescelta, ti basta 
sostituire l'AND con un OR.

Grazie di nuovo,funziona tutto ok,c'e' solo il problema che la conversione
in maiuscolo avviene solo dopo che sono passato ad un'altra righa e non ad
un'altra colonna della DBGrid.
Vorrei che siano contemporaneamente in azione,ma forse chiedo troppo.
Ho provato la procedura Table1.onBeforePost anche sull'evento onColEnter,ma
si blocca tutto.
Comunque grazie,cerchero' di risolvere da solo l'inconveniente.
Nel frattempo,con un po' di fortuna avevo risolto il problema delle
citta',quello dei campi non sarei mai stato capace senza il tuo aiuto.
Ciao
Luigi


 si blocca tutto.
Effetivamente hai ragione:
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
curcell:=dbgrid1.SelectedField;
Table1BeforePost(table1);
end;
Facendo cosě il problema si risolve. :)

 end;
posso chiederti come mai fai quel "doppio passaggio"? è dovuto solo al fatto di aver
scritto il codice "al volo"!?!?
puoi semplicemente scrivere:
    CharUpperBuff(pchar(edit1.Text),1);
ciao
Giò

     CharUpperBuff(pchar(edit1.Text),1);
Prova a farlo e vedrai che non funzia...
Così come l'hai scritto non fa assolutamente niente, ma neanche se fai
Edit1.Text := CharUpperBuff(pchar(edit1.Text),1);
perché CharUpperBuff ritorna un PChar, e ovviamente TEdit.Text è di tipo
TCaption, quindi sono incompatibili.
Ah, nel caso ti venisse il dubbio, non funzia neanche con
Edit1.Text := String(CharUpperBuff(pchar(edit1.Text),1));
--
Jax

 Prova a farlo e vedrai che non funzia...
[CUT]
giusto...sigh..

Io uso questa procedura
procedure TForm1.DBEdit1Change(Sender: TObject);
var Cursor:Integer;
begin
  if DBEdit1.Text <> '' then
    begin
      Cursor:=DBEdit1.SelStart;
      DBEdit1.Text := UpperCase(Copy(DBEdit1.Text,1,1)) +
LowerCase(Copy(DBEdit1.Text,2,Length(DBEdit1.Text)));
     DBEdit1.SelStart := Cursor;
    end;
end;
--------------------------------
Inviato via 
http://usenet.libero.it

 procedure TForm1.DBEdit1Change(Sender: TObject);
Visto che siamo in vena di soluzioni, io mi sono fatto una semplicissima
funzione che, oltre a uppercasare la prima lettera, lowercasa tutto il
resto. Ovviamente se non vi va bene, cambiatela.
function Capital(s: String): String;
begin
 Result := '';
 if s = '' then Exit;
 s := AnsiLowerCase(s);
 s[1] := UpCase(s[1]);
 Result := s;
end;
Niente di piů facile :)
--
Jax

 Facendo cosě il problema si risolve. :)
 Si risolve solo se metto sull'evento datasource on change
anche la seguente riga:
curcell:=field
curcell:=dbgrid1.selectedfield;
altrimenti quando ritorno su una cella gia' editata con un nome di citta,mi
da' un messaggio di errore tipo AccessViolation.
Pero' dato che ho diverse DBGrid la cosa va bene solo per la DBGrid1,secondo
me (da profano),si dovrebbe nella riga di cui sopra
(curcell:=dbgrid1.selectedfield,)far riferimento a tutte le DBGrid,come si
fa?
Spero di essere stato chiaro.
Poi un'altra cosa,vorrei che se si digita una citta che non e'
nell'elenco,il focus ritorni alla cella diciamo incriminata e mi cancelli
l'errata digitazione.
Grazie di tutto.
Luigi
Grazie di nuovo
Luigi