Newsgroup: it.comp.appl.access
Titolo: Annidare rstclone..è possibile?

Mi trovavo con la mia bella form tutta funzionante che poteva essere aggiornata
attraverso un recordsetclone.
Ora il destinatario del db mi dice: " moooolto bello, ma la maschera ( continua) ha
troppi campi. Non potresti separare i campi principali dai campi dettagli? "
  Allora ho pensato " che problema c'è, creo una popup dei dettagli che vado ad aggiornare se occorre"
Ma credo che l'impresa sia piu' ardua di quanto ho pensato.
Al momento faccio in modo che su un progetto_in_sospeso, vado a dare conferma che il progetto è stato accettato, dandomi
la possibilità di modificare, nel caso non fossero uguali, alcuni dettagli_di_progetto.
Quindi, se il progetto_accettato è uguale al progetto_in_sospeso, lo copio pari pari con un check di conferma.
Se è accettato ma necessita di modifiche lo accetto, ma lascio liberi i campi_dettaglio da modificare.
Il tutto in una maschera sola...ma con due maschere?
In teoria dovrei, nel caso A fare un recordsetclone sulla Form1 e sulla Form2(devono essere tutte e due attive?) e chiudere connection.
Nel caso B fare un recordsetclone sula Form1, far aprire la form2, aggiornare a manina e poi tornare alla form1.
Ma è possibile "annidare" i rstclone?
Function ProgettoInProgress()
Dim Con As ADODB.Connection
Dim lngStore As Long
Set Con = CurrentProject.Connection
c
    lngStore = Me!ID
             With Rst
             .AddNew
             !Cliente = Me.Cliente.Value
             !Attività = "ProgettoInEssere"
             Bla, Bla, Bla
                         .Updat
              Me.RecordsetClone.FindFirst "Id= " & lngStore
              Me.Bookmark = Me.RecordsetClone.Bookmark
              Me.Requery
              DoCmd.GoToRecord , , acLas
              DoCmd.RunCommand acCmdSaveRecord
          .Close
con.close
Cosa faccio adesso...apro la form2 e creo
Set Rst1 = New ADODB.Recordset
Rst.Open "SELECT DettagliProgetto.* FROM DettagliProgetti", Con, adOpenKeyset, adLockOptimistic, adCmdTableDirect
o sto sbagliando e occore un'altra procedura?
Cristina...e grazie per l'aiuto
Ciao

 Ma credo che l'impresa sia piu' ardua di quanto ho pensato.
[cut]
Perche' *annidati*? casomai e' lo *stesso* recordset.
Normalmente in questi casi uso il controllo a schede con "testata" i 
dati che devono esere sempre visibili e  300000000 schede per il resto 
assegnando lo stesso recordset (non il recordsetclone)
Comunque puoi provare a fare la *set* del recordset, piu'  o meno clone, 
che ti interessa.
--
ac

Alessandro Cara ha scritto:

Ciao Alessandro
ti ringrazio dell'intervento, ma c'è qualcosa che non capisco.
Hai ragione, in realtà il record è lo stesso , solo suddiviso in due form.Ok
Ma perchè Set?
Devo usare per forza le maschere continue; non posso usare quelle a schede...
Mi hanno insegnato, per duplicare un record ( che è quello che devo fare)ad usare la funzione
recordsetclone ( ..e funziona) :-)
Cosa posso fare con Set?
Fare riferimento a più form?
Ho provato a guardare l'help in linea...mamma mia ...qualcosa di più "criptico" non potevano farlo!!!
Mi dai una mano?
Grazie
CB

Cristina Bernazzani ha scritto:

*set* perche' il recordset e' un oggetto e non una variabile semplice.
Se io ho un recordset in un form (attenzione il controllo a schede *non* 
e' un form e' un semplice contenitore in cui posso inserire tutto cio' 
che voglio,controlli associati o non o subform) posso/devo fare set 
me.recordset = altroForm.recordset.
Il recordsetclone e' una *copia* del recordset  e necessita di 
risincronizzazione mentre il recorset e' la origine dei dati per il 
form. Se tu usi lo stesso recordset prelevando di volta in volta solo i 
*fields* che ti interessano hai *gratis* la sincronizzazione.
Il fatto che usi form continue non impatta, la tecnica puo' essere usata 
su qualsiasi tipo form associato. A memoria mi sembra che ci fosse un 
solo problema: se si filtra o riordina il recordset di "altraForm" va 
riassegnato (almeno nella mia versione di access)
Non ho compreso il fatto di "duplicare il record". Qual'e' il motivo per 
cui lo devi duplicare? Io avevo capito che ti avevano chiesto una 
diversa distribuizione di visualizzazione dei dati.
--
ac


