Post by Riddler ?Ciao Norman, anche tu dopo una nottataccia già al lavoro eh? :-)
[...]
Post by Norman JonesSet rng3 = rw.Cells(1, 7).Resize(1, 2) '<<=== cols I:J <---------- PUNTO 1
If rng2.Value = sStr Then
If Application.CountA(rng3) = 2 Then <---------- PUNTO 2
If rng1.Value > myDate Then
myDate = rng1.Value
Set rngOut = rw
End If
[...]
Punto1
Set rng3 = rw.Cells(1, 7).Resize(1, 2)
E se selezionassi "solo" la J comprometterebbe il funzionamento ...
provo ...
Punto 2
If Application.CountA(rng3) = 2
Allora è questa la sottogliezza?
Mi dicequanti valori sono non vuoti? ( perà la colonna I non va
contata nel conteggio ... )
vado a provare ...
Grazie ancora!
Riddler ?
Ciao Riddler ?
Se ho ben capito quello che vuoi ottenere è un 'marker' in
corrispondenza delle righe con data più recente di CodiceIn dove
CodiceOut1 e CodiceOut2 non sono nulli. Vi è allora una funzione di
aggregazione ( MAX(<campo data>) con raggruppamento per codice ( GROUP
BY <campo CodiceIN>). Questa selezione deve essere però filtrata (
clausola WHERE ) con un criterio in base al quale il codice non deve
appartenere ( NOT IN )
all'elenco delle pratiche incomplete. Questa è una subquery nidificata
nella query principale: selezionami i codiciIN dove anche uno dei
codiciOUT è nullo.
In una copia della tua cartella denomina i tuoi dati (Colonna A:D),
comprensivi della prima riga con i nomi delle colonne, con il nome
'Dati' nella finestra Definisci Nomi. I nomi dei campi ( prima riga )
devono essere: Data; CodiceIN; CodiceOUT1; CodiceOUT2.
Con attivo il foglio2 vuoto lancia da un modulo questa routine:
Sub TestQuery()
With ActiveSheet.QueryTables.Add(Connection:="ODBC;DBQ=" &
ThisWorkbook.FullName _
& ";DefaultDir=" & ThisworkbookPath & "\" _
& "DMN\Documenti;Driver={Driver do Microsoft Excel(*.xls)};" _
& "DriverId=790;FIL=excel
8.0;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;" _
&
"ReadOnly=1;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;",
_
Destination:=Range("A1"))
.CommandText = _
"SELECT MAX(Dati.Data ) , Dati.CodiceIN" _
& vbCrLf & "FROM `C:\DatiOrigine`.Dati Dati" _
& vbCrLf & "WHERE (Dati.CodiceIN Not In" & vbCrLf & _
" (SELECT Dati.CodiceIN" & vbCrLf & "FROM `C:\DatiOrigine`.Dati
Dati" _
& vbCrLf & "WHERE (Dati.CodiceOUT2 Is Null) OR " _
& "(Dati.CodiceOUT1 Is Null)))" & vbCrLf & _
"GROUP BY Dati.CodiceIN;"
.Name = "StatoPratiche"
.FillAdjacentFormulas = True
.Refresh BackgroundQuery:=False
End With
End Sub
Dovresti ottenere una tabella a 2 colonne ( già denominata
StatoPratiche); inserisci nella colonna C la formula da C2 in poi
=CONCATENA(A2;B2). Ottieni un codice univoco.
Nel foglio dove hai i dati di origine, inserisci nella cella E2 la
seguente formula (limitata per esemplificazione solo alle prime 9 righe
di dati) e copiala fino alla fine dei dati:
=SE(VAL.NON.DISP(CONFRONTA(CONCATENA(A3;B3);Foglio2!$C$2:$C$10;0))=FALSO;"COMPLETO";SE(VAL.NON.DISP(CONFRONTA(B3;Foglio2!$B$2:$B$10;0))=FALSO;"";"NON
COMPLETO"))
Nel caso accodi nuovi dati aggiorna l'indirizzo dell'intervallo
denominato 'Dati'; sia in questo caso che dopo semplice modifica dei
dati esistenti aggiorna la query sul foglio 2 dalla barra flottante che
dovrebe essere visibile ( pulsante con punto esclamativo rosso ).
So che la logica SQL è ostica ma rincorrere laboriosi algoritmi in
puro VBA per ottenere un risultato analogo ma poco riciclabile non è a
mio avviso una strada consigliabile.
Ciao Elio