Newsgroup: it.comp.appl.access
Titolo: aggiornamento access -> outlook

ciao a tutti!
Premesso che sto sperimentando e non so praticamente nulla di visual basic,
sto cercando di fare in modo che access prenda i contatti da una tabella e
il mandi ad outlook, smistandoli in ragione della tipologia dei medesimi. La
cosa funziona, ma al momento i contatti vengono creati nella cartella
"contatti" principale, mentre vorrei che li creasse in una sottocartella
specifica, o in alternativa li spostasse in un secondo momento: a questo
proposito il codice (per i contatti della categoria AGENTI) è il seguente:
Sub moveAGE()
Dim myOlApp As Outlook.Application
Dim myItem As ContactItem
Set myOlApp = CreateObject("Outlook.Application")
Set myNameSpace = myOlApp.GetNamespace("MAPI")
Set myContactFolder = myNameSpace.GetDefaultFolder(olFolderContacts)
Set myItems = myContactFolder.Items
Set myDestFolder = myContactFolder.Folders("AGENTI")
Set myItem = myItems.FindFirst
While TypeName(myItem) <> "Nothing"
    myItem.Move myDestFolder
    Set myItem = myItems.FindNext
Wend
End Sub
però non accade nulla..
qualcuno mi può aiutare? grazie mille

 ha scritto nel messaggio 
news:LHZ7e.67185$zZ1.1...@twister1.libero.it...

Direi che è un ottimo inizio.
Come suggerimento generale ti consiglio sempre di dichiarare tutte le 
variabili in modo che mentre digiti puoi controllare tutte le proprietà e 
tutti i metodi dell'oggetto che stai sperimentando.
Il tuo problema si verifica perché per inserire dati in cartelle non 
predefinite occorre utilizzare i metodi Add e Save dell'insieme Items.
Eccoti un esempio da inserire in un modulo Access:
Sub moveAGE()
'dichiarazione delle variabili
    Dim myOlApp As Outlook.Application
    Dim myNameSpace As Outlook.NameSpace
    Dim myFolder As Outlook.MAPIFolder
    Dim myItems As Outlook.ContactItem
'creazione dei riferimenti
    Set myOlApp = CreateObject("Outlook.Application")
    Set myNameSpace = myOlApp.GetNamespace("MAPI")
    Set myFolder = 
myNameSpace.GetDefaultFolder(olFolderContacts).Folders("AGENTI")
    Set myItems = myFolder.Items.Add
'definizione del nuovo contatto
    With myItems
        .FirstName = "paolino"
        .LastName = "paperino"
        .Email1Address = "p.pap...@paperopoli.pap"
        .Save
    End With
'liberazione delle risorse (è quasi il 25 aprile...)
    Set myOlApp = Nothing
    Set myNameSpace = Nothing
    Set myFolder = Nothing
    Set myItems = Nothing
End Sub
Per automatizzare l'inserimento dovrai sostituire al blocco "definizione del 
nuovo contatto" del codice capace di leggere i dati dalla tabella di origine 
che contiene gli agenti (che purtroppo non so come è fatta).
Supponendo che tu abbia una tabella tblAgenti con Nome, Cognome, Mail il 
blocco di codice che inserisce tutti i nomi della tabella nei contatti di OL 
sarà così (sostituisci questo a tutto il blocco "definizione del nuovo 
contatto"):
'definizione del nuovo contatto
    Dim rstAgenti As New ADODB.Recordset
    rstAgenti.Open "tblAgenti", CurrentProject.Connection, , , adCmdTable
    With rstAgenti
        Do Until .EOF
            myItems.FirstName = .Fields("Nome")
            myItems.LastName = .Fields("Cognome")
            myItems.Email1Address = .Fields("Mail")
            .MoveNext
        Loop
        .Close
    End With
E' solo un inizio: tutto dipende da come è fatta la tabella di origine, se 
va bene così com'è, se deve essere filtrata da una query, ecc.
Buona sperimentazione.
Se invece desideri spostare gli elementi dopo che sono stati creati, puoi 
simulare una regola da vba tramite l'evento ItemAdd di Outlook (studialo 
dalla guida in linea), ma le cose si complicano un bel po' perchè devi 
creare codice su Outlook con annessi problemi se dovrai distribuire 
l'applicazione.
vtt