Hai ragione; se non si sa dove si vuole andare è difficile capire.
Cerco di non essere mai troppo prolissa per non risultare antipatica con post troppo lunghi.
Ma ci provo.
Perchè duplico un record.
L'azienda lavora su un documento principale, dal quale vengono poi elaborate molte informazioni, che è una specie di "work in progress":
22-mag-08 Azienda, Attività, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo,
24-mag-08 Azienda, Attività, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo, Campo,
Bene.
Queste attività giornaliere, richiedono molta attenzione nell'essere completate.Le stesse vengono (ad oggi ) poi rieditate quando [Attività]
passa da Progetto a Progetto_Entrato.
L'azienda utilizza poi questi dati per fare delle statistiche approfondite.
L'azienda desidera:
1) Mantenere una cronologia delle attività giornaliere
2) Non dover rieditare (evitando errori) un ordine (30 campi) che prima era un progetto
3) Nel caso variassero alcune condizioni poterle correggere
3) Risparmiare tempo
Ora; se non ci fosse stata la necessità 1), bastava un flag in una check_control. Ma c'è la necessità di tenere traccia di quando e come è stata fatto 
un progetto e di come e quando si è concluso.Se ci sono dei cambiamenti tra il progetto e il progetto_entrato, occorre comuque rieditare un nuovo 
record; tanto vale duplicare il record in entrambi i casi. Tieni traccia dei movimenti e analizzi le differenze, che in alcuni casi ti restituiscono 
dei parametri di valutazione.( e.g Quanto tempo trascorso, quanti avevano chiesto uan cosa e poi ne hanno fatta un'altra, quali fattori tra tutti i 
progetti_Proposti sono stati fondamentali per farli diventare _Accettati, etc, etc)
Nella necessità 2 e 3 e 4) va da se..non dover rieditare 30 campi, evitare errori e fare tutto con pochi click.
Quindi con un rstclone (condizionato da un if) duplico semplicemente, variando alcuni valori, il record originale, o nel caso, lo duplico in modo 
parziale e faccio in modo che possano essere modificati solo alcuni dettagli.
Ora , siccome la form a maschera continua, ha molti campi e sembra essere un po' troppo pesante, l'azienda mi chiede la possibilità di "splittare" i 
campi in due form separate, 1DatiPrincipali e 2Dettagli, in modo da apparire visivamente meno complesso.
Ecco la mia necessità di continuare ad utilizzare la funzione in oggetto, ma in questo caso facendola agire non piu' su una sola form , ma su due.
Spero di essere riuscita a spiegarmi bene, operazione che sto scoprendo non essere per niente facile :-)
Ciao
Cri


Nel frattempo ho guardato il  codice che usi.
I due problemi sono distinti.
Quello che fai per "storicizzare" l'informazione va bene.
Immagino che il tutto avvenga tramite click su un bottone "Duplica" o 
qualcosa del genere (o anche evento di "dirty")
La visualizzazione dei dati e' un'altra storia.
Io continuo a preferire il controllo a schede per la visualizzazione 
"parzializzata" ma temo che ti ci vorrebbe un po' per mettere su il 
giochino visto la tua non conoscenza del TabControl (controllo a schede).
Se preferisci la pop up.
Tramite un bottone (un bottone su ogni riga della form continua o evento 
di doppio click di form) puoi aprire un form impostando il parametro 
"condizioneWhere" sulla openform
i.e
docmd.OpenForm NomeMaschera, Visualizzazione, NomeFiltro, 
CondizioneWHERE, ModalitàDati, ModalitàFinestra, ArgomentiApertura
i.i.e.
docmd.openform nomemask,,,"id=" & 
me.id
,,acDialog
il form puo' avere la stessa fonte dati (recordsource) del form 
chiamante e visualizzare solo le informazioni di "Dettaglio".
In prima approssimazione non dovresti fare altro.
--
ac


