Newsgroup: it.comp.appl.access
Titolo: Modificare una relazione da codice

Buongiorno a tutti,
ho un database strutturato con varie tabelle collegate fra loro. Fra queste ve ne sono due (Dipendenti e Mansione) legate fra loro in relazione uno-a-,molti (un Dipendente può avere una Mansione, una Mansione può appartenere a più Dipendenti). Ora mi è stato chiesto di modificare la relazione uno-a-molti in molti-a-molti, consentendo quindi la possibilità di assegnare più Mansioni allo stesso Dipendente.
Il progetto è già avviato da parecchio, quindi ci sono svariati records già inseriti, quindi io dovrei modificare tale relazione via codice (VBA), scrivendo una routine che effettui la modifica richiesta conservando i dati esistenti; i Dipendenti devono conservare la Mansione eventualmente già assegnatagli (non è obbligatoria) ma deve esserci anche la possibilità di aggiungerne altre.
La modifica della maschera di inserimento non mi preoccupa, dovrò aggiungere una sottomaschera per le Mansioni, ma non so come fare a modificare il BE (che ovviamente è separato dal FE).
Gli utenti usano Access 2010 o versioni successive (io sviluppo con Access 2019)
Grazie
Franco


non mi è chiaro perchè devi usare vba
non puoi semplicemente crearti una tabella DipendentiMansioni con campi 
IDMansione e IDDipendente messi in chiave primaria.
con una query di accodamento la popoli con iddipendente e idmansione gia 
presenti nella tabella dipendenti per non perdere le relazioni esistenti.
 
fatto questo dalla finestra di progettazione relazioni di access 
cancelli la relazione uno a molti tra dipendenti e mansioni e crei le due
dipendenti-->DipendentiMansioni
e
mansioni-->DipendentiMansioni
 
BFS

 mansioni-->DipendentiMansioni
 
immagino che il suo UCAS abbia dato qualche direttiva in tal senso :-) 
comunque la tua soluzione mi sembra semplice e pratica
 
-- 
/-\ /\/\ /\/\ /-\ /\/\ /\/\ /-\ T /-\
-=- -=- -=- -=- -=- -=- -=- -=- - -=-
........... [ al lavoro ] ...........


Grazie a tutti per la risposta, effettivamente sarebbe la soluzione più semplice, se io avessi accesso al BE, che è su server aziendale e utilizzato da più utenti.
Per questo ho pensato alla modifica del BE via codice, posso creare una nuova tabella in sql con CREATE TABLE ecc..., posso accodare i dati già presenti nella nuova tabella, però non conosco poi i comandi per modificare le relazioni, o meglio per eliminare la relazione esistente tra le tabelle Dipendenti e Mansioni e creare quelle tra le due tabelle menzionate e la nuova tabella appena creata.
Io ho già una routine che avvisa gli utenti attivi di scollegarsi per imminente manutenzione, dopo di che avvio la modifica del BE. Purtroppo ignoro i comandi adatti.
Saluti
Franco


RISOLTO
Girovagando in Internet sono riuscito a trovare i comandi che mi servivano ad effettuare le mie operazioni. Ho dovuto fare più step ma alla fine sono arrivato al risultato atteso, mischiando SQL e VBA.
Vi elenco i passaggi, se possono servire a qualcuno, o se invece qualcuno può suggerirmi una soluzione migliore.
1 - con due mie vecchie funzioni (PercorsoDB e NomeDB) che allego in basso raggiungo il BE in qualunque posto si trovi.
2 - creo la tabella intermedia TabPersonaleMansioni
    Set DBS1 = OpenDatabase(PercorsoDB("BE") & NomeDB("BE"))
    SQL1 = "CREATE TABLE TabPersonaleMansioni (PMID COUNTER PRIMARY KEY ); "
    DBS1.Execute SQL1
3 - aggiungo le due chiavi esterne
    SQL1 = "ALTER TABLE TabPersonaleMansioni ADD COLUMN ManID INTEGER, CONSTRAINT ManID FOREIGN KEY (ManID)  REFERENCES TabMansioni;"
    DBS1.Execute SQL1
    SQL1 = "ALTER TABLE TabPersonaleMansioni ADD COLUMN PerCID CHAR(10), CONSTRAINT PerCID FOREIGN KEY (PerCID)  REFERENCES TabPersonale;"
    DBS1.Execute SQL1
4 - copio i dati dalla TabPersonale.ManID nella nuova tabella creata TabPersonaleMansioni
    Set RST2 = DBS1.OpenRecordset("TabPersonale")
    Set RST3 = DBS1.OpenRecordset("TabPersonaleMansioni")
    RST2.MoveFirst
    Do While Not RST2.EOF
        If Not IsNull(RST2.Fields("ManID")) Then
            RST3.AddNew
            RST3.Fields("PerCID") = RST2.Fields("PerCID")
            RST3.Fields("ManID") = RST2.Fields("ManID")
            RST3.Update
        End If
        RST2.MoveNext
    Loop
5 - elimino la relazione tra le tabelle TabMansioni e TabPersonale, con VBA perché non ho trovato il rispettivo comando in SQL
    Call EliminaRelazioni("TabMansioni", "TabPersonale")               'funzione di Mirko Caporali trovata in questi giorni, che allego in basso
6 - elimino l'indice della tabella
    SQL1 = "DROP INDEX ManID ON TabPersonale;"
    DBS1.Execute SQL1
