logo MC2 E-Learning S.a r.l.
Logo Einstein grigio sfumato
e = m x c al quadrato





Collegarsi ad una attività correlata con il VBA

Impariamo come collegarsi via codice ad una attività correlata con il VBA Visual Basic for Application







Passiamo al database Entertainment e diamo un’occhiata alla maschera frmContracts, che è la “centrale operativa” di questa applicazione.

L’attività della RM Production è incentrata sugli ingaggi dei gruppi nei club, la formulazione dei contratti e il controllo del pagamento delle commissioni.

Questo tutorial esplora alcune delle attività che sono automatizzate nella maschera frmContracts.

Una delle attività fondamentali nella maschera principale frmContracts, illustrata nella figura seguente  è seguire i pagamenti delle commissioni sui contratti attivi.

Quando ci si sposta da contratto a contratto in questa maschera, il pulsante Payments sarà attivato o disattivato a seconda dello stato di quel particolare contratto.

La routine evento Su Corrente dellamaschera (Form_Current) esamina il campo di stato del contratto e imposta di conseguenza la proprietà Abilitato del pulsante (figura 1).

Spostiamoci su un contratto attivo e facciamo clic sul pulsante Payments per vedere che cosa succede.

Si dovrebbe vedere la maschera frmPayments che si apre, come nella figura (figura 2).

Questa maschera, nella quale si immettono i pagamenti per il contratto in questione, si apre come maschera modale, cioè a scelta obbligatoria, cosicché l’utente deve introdurre tutti i pagamenti prima di spostarsi su un altro contratto.

Se si apre la maschera frmPayments in visualizzazione Struttura, come si vede nella figura, si scoprirà che non ha un’origine dei record figura 3).

E allora, come funziona questa maschera? Dal momento che sappiamo che questa maschera verrà sempre utilizzata per modificare i dati relativi a un preciso contratto, non c’è motivo di sostenere il carico addizionale di aprire un altro recordset nella tabella tblContracts, particolarmente considerando che non è necessario modificare i dati del contratto nella maschera Payments.

La sottomaschera è associata alla tabella tblCommissions e la sua proprietà Collega Campi Master del controllo della sottomaschera fa riferimento al controllo non associato ContractNo nella maschera principale.

Gli altri controlli nella maschera sono lì semplicemente per confermare i dati del contratto e sono bloccati (non aggiornabili).

Questa maschera viene aperta e riempita dalla routine evento Su clic per il pulsante Payment nella maschera principale frmContracts.

Il codice è il seguente:

Private Sub cmdPayment_Click()
Dim frm As Form
   ' Controlla se vi sono dati non salvati in questa maschera
      If Me.Dirty Then
        ' Se è così, devono avere valori validi
        ' per GrouplD e ClubID
        If IsNothing(Me!GroupID) Or IsNothing(Me!ClubID) Then
            MsgBox "You can't save a contract without a " & _
                "Group Name and Club Name.", vbCritical, "Payments"
            Me!GroupName.SetFocus
            Exit Sub
        End If
        ' Salva i dati “dirty”
        DoCmd.RunCommand acCmdSaveRecord
    End If
     ' Apre la maschera correlata per i pagamenti, nascosta
    DoCmd.OpenForm FormName:="frmPayments", WindowMode:=acHidden
    ' Imposta una variabile maschera per ragioni di efficienza
    Set frm = Forms!frmPayments
    ' Inserisce i dati non associati sui pagamenti
    ' ....è il ContractNo quello che fa funzionare
    ' la sottomaschera
    frm!ContractNo = Me!ContractNo
    frm!GroupName = Me!GroupID.Column(0)
    frm!ClubName = Me!ClubID.Column(0)
    frm!BeginningDate = Me!BeginningDate
    frm!EndingDate = Me!EndingDate
    ' Porta il focus sulla sottomaschera
    frm!fsubPayments.SetFocus
    ' e rende visibile la maschera
    frm.Visible = True
End Sub

Dopo aver accertato che tutti gli eventuali cambiamenti sono stati salvati, il codice apre frmPayments come maschera nascosta (cosicché non lo vedremo mentre incolla i dati del contratto), copia i dati dello schermo nella maschera e poi la rende visibile.

Si osservi che non ci sono maschere per introdurre nel database nuove righe per le commissioni.

Queste righe vengono create automaticamente da un’altra routine VBA, che viene eseguita ogni volta che si conclude un aggiornamento nella maschera frmContracts (nell’evento Dopo Aggiornamento).

Il codice è il seguente:

Private Sub Form_AfterUpdate()
Dim db As Database, rst As Recordset, qd As QueryDef
Dim varMonday As Variant, curOwed As Currency, intWeeks As Integer, intI As Integer
    On Error GoTo LoadComBail
    DoCmd.Hourglass True
    Set db = CurrentDb()
    ' Se non è un contratto RMP attivo o in attesa, provvede ‘a cancellare il file Cornmissions
    If IsNothing(Me!Status) Or Me!Status = "D" Or Me!Status = "SB" Or Me!CommissionAgent1 <> "RMP" Or IsNull(Me!CommissionAgent1) Then
        Set qd = db.CreateQueryDef("", "Delete * From qryCommissions;")
        qd![Forms!frmContracts!ContractNo] = Me!ContractNo
        qd.Execute
        qd.Close
        DoCmd.Hourglass False
        Exit Sub
    End If
    ' Contratto RMP Active, Pending o Paid - controlla che le Commissions siano corrette
    Set qd = db.QueryDefs("qryCommissions")
    qd![Forms!frmContracts!ContractNo] = Me!ContractNo
    Set rst = qd.OpenRecordset(dbOpenDynaset)
    curOwed = CCur(CLng(Me!ContractPrice * Me![Commission1%] * 100) / 100)
    varMonday = Me![BeginningDate] - WeekDay(Me![BeginningDate], 2) + 1
    ' Se le condizioni del contratto vanno oltre un lunedì, ricalcola il primo giorno
    ' della settimana da fatturare
    If Me![ContractLastDay] > 7 Then varMonday = varMonday + 7
    intWeeks = CInt(Me!EndingDate - varMonday + 7) \ 7
    ' Imposta un array che contiene tutte le settimane valide per questo contratto
    ReDim varWeekBeginning(1 To intWeeks + 1) As Variant
    ReDim intHit(1 To intWeeks + 1) As Integer
    For intI = 1 To intWeeks
        varWeekBeginning(intI) = varMonday
        varMonday = varMonday + 7
    Next intI
    varWeekBeginning(intWeeks + 1) = #1/1/2099#
    intI = 1
    ' Trova i record delle commissioni che corrispondono e li aggiorna
    Do Until rst.EOF
        Do Until varWeekBeginning(intI) >= rst!WeekBeginning
            intI = intI + 1
        Loop
        If varWeekBeginning(intI) = rst!WeekBeginning Then
            rst.Edit
            rst!AmountOwed = curOwed
            If Me!Status = "Pd" Then rst!AmountPaid = curOwed
            intHit(intI) = True
            rst.Update
            Else
            rst.Delete
        End If
        rst.MoveNext
    Loop
    '  Ora aggiunge gli eventuali mancanti
    For intI = 1 To intWeeks
        If Not intHit(intI) Then
            rst.AddNew
            rst!ContractNo = Me!ContractNo
            rst!WeekBeginning = varWeekBeginning(intI)
            rst!AmountOwed = curOwed
            If Me!Status = "Pd" Then rst!AmountPaid = curOwed
            rst.Update
        End If
    Next intI

    rst.Close
    DoCmd.Hourglass False
    Exit Sub
LoadComBail:
    MsgBox "Unexpected Error. " & Err & " " & Error, 16
    Exit Sub

End Sub

In breve, questa routine fa quanto segue:

1 Verifica che questo sia un contratto attivo per il quale RM Production è l’agente commissionario principale. Se il contratto non è attivo, la routine verifica che non esistano righe per questo contratto nella tabella tblCommissions e si arresta.

2 In base ai valori BeginningDate ed EndingDate del contratto, la routine costruisce un array interno che contiene la data di Lunedì in una settimana contrattuale e un altro array che contiene un flag per indicare se quella settimana esiste già nella tabella tblCommissions. La routine calcola anche l’ammontare della commissione per settimana.

3 La routine percorre tutte le righe esistenti per questo contratto, cercando le settimane corrispondenti. Se trova una settimana che non corrisponde, cancella la riga. Se trova una settimana che corrisponde, imposta il flag “found” e verifica che l’ammontare della commissione sia esatto.

4 Per ogni settimana nell’array calcolato che non trova nella tabella tblCommissions, la procedura costruisce unanuova riga.



Esempi di accesso ai dati con VBA Microsoft Access

Tutorials su Microsoft Access




Dr.Maurizio Cucchiara
autore del corso:
"Corso Base di Microsoft Access"
disponibile on line su questo sito
MC2 E-Learning S.a r.l.
Formazione per il Web
http://www.mc2.it/html/access.html


Cerca sul web con Google:


Google