...mi stai facendo incuriosire sui TabControl...adesso vado a vedere cosa ci si puo' fare :-)
Adesso ho capito cosa vuoi dirmi.
In realtà sono sempre sullo stesso recordsource e devo solo by-passare tra due visualizzazioni diverse ( ed aggiornare due form diverse)
Se non ho capito male, provo a rivedere il processo logico.
Sono sulla mia form Principale, pulsante su piede di maschera ( verrebbe bruttino su ogni record) "Formalizza"..doppio click
Set Rst = New ADODB.Recordset
         Rst.Open "..................
         lngStore = Me!ID
             With Rst
              response = MsgBox("La chiusura è corrispondente al progetto originale?" & (Chr(13)) & (Chr(13)) & "Premi SI se non devi apportare 
nessuna modica." & (Chr(13)) & _
              "Premi NO se la chiusura è diversa dal progetto originale." & (Chr(13)) & (Chr(13)) & "Premi ANNULLA se vuoi ricontrollare e confermare" 
& (Chr(13)) & _
              "in un secondo tempo!", vbYesNoCancel)
              If response = vbYes Then
             .AddNew
             !Cliente=Me.Cliente.Value
             !NomeProgetto=Me.NomeProgetto.Value
             eccetera...aggiorno i campi della maschera principale!
             .update
............a questo punto non chiudo l'azione sul rst..ma
             docmd.openform "Dettagli",,,"id=" & Me.id, acdialog
............e continuo sulla nuova form le azioni di aggiornamento Dettagli
            !ValoreProgetto=Me.ValoreProgetto.Value
            !TempoConsegna=Me.TempoConsegna.value
            ..etc
            .update
            DoCmd.RunCommand acCmdSaveRecord
......torno alla form principale....
                docmd.close
               docmd.openform "Progetti",,,"id=" & Me.id, acdialog
.....torno al record dal quale parte il tutto..
Me.RecordsetClone.FindFirst "Id= " & lngStore
              Me.Bookmark = Me.RecordsetClone.Bookmark
              .update
...aggiorno la maschera
              Me.Requery
...mi sposto nell'ultimo record creato
       Docmd.Gotorecord,,acLast.......'aprendo la maschera su ORDER BY "Date , Now",(pur essendoci  la data estesa preferisco mantenere separati i due 
valori per altri motivi)e unendolo alla funzione lngstore, riesco a posizionarmi sempre ed inequivocabilmente sull'ultimo record creato...
..ed aggiorno i valori di controllo ..
......Me.DataChiusura=Date()
       Me.Check_Control=True
.....chiudo con tutte le opzioni del caso
DoCmd.RunCommand acCmdSaveRecord
             .Close
     Con.Close
ElseIf
.........
ti sembra corretto come processo?
Ps. Ho dato una occhiata mooooooolto veloce alle strutture a schede. Mi sembra molto adatta ad una visione " per record" ed in più
è molto "windows Like" ...sembra di rivedere tante forms " opzioni di programma" ...sono complesse da impostare? Potrebbero essere uan alternativa?
Ciao
Cristina

 alternativa?
il cielo.

 riga corrente.
[CUT]
Non sono d'accordo
Mi sembra di  notare invece dal codice che Cristina utilizza il
metodo
di Don Karl per il riferimento all'Id del record
lngStore = Me!ID
...
Me.RecordsetClone.FindFirst "Id= " & lngStore
              Me.Bookmark = Me.RecordsetClone.Bookmark
se è cosi' io l'ho testato mille volte. Torni immancabilmente al
record *corrente* dal quale sei
partito.
LngStore memorizza l'Id del record *genitore*
Ciao
Eddie

Eddie ha scritto:

Non e' questa la questione. Infatti quella istruzione serve per 
"risincronizzare" ed e' chiara e fa parte del passo 1.
Se e' al mio N.B. a cui ti riferisci, questo e' relativo  ad un'altra 
questione che, dato che avevo tagliato tutto, non si evince dal contesto.
Per gestire quello a cui mi riferivo il lngStore deve essere o una 
variabile pubblica o di form su cui conservare l'ID al momento 
dell'evento di current (o exitForm) e questo da farsi nel Passo 2.
Non mi e' ancora capitato di vedere suggerimenti di Karl che falliscono ;<)
--
ac


