Italian community of Lazarus and Free Pascal

Programmazione => Componenti Aggiuntivi => Topic aperto da: antoniog - Aprile 24, 2021, 09:57:34 pm

Titolo: [RISOLTO]Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 24, 2021, 09:57:34 pm

Buonasera, nuovo problema con Lazreport.Se il testo di un campo DBmemo è più lungo dello spazio che rimane nella pagina Lazreport salta pagina, al posto di completare la pagina con parte del testo e scrivere la restante parte su una nuova pagina, lasciando a volte meta pagina vuota. Non oso pensare cosa succederebbe se il testo fosse più lungo di una intera pagina...
Qualcuno ha affrontato questo problema?

Allego immagine esplicativa
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 24, 2021, 10:29:13 pm
Ciao, infatti per questo ti avevo detto, nel tuo precedente topic: Io in una stampa di questo tipo userei un memo di una sola riga, ripetuto tante volte. In questo modo decido io cosa mettere in ogni riga e che lunghezza deve avere il testo contenuto.
Prima mi riverso ogni riga dei dbmemo o dei memo in un record di un tmemdataset e poi faccio un report che "pesca" i record dal tmemdataset.
Poi può darsi che esista un modo per posizionare un memo a cavallo di due pagine.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 25, 2021, 12:03:23 am
Tito Livio, la cosa sembra interessante, hai qualche linea di codice per renderla fattibile?
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 25, 2021, 12:49:59 am
Ciao, io procedo così:

-prendo un componente tmemorydataset (mreferto_rx) e tramite la proprietà fielddefs creo dei campi.
Nel mio esempio ho un campo solo ma nel tuo caso vedo che hai nel report 5 colonne quindi penso che dovresti avere 5 campi.

-poi al momento di stampare:

    mreferto_rx.Clear(False);
    ...
    sqlquery1.first;
    while not sqlquery1.eof do
    begin
      for i := 0 to form1.dbmemo1.Lines.Count - 1 do
          mreferto_rx.AppendRecord([form1.dbmemo1.Lines [ i ] ] );
      ...
      mreferto_rx.AppendRecord([... altre voci ..]);
      sqlquery1.next
    end;
    mreferto_rx.AppendRecord([... conclusione ...]);

-poi creo un report come in allegato