> [CUT]

ciao vtt, innanzitutto grazie mille per il tuo prezioso aiuto: stavo
iniziando a disperare..
 mi scuso in anticipo se sarò un pò prolisso..
sto provando a modificare il tuo codice, x ora non mi genera i contatti, ma
non mollo! :)
se non ho capito male mi suggerisci di "esportare" i contatti direttamente
nella cartella di destinazione, piuttosto che in quella principale e poi
spostarli: seguirò senz'altro il tuo consiglio.
riassumedo:
1) ho fatto n sub (per ciascuna categoria di contatti) preposte
all'eliminazione della cartella già esistente in outlook, ad esempio (per
gli agenti nazionali):
Sub delFldAGEITA()
Dim myOlApp As Outlook.Application
    Set myOlApp = CreateObject("Outlook.Application")
    Set myNameSpace = myOlApp.GetNamespace("MAPI")
    Set myFolder = myNameSpace.GetDefaultFolder(olFolderContacts)
    Set myOldFolder = myFolder.Folders("AGENTI_ITALIA")
    myOldFolder.Delete
End Sub
2) poi altre n che si occupano di crearne di nuove:
Sub mkFldAGEITA()
Dim myOlApp As Outlook.Application
    Set myOlApp = CreateObject("Outlook.Application")
    Set myNameSpace = myOlApp.GetNamespace("MAPI")
    Set myFolder = myNameSpace.GetDefaultFolder(olFolderContacts)
    Set myNewFolder = myFolder.Folders.Add("AGENTI_ITALIA")
End Sub
3)infine, attraverso una query di eliminazione e una di accodamento alla
tabella "contatti", quest'ultima viene riempita con i contatti scelti di
volta in
volta, e a questo pt la terza sub si occupava di "esportarli" nella cartella
di default dei contatti di outlook("Contatti"):
Sub createAGEITA()
Dim myOlApp As Outlook.Application
Dim myItem As ContactItem
Dim rst1 As New Recordset
'   apre cartella Contatti in Outlook.
    Set myOlApp = CreateObject("Outlook.Application")
'   apre la tabella con i contatti da esportare
With rst1
    .ActiveConnection = CurrentProject.Connection
    .Open "contatti"
End With
'   esporta i contatti nella cartella principale Contatti di Outlook
  Dim rst1 As New ADODB.Recordset
    rst1.Open "contatti", CurrentProject.Connection, , , adCmdTable
    With rst1
        Do Until .EOF
    Set myItem = myOlApp.CreateItem(olContactItem)
    With myItem
        .FirstName = IIf(IsNull(rst1.Fields(1)), "", rst1.Fields(1))
        .CompanyName = IIf(IsNull(rst1.Fields(3)), "", rst1.Fields(3))
        .JobTitle = IIf(IsNull(rst1.Fields(4)), "", rst1.Fields(4))
        .BusinessAddressStreet = IIf(IsNull(rst1.Fields(5)), "",
rst1.Fields(5))
        .BusinessAddressCity = IIf(IsNull(rst1.Fields(8)), "",
rst1.Fields(8))
        .BusinessAddressPostalCode = IIf(IsNull(rst1.Fields(10)), "",
rst1.Fields(10))
        .BusinessAddressCountry = IIf(IsNull(rst1.Fields(11)), "",
rst1.Fields(11))
        .BusinessTelephoneNumber = IIf(IsNull(rst1.Fields(28)), "",
rst1.Fields(28))
        .BusinessFaxNumber = IIf(IsNull(rst1.Fields(27)), "",
rst1.Fields(27))
        .HomeTelephoneNumber = IIf(IsNull(rst1.Fields(34)), "",
rst1.Fields(34))
        .MobileTelephoneNumber = IIf(IsNull(rst1.Fields(37)), "",
rst1.Fields(37))
        .Email1Address = IIf(IsNull(rst1.Fields(65)), "", rst1.Fields(65))
        .Email2Address = IIf(IsNull(rst1.Fields(67)), "", rst1.Fields(67))
        .Categories = IIf(IsNull(rst1.Fields(83)), "", rst1.Fields(83))
        .Save
    End With
    rst1.MoveNext