..infatti, donkarl è preziosissimo :)
Allora mi scuso ...mi riferivo al tuo NB e sembrava indirizzato a
contestare "Se metti un solo bottone perdi il riferimento all'ID"
..ne approfitto riprendendo proprio quell'esempio.
In un altro db non mi riesce di utilizzare la stessa funzione con un
valore
stringa (codice univoco che viene generato ad hoc)
Dim strStore as Variant
strStore = Me!Codiceprodotto
...
Me.RecordsetClone.FindFirst "Codiceprodotto = " & strStore
              Me.Bookmark = Me.RecordsetClone.Bookmark
Mi da " errore di sintassi" ..ne sai il perchè?
Sull'help di a03 usa chiaramente anche le variabili stringa per
trovare il bookmark.
Grazie se puoi e ciao
Eddie


certo ma la variabile stringa la racchiude fra apici
i.e.
..... .Findfirst "CodiceProdotto='" & strStore & "'"
1) Le variabili numeriche non sono delimitate
2) Le variabili stringa sono delimitate da apice o virgolette
2) Le variabili tipo "date" sono delimitate da diesis (#)
N.B. il tipo non e' il tipo della tua variabile locale (i.e. strstore) 
ma il tipo campo definito a livello di tabella.
La condizione di findfirst e' di fatto una "WHERE" sql senza la parolina 
*where*
..... e non usa la findfirst per trovare il bookmark, usa la findfirst 
per "ritrovare" il record perduto e poiche' il form e' linkato al 
recordset e non al recordsetclone per riallineare i due riassegna al 
form il "segnalibro" di recordsetclone
--
ac

Alessandro Cara ha scritto:
[cut]
P.S.
Se invece di usare quell'impiccio del bookmark fai la findfirst 
direttamente sull'oggeto recordset dovresti avere lo stesso risultato
--
ac


Ti ringrazio ac.
Una piccola riflessione; ma voi dove le trovate queste informazioni?
Perchè i casi sono due; o io non sono portato alla programmazione
oppure non uso gli strumenti giusti, oppure c'è una grandissima
confusione.
Costruire Applicazioni con Access Mike Davis 45 € ..di tutto di più ,
ma alla findfirst dedica una riga dove
indica : rst.findfirst "Paese= 'Spagna' " ( usando gli apici per
indicare la stringa cercata e chiudendo la stringa stessa con 2
virgolette,quindi chiudendo un parametro di stringa normale "
Miocampo='verde' "  non con 4 , come fai tu. Nessun accenno
all'utilizzo di un campo come variabile.
Analisi dei dati con Access O'Really 30 € ..utile, ma nemmeno un
accenno al metodo findfirst del recordset.
Help di Access: Metodo FindFirst: Bla bla bla ....Quando si eseguono
ricerche in campi contenenti date è necessario utilizzare il formato
data americano (mese-giorno-anno) anche se non si sta utilizzando la
versione americana del modulo di gestione di database Microsoft Jet;
altrimenti i dati potrebbero non essere individuati. Per convertire la
data, utilizzare la funzione Format di Visual Basic. Ad esempio:
rstEmployees.FindFirst "HireDate > #" _
   & Format(mydate, 'm-d-yy' ) & "#"
Questo potrebbe avvicinarsi a quanto da te indicato, ma..per le
stringhe? "%", "?" "i", "s"..qualsiasi cosa...non se ne parla..
Se un linguaggio di programmazione deve avere regole, come qualsiasi
linguaggio, mi chiedo perchè siano cosi' difficilmente reperibili. E
comincio a capire quei programmatori che quando gli dici che stai
costruendo un piccolo gestionale con Vb o Vba , ti guardano  con un
sorrisetto di sufficienza.
Sembra cosi' tutto aleatorio, frammentato, impreciso, un po' alla
napoletana...a furia di provare qualcosa accadrà :-)
Sto approcciando anche il C...accidenti; al di là della estrema
somiglianza al vb ( a parte gli oggetti ovviamente) , ci sono delle
regole e sono quelle, precise, indicate, evidenti...
Ergo; esiste un luogo, un libro, un guru , che documenti queste cose?
Ciao ac e grazie (e scusa per lo sfogo)
Eddie


PS. 2) Le variabili tipo "date" sono delimitate da diesis (#)
..suoni per caso ?
Solo chi conosce la musica chiama Diesis il "cancelletto" ...io suono
chitarra e piano
Ciao
Ed.

 Ergo; esiste un luogo, un libro, un guru , che documenti queste cose?
Il NG, il NG, il NG (piu' di un Guru)
--
ac

 ac
Ok ok ...cazziato e messaggio chiarissimo =
Do.cmd.StudiadiPiù,,acEMeglio    :-)))
Comunque ecco qui il codice incriminato
Me.RecordsetClone.FindFirst "Codiceprodotto = ' " & strStore & " ' "
mancavano gli apici mancavano ( che ho scoperto vanno usati nel caso
di caselle di testo)
...vado a studiare :-)
Ciao
Ed.

