Newsgroup: it.comp.appl.access
Titolo: evitare ripetizioni nel codice

ciao a tutti
 
già postato..........
 
chiedo una dritta per evitare le ripetizioni.........
Grazie 
 
  Dim rst As DAO.Recordset
  Dim strSql As String
  Dim X As Variant, x1 As Variant, x2 As Variant
 
  strSql = "SELECT * FROM TbImpostazioni" _
    & " WHERE IdProdotto1 = " & Frm!CboProdotto.Value _
    & " And IdCliente1 = " & cliCriterio()
  Set rst = CurrentDb().OpenRecordset(strSql)
 
  If Not rst.EOF Then
    X = rst!IdBancale
    x1 = rst!IdConfezione
    x2 = rst!IdUnitàMisura
    GoTo Fine
 
  End If
 
  strSql = "SELECT * FROM TbImpostazioni WHERE IdProdotto = " & Frm!CboProdotto.Value
  Set rst = CurrentDb().OpenRecordset(strSql)
 
  If Not rst.EOF Then
    X = rst!IdBancale
    x1 = rst!IdConfezione
    x2 = rst!IdUnitàMisura
 
  End If
 
  strSql = "SELECT * FROM TbImpostazioni WHERE IdCliente = " & cliCriterio()
  Set rst = CurrentDb().OpenRecordset(strSql)
 
  If Not rst.EOF Then
    X = rst!IdBancale
    x2 = rst!IdUnitàMisura
 
  End If
 
Fine:
  Frm!CboBancale.Value = IIf(X = "", 1, X)
  Frm!CboUnitàMisura.Value = IIf(x2 = "", 1, x2) 
  Frm!CboConfezione.Value = IIf(x1 = "", Frm!CboConfezione.Value, x1)
 
  Set rst = Nothing

Franco, seguo la tua LOGICA... anche se non capisco quali siano e se ci siano campi UNIVOCI...!
 
Riassumo:
 
CERCO Nella [TbImpostazioni] un Record(speriamo sia uno) che abbia:
 
IdProdotto1 = X AND IdCliente1 = Y ma se non c'è mi accontento di:
 
IdProdotto1 = X  ma se non c'è provo 
      ---> (Puoi avere PRODOTTI senza Clienti...? se ti rispondi NO a che serve questo...?)
 
IdCliente1 = Y  
      ---> (in questo caso sei certo venga resatituito SOLO 1 Record..? ma a quale prodotto appartiene...?)
 
Questo 3° Tenativo è estremamente strano e fuorviante... ma anche il 2° in realtà...
 
In sostanza ... invece che dirci come rifare quello che scrivi, assolutamente ILLOGICO, non fai prima a spiegare lo scenario e chiedere cosa devi ottenere...?
 
@Alex

 scenario e chiedere cosa devi ottenere...?
 
-- 
Greg


ciao Alex grazie e Buon Anno
 
posso avere 3 situazioni diverse:
1° query
strSql = "SELECT * FROM TbImpostazioni" _
& " WHERE IdProdotto1 = " & Frm!CboProdotto.Value _
& " And IdCliente1 = " & cliCriterio()
X = rst!IdBancale
x1 = rst!IdConfezione
x2 = rst!IdUnitàMisura
se tutti e 3 esistono, la procedura termina.
_____________
 
2° query
strSql = "SELECT * FROM TbImpostazioni WHERE IdProdotto = " & Frm!CboProdotto.Value
 
3° query
strSql = "SELECT * FROM TbImpostazioni WHERE IdCliente = " & cliCriterio()
 
metre la 2° è in un certo senzo legata alla 3° query
cioè...
 
se.........
X = rst!IdBancale
x2 = rst!IdUnitàMisura
della 3° query esistono
 
prendono il posto
X = rst!IdBancale
x2 = rst!IdUnitàMisura
della 2° query, sia che esistano o meno.
 
 
per completare...
se tra la 2°query e 3°query
X = rst!IdBancale
x1 = rst!IdConfezione
x2 = rst!IdUnitàMisura
non esistono
X sarà = 1
x1 sarà = Frm!CboConfezione.Value (cioè da impostare al momento)
x2 sarà = 1
 
