[Risolto] Interfaccia XSearchable

Creare una macro - Scrivere uno script - Usare le API
Rispondi
geovign
Messaggi: 215
Iscritto il: domenica 13 gennaio 2019, 11:19
Località: Modena

[Risolto] Interfaccia XSearchable

Messaggio da geovign »

Un saluto al forum.
Sto cercando di modificare la macro per l'aggiornamento del magazzino proposta, e fino ad oggi utilizzata, da @lucky63 in questa discussione; nel particolare sto cercando eliminare l'impiego della cella di appoggio A2, con funzione CONTA.SE .
A tale proposito ho utilizzato l'interfaccia XSearchable. Tutto funziona correttamente, ma, se il prodotto ricercato è presente in due o più righe consecutive, la macro si blocca.
In pratica, il prodotto "120 GIORNI ANTISTRESS" è presente, nel foglio "Movimenti Fert", quattro volte (righe 7,14,16,17). L'interfaccia trova tre corrispondenze in quanto le righe 16 e 17 le racchiude in un intervallo di celle. In questo modo l'istruzione "Ricerca = oFound(i).getCellAddress.Row" (riga 127 del codice) ovviamente da errore.
Come è possibile gestire l'errore?
Allego file.
Saluti.
Geo
Allegati
Modifica_macro_magazzino.ods
(19.56 KiB) Scaricato 156 volte
Ultima modifica di geovign il sabato 13 giugno 2020, 19:45, modificato 1 volta in totale.
LibO 7 su LinuxMint 21
patel
Volontario attivo
Volontario attivo
Messaggi: 4019
Iscritto il: venerdì 30 aprile 2010, 8:04
Località: Livorno

Re: Interfaccia XSearchable

Messaggio da patel »

geovign ha scritto:....
A tale proposito ho utilizzato l'interfaccia XSearchable....
Puoi spiegare meglio ?
-------------------
Libre Office 7.5.3.2 su Windows 11
allega un file di esempio, guadagnerai tempo tu e lo farai risparmiare a chi ti aiuta
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Interfaccia XSearchable

Messaggio da unlucky83 »

Ti serve supportsService

Codice: Seleziona tutto

if oFound(i).supportsService("com.sun.star.table.Cell") then
' oFound(i) è una cella
else
' oFound(i) è un cellrange
end if
Cosi è come dovresti modificare la macro per non avere l'errore. Lascio a te la gestione del cellrange

Codice: Seleziona tutto