Spero possa esserti utile
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 25, 2021, 02:27:14 am
Tito Livio, cioè tu fai tanti record quante sono le linee del campo memo? la proposta è buona ma nel mio caso non credo che funzioni perchè ho molti campi che sono raggruppati e non credo di potere far funzionare all'interno di un ciclo un'altro ciclo.
Gli articoli sono raggruppati da un codice, tutte le linee del memo (composto da due campi, uno : codice e uno :memo) dovrebbero avere il codice del gruppo, potrebbe funzionare ma mi creerà un'infinità di record per ogni articolo. Al momento penso di provare con gli script cercando di fare leggere a Lazreport il campo memo una riga per volta
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 25, 2021, 12:30:52 pm
Probabilmente nel tuo caso questa mia soluzione si adatta poco, comunque in stampe più complicate, usando più campi e gli script nel report, riesco a gestire  il raggruppamento (che poi faccio fare al Lazreport), il salto pagina, il font della riga e l'inserimento immagini.
Invece volevo chiederti, come mai hai lasciato il Fortes Report?
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 25, 2021, 03:13:24 pm
dall'esempio che hai postato, l'elaborazione viene fatta su un sull'ultimo o campo, di un solo record, sbaglio?
io ho molti record che si ripetono, i cicli utilizzano diverse FRvariabili e 3 ZTable collegate. Comunque grazie, proverò a elaborare il concetto.
Non ho lasciato Fortesreport, prima di Lazarus utilizzavo Delphi 4 e 7 con quickReport che è molto simile a Fortes, utilizzo la versione CE ed è molto valida, molto flessibile e programmabile ma quando si apportano modifiche si deve ricompilare il programma e non si  può modificare il report a runtime mentre con Lazreport fare e modificare anche a runtime è possibile. Lazreport  non è meno flessibile di Fortes, negli script si possono richiamare procedure e funzioni esterne che restituiscono valori per la stampa, l'utilizzo di variabili esterne è funzionale, mi trovo molto bene per la gestione grafica, ho risolto uno alla volta le difficoltà ed ora sono all'ultima che è veramente complessa, si dovrebbe calcolare la lunghezza del campo dbmemo, verificare quante righe mancano a fine pagina e se la pagina non è capiente dividere il testo in due parti, uno scherzo ;D . La tua soluzione può essere invece utilizzabile nella stesura di relazioni anche molto lunghe.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 26, 2021, 12:49:49 am
questa istruzione:
for i := 0 to form1.dbmemo1.Lines.Count - 1 do
da errore:
Error: identifier idents no member "Lines"
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 26, 2021, 12:18:56 pm
Potrebbe essere:
-Penso che tu non abbia fatto la uses della unit DBcontrols.
A me funziona anche col dbmemo vuoto e con il file chiuso.
-Mi sembra di capire che tu usi Zeoslib, io non lo conosco, uso i componenti standard.
Il comportamento diverso del componenete dbmemo potrebbe essere dovuto a questo.
Con l'occasione mi sono accorto che il codice di esempio che ti ho dato è incompleto. Cioè la tabella tmemdataset prima di essere azzerata con clear, deve essere chiusa ti riporto il mio codice così corretto:
Codice: [Seleziona]
  if memdataset1.Active then
    memdataset1.close;
  memdataset1.Clear(False);
  memdataset1.Open;
  for i := 0 to dbmemo3.Lines.Count - 1 do
   memdataset1.AppendRecord([dbmemo3.Lines[i]] );
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 26, 2021, 09:12:41 pm
Ave Tito Livio, il tuo codice funziona, l'idea di dividere il testo nel DBMemo in tanti record quante sono le linee è stata una bella intuizione.
Ma io non ho risolto il problema, Lazreport salta comunque pagina quando vuole lui
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 26, 2021, 11:15:12 pm
Dovresti dirmi in che senso "salta pagina quando vuole lui".
Può darsi che ci vuole una banda di tipo pedice di pagina per lasciare un certo margine.
Io,quando non riesco a risolvere in altro modo, uso un campo del tmemdataset chiamato "pagina". Poi faccio raggruppare al Lazreport per "pagina" e spunto "force new page"
nell'intestazione di gruppo.
In questo modo posso decidere quali record stampare nella stessa pagina, assegnandogli a tutti lo stesso numero pagina.
Ovviamente so quante righe possono entrare nella stessa pagina.
Se c'è gia un altro gruppo all'interno della pagina non è un problema perchè funzionano i gruppi annidati. Fino a 2 livelli l'ho provato.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 27, 2021, 01:52:36 am
Tito Livio, il salto pagina avviene quando il testo non entra completamente in quel che resta della pagina.
Ho tre tabelle collegate, la tabella "misure" ha mastersource "totarticoli", la tabella "Totarticoli" ha mastersource la tabella "Lotti",
quindi iniziando il ciclo da "Lotti" tutto il resto viene elaborato correttamente e la stampa è accettabile.
Ho provato ad usare le tue linee di codice ed in Lazreport e ho inserito:
1. una Master Data collegata a Totarticoli dove stampo il codice articolo
2. Una Master Data collegata collegata al MemDataset
3. una Detail Data stampa i record della descrizione ricavati da Totarti
L'aggiunta di record in MemDataset.Descrizione avviene durante l'elaborazione del Report attraverso un campo DBMemo invisibile collegato a Totarti e con il seguente codice nell' OnDataChange del DataSource di Totarti:
Codice: [Seleziona]

procedure TGescompF.DTotartiDataChange(Sender: TObject; Field: TField);
var
       i:integer;
begin
  if Dataprogetto.MemTotarti.Active then
      Dataprogetto.MemTotarti.close;
    Dataprogetto.MemTotarti.Clear(False);
    Dataprogetto.MemTotarti.Open;
    Dataprogetto.MemTotarti.AppendRecord([Dataprogetto.TotartiCodice.Text] );
    for i := 0 to GescompF.dbmemo28.Lines.Count - 1 do
     Dataprogetto.MemTotarti.AppendRecord([GescompF.dbmemo28.Lines[i]] );