Loop
End Sub
se non ho capito male te ne hai fatta una di alternativa a questa: l'ho
adattata al mio db e il risultato è questo:
Sub createAGEITA()
'dichiarazione delle variabili
    Dim myOlApp As Outlook.Application
    Dim myNameSpace As Outlook.NameSpace
    Dim myFolder As Outlook.MAPIFolder
    Dim myItems As Outlook.ContactItem
'creazione dei riferimenti
    Set myOlApp = CreateObject("Outlook.Application")
    Set myNameSpace = myOlApp.GetNamespace("MAPI")
    Set myFolder =
myNameSpace.GetDefaultFolder(olFolderContacts).Folders("AGENTI_ITALIA")
    Set myItems = myFolder.Items.Add
'definizione del nuovo contatto
    Dim rst1 As New ADODB.Recordset
    rst1.Open "contatti", CurrentProject.Connection, , , adCmdTable
    With rst1
        Do Until .EOF
            myItems.FirstName = .Fields("Nome")
            myItems.CompanyName = .Fields("Società")
            myItems.JobTitle = .Fields("Posizione")
            myItems.BusinessAddressStreet = .Fields("Viauff")
            myItems.BusinessAddressCity = .Fields("Cittàuff")
            myItems.BusinessAddressPostalCode = .Fields("CAPuff")
            myItems.BusinessAddressCountry = .Fields("Paeseuff")
            myItems.BusinessTelephoneNumber = .Fields("Ufficio")
            myItems.BusinessFaxNumber = .Fields("Faxuff")
            myItems.HomeTelephoneNumber = .Fields("Abitazione")
            myItems.MobileTelephoneNumber = .Fields("Cellulare")
            myItems.Email1Address = .Fields("Indirizzopostaelettronica")
            myItems.Email2Address = .Fields("Indirizzopostaelettronica2")
            myItems.Categories = .Fields("Categorie")
            .MoveNext
        Loop
        .Close
    End With
'liberazione delle risorse (25 aprile)
    Set myOlApp = Nothing
    Set myNameSpace = Nothing
    Set myFolder = Nothing
    Set myItems = Nothing
End Sub
questa purtroppo non mi genera i contatti desiderati. sto sicuramente
sbagliando da qualche parte, ma non riesco a capire dove..

 ha scritto nel messaggio 
news:S0S8e.52353$IN.9...@twister2.libero.it...

Niente di grave: colpa mia.
Nel passaggio da Paolino Paperino al recordset rst1 ho dimenticato il metodo 
Save, che come suggerisce il nome serve a salvare tutta la baracca.
devi aggiungere: myItem.Save prima di .MoveNext.
Tutto funzionerà a meraviglia: provata personalmente! Sorry.
Mi servono però alcuni chiarimenti perché forse sono percorribili altre 
strade più lineari.
Primo:
in 1) e 2) cancelli e ricrei la cartella Contatti\AGENTI_ITALIA. Perché? 
Probabilmente vuoi resettare il suo contenuto.
Secondo:
in 3) non capisco bene come agiscono le query di eliminazione e accodamento: 
cosa e dove eliminano? cosa e dove accodano?
Ciao
vtt 

 ha scritto nel messaggio 
news:S0S8e.52353$IN.9...@twister2.libero.it...

Mi ricorreggo:
myItems.Save
vtt 


ciao vtt, grazie ancora. verso sera apporterò la correzione da te suggerita.
la accoppiata di sub 1 e 2 eliminano ciascuna cartella e la ricreano proprio
per il motivo che te sospetti (resettarne il contenuto);
la query di eliminazione e quella di accodamento mi servono a svuotare e
riempire una tabella (che ho chiamato Contatti, e possiede la stessa
struttura del foglio xls ottenuto esportando i contatti da outlook) che uso
solo per eseguire l'aggiornamento di outlook prendendo i dati dalla tabella
di origine che li contiene: molto macchinoso, probabilmente potrei filtrare
i dati con una sola query ed evitarmi le 2 query (di eliminazione e di
accodamento) e la tabella contatti temporanea..
grazie mille intanto, stasera ti faccio sapere come è andata!