7 - elimino il campo ManID dalla tabella TabPersonale
    SQL1 = "ALTER TABLE TabPersonale DROP COLUMN ManID;"
    DBS1.Execute SQL1
 
Di seguito le tre funzioni
 
Function PercorsoDB(strQuale As String) As String
'restituisce il percorso del DB utilizzato
'strQuale = stabilisce se trovare il percorso del file Beck End o del file Front End
'valori ammessi per strQuale:
'BE = Beck End o server
'FE = Front End o client
'usa la libreria DAO
On Error GoTo Errore
    Dim DBS1 As DAO.Database
    Dim N As Integer
    Set DBS1 = CurrentDb
    Select Case strQuale
    Case "BE"   'file beck end
        For N = 0 To DBS1.TableDefs.count - 1
            If DBS1.TableDefs(N).Connect <> "" Then
                PercorsoDB = Mid(DBS1.TableDefs(N).Connect, 11)
                Exit For
            End If
        Next N
        Do While Right(PercorsoDB, 1) <> "\"
            PercorsoDB = Left(PercorsoDB, Len(PercorsoDB) - 1)
        Loop
    Case "FE"   'file front end
        PercorsoDB = DBS1.Name
        Do While Right(PercorsoDB, 1) <> "\"
            PercorsoDB = Left(PercorsoDB, Len(PercorsoDB) - 1)
        Loop
    End Select
Uscita:
    Set DBS1 = Nothing
    Exit Function
Errore:
    MiaMsgBox "Si è verificato il seguente errore:@N° " & Err.Number & " - " & Err.description & "@"
    Resume Uscita
End Function
 
Function NomeDB(strQuale As String, Optional bolEstensione As Boolean = True) As String
' Restituisce il nome del DB corrente
'strQuale = stabilisce se trovare il percorso del file Beck End o del file Front End
'valori ammessi per strQuale:
'   BE = Beck End o server
'   FE = Front End o client (valore di default)
'bolEstensione = determina se il nome dev'essere con o senza l'estensione
'Valori di bolEstensione:
'   VERO = con estensione (default)
'   FALSO = senza estensione
'usa la libreria DAO
On Error GoTo Errore
    Dim DBS1 As DAO.Database
    Dim intLunghezzaPercorso As Integer
    Dim strNomeEstensione As String
    Dim strSoloNome As String
    Dim strNomeCompleto As String
    Dim N As Integer
    Set DBS1 = CurrentDb
    Select Case strQuale
    Case "BE"
        For N = 0 To DBS1.TableDefs.count - 1
            If DBS1.TableDefs(N).Connect <> "" Then
                strNomeCompleto = Mid(DBS1.TableDefs(N).Connect, 11)
                Exit For
            End If
        Next N
        intLunghezzaPercorso = Len(PercorsoDB("BE"))
        strNomeEstensione = Right(strNomeCompleto, Len(strNomeCompleto) - intLunghezzaPercorso)
        strSoloNome = strNomeEstensione
        '
        Do While Right(strSoloNome, 1) <> "."
            strSoloNome = Left(strSoloNome, Len(strSoloNome) - 1)
        Loop
        strSoloNome = Left(strSoloNome, Len(strSoloNome) - 1)
        '
        If bolEstensione = True Then
            NomeDB = strNomeEstensione
        Else
            NomeDB = strSoloNome
        End If
    Case "FE"
        intLunghezzaPercorso = Len(PercorsoDB("FE"))
        strNomeEstensione = Right(DBS1.Name, Len(DBS1.Name) - intLunghezzaPercorso)
        strSoloNome = strNomeEstensione
        '
        Do While Right(strSoloNome, 1) <> "."
            strSoloNome = Left(strSoloNome, Len(strSoloNome) - 1)
        Loop
        strSoloNome = Left(strSoloNome, Len(strSoloNome) - 1)
        '
        If bolEstensione = True Then
            NomeDB = strNomeEstensione
        Else
            NomeDB = strSoloNome
        End If
    End Select
Uscita:
    Set DBS1 = Nothing
    Exit Function
Errore:
    MiaMsgBox "Si è verificato il seguente errore:@N° " & Err.Number & " - " & Err.description & "@"
    Resume Uscita
End Function
 
Function EliminaRelazioni(strTabella1 As String, strTabellaMolti As String)         'di Mirko Caporali
'elimina una relazione tra due tabelle
'strTabella1 = la tabella con l'indicazione univoca del valore (lato 1)
'strTabellaMolti = la tabella con più occorrenze del valore (lato Molti)
'usa la libreria DAO
    Dim DBS1 As DAO.Database
    Dim RLT1 As DAO.Relation
    Dim strParte1 As String
    Dim strParteMolti As String
    Dim strNomeRelazione As String
    ' Individua il nome della relazione da eliminare
    Set DBS1 = CurrentDb
    For Each RLT1 In DBS1.Relations
        ' Tabella parte 1
        strParte1 = RLT1.Table
        ' Tabella parte molti
        strParteMolti = RLT1.ForeignTable
        If strParte1 = strTabella1 And strParteMolti = strTabellaMolti Then
            ' Relazione trovata
            strNomeRelazione = RLT1.Name
            ' Elimina la relazione
            DBS1.Relations.Delete strNomeRelazione
        End If
    Next RLT1
End Function
 
Spero che possa tornare utile a qualcuno.
Saluti
Franco