end; 
Mettendo un controllo sulle righe del MemDataset ho verificato che la lunghezza del testo contenuto in un record può essere anche di molte righe sul Report,naturalmente in base al width del Rettangolo che lo contiene, quindi per esempio stampa il codice e salta pagina lasciando molte righe in bianco. Dovrei provare a ricavare in MemDataset record con numero di caratteri corrispondenti alla larghezza di una riga prevista nel report che in questo caso è 320.
Grazie per l'aiuto.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 27, 2021, 05:18:29 pm
Stabilire il numero di caratteri per record è una stupidaggine perchè taglia e va a capo.
Niente da fare! anche il codice seguente, da inserire in "OnEnterRect" del frReport,  funziona per stampe di un solo record:
Codice: [Seleziona]

if (View is TfrMemoView) then
      if (View as TfrMemoView).Name = 'Memo27' then
        (View as TfrMemoView).Memo.Text := Form1.DBMemo28.Lines.Text;   
Forse dovrò tornare a Fortes Report...
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 27, 2021, 09:04:01 pm
Ciao,
mi potresti fare vedere, con una immagine, la banda masterdata che colleghi al tmemdataset?
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 27, 2021, 09:32:26 pm
Scusami ma è difficile capire a distanza il problema, da quello che ho capito mi viene di dirti che:
La riga del report, la lunghezza del record di MemTotArti e la larghezza di Dbmemo28 devono essere "compatibili".
Cioè vedi quanti caratteri possono e vuoi far entrare in una sola riga (senza andare a capo) del Report, poi la diminuisci un pochino ed hai la lunghezza del record e poi la larghezza di Dbmemo 28 deve essere tale che ogni sua riga starà sempre sotto la lunghezza del record.
In questo modo sei sicuro che ad una riga di dbmemo28 corrisponderà sempre una sola riga del report.
Si devono fare dei tentativi perchè il carattere è quasi sempre proporzionale.
Se vuoi, puoi farmi avere il .lrf.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 27, 2021, 10:42:26 pm
Ciao Tito Livio, allego l'immagine di Lazreport e della relativa stampa.
Come potrai vedere il numero a sinistra del codice, oltre al codice, sono il progressivo di Totarti, poi segue la descrizione che è di MemTotarti realizzata con il tuo codice leggermente modificato già postato, i numeri, uguali al numero progressivo del codice, sono i vari record del MemDataset. Al termine della descrizione c'è la descrizione della misura (altra tabella collegata) e poi il totale dell'articolo del Table Totarti, in fondo alla pagina "Page Footer" il totale progressivo fino alla pagina. Il problema è solo nella lunghezza del record della descrizione "Totarticoli" o del record "MemTotarti" che se è più lungo delle righe restanti della pagina obbliga ad un salto pagina. Penso che il problema sia solo di Lazreport e che non sia possibile correggerlo se non intervendo nel pacchetto.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 27, 2021, 11:05:35 pm
non voglio entrare nel merito che in Lazreport puoi definire la pagina A3,A4 ecc. ma non puoi definire quante righe per pagina, ed allora, usando Memdataset, bisognerebbe riuscire a fare record (finiti e logici) di ridotta lunghezza.
La larghezza del DBmemo per la creazione dei record di MemDataset non influisce sul risultato.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 28, 2021, 12:25:12 am
Vorrei sapere: il testo "NOLO ATTREZZATURE - Nolo di ponteggio tubolare esterno eseguito... verticale)" lo hai messo tutto dentro un unico record del memdataset?
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 28, 2021, 12:50:39 am
Se è così , cioe se fai record così lunghi il problema è questo.
Il width del dbmemo deve essere tale che ci entra nella riga soltanto "NOLO ATTREZZATURE - Nolo di ponteggio tubolare".
Altrimenti se vai a mettere una stringa lunga ottieni un memo lungo (cioè alto) che Lazreport non mette a cavallo di due pagine.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 28, 2021, 01:06:40 am
Citazione
Vorrei sapere: il testo "NOLO ATTREZZATURE - Nolo di ponteggio tubolare esterno eseguito... verticale)" lo hai messo tutto dentro un unico record del memdataset?
quella che vedi fra gli stessi numeri sono i record creati dal DBMemo riga al MemDataset.
se diminuisci la lunghezza delle righe la il testo viene spezzato casualmente ed a capo, per esempio la parola ponteggio viene spezzata in "pon" e "teggio" a capo perchè in un'altro record.
Non serve a niente ridurre la larghezza di DBMemo perchè la riga ha sempre la stessa lunghezza (ho provato inutilmente)
Mi dispiace Tito Livio ma siamo molto lontani dalla soluzione!
Chi ha sviluppato Lazreport ha logicamente previsto il ritorno a capo alla fine di un riga di un record e non ha considerato l'estetica della pagina.
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 28, 2021, 02:26:02 pm
errata corrige ......
La larghezza del DBMemo influisce sulla dimensione del record di MemDataset solo se è visibile, da invisibile la dimensione del record viene stabilita dal programma.
Quindi lavorando sulla larghezza del DBMemo si può arrivare ad una stampa accettabile, certo bisogna stabilire la dimensione del carattere (anche il maiuscolo ed il minuscolo influiscono) ed accettare qualche ritorno a capo non proprio perfetto.
Da risolvere il DBMemo che non posso lasciare visibile
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: tito_livio - Aprile 28, 2021, 06:55:10 pm
Ciao,
potresti mettere il dbmemo visibile in un form, creato ma al quale nessuno potrà accedere
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Aprile 30, 2021, 12:02:42 am
Ave Tito Livio, ti ringrazio per l'aiuto, ho imparato altre cose, ma non si può aggirare il problema, ed è un grande problema, ed a questo punto preferisco il salto pagina ma con descrizione completa e leggibile che un non salto pagina con descrizione non correttamente impaginata. Usando Lazreport dovrò accettare questo limite del pacchetto oppure potrò tornare a Fortes Report che mi consente di gestire le righe per pagina.

Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Maggio 14, 2021, 10:56:26 pm
Il sistema sopra usato con i record di un Memdataset funziona su windows ma non su Linux perchè su linux la larghezza del DBMemo non definisce la lunghezza della linea che invece viene definita, penso,  da un ritorno a capo tipo #10#13.
Allora bisogna sperimentare altro. Un problema semplice che diventa complesso...
Titolo: Re:Lazreport problemi con testo dbmemo lungo
Inserito da: antoniog - Giugno 15, 2021, 12:10:57 am
Tempo fa in un forum inglese avevo visto e salvato  le istruzioni per scrivere un testo lungo su più pagine, avevo provato ad utilizzarla senza successo. In questi ultimi giorni ho  riprovato ad utilizzarla e ci sono riuscito.
Per potere scrivere un testo lungo di un campo TEXT su più pagine:
Mettere sulla propria form un un TMemo, il nome dell'esempio Memo2, nel TDataSource della Tabella che interessa inserire il seguente codice nell'evento onDataChange
Codice: [Seleziona]