ciao vtt, ti spiacerebbe inviarmi il codice che a te funziona, modificando
il mio come da te suggerito non funziona.
se adatto il tuo alle mie tabelle forse è meglio.. altrimenti non ne esco
piu!
ciao e grazie


Come avrai notato la mia presenza è un po' intermittente, ma l'importante è
risolvere il problema.
Per prima cosa dimmi se la routine più semplice, quella con Paolino
Paperino, funziona. Se così non è il problema sta a monte...
Nella routine precedente ho comunque commesso un'altra imperfezione, 
sbagliando la posizione del metodo Add, ma avrebbe comunque dovuto 
funzionare inserendo un solo nuovo contatto anziché tutti.
Innanzitutto ho creato manualmente una tabella 'contatti' con i campi che ti
interessa inserire.
Questa tabella è appunto caratterizzata dai campi testo:
Nome, Società, Posizione, Viauff, Cittàuff, CAPuff, Paeseuff, Ufficio,
Faxuff, Abitazione, Cellulare, Indirizzopostaelettronica,
Indirizzopostaelettronica2, Categorie
e dovrebbe quindi essere uguale alla tua. Tieni presente che se preferisci i 
riferimenti numerici tipo.Fields(n) va bene lo stesso.
Tramite il seguente codice in un modulo di Access, tutti i nominativi
contenuti in tabella vengono trasferiti nella sottocartella
Contatti\AGENTI_ITALIA di Outlook (che deve però già essere stata creata).
Sub createAGEITA()
'dichiarazione delle variabili
   Dim myOlApp As Outlook.Application
   Dim myNameSpace As Outlook.NameSpace
   Dim myFolder As Outlook.MAPIFolder
   Dim myItems As Outlook.ContactItem
   Dim rstContatti as New ADODB.Recordset
   Set myOlApp = CreateObject("Outlook.Application")
   Set myNameSpace = myOlApp.GetNamespace("MAPI")
   Set myFolder = 
myNameSpace.GetDefaultFolder(olFolderContacts).Folders("AGENTI_ITALIA")
'inserimento dei nuovi contatti
   rstContatti.Open "contatti", CurrentProject.Connection, , , adCmdTable
   With rstContatti
       Do Until .EOF
           Set myItems = myFolder.Items.Add
           myItems.FirstName = .Fields("Nome")
           myItems.CompanyName = .Fields("Società")
           myItems.JobTitle = .Fields("Posizione")
           myItems.BusinessAddressStreet = .Fields("Viauff")
           myItems.BusinessAddressCity = .Fields("Cittàuff")
           myItems.BusinessAddressPostalCode = .Fields("CAPuff")
           myItems.BusinessAddressCountry = .Fields("Paeseuff")
           myItems.BusinessTelephoneNumber = .Fields("Ufficio")
           myItems.BusinessFaxNumber = .Fields("Faxuff")
           myItems.HomeTelephoneNumber = .Fields("Abitazione")
           myItems.MobileTelephoneNumber = .Fields("Cellulare")
           myItems.Email1Address = .Fields("Indirizzopostaelettronica")
           myItems.Email2Address = .Fields("Indirizzopostaelettronica2")
           myItems.Categories = .Fields("Categorie")
           myItems.Save
           .MoveNext
       Loop
       .Close
   End With
'liberazione delle risorse (25 aprile)
   Set myOlApp = Nothing
   Set myNameSpace = Nothing
   Set myFolder = Nothing
   Set myItems = Nothing
