View Full Version : [Access] Macro ImpostaValore
In una maschera di un db Access 2007 ho una casella di riepilogo basata su una query di selezione, e che quindi mostra tutti i record che hanno impostato il campo "stato" su X
Mi serve fare una macro (o qualcosa) che cliccando 2 volte su uno dei record visualizzati possa far cambiare lo stato di questo record da X a Y e che contemporaneamente immetta nel campo DataY la data odierna
E' possibile? ....cercando online ho solo sentito parlare di una macro "impostaValore" ma sul mio access non la vedo...
Come si fa?:D
john_revelator
13-06-2009, 01:33
Ti ho scritto questo codice testandolo su access versione xp ma credo vada bene anche sul 2007. Nella query che usi per popolare la listbox recupera anche l'id che identifica ogni singolo record, visto che tale identificativo ti servirà in fase di update.
Private Sub lstNomi_DblClick(Cancel As Integer)
Dim i, identificativo As Long
Dim strSQL As String
For i = 0 To Me.lstNomi.ListCount - 1
If Me.lstNomi.Selected(i) = True Then
identificativo = lstNomi.Column(0, i)
strSQL = "update tabella set stato = 'Y',data = date() where id = " & identificativo
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
End If
Me.Refresh
Next
End Sub
Colgo l'occasione per chiedere se una volta eseguita la query, se si sono disabilitati i warning, esiste un modo per sapere se la query è andata a buon fine ed eventualmente quanti record sono stati modificati. :)
john_revelator
13-06-2009, 02:22
Mi rispondo da solo. Usando db.execute che a quanto leggo è preferibile rispetto a docmd.runsql è possibile recuperare il numero di righe "affette" dalla query. :)
Io invece tendo a usarli indistintamente badando solo al fatto che la query va comunque a buon fine. Bisogna che mi disabitui.
Private Sub lstNomi_DblClick(Cancel As Integer)
On Error GoTo errHandler
Dim i, identificativo As Long
Dim strSQL As String
Dim db As DAO.Database
Set db = CurrentDb
For i = 0 To Me.lstNomi.ListCount - 1
If Me.lstNomi.Selected(i) = True Then
identificativo = lstNomi.Column(0, i)
strSQL = "update tabella set stato = 'y',data = date() where id = " & identificativo
DoCmd.SetWarnings False
db.Execute strSQL, dbFailOnError
DoCmd.SetWarnings True
End If
Next
Me.Refresh
MsgBox "Righe aggiornate: " & db.RecordsAffected
errHandler:
If Err.Number <> 0 Then
MsgBox Err.Number & ": " & Err.Description, vbExclamation, "Errore esecuzione query"
Exit Sub
End If
End Sub
edit. In realtà mi sono reso conto, provando su una selezione multipla, che il conteggio era sempre pari a uno. Visto che ovviamente la query viene eseguita dentro il ciclo for sul singolo record. Quindi servirebbe inizializzare un contatore a zero e incrementarlo dopo ogni query.
Vado a dormire che è meglio. ;)
Ok, ma probabilmente ho qualche lacuna e non so come far funzionare il tutto :(
Come devo modificare il codice se devo aggiornare il campo che si chiama "IDstatoF" che sta all'interno della tabella "Contratti".
La casella di riepilogo (basata sulla query di selezione dello stato si chiama "LavorazioneDaInserire") e mi visualizza i campi cognome, nome, ragione_sociale (che stanno xò nella tabella Anagrafica).
Come faccio a far funzionare tutto sapendo che a quel nominativo è associato un IDcontratto (della tabella Contratti) a cui corrisponderà di conseguenza anche l'IDstatoF?
Rispondo qui a tuo pvt.
Anzitutto la struttura del DB, dove c'è un po' di confusione. Corrisponde a questa ?
Anagrafica
> IDcliente ( PK )
> cognome
> nome
> ragione_sociale
Contratti
> IDcontratto
> IDcliente ( FK su Anagrafica.IDcliente )
> IDstatoF ( X o Y )
> DataY ( ? )
1 cliente --> molti contratti.
Quindi il campo DataY è in Contratti e serve a memorizzare la data in cui l'utente, facendo doppio-click su quella listbox, ha modificato IDstatoF, ok ?
Poi, la listbox come la popoli ? Posta il codice Sql della query.
E' una listbox multi-colonna ? IDcontratto è presente nella listbox ?
Da quanto ho capito quello che chiedi è una semplice UPDATE su Contratti, da lanciare al doppio-click dell'utente su un item della listbox, niente di arduo. Intanto direi che john_revelator ha già postato un esempio di codice opportuno, da riadattare al tuo caso...
Si, la struttura è quella
Nella listbox non c'era l'idcontratto ma forse è meglio aggiungerla, sia poi per semplicità sia x evitare problemi nel caso di + contratti per cliente
l'attuale listbox è:
SELECT LavorazioneInApprovazione.cognome, LavorazioneInApprovazione.nome, LavorazioneInApprovazione.ragione_sociale, LavorazioneInApprovazione.IDcontratto
FROM LavorazioneInApprovazione
ORDER BY LavorazioneInApprovazione.cognome;
poi volevo chiedere...ma se lo stato di default lo metto ad esempio a "1" e voglio farlo passare automaticamente a "2" quando completo un altro campo è possibile? nel senso che una volta che scrivo un valore in un campo della tabella Contratti es "numero_pratica" automaticamente "IDstatoF" passa da "1" a "2"
Si, la struttura è quella
Nella listbox non c'era l'idcontratto ma forse è meglio aggiungerla, sia poi per semplicità sia x evitare problemi nel caso di + contratti per cliente
l'attuale listbox è:
SELECT LavorazioneInApprovazione.cognome, LavorazioneInApprovazione.nome, LavorazioneInApprovazione.ragione_sociale, LavorazioneInApprovazione.IDcontratto
FROM LavorazioneInApprovazione
ORDER BY LavorazioneInApprovazione.cognome;
Quindi Anagrafica adesso si chiama LavorazioneInApprovazione ?
Devi essere più preciso, sennò non finiamo più. :p
Diamo una sistemata alla query per popolare la ListBox. Così non va. Inoltre LavorazioneInApprovazione non ha un IDcontratto perciò l'ultimo campo verrebbe interpretato da Access come parametro esterno...
Semmai questa :
SELECT LavorazioneInApprovazione.cognome, LavorazioneInApprovazione.nome, LavorazioneInApprovazione.ragione_sociale, Contratti.IDcontratto
FROM LavorazioneInApprovazione, Contratti
WHERE LavorazioneInApprovazione.IDcliente = Contratti.IDcliente
ORDER BY LavorazioneInApprovazione.cognome;
Ok, la salvo e poi creo la ListBox ( Lista1 ) associata alla query.
A questo punto ho una lista a 4 colonne. L'indice in base 0 della colonna IDcontratto è quindi 3.
> Doppio click su Lista1 :
Private Sub Elenco1_DblClick(Cancel As Integer)
Dim idContratto As Long
idContratto = Elenco1.Column(3)
Dim strSql As String
strSql = "UPDATE Contratti SET IDstatoF = 'Y', DataY = #" & Now & "# " & _
"WHERE IDcontratto = " & idContratto
DoCmd.SetWarnings False
DoCmd.RunSQL strSql
DoCmd.SetWarnings True
End Sub
E hai finito. ;)
poi volevo chiedere...ma se lo stato di default lo metto ad esempio a "1" e voglio farlo passare automaticamente a "2" quando completo un altro campo è possibile? nel senso che una volta che scrivo un valore in un campo della tabella Contratti es "numero_pratica" automaticamente "IDstatoF" passa da "1" a "2"
Sa tanto di Trigger, e Access non li supporta, perciò dovrai andare con VBA...
lavorazioneinapprovazione è la query che ho fatto per selezionare tutti i record che hanno IDstato impostato a "1", in pratica ho una maschera con 3 caselle di riepilogo e ognuno è basata su una query che seleziona solo i record con rispettivamente IDstato= 1 , idstato=2 e idstato=3
Cmq adesso provo un po' e vedo se riesco a far qualcosa :D
lavorazioneinapprovazione è la query che ho fatto per selezionare tutti i record che hanno IDstato impostato a "1", in pratica ho una maschera con 3 caselle di riepilogo e ognuno è basata su una query che seleziona solo i record con rispettivamente IDstato= 1 , idstato=2 e idstato=3
Ah, quindi fai una query su un'altra query... :mbe:
Ma non era più semplice fare tutto in una query sola ?
> Query che popola la ListBox1 :
SELECT Anagrafica.cognome, Anagrafica.nome, Anagrafica.ragione_sociale, Contratti.IDcontratto
FROM Anagrafica, Contratti
WHERE Anagrafica.IDcliente=Contratti.IDcliente
AND Contratti.IDstatoF = 1
ORDER BY Anagrafica.cognome;
> Query che popola la ListBox2 :
SELECT Anagrafica.cognome, Anagrafica.nome, Anagrafica.ragione_sociale, Contratti.IDcontratto
FROM Anagrafica, Contratti
WHERE Anagrafica.IDcliente=Contratti.IDcliente
AND Contratti.IDstatoF = 2
ORDER BY Anagrafica.cognome;
> Query che popola la ListBox3 :
SELECT Anagrafica.cognome, Anagrafica.nome, Anagrafica.ragione_sociale, Contratti.IDcontratto
FROM Anagrafica, Contratti
WHERE Anagrafica.IDcliente=Contratti.IDcliente
AND Contratti.IDstatoF = 3
ORDER BY Anagrafica.cognome;
Per la gestione del doppio-click, il codice ce l'hai già... ;)
eh si...infatti inizio a capire adesso come funziona:D
Ho fatto come hai detto e preso la routine dalla risposta precedente ma mi dice errore di runtime 94; utilizzo non valido di Null
e sulla riga segnata me la evidenzia nel debug
Option Compare Database
Private Sub Elenco2_DblClick(Cancel As Integer)
Dim idCon As Long
idCon = Elenco2.Column(3) <----
Dim strSql As String
strSql = "UPDATE Contratti SET IDstatoF = '3', DataApprovazione = #" & Now & "# " & _
"WHERE IDcontratto = " & idCon
DoCmd.SetWarnings False
DoCmd.RunSQL strSql
DoCmd.SetWarnings True
End Sub
Ho fatto come hai detto e preso la routine dalla risposta precedente ma mi dice errore di runtime 94; utilizzo non valido di Null
e sulla riga segnata me la evidenzia nel debug
Option Compare Database
Private Sub Elenco2_DblClick(Cancel As Integer)
Dim idCon As Long
idCon = Elenco2.Column(3) <----
Dim strSql As String
strSql = "UPDATE Contratti SET IDstatoF = '3', DataApprovazione = #" & Now & "# " & _
"WHERE IDcontratto = " & idCon
DoCmd.SetWarnings False
DoCmd.RunSQL strSql
DoCmd.SetWarnings True
End Sub
Ma Elenco2 ha o no 4 colonne ? Sulla 4a colonna ( la column 3 in base 0 ) ci deve essere un idcontratto, non deve essere un campo null.
Inoltre l'Update che usi così non va. Nei campi numerici gli apici singoli non vanno :
strSql = "UPDATE Contratti SET IDstatoF = 3, DataApprovazione = #" & Now & "# " & _
"WHERE IDcontratto = " & idCon
che figata funziona tutto!
come modifico il codice per far si che dopo aver fatto doppio click (e quindi aggiornato IDstato e dataApprovazione) la maschera (che si chiama Lavorazione) si aggiorni?
che figata funziona tutto!
come modifico il codice per far si che dopo aver fatto doppio click (e quindi aggiornato IDstato e dataApprovazione) la maschera (che si chiama Lavorazione) si aggiorni?
Finalmente ! :D
Puoi aggiornare ogni singola lista semplicemente con .Requery.
Es.:
Elenco1.Requery
O anche a livello di Form :
Me.Requery
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.