procedure TGescompF.DTotartiDataChange(Sender: TObject; Field: TField);
begin
  GescompF.Memo2.Clear;
  GescompF.Memo2.Text:=DataProgetto.TotartiAnnotazion.AsString;
  GescompF.Memo2.Text:= StringReplace(GescompF.Memo2.Text, '[', '-', [rfReplaceAll]);
  GescompF.Memo2.Text:= StringReplace(GescompF.Memo2.Text, ']', '-', [rfReplaceAll]);
end;

questa routine copia il testo contenuto nel campo TEXT della Tabella, in questo caso TotartiAnnotazion nel TMemo inserito nella Form così da consentirmi, senza modificare nulla dei dati, di eliminare le criticità per Lazreport come per esempio le parentesi quadre.

Selezionare TFrRporto, nel mio caso FrReport1 e nell'evento OnEnterRect inserire il seguente codice:
Codice: [Seleziona]

procedure TGescompF.frReport1EnterRect(Memo: TStringList; View: TfrView);
begin
   if (View is TfrMemoView) then
     if (View as TfrMemoView).Name = 'Memo27' then
       (View as TfrMemoView).Memo.Text := GescompF.Memo2.Lines.Text;
end;   

Aprire il designer di Lazreport e inserire una MasterData Band, right-click e selezionare 
"Stretched" & "Break"
Inserire un Rettangolo sulla MasterData Band,name  Memo27,  right-click e selezionare  "Stretched" & "wordwrap", risultato allegato. Problema risolto.
L'elemento Memo2 deve essere visibile e per non farlo vedere si possono impostare : BorderStyle su bsNone e Font-Color su clNone.
Cosi funziona sia sotto Windows che sotto Linux.