End Sub
Poiché adesso funziona tutto passiamo alle cose un po' più avanzate (eh eh 
eh)...
Anziché la tabella contatti, che se non sbaglio contiene tutti i contatti
della cartella contatti di Ol (bella filastrocca!), ti consiglio caldamente 
di creare
la seguente query SQL che chiamerai qryContatti (copiala e incollalla senza
alcun adattamento facendo attenzione che sia su una sola riga):
SELECT * FROM [Contatti] IN 'C:\'[Outlook 9.0;MAPILEVEL=Cartelle 
personali|];
Questa query, un po' più veloce, presenta il vantaggio che può essere 
personalizzata a tuo piacimento con dei criteri di filtro dalla 
visualizzazione struttura; ad esempio ti farà vedere solo i contatti 
italiani o di un dato paese o con determinati campi non nuli, ecc. ecc.
Ti permette inoltre di effettuare cancellazioni dirette.
Ovviamente dovrai correggere tutto il recordset rstContatti (ex rst1) sia 
nel metodo Open, sia nei metodi Fields.
A questo punto mi chiedo però se non valga la pena  di creare una 
automazione di Access da Outlook (e non viceversa come in questi esempi) in 
modo da fare tutto da Ol stesso oppure eliminare Access ed analizzare i dati 
senza la creazione di recordset (diventeremo però molto OT per questo 
newsgroup e non so se ci sarà permesso di continuare questa chiacchierata 
pubblica).
Il tutto dipende se la tua soluzione deve essere distribuita in altre 
macchine, magari senza Access installato.
Ma affrontiamo le cose una per volta.
Buon lavoro
vtt

> [CUT]

ciao vtt, funziona alla grande! non puoi immaginare la felicità!... :)
per quanto riguarda la tabella Contatti, questa è una tabella che uso di
volta in volta per esportare i contatti in outlook; tutti i contatti, in
realtà, si trovano in un'altra tabella, (TUTTI_contatti) la quale accoglie i
contatti per ogni categoria (CLIENTI, FORNITORI, PARTNERS, VARIE). in
pratica il processo è il seguente:
1. la query q_cont_elim elimina il contenuto della tabella Contatti;
2. le queries q_cont_CLI, q_cont_FORN, ecc accodano alla tabella Contatti i
contatti di volta in volta selezionati;
3. la routine che mi hai inviato (adattata per ciascuna categoria, e che
riporto qui di seguito) esporta i contatti accodati al punto 2 alla
cartella di outlook corrispondente.
Sub createAGEITA()
'dichiarazione delle variabili
   Dim myOlApp As Outlook.Application
   Dim myNameSpace As Outlook.NameSpace
   Dim myFolder As Outlook.MAPIFolder
   Dim myItems As Outlook.ContactItem
   Dim rst1 As New ADODB.Recordset
   Set myOlApp = CreateObject("Outlook.Application")
   Set myNameSpace = myOlApp.GetNamespace("MAPI")
   Set myFolder =
myNameSpace.GetDefaultFolder(olFolderContacts).Folders("AGENTI ITALIA")
'inserimento dei nuovi contatti
   rst1.Open "contatti", CurrentProject.Connection, , , adCmdTable
   With rst1
       Do Until .EOF
           Set myItems = myFolder.Items.Add
           myItems.FirstName = IIf(IsNull(rst1.Fields("Nome")), "",
rst1.Fields("Nome"))
           myItems.CompanyName = IIf(IsNull(rst1.Fields("Società")), "",
rst1.Fields("Società"))
           myItems.JobTitle = IIf(IsNull(rst1.Fields("Posizione")), "",
rst1.Fields("Posizione"))
           myItems.BusinessAddressStreet =
IIf(IsNull(rst1.Fields("Viauff")), "", rst1.Fields("Viauff"))
           myItems.BusinessAddressCity =
IIf(IsNull(rst1.Fields("Cittàuff")), "", rst1.Fields("Cittàuff"))
           myItems.BusinessAddressPostalCode =
IIf(IsNull(rst1.Fields("CAPuff")), "", rst1.Fields("CAPuff"))
           myItems.BusinessAddressCountry =
IIf(IsNull(rst1.Fields("Paeseuff")), "", rst1.Fields("Paeseuff"))
           myItems.BusinessTelephoneNumber =
IIf(IsNull(rst1.Fields("Ufficio")), "", rst1.Fields("Ufficio"))
           myItems.BusinessFaxNumber = IIf(IsNull(rst1.Fields("Faxuff")),
"", rst1.Fields("Faxuff"))
           myItems.HomeTelephoneNumber =
IIf(IsNull(rst1.Fields("Abitazione")), "", rst1.Fields("Abitazione"))
           myItems.MobileTelephoneNumber =
IIf(IsNull(rst1.Fields("Cellulare")), "", rst1.Fields("Cellulare"))
           myItems.Email1Address =