cioè............
Frm!CboBancale.Value = IIf(X = "", 1, X)
Frm!CboUnitàMisura.Value = IIf(x2 = "", 1, x2) 'va prima della confezione, perchè in assenza della stessa, l'Unità Misura non viene inserita
- nascondi testo citato -


Quando nella 1° query dici "se tutti e 3 esistono la procedura termina"... dove fai il controllo..? 
Da nessuna parte... quando controlli EOF controlli solo che esista 1 record e non ha nulla a che vedere con l'affermazione sopra.
Ora tu dici una cosa ma ne fai un'altra... o meglio ti esprimi in modo non tecnicamente sostenibile... quindi si fa veramente molta fatica...
Nel primo controllo ad esempio potresti avere 1 record quindi EOF =FALSE ma poi i campi interni sono VUOTI o NULL... che esistano è ovvio i campi esistono ma che il loro contenuto sia valido... è altro.
Detto questo non si usa il goto... si usa eventualmente ELSE... e si nidifica la 2° verifica... che nel tuo caso sono 2° e 3°...
Purtroppo anche in queste 2 verifichi solo EOF e non serve affatto.
 
Personalmente farei solo 1 Query con l'OR delle 2 condizioni... così estrai solo 1 Recordset che vale per tutte e 3 le possibilità...
Poi condizioni in base al valore... delle condizioni...
 
Se IdProdotto=condizione1 and IdCliente=condizione2 then
  Equivalente alla 1° query
Altrimenti se IdProdotto=Condizione1
  Equivalente alla 2° query
Altrimenti
  Equivalente alla 3° query
Fine
 
Sono 10 righe in tutto...
Ora prova a riscrivere il codice e riproporre il tutto.
 
@ALEX

Ovviamente devi ciclare... ma anche nel tuo codice nemmeno ti preoccupi che il Recordset abbia più di 1 Records... e come ti ho spiegato la possibilità esiste... e non dici cosa fai...
 
Franco... molto molto molto... male.
 
@ALEX


ciao Alex e grazie 1000
 
la prima e terza query sono univoche, quindi...
o contengono i dati o non li contiene affatto; 
quindi, If Not rst.EOF Then è corretto. 
Ho provato tantissime volte, ma senza ottenere alcun risultato.
Il problema è che non riesco a creare un'unica query che soddisfi
tutte e tre le condizioni.
 
Ho provato anche cosi', ma non va ancora bene...
Dim rst As DAO.Recordset
Dim strSql As String
Dim Opzione As Integer
Dim x1 As Variant, x2 As Variant, x3 As Variant
 
Opzione = 1
 
Do
strSql = vbNullString
strSql = strSql & "SELECT * FROM TbImpostazioni "
Select Case Opzione
  Case Is = 1
  strSql = strSql & "WHERE IdProdotto1 = " & Frm!CboProdotto.Value
  strSql = strSql & "And IdCliente1 = " & cliCriterio()
  Case Is = 2
  strSql = strSql & "WHERE IdCliente = " & cliCriterio()
  Case Is = 3
  strSql = strSql & "WHERE IdProdotto = " & Frm!CboProdotto.Value
 
End Select
 
Set rst = CurrentDb().OpenRecordset(strSql)
 
If rst.EOF And Opzione = 1 Then
  Opzione = 3
ElseIf rst.EOF And Opzione = 3 Then
  Opzione = 2
Else
  Opzione = 1
 
End If
 
Loop Until Opzione = 1
 
If Not rst.EOF Then
  x1 = rst!IdBancale
  x2 = rst!IdConfezione
  x3 = rst!IdUnitàMisura
 
End If
 
Frm!CboBancale.Value = IIf(x1 = "", 1, x1)
Frm!CboUnitàMisura.Value = IIf(x3 = "", 1, x3)
Frm!CboConfezione.Value = IIf(x2 = "", Frm!CboConfezione.Value, x2)
 
Set rst = Nothing
 
 
 
 
 

 Ovviamente devi ciclare... ma anche nel tuo codice nemmeno ti preoccupi che il Recordset abbia più di 1 Records... e come ti ho spiegato la possibilità esiste... e non dici cosa fai...
 