Eddie ha scritto:

Nessuna cazziata. Voleva essere solo una esortazione costruttiva.
E poi visto che sai suonare, io purtroppo no, e' stata una meschina 
vendetta ;<)
Pero' so cose' la sensibile e la dominante e con un po' di sforzo anche 
la biscroma.
P.S. docmd e' senza punto ;<)) e la acEMeglio e' una costante che dovro' 
guardarmi ;<))))))))))))))
P.P.S. Attenzione questa affermazione e' falsa:"( che ho scoperto vanno 
usati nel caso di caselle di testo)"
La casella di testo, anzi la proprieta' *.value* delle caselle di 
testo(*), e' tipo stringa (forse piu' *variant* che stringa) ma questo 
non vuol dire che se usi quel valore lo devi *obbligatoriamente* 
racchiudere fra apici.
(*) La casella di testo di per se e' un *oggetto*.
P.P.P.S.:NB "Codiceprodotto = ' " & strStore & " ' "
e' diverso da
"Codiceprodotto = '" & strStore & "' "
Con buona possibilita' (forse ottima) rischi di non trovare quello che 
cerchi.
--
ac

 >>>> direttamente sull'oggetorecordsetdovresti avere lo stesso risultato


Sai perchè mi piace la programmazione?
Perche' qualsiasi errore tu possa incontrare , non è mai la macchina a
a sbagliare, ma tu che non hai fatto bene
quello che dovevi fare.
Esattamente come suonare uno strumento ; lui non sbaglia mai. Sei tu
che non hai affinato la tecnica.
Un piccolo bagno di umiltà per ricordarti che puoi solo continuare ad
imparare e migliorare.
Response.P.S: Quel do.cmd , sorry , è stato un errore dettato dalla
necessità di essere veloce ( dovevo lasciare l'ufficio) e spesso le
dita vanno piu' veloci della mente.
 Response.P.P.S: Scusa alle volte mi esprimo male. Volevo dire che ,
come ho visto sul sito di DonKarl, in un altro esempio di FindFirst ,
lui precisa che se il valore cercato non è numerico ( Long) ma,  ad
esempio , di testo , quello che prima era :
Me.RecordsetClone.FindFirst "Id = " & strStore
diventa
Me.RecordsetClone.FindFirst "Codiceprodotto = ' " & strStore & " ' "
Uso una variabile "Variant" . La mia strStore è composta da lettere/
numeri
Ora non ho ancora la sufficiente ed approfondita conoscenza di tutto ,
ma la spiegazione di DonKarl mi ha risolto il problema:
www.donkarl.com/it?FAQ4.4
Quindi la mia variabile è di dipo "Variant"  e ritorno, dopo tutto il
lavoro sul recordset , esattamente nel record [CodiceProdotto] dal
quale sono partito..
NBBBBB & Response P.P.P.S: Ho vuolutamente "allargato il codice per
evidenziare gli apici , che , non so sul tuo client di newsgroups
( io uso web googlegroups )  , ma nel web vengono tutti impastati ed
alcune cose si amalgamano troppo  . Quindi ho forzosamente "staccato"
gli apici per farli notare.
In realtà è formattato cosi' : Me.RecordsetClone.FindFirst
"Codiceprodotto = '" & strStore & "'"
Che non è proprio istintivamente comprensibile
A proposito..non c'è un client decente, col quale formattare meglio il
testo ? Thunderbird è un po' grezzo e googlegroups primitivo ...:-))
Ciao Ed.