IIf(IsNull(rst1.Fields("Indirizzopostaelettronica")), "",
rst1.Fields("Indirizzopostaelettronica"))
           myItems.Email2Address =
IIf(IsNull(rst1.Fields("Indirizzopostaelettronica2")), "",
rst1.Fields("Indirizzopostaelettronica2"))
           myItems.Categories = IIf(IsNull(rst1.Fields("Categorie")), "",
rst1.Fields("Categorie"))
           myItems.Save
           .MoveNext
       Loop
       .Close
   End With
'liberazione delle risorse
   Set myOlApp = Nothing
   Set myNameSpace = Nothing
   Set myFolder = Nothing
   Set myItems = Nothing
End Sub
ora che la cosa funziona mi chiedo se non sia possibile far cercare alla sub
in queries che filtrino i contatti contenuti nella tabella TUTTI_cont (già
esistenti e che già utilizzo per altri scopi), anzichè nella tabella
Contatti: questo mi consentirebbe di saltare la fase 1. e 2., e di eliminare
svariate queries e la tabella Contatti... è possibile fare ciò??
ho provato a creare la qryContatti come da te suggerito, ma access mi da
errore...
ps: preferirei tenere la procedura in access, anzichè in outlook
ancora grazie di cuore per il tuo aiuto!

 ha scritto nel messaggio 
news:J1cae.60030$IN.10...@twister2.libero.it...

Wow, problema risolto! Bisogna festeggiare!
Ma non esageriamo: la strada all'ottimizzazione è ancora lunga...
1) qryContatti
serve solo se le tabelle di Access sono create a partire da Outlook.
gli errori sono normalmente dovuti alla sintassi, quindi oltre il copia e 
incolla e la conversione in riga unica controlla anche la presenza dello 
spazio tra 'Cartelle' e 'personali' (la sfiga è che nel messaggio va 
automaticamente a capo lì).
Se vuoi accedere direttamente ad una 'Sottocartella' tramite query usa 
questa variante:
SELECT * FROM [Sottocartella] IN 'C:\'[Outlook 9.0;MAPILEVEL=Cartelle
personali|Contatti];
Credo che tramite questo tipo di query tu possa già fare una serie di 
operazioni di filtraggio (dalla visualizzazione struttura) tali da evitare 
il processo di esportazione che, perdonami, non ho ancora capito bene (vedi 
3).
2) perchè sostituisci il campo nullo con una stringa vuota?
se vuoi evitare le generazione dell'errore 94 è più corretto utilizzare un 
trap degli errori.
Modifica la routine funzionante in questo modo:
Sub createAGEITA()
On Error GoTo ErroriMaledetti
   'dichiarazione delle variabili
   ...
   Set myItems = Nothing
Exit Sub
ErroriMaledetti:
   'valore nullo non consentito
   If Err.Number = 94 Then Resume Next
End Sub
3) Verifica se ho capito: devi essere paziente...
a. hai una tabella di Access chiamata TUTTI_contatti, esistente per i fatti 
suoi, con struttura analoga alla esportazione in Excel, ma che non ha nulla 
a che vedere con Outlook e che quindi non viene costruita da dati contenuti 
in esso.
b. la tabella TUTTI_contatti possiede un campo utile alla loro 
classificazione (es: Categoria che contiene i valori CLIENTI, FORNITORI, 
PARTNERS, VARIE, ecc.)
c. a seconda di determinate caratteristiche vuoi esportare un sottoinsieme 
di TUTTI_contatti in Outlook (i contatti che esporti devono anche essere 
cancellati da TUTTI_contatti? mi sembra di no).
d. per effettuare l'esportazione utilizzi alcune query che riempono una 
tabella di Access chiamata Contatti.
e. vuoi però anche resettare le sottocartelle specifiche di Outlook quando 
inserisci i nuovi contatti. in questo caso mi sembrà però più semplice 
creare un recordset rst1 ad hoc che si occupa della esportazione diretta da 
TUTTI_contatti che funziona come q_cont_CLI, q_cont_FORN. (se mi mandi l'sql 
di queste possiamo vedere come creare rst1)
Da questa avventura entrambi ne sapremo molto di più di Access&Outlook.
vtt 


indubbiamente!! : )
ciao a presto