ho una tbimpostazioni, con tre maschere per l'inserimento dati.
Quindi inserisco: 
per singolo cliente (cioè personalizzato)
1)IdCliente1, IdProdotto1, IdBancale, IdConfezione, IdUnitaMisura
 
per tutti i clienti in generale
1)IdProdotto, IdBancale, IdConfezione, IdUnitaMisura
 
per singolo cliente (cioè personalizzato)
1)IdCliente, IdBancale, IdUnitaMisura
 
 


a questo punto,
apro maschera con sottomaschera;
se il prodotto selezionato riguarda il primo punto (1
avro' in automatico:
IdBancale, IdConfezione, IdUnitaMisura impostati per quel cliente
 
nel secondo punto (2
avro' in automatico:
IdBancale, IdConfezione, IdUnitaMisura per ogni cliente tranne
per quello del primo punto (solo se è inserito lo stesso prodotto)
 
nel terzo punto (3
avro' in automatico:
IdBancale, IdUnitaMisura impostati per quel cliente
______________
in tutti gli altri casi avro' (se non inseriti nell'impostazione predefinita), per....
IdBancale = 1
IdConfezione = CboConfezione (cioè null, da impostare al momento) 
IdUnitaMisura = 1
 
 
 
 
 
 

 chiedo una dritta per evitare le ripetizioni.........
 
Le ripetizioni di codice, in genere, si evitano facendo chiamate a 
/funzioni/
Si cercano i fattor comuni e quando tali fattori sono sono in 
maggioranza rispetto ai non fattori si puo' /pensare/ di usare
/funzioni/
Spesso e' utile anche definire /Classi/ ma questo credo che, al momento, 
sia un concetto non facilmente trasmissibile.
 
-- 
ac (x=y-1)
Aborro il Killfile
(La violenza e' l'ultimo rifugio degli incapaci -Salvor Hardin-)

 sia un concetto non facilmente trasmissibile.
 
proviamoci
 
grazie
 
 


CLASSI...? No Grazie.
Lasciamo perdere per ora le classi che già per un utente medio evoluto di Access sono quelle di scuola, ma tu hai una preparazione attualmente NON  ancora adeguata.
Certo se vuoi provarci puoi studiarle e, di conseguenza cimentarti..., ma fossi in te prima, cercherei di consolidare quanto meno le basi, su cui il terreno ancora è cedevole...!
 
Torno a noi, ma chiudo:
 
Se invece di questa:
strSql = "SELECT * FROM TbImpostazioni" _
& " WHERE IdProdotto1 = " & Frm!CboProdotto.Value _
& " And IdCliente1 = " & cliCriterio() 
 
 
Fai questa:
strSql = "SELECT * FROM TbImpostazioni" _
& " WHERE IdProdotto1 = " & Frm!CboProdotto.Value _
& " OR IdCliente1 = " & cliCriterio() 
 
Cosa ottieni...?
Un Recordset che soddisfa tutte le 3 esigenze, quello che non comprendo, è che seguendo il tuo Ragionamento, in ogni caso questo Recordset sarà popolato da 1 ed un solo RECORD, ho applicato semplicemente il teorema dei 3 Carabinieri alle tue affermazioni... anche se le ritengo dubbie...
 
Chiaramente implementadno un If...ElseIf...ElseIf...Else...End if condizioni i dati e chiudi.
 
Non mi addentro nel dettaglio in quanto è indispensabile tu faccia esercitazioni di LOGICA e non COPIA/INCOLLA...
 
@Alex

 Un Recordset che soddisfa tutte le 3 esigenze, quello che non comprendo, è che seguendo il tuo Ragionamento, in ogni caso questo Recordset sarà popolato da 1 ed un solo RECORD, ho applicato semplicemente il teorema dei 3 Carabinieri alle tue affermazioni... anche se le ritengo dubbie...
 
Perchè le ritieni dubbie?
 
grazie ancora

Perché una tabella ha solo la PK univoca... altrimenti c'è qualche cosa che non torna.
 
@ALEX

 @ALEX
 
ciao Alex
questa è la query che soddisfa tutte e tre le condizioni
 
  strSql = "SELECT * FROM TbImpostazioni" _
  & " WHERE IdProdotto1 = " & Frm!CboProdotto.Value _
  & " And IdCliente1=cliCriterio()" _
  & " Or IdProdotto = " & Frm!CboProdotto.Value _
  & " Or IdCliente = " & cliCriterio()
  Set rst = CurrentDb().OpenRecordset(strSql)
 
però in due casi mi restituisce 2 record anzichè uno solo,
come mi devo comportare in questa situazione?
 
grazie
 
 
 

Appunto... 
 
Se hai 2 records non è un problema fai un ciclo ed all'interno analizzi i valori della condizione... se veri entrambi è la tua prima condizione... assegni i valori ed esci.
 
Altrimenti se sono 2 records significa che uno soddisfa la 1° è l'altro la 2° condizione.
 
Controlli la prioritaria assegni i valori ed esci... altrimenti movenext e passi al 2° ed assegni...
 
@ALEX


ciao Alex
mi sono bloccato.........
in pratica non riesco a far funzionare il terzo punto,
dove se il record appartenente a
 
IdCliente = " & cliCriterio(), esiste (del terzo punto) con:
d- x1 = rst!IdBancale
e- x2 = rst!IdUnitàMisura 
 
devono sovrascrivere i record relativi a 
IdProdotto = " & Frm!CboProdotto.Value (del secondo punto)
 
a- x1 = !IdBancale <--- (d
b- x2 = !IdConfezione
c- x3 = !IdUnitàMisura <--- (e
___________
 
  If Not rst.EOF Then
    With rst
    .MoveFirst
    While Not .EOF
      x1 = !IdBancale
      x2 = !IdConfezione
      x3 = !IdUnitàMisura
 
     .MoveNext
    Wend
    End With



forse cosi???
 
  strSql = "SELECT * FROM TbImpostazioni" _
  & " WHERE IdProdotto1 = " & Frm!CboProdotto.Value _
  & " And IdCliente1=cliCriterio()" _
  & " Or IdProdotto = " & Frm!CboProdotto.Value _
  & " Or IdCliente = " & cliCriterio() _
  & " ORDER BY IdCliente1 DESC"
  Set rst = CurrentDb().OpenRecordset(strSql)
 
  If Not rst.EOF Then
    With rst
    .MoveFirst
    While Not .EOF
      x2 = !IdConfezione
      .MoveLast
      x1 = !IdBancale


Cosi cosa...? Non hai scritto nulla...
 
Perchè non ti fai un diagramma di flusso visto che hai così tante difficoltà...?
 
La dimanica può essere:
0 Record
1 Record (in questo caso può essere Vero(Cond1 AND Cond1) Oppure (Cond1) Oppure Cond2
2 Records (in questo caso sono vere Cond1(su un Record) e Cond2(sull'altro Record)
 
 
Quindi:
 
With rst
  if Not .EOF Then
      .MoveFirst
      If Condizione1 AND Condizione 2 THEN
        ' QUI' SI VERIFICA IL PRIMO CASO
        ' significa che in realtà avrai solo 1 RECORD quindi
        ' Assegna quello che ti serve
      Else
        ' Quì entri se NON sono verificate entrambe le condizioni
        ' ma puoi avere 1 Record oppure 2 a prescindere.
        ' CERCO la priorità 1 tra le 2 che rappresenta il 2°CASO
        Do Until Condizione1
          ' Assegna quello che ti serve
          ' ESCI
          .MoveNext
        Loop
        .MoveFirst
        ' QUI' DEVI VERIFICARE IL TERZO CASO
        Do Until Condizione2
          ' Assegna quello che ti serve
          ' ESCI
          .MoveNext
        Loop
 
        ' Se sei quì significa che era vuoto quindi impossibile...          
     End If
   End If
End With
 
 
@Alex

cut
 
grazie Alex
 
il mio problema è come scrivere la 3 condizione
 
nella query ho 2 records
p.e.
record1               record2   
IdImpostazioni 42  -  IdImpostazioni 46
IdCliente null     -  IdCliente 58
IdCliente1 null    -  IdCliente1 null
IdProdotto 1042    -  IdProdotto null
IdProdotto1 null   -  IdProdotto1 null
IdBancale 1        -  IdBancale 2
IdConfezione 1     -  IdConfezione null 
IdUnitaMisura 1    -  IdUnitaMisura 2
 
e devo ottenere questo risultato:
p.e.
IdProdotto 1042
IdBancale 2
IdConfezione 1
IdUnitaMisura 2
 
in pratica 
IdBancale e
IdUnitaMisura
del record 2
devono prendere il posto
di quelli nel record 1
 
  With rst
  If Not .EOF Then
      .MoveFirst
      If IsNull(!IdCliente) And IsNull(!IdCliente1) Then
        ' QUI' SI VERIFICA IL PRIMO CASO
        ' significa che in realtà avrai solo 1 RECORD quindi
        ' Assegna quello che ti serve
        x1 = !IdBancale
        x2 = !IdConfezione
        x3 = !IdUnitàMisura
      Else
        ' Quì entri se NON sono verificate entrambe le condizioni
        ' ma puoi avere 1 Record oppure 2 a prescindere.
        ' CERCO la priorità 1 tra le 2 che rappresenta il 2°CASO
        Do Until Not IsNull(!IdCliente1)
          x1 = !IdBancale
          x2 = !IdConfezione
          x3 = !IdUnitàMisura
          ' Assegna quello che ti serve
          ' ESCI
          .MoveNext
        Loop
        .MoveFirst
        ' QUI' DEVI VERIFICARE IL TERZO CASO
        Do Until Not IsNull(!IdCliente)
          ???????????????


Franco scusa ma io non ho capito ASSOLUTAMENTE NULLA...!
 
Dico questo perché io ti ho scritto una cosa è tu fai il contrario... quindi siccome il sistema è tuo a non capire cosa devi fare sono sicuramente io...
 
Ti suggerisco tuttavia di controllare l'antitesi di quanto fai adesso rispetto al primo post... rispetto quindi a quello su cui io ho basato il mio ragionamento che evidentemente ora deve essere cambiato... oppure era giusto e tu ora hai fatto il contrario ..?
 
Devi capire tu... perché io proprio non saprei... o meglio per me va bene uguale.
 
@ALEX


ciao Alex
mi è sufficiente sapere, (nel caso che ho due records) come faccio a sapere 
in quale dei due records mi trovo?
 
grazie

Come ho cercato di spiegarti... il caso 2 records e il più semplice concettualmente perché uno soddisfa una condizione è l'altro l'altra...
Quale delle 2 vuoi usare per prima..? 
Cerca tra i 2 il record che la soddisfa... 
Se non è il primo è il secondo...
 
Il codice che ti ho scritto... FA QUELLO perché tu non lo comprenda e ritenga necessario stravolgerlo lo lascio a te capirlo...
 
Non ne ho più di cartucce... e penso che tu debba ragionarci non fare copia/incolla giustamente ma lo devi fare in modo ragionato e secondi me tu non sai minimamente fare debug.
 
@ALEX

 Non ne ho più di cartucce...
 
Francodellavalle  vince per abbandono alla 127' ripresa ;-)



Ciao Alessandro
No! mai
 
Anzi ringrazio tantissimo Alex.
Ora voglio studiare bene tutto quello
che mi ha spiegato.

 Non ne ho più di cartucce... e penso che tu debba ragionarci non fare copia/incolla giustamente ma lo devi fare in modo ragionato e secondi me tu non sai minimamente fare debug. 
poco ma uso F8
 
comunque, cio' che mi hai spiegato, mi è stato utile.......
;-)
 
  With rst
    If Not .EOF Then
      .MoveFirst
      If IsNull(!IdCliente1) Then
        x1 = !IdBancale
        x2 = !IdConfezione
        x3 = !IdUnitàMisura
        .MoveFirst
        Do Until .EOF
          x1 = !IdBancale
          x3 = !IdUnitàMisura
          .MoveNext
        Loop
      Else
        x1 = !IdBancale
        x2 = !IdConfezione
        x3 = !IdUnitàMisura
 
      End If
 
    End If
 
  End With
 
ancora grazie