For i = 0 To Trovati -1
			if oFound(i).supportSservice("com.sun.star.table.Cell") then
				Ricerca = oFound(i).getCellAddress.Row
				REM Scrive i dati in Magazzino
					If ContatoreRiscontri = 1 Then
						'' NOME PRODOTTO Fertilizzante viene trascritto solo se contatore =1
						Magazzino.GetCellByPosition(1,RigaMAG).String = Movimenti.GetCellByPosition(2,Ricerca).String
						'' DITTA PRODUTTRICE  viene trascritto solo se contatore =1
						Magazzino.GetCellByPosition(2,RigaMAG).String = Movimenti.GetCellByPosition(3,Ricerca).String
						ContatoreRiscontri = ContatoreRiscontri +1
					End If
					'' DATA
					Magazzino.GetCellByPosition(3,RigaMAG).Value = Movimenti.GetCellByPosition(1,Ricerca).Value
					'' U.M.
					Magazzino.GetCellByPosition(4,RigaMAG).String = Movimenti.GetCellByPosition(4,Ricerca).String
					''GIACENZA INIZIALE
					If Movimenti.GetCellByPosition(5,Ricerca).Value > 0 Then
						Magazzino.GetCellByPosition(5,RigaMAG).Value = Movimenti.GetCellByPosition(5,Ricerca).Value
					End If
					''QUANTITÀ ACQ.TA
					If Movimenti.GetCellByPosition(6,Ricerca).Value > 0 Then
						Magazzino.GetCellByPosition(6,RigaMAG).Value = Movimenti.GetCellByPosition(6,Ricerca).Value
					End If
					''QUANTITÀ USATA
					If Movimenti.GetCellByPosition(7,Ricerca).Value > 0 Then
						Magazzino.GetCellByPosition(7,RigaMAG).Value = Movimenti.GetCellByPosition(7,Ricerca).Value
					End If
					GiacenzaFinale = GiacenzaFinale _
					+ Magazzino.GetCellByPosition(5,RigaMAG).Value _
					+ Magazzino.GetCellByPosition(6,RigaMAG).Value _
					- Magazzino.GetCellByPosition(7,RigaMAG).Value
					oFunction = createUnoService("com.sun.star.sheet.FunctionAccess")
					args1(0)=GiacenzaFinale
					args1(1)=2   'arrotondamento a due decimali
					GiacenzaFinaleArr = oFunction.callFunction("ROUND", args1())  'GiacenzaFinale arrotondato a 2 decimali
					RigaMag = RigaMag +1
					RigaDaAggiungere = Magazzino.getCellRangeByName("B" & RigaMAG+1).getRangeAddress() 
					Magazzino.insertCells(RigaDaAggiungere, com.sun.star.sheet.CellInsertMode.ROWS)
			Else
			''''qui devi gestire i range trovati
			End if
			Next i
 Editato: Corretto l'errore di battitura segnalato nei messaggi a seguire. Ora c'è il termine corretto supportsService al posto dell'errato supportservice iniziale 
Ultima modifica di unlucky83 il sabato 13 giugno 2020, 19:33, modificato 1 volta in totale.
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
geovign
Messaggi: 215
Iscritto il: domenica 13 gennaio 2019, 11:19
Località: Modena

Re: Interfaccia XSearchable

Messaggio da geovign »

Ciao @patel.
Anziché utilizzare una cella di appoggio con formula nel foglio Movimenti, ho impostato la ricerca del prodotto utilizzando l'interfaccia XSearchable con queste righe di codice:

Codice: Seleziona tutto

....
'cerco all'interno della tabella
InRange = Movimenti.getCellRangeByName("C5:C" & Test)
oDescriptor = InRange.createSearchDescriptor()
ProdottoFert = Movimenti.getCellRangeByName("C" & Test).string
With oDescriptor
.SearchString = ProdottoFert
.SearchWords = True
.SearchType = 1  
.SearchCaseSensitive = False
End With
oFound = InRange.findAll(oDescriptor)
Trovati = oFound.Count	
etc...
e fino a qua funziona.
Successivamente, per compilare il magazzino, anziché utilizzare un ciclo for/next nella tabella e quindi compilare il magazzino, ripeto le stesse righe di codice indicate sopra per trovare le celle che contengono il nome del prodotto ricercato ed, a questo punto, eseguo il ciclo for/next esclusivamente all'interno di "oFound" e poi compilo il magazzino. E qua si manifesta l'errore descritto al primo post.
La prima ricerca individua la cella che contiene, per la prima volta, il nome del prodotto, la seconda ricerca individua tutte le celle che contengono il nome del prodotto per poi eseguire la compilazione del magazzino, suddiviso per prodotto.
Spero di essere stato un po' più chiaro.
Ciao @unlucky83,
quindi, se ho capito bene, una discriminante per verificare se "oFound(i)" è una cella oppure un range di celle, consiste nel supporto oppure no al servizio "com.sun.star.table.Cell".
Per la gestione del cellrange ho provato e funziona un ciclo for/next così impostato:

Codice: Seleziona tutto

For i = 0 To Trovati -1
if oFound(i).supportservice("com.sun.star.table.Cell") then  'se vero si tratta di una cella
Ricerca = oFound(i).getCellAddress.Row
   'seguono istruzioni per compilazione magazzino
else      'altrimenti si tratta di un range di celle
For a = oFound(i).getRangeAddress.StartRow to oFound(i).getRangeAddress.EndRow
Ricerca = a
  'seguono istruzioni per compilazione magazzino
end if
Saluti
Geo
LibO 7 su LinuxMint 21
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Interfaccia XSearchable

Messaggio da unlucky83 »

Hai capito bene e mi sembra corretto il modo di gestire i cellrange :super:
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
patel
Volontario attivo
Volontario attivo
Messaggi: 4019
Iscritto il: venerdì 30 aprile 2010, 8:04
Località: Livorno

Re: Interfaccia XSearchable

Messaggio da patel »

Se provo ad eseguire la riga

Codice: Seleziona tutto

if oFound(i).supportservice("com.sun.star.table.Cell") then
mi dice proprietà o metodo SupportService non trovato
-------------------
Libre Office 7.5.3.2 su Windows 11
allega un file di esempio, guadagnerai tempo tu e lo farai risparmiare a chi ti aiuta
geovign
Messaggi: 215
Iscritto il: domenica 13 gennaio 2019, 11:19
Località: Modena

Re: Interfaccia XSearchable

Messaggio da geovign »

Ciao @patel,
mi hai anticipato, la riga corretta è

Codice: Seleziona tutto

if oFound(i).supportsService("com.sun.star.table.Cell") then
"supports" con la "s" finale.
Saluti
Geo
LibO 7 su LinuxMint 21
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Interfaccia XSearchable

Messaggio da unlucky83 »

Chiedo scusa per la svista...il metodo supportsService lo avevo testato in un'altra macro e poi ho modificato il codice che ho presentato nel messaggio precedente senza testarlo e non mi sono accorto dell'errore di battitura. :knock:
Modifico il messaggio precedente.
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
geovign
Messaggi: 215
Iscritto il: domenica 13 gennaio 2019, 11:19
Località: Modena

Re: Interfaccia XSearchable

Messaggio da geovign »

Il codice funziona correttamente, ma non è preciso. Nella prima ricerca del prodotto, quella impostata in sostituzione della cella di appoggio, quando incontra due celle consecutive con lo stesso prodotto, mi crea più "magazzini" dello stesso (vedi immagine allegata). L'istruzione "oFound.supportsService("com.sun.star.table.Cell"), non funziona se applicata all'oggetto intero (spero di essermi fatto capire).
Tra le proprietà dell'oggetto oFound ho trovato la voce "RowDescription" che descrive ogni singola riga trovata, racchiusa in un array.
Quindi ho modificato il codice nel seguente modo (riporto solo parte della macro oggetto della nuova modifica, il resto è nel file allegato) :

Codice: Seleziona tutto

...
For Test = 5 To UltimaRigaMOV +1 
Riscontro = 0
'cerco all'interno della tabella
InRange = Movimenti.getCellRangeByName("C5:C" & Test)
oDescriptor = InRange.createSearchDescriptor()
ProdottoFert = Movimenti.getCellRangeByName("C" & Test).string
With oDescriptor
    .SearchString = ProdottoFert
    .SearchWords = True
    .SearchType = 1  
    .SearchCaseSensitive = False
End With
oFound = InRange.findAll(oDescriptor)
Trovati = oFound.Count	
'Condizione per proseguire: avere trovato una sola corrispondenza e che non sia un intervallo di celle (sfrutto la proprietà RowDescriptions di oFound)
'Con una sola cella, l'array RowDescription presenta un solo elemento, quindi Lbound=0 ed Ubound=0
if Trovati = 1 and Ubound(oFound.RowDescriptions) = 0 then Riscontro = 1
'Se il riscontro = 1 allora fai partire verifica da quel punto in avanti per il raggruppamento
If Riscontro = 1 Then
GiacenzaFinale = 0
ContatoreRiscontri = 1
'Ripeto la ricerca del prodotto, però cambio il range di celle
InRange= Movimenti.getCellRangeByName("C" & Test & ":C" & UltimaRigaMOV +1 )
oDescriptor = InRange.createSearchDescriptor()
With oDescriptor
.SearchString = ProdottoFert
.SearchWords = True
.SearchType = 1  
.SearchCaseSensitive = False
End With
oFound = InRange.findAll(oDescriptor)
'creo l'insieme di nomi delle righe trovate
arrDescRighe = oFound.RowDescriptions
'ciclo all'interno dell'insieme per compilare il magazzino del prodotto
For i = LBound(arrDescRighe) to UBound(arrDescRighe)
'prelevo il solo numero della riga dalla stringa di descrizione e modifico il tipo di variabile da testo a numero 
Ricerca = (Val(Mid(arrDescRighe(i),5))) -1
'Scrive i dati in Magazzino
etc...
Un grazie a tutti.
Saluti
Geo
Allegati
Modifica_macro_magazzino_Geo.ods
(22.69 KiB) Scaricato 150 volte
VIGNASOIL_doppio.png
LibO 7 su LinuxMint 21
Rispondi