Newsgroup: it.comp.appl.access
Titolo: E' possibile costruire moduli esterni al DB ? Ossia :

E' possibile, in un certo vba di un dato DB Access, richiamare
direttamente funzioni o procedure che  risiedono in  altri  DB 
Access ? Se si, come si dovrebbe procedere ? 
 
Con "direttamente" intendo  senza  artifici  come aprire il DB
esterno,  chiamare  una  form  e  fargli eseguire  la sub o la 
function nelle modalita' che conosciamo. 
 
Ossia intendo qualcosa come : 
if x > 0 then 
  e =  DBESTERNO(...).miafunzione(x) 
endif
 
Grazie   
 
 
 

Si... basta inserire il DB_EXT nei Riferimenti del DB... e puoi usarlo come fosse una Lib esterna.
 
Attenzione ai Moduli di Classe che vanno modificati esportandoli in TXT, si modifica un Parametro che consente di Esporre la Classe, e si reimportano.
 
@Alex

 e si reimportano.
 
Eh ? 
Per ora m' accontenterei dei moduli normali :-)


Tanto lui le classi non le usa ;-)
 
-- 
ac (x=y-1)
Aborro il Killfile
(La violenza e' l'ultimo rifugio degli incapaci -Salvor Hardin-)
 
---
Questa e-mail è priva di virus e malware perché è attiva la protezione avast! Antivirus.
http://www.avast.com
 
 

Che ne so io come lo hai chiamato... devi immaginare che il FILE MDB con i Moduli sia una Libreria, quindi lo vai a cercare e lo inserisci...
 
Una volta inserito ti appare il Modello Oggetti con i Metodi e Properietà, Oggetti ecc...
 
@Alex

 Proprietà, Oggetti ecc...
 
Si, perfetto. Ma come si fa ad inserire un mio DB tra le librerie ?
Non l' ho mai fatta una cosa del genere. 
 
 

 Tanto lui le classi non le usa ;-)
 
Ora le uso
 
 
 

Quello stranissimo Pulsante SFOGLIA ti tice nulla...?
 
@Alex 


good allora tieni in buon conto il suggerimento.


 Quello stranissimo Pulsante SFOGLIA ti tice nulla...?
 
Scusa ... quale pulsante sfoglia ? 
 
Io ho un certo  DB  access A che devo inserire nella libreria dei 
riferimenti di un altro DB access B. Ok ? Immagino  dovro' quindi
copiare  questo DB A  in un certo percorso. 
 
Credo almeno.  O no ? E quale e' questo percorso ? 
 

 good allora tieni in buon conto il suggerimento.
 
Ok
 
 

radica...@gmail.com
 has brought this to us :

Ma non ti sei ancora accorto che @Alex e Alessandro sono
come il Gatto e la Volpe?
Ti prospettano fantasiose soluzioni esotiche, poi ti lasciano lì,
a mezza via... coitus interruptus.
 
È come la storia dei Moduli di Classe dei quali discutemmo
(o ci fu anche una dichiarazione di guerra? non ricordo...)
anni addietro, dove io, canuto artigiano aduso a lavorar
con mani e piedi, sostenevo che non servivano un cazzo,
ovvero - più correttamente - che le stesse cose si potevano
fare altrettanto bene usando per l'appunto mani e piedi.
 
Quella di metter un database esterno nelle References
mi par cosa di stessa natura e funzione.
 
Un saluto a tutti, anche a quel vecchio volpone di @Alex che,
bontà sua, ogni tanto ci diletta del suo uscir dal letargo.
 
Bruno

 
 
Ricambio i saluti
 
 
 

 good allora tieni in buon conto il suggerimento.
 
Vorrei  chiederti : sto  cercando  un modo per costruire una classe che
intercettando gli errori possa validamente sostituire la gestione degli
errori (piuttosto involuta) del vba.
 
Ma  non sembra sia possibile. Mi  sbaglio ? Spero di si perche' sarebbe
una manna dal cielo poterla fare. 
 
 
 

 Bruno
 
Ciao Bruno
 
@Alex

 Su questo concordo pienamente...
 
Perdonami : 
se  prima (come invece dice Campanini) non mi stavi sfottendo
ebbene mi piacerebbe davvero sapere come inserire in libreria
un DB access. E' interessante.
 
se  invece mi stavi sfottendo beh ... diciamo che ti diverti
con poco, beato te ;-) 
 


Ma sant'iddio radicale. Sul menu' del codice hai una entrata 
"Riferimenti". Quello che hai li sono tutte "librerie" che ti possono 
servire se hai esigenza di qualche "modulo" particolare.
E ci sono sempre "riferimenti" collegati.
Ora attraverso quel menu' cercati il DB esterno e collegalo come fosse 
una "libreria" a quel punto tutto cio' che e' definito in quel /tuo/ DB 
esterno ti e' visibile.


 fare altrettanto bene usando per l'appunto mani e piedi.
 
Su questo continuiamo a non intenderci. Qualsiasi cosa si puo' fare 
usando il pallottoliere (e di questo radicale sa tutto visto che e' il 
soprannome che mi ha dato).
Se dall'uso del pallottoliere pero' riesci a desumere modi piu' "puliti" 
ed "esaustivi" e' il valore aggiunto che si da.
Scommetto che le funzioni le usi. Perche'? A che servono? visto che se 
ne puo' tranquillamente fare a meno!
Perche' usare anche le mani quando basterebbero solo i piedi?
 
E comunque usando le classi certe cose si fanno "meglio" come certe cose 
si fanno meglio usando le "funzioni" (rispetto a non usarle)
 
Ma come diceva un saggio ognuno e' padrone di eleggere modi e tempi 
della propria distruzione.


 con poco, beato te ;-)
 
Prima non stavo sfottendoti, ma ora decisamente si e lo meriti, e ti assicuro che mi diverto veramente con pochissimo... quindi immagina quanto mi sto divertendo ora...
 
@Alex

 immagina quanto mi sto divertendo ora...
 
Beh, vediamo il lato positivo : almeno ti faccio divertire :D 
 
 

 esterno ti e' visibile.
 
Ahem ... :D 
Si. 
 
Scusate. Vi ringrazio molto per la pazienza. Davvero.
 
 

 un DB access. E' interessante.
 
1 - Manualmente
VBE ==> References ==> Browse: scegli il file
        che vuoi inserire nelle librerie.
 
 
2 - Via VBA:
    Private Sub Command15_Click()
        Dim i As Reference
        For Each i In Application.References
            If i.Name = "MyDB" Then
                Exit Sub
            End If
        Next
        Application.References.AddFromFile _
        "D:\Access\MDB\MyDB.accdb"
    Exit Sub
 
Bruno

Bruno Campanini presented the following explanation :

Dimanticavo, per eliminare la Reference:
=============================
Private Sub Command28_Click()
Dim i As Reference
For Each i In Application.References
    If i.Name = "MyDB" Then
        GoTo RemoveRef
    End If
Next
 
Exit Sub
RemoveRef:
    Application.References.Remove i
End Sub
===============================
 
Bruno

 
 
Chiarissimo, grazie mille anche a te. 
 

 Beh, vediamo il lato positivo : almeno ti faccio divertire :D
 
Ridere è il termine più adeguato... ma il mio è solo sarcasmo.
 
@Alex


Non so quale sia il tuo obiettivo.
Non mi sono mai posto il problema piu' di tanto.
Normalmente, quando mi serve gestire l'errore, uso la forma con resume 
next che consente di evitare salti incondizionati e gestire /inline/ 
l'errore o chiamando una funzione/classe a cui passo l'oggetto err.



Ti chiedo scusa. Davvero. 

 Non mi sono mai posto il problema piu' di tanto.
 
Va bene, se ti va di pensarci un attimo fammi sapere.

On Friday, November 7, 2014 3:02:57 PM UTC+1, Bruno Campanini wrote:

Fatto.
Solo che non ho capito come si deve fare per chiamare 
una funzione scritta nel modulo X del DB A cosi' referenziato
quando programmo  in un modulo Y del DB B che referenzia A.
 
Ossia : ok, ho referenziato il DB A *dal* DB B. Ora il DB B
"vede" il DB A. 
 
In un modulo del DB B mi serve chiamare una funzione che 
sta nel modulo X del DB A. 
 
Come cavolo devo fare ? :-) 

After serious thinking 
radica...@gmail.com
 wrote :

Fa' quel che faresti se la dovessi chiamare dal DB A.
 
Bruno


 
se il nome e' unico non devi fare nulla la chiami e basta se il nome e' 
/duplicato/, come si fa di solito, si premette il nome della libreria.
 
se tu hai la libreria ADO e la libreria DAO e se queste hanno oggetti di 
nome uguali li chiami prefissando, appunto, con ADO. o con DAO.
se hai una sola libreria chiami l'oggetto (come di solito si fa) punto.


 che e' piuttosto involuto.
 
mi pare di aver scritto che uso "on error resume next" e non "on error 
go to label" e quindi il normale /trapping/ me lo faccio io (quando mi 
serve).
 
Per intercettare l'errore si deve scendere a livello piu' basso.
Qui l'unico che si e' cimentato con questo problema (cioe' scendere a 
livello piu' basso)  e' @Alex.
Fare una classe (o quello che e') come dici tu e' riproporre pari pari 
il problema perche' /generalizzare/ quella classe significa sapere come 
e dove e perche' e quando  si e' verificato l'errore e come ben sai 
talvolta gli errori possono /quasi/ essere voluti dalla logica 
dell'applicazione.
Sugli errori di /sistema/ ritengo inoltre /molto/ complicato 
intervenire, anzi inutile.



Non la vede. Nel DB B non vede la funzione del DB A.
Devo riferirmi ad A in qualche modo o nisba.
 
 

Il 07/11/2014 18:52, Alessandro Cara ha scritto:
ps
se il nome e' duplicato (se non erro) non e' che non lo faccia. Prende 
il primo nome in elenco, cioe' l'oggetto della prima libreria che lo 
contiene secondo l'ordine assegnato nei riferimenti.
Su questa cosa si sono "scrociati" /nel tempo/ parecchi utenti del NG.


Il 07/11/2014 18:52, Alessandro Cara ha scritto:
pps: la /roba/ deve essere definita come "public" (sempre se non erro e 
se ricordo adeguatamente)


Il giorno venerdì 7 novembre 2014 18:38:18 UTC+1, Bruno Campanini ha scritto:

Ok, funziona. Ma la devo dichiarare pubblica. 
 

 intervenire, anzi inutile.
 
mh

 errore e la linea dove s'e' verificato
 
Il tuo problema non e' quindi l'errore in se ma il nome funzione e il 
numero di riga. Per fare questo c'e' della roba in giro sul web. Anche 
su "accessgroup" (credo). Dovrebbe, inoltre,  esserci fra i vecchi post 
piu' di un 3d sull'argomento, prova a cercare sui messaggi di questo NG, 
le parole chiave di ricerca immagino te le sappia inventare.
 
Se non ricordo male c'e' necessita' di "collegare" una libreria che 
contiene del codice per poter fare quello che chiedi.


 Per fare questo c'e' della roba in giro sul web. 
 
Gia' lo faccio, ma e' laborioso. Ok, cerchero' di guardare in 
giro secondo i tuoi suggerimenti comunque. 
 
Grazie

 se ricordo adeguatamente)
 
Si esatto

Non so se questo ESEMPIO può essere utile a capire come Ereditare EVENTI di Oggetti... vedete voi:
 
http://forum.masterdrive.it/access-79/events-tracer-69222/
 
 
Saluti
@Alex

 
http://forum.masterdrive.it/access-79/events-tracer-69222/
 
 
Grazie, ma ...
mi  son sempre chiesto perche' mai il VBA non abbia una classe sua, 
diciamo "nativa"  (passatemi l' espressione) e ricca di info e dati
per intercettare gli errori nel codice e che possa essere esplorata 
dal programmatore.
 
Non so, magari commetto qualche errore logico di fondo.
 
 
 

Il VBA non ha errori da gestire.
Gli errori sono legati alle SUB/FUNCTION/CLASSI ed OGGETTI, o meglio agli eventi che gli Oggetti generano.
Una Classe GENERICA non ha nemmeno senso di essere nominata... in se.
 
Se guardi infatti nelle Librerie le Classi ERROR esistono ma associate ad Oggetti...
 
Class Errors
    Membro di ADODB
 
Class Error
    Membro di ADODB
 
Property Errors As Errors
    sola lettura
    Membro di ADODB.Connection
 
Class Error
    Membro di DAO
 
Class ErrObject
    Membro di VBA
 
Class MacroError
    Membro di Access
 
 
Ecc... ed "ecc" significa che questo è il motivo per cui la domanda non è da fare.
 
Saluti
@Alex

 Il VBA non ha errori da gestire.
 
Affermazione un po' ambigua. In che senso il "VBA" ? 

La  domanda si  puo'  fare  invece,  dal momento che gli errori (tutti
quegli errori o meglio quelle "fonti" di errore  che  hai  giustamente
elencato) vengono  intercettate  se  si "accende" il trapping  tramite
l'istruzione "on error" (nelle sue varie accezioni).
 
Quindi, anche se non  conosco  i  dettagli della cosa, ho abbastanza buon
senso per poter tranquillamente asserire che, anche se piuttosto involuta,
un "qualcosa" che fa da "centro di smistamento" di tutte le fonti di errore
e a cui e' possibile accedere per  vedere che errore s' e' verificato c'e' 
GIA'. 
 
E quindi eccome se ha senso.


Ma no.... cosa stai dicendo...!
Oggetti specifici con errori specifici... non esiste una PIZZA CAPRICCIOSA per gli errori...!
 
Quello che tu definisci ON ERROR è solo una parte del problema, nel senso che dirotta l'errore che viene generato dalle istruzioni nella SUB/FUNCTION all'interno della Sub/Function stessa...
Esiste anche l'Evento OnError di Form, se vogliamo dirla tutta, e non si intercetta con On Error da nessuna parte...!
Se poi vuoi realizzare una gestione errori CENTRALIZZATA per tua comodità, certo che può avere un senso, ma è una TUA comodità e ribadisco che NON HA SENSO pensarla come CARENZA DEL SISTEMA.
 
Ad essere sinceri poi una gestione errori centralizzata senza un'attendibile STACKERROR è una mezza pippa... e sappiamo bene che a parte TOOL esterni il VBA non consente in modo nativo l'analisi in STACK... e questo a maggior ragione rende relativo e parziale il discorso di comodità.
 
Ora mi sono annoiato perchè stiamo parlando di una cavolata.
 
Saluti
@Alex

 Ora mi sono annoiato perchè stiamo parlando di una cavolata.
 
Gira che ti rigira son tutte cavolate, e' vero. Ma tutte tutte 
eh: tanto alla fine se deve mori', no ? ;-)
 
 

 eh: tanto alla fine se deve mori', no ? ;-)
 
Sì ma è un po' da stolti morir di cavolate.
Io ho sempre avuto problemi a risolvere gli errori
del codice e dell'utente, mai a "gestire"
le modalità della loro rappresentazione.
Ma è materia talmente ovvia e scontata che non trovo
espressioni sensate per esprimermi.
 
Quando vedo poi dello pseudo codice - absit iniuria verbis! -
mi si drizzan tutti i peli del c...
Ché è una cosa - lo pseudo codice - che al programmatore
non serve proprio a nulla.
Ché quando ci vai a togliere lo "pseudo" per farlo
diventare "codice" il più delle volte t'accorgi
che sei completamente fuori strada.
 
Sto declinando un'autobiografia, non intendo
generalizzare.
 
@Alex, e tu radicale da 1/1000, avete mai provato
il VBA di Outlook?
 
Bruno

 il VBA di Outlook?
 
Io personalmente ho buttato giu' alcune routine in Outlook. Ha
un modello oggetti un po' particolare, sui generis. 
 
Perche' ?
 
 
 

 Perche' ?
 
Perché quello quando ti spara un errore nemmeno ti riporta
sulla riga che l'ha generato.
Ti stampa un messaggio con un codice di errore e una descrizione
che il più delle volte nulla ha a che vedere con la causa.
E ti va bene se non devi chiudere e riaprire Outlook per
riprendere a lavorare.
 
Di quello varrebbe la pena lamentarsi!
 
Bruno

 Di quello varrebbe la pena lamentarsi!
 
Ok : BUUUUHHH ! BUUUUHHH BASTARDI questi della Microsoft ! 
Contento ? :-)
 
Vedi : 
Io non mi "lamentavo" della gestione degli errori del VBA, 
non serve "lamentarsi". 
 
Semplicemente  osservavo  che, essendo un po' involuta, forse
sarebbe il  caso di farmela da me con una bella classe. Tutto
qui. 
 
Ma pare che sia alquanto  problematico  quindi ...  pazienza.
 
 
 
 
 
 
 
 
 
 

 il VBA di Outlook?
 
E che sara' mai!?
Ha sempre le tre istruzioni che ogni linguaggio possiede
1) Sposta sta cosa da qui a li
2) Verifica se una cosa e' vera/falsa
3) Salta di qua o di la
 
Se poi tu ti riferisci all' "ambiente" Outlook e' tutto un altro paio di 
maniche (modo colto di rappresentare il problema). Ogni ambiente ha i 
suoi pro ed i suoi contro. Ora ce la possibilita' di fare il debug 
"inline" del javascript ma, qualche hanno fa, se si voleva rodere 
veramente bastava prendere un errore e allora si erano i famosi volatili 
per diabetici.
Per uno come me nato quando per risolvere un errore dovevi 
"interpretare" il /dump/ di memoria ora e' arrivata l'America.
(anzi  "era" arrivata, visto che ho attaccato la penna al chiodo) ;-)


 (anzi  "era" arrivata, visto che ho attaccato la penna al chiodo) ;-)
 
Beh, prova a staccare la penna dal chiodo e a inviarmi quelle
30-40 righe di codice che da Outlook trasferiscono tutte
le SentMail a una tabella di Access.
Unitamente all'elenco dei moccoli che hai dovuto tirare...
 
Bruno

 Unitamente all'elenco dei moccoli che hai dovuto tirare...
 
Veramente "feci" (ma mi ricordo vagamente) il contrario, da Access 
accedevo alla "base dati" Outlook che, mi sembra di ricordare, in alcuni 
suoi aspetti era piuttosto strana.


 suoi aspetti era piuttosto strana.
 
Si, e' strana : 
il modello oggetti di Outlook e' abbastanza sui generis  per quanto 
concerne l' accesso alle varie tipologie di posta. C'e' una ragione
ma ... non ricordo piu' quale. 
 
 
 

 le SentMail a una tabella di Access.
 
Se ti fa piacere ti "smandrappo" qui l' intero modulo (in access) che
tempo fa  ho  creato  per  far  si   che  questo   potesse  governare 
l' outlook come un pupazzo :-) 
 
Ho  creato  un orologio  di  sistema tramite una declare che ogni tot 
obbligava l' access ad esplorare  l' outlook   ed  a  bersi  tutte le 
mails, a cancellare quelle gia' lette e altri cazzi ecc ecc (poi lo vedi
dal codice)
 
L' orologio di sistema (molto affidabile se fatto con la API di windows)
chiamava  una  routine  in  call - back. Se  sei interessato di spadello 
pure quella :-) 
 
Ecco qua, fammi sapere :
 
Public Sub Elimina_Mails_Gia_Lette()
 
On Error GoTo ERRORE
 
Dim OTLK                  As Outlook.Application
Dim Session               As Outlook.Namespace
Dim Mail                  As Outlook.MailItem
Dim myNameSpace           As Outlook.Namespace
Dim Folder_Out            As Outlook.Folder
Dim Folder_In             As Outlook.Folder
Dim j                     As Long
Dim N                     As Long
Dim Radice                As String
Dim S                     As Form
 
' ------------- routine -------------------------------------------------------Set OTLK = GetObject(, "outlook.application")
Radice = ""
Set Session = OTLK.GetNamespace("MAPI")
Set Folder_In = Session.folders.Item(Radice).folders.Item("inbox")
Set Folder_Out = Session.folders.Item(Radice).folders.Item("elaborate")
Set S = G_Sys_Stato.Sentinella
N = Folder_In.Items.Count
 
If N = 0 Then Exit Sub
 
For i = N To 1 Step -1
    Set Mail = Folder_In.Items(i)
    If Not Mail.UnRead Then Mail.Move Folder_Out
Skip_Mail:
Next i
 
DoEvents: Exit Sub
 
ERRORE:
Select Case Err.Number
   Case 429 ' outlook chiuso
        S.stato_outlook_.Value = "Chiuso": S.Refresh: DoEvents: Exit Sub
   Case Else
        GoTo Skip_Mail
End Select
 
End Sub
 
Public Sub Legge_Mails()
 
     On Error GoTo ERRORE
 
     Dim OTLK          As Outlook.Application
     Dim Mail          As Outlook.MailItem
     Dim Session       As Outlook.Namespace
     Dim Folder        As Outlook.MAPIFolder
     Dim Max_Mails     As Long
     Dim Allegati      As New ADODB.Recordset
     Dim POSTA         As New ADODB.Recordset
     Dim Mittente      As String
     Dim Oggetto       As String
     Dim Anomalie      As String
     Dim M             As Long
     Dim A             As Long
     Dim Allegato      As String
     Dim N_Allegati    As Long
     Dim S             As Form
' ------------- routine ------------------------------
Set OTLK = GetObject(, "outlook.application")
Set Session = OTLK.Session
Set Folder = Session.GetDefaultFolder(olFolderInbox)
Set S = G_Sys_Stato.Sentinella
 
If Folder.Items.Count = 0 Then Set Folder = Nothing: Set Session = Nothing: Exit Sub
 
Max_Mails = 10
 
POSTA.LockType = adLockOptimistic:    POSTA.CursorType = adOpenStatic:       POSTA.CursorLocation = adUseClient
Allegati.LockType = adLockOptimistic: Allegati.CursorLocation = adUseClient: Allegati.CursorType = adOpenStatic
 
POSTA.Open "select * from posta_in where 1=0;", G_Sys_Stato.CN_LS
Allegati.Open "select * from allegati_in where 1=0;", G_Sys_Stato.CN_LS
 
If Max_Mails > Folder.Items.Count Then Max_Mails = Folder.Items.Count
 
For M = Max_Mails To 1 Step -1
 
  Set Mail = Folder.Items(M)
 
  ' controllo già letta
  If Not Mail.UnRead Then GoTo Skip_Mail
 
  Mail.UnRead = False
  'controllo esistenza indirizzo
  Mittente = Trim(Mail.SenderEmailAddress)
  G_Indirizzi.MoveFirst
  G_Indirizzi.Find "indirizzo_='" & Mittente & "'"
  If G_Indirizzi.EOF Then GoTo Skip_Mail
 
 ' controllo indirizzo esterno : in questo caso nel corpo
 ' deve essere presente la password
 ' e deve essere inserita ALL' INIZIO del corpo della mail
 
  If Not IsNull(G_Indirizzi.Fields("esterno_").Value) Then
     If G_Indirizzi.Fields("esterno_").Value Then
        If Not (InStr(Mail.Body, G_Password) = 1) Then Anomalie = "indirizzo esterno ma password mancante.;"
     End If
  End If
 
  'controllo esistenza funzione
  Oggetto = Trim(Replace(Mail.Subject, " ", ""))
  G_Funzioni.MoveFirst
  G_Funzioni.Find "funzione_='" & Oggetto & "'"
 
  If (G_Funzioni.EOF) Then Anomalie = Anomalie & "funzione non esistente.;"
 
  ' controllo funzione benformata
  Anomalie = Anomalie & Richiesta_Ben_Formata(Mail.Subject, Mail.Body)
 
  'controllo abilitazione indirizzo -> funzione
  G_Indirizzi_Funzioni.MoveFirst
  G_Indirizzi_Funzioni.Find "indirizzo_='" & Mittente & "'"
  If G_Indirizzi_Funzioni.EOF Then
     Anomalie = Anomalie & "indirizzo non esistente nelle abilitazioni.;"
  Else
     If IsNull(G_Indirizzi_Funzioni.Fields("abilitato_").Value) Then
        Anomalie = Anomalie & "indirizzo esistente nelle abilitazioni ma non abilitato alla funzione.;"
     Else
        If Not (G_Indirizzi_Funzioni.Fields("abilitato_").Value) Then
           Anomalie = Anomalie & "indirizzo esistente nelle abilitazioni ma non abilitato alla funzione.;"
        End If
     End If
  End If
 
  K = "{" & Kiave() & "}"
 
  POSTA.AddNew
 
     POSTA.Fields("kiave_").Value = K
     POSTA.Fields("numero_allegati_").Value = Mail.Attachments.Count
     POSTA.Fields("cc_nascosti_").Value = Mail.Bcc
     POSTA.Fields("corpo_").Value = Mail.Body
     POSTA.Fields("cc_").Value = Mail.CC
     POSTA.Fields("id_").Value = Mail.EntryID
     POSTA.Fields("oggetto_").Value = Oggetto
     POSTA.Fields("mittente_").Value = Mittente
     POSTA.Fields("dt_ricezione_").Value = Mail.ReceivedTime
     POSTA.Fields("elaborata_").Value = False
     POSTA.Fields("Anomalie_").Value = Anomalie
  POSTA.Update
  DoEvents
 
  ' registra e salva tutti gli allegati (solo se non sono state riscontrate anomalie)
 
  N_Allegati = Mail.Attachments.Count
 
  If (N_Allegati > 0) And (Anomalie = "") Then
     KK = K
     For A = 1 To N_Allegati
         Allegato = G_ALLEGATI_IN & KK & Mail.Attachments.Item(i).FileName
         Allegati.AddNew
            Allegati("Kiave_").Value = KK: Allegati("Kiave_Posta_").Value = K: Allegati("Nome_").Value = Allegato
         Allegati.Update
         Mail.Attachments.Item(i).SaveAsFile Allegato
         DoEvents
         KK = "{" & Kiave() & "}"
     Next A
  End If
Skip_Mail:
  Anomalie = ""
Next M
 
Allegati.Close: Set Allegati = Nothing: POSTA.Close: Set POSTA = Nothing: DoEvents
Exit Sub
ERRORE:
Select Case Err.Number
   Case 429 ' outlook chiuso
        S.Sentinella.stato_outlook_.Value = "Chiuso": S.Refresh: DoEvents: Exit Sub
   Case Else
        GoTo Skip_Mail
End Select
 
End Sub
Public Sub Elabora_Mails()
Dim POSTA_IN  As New ADODB.Recordset
Dim P         As POSTA
 
POSTA_IN.LockType = adLockOptimistic: POSTA_IN.CursorLocation = adUseClient: POSTA_IN.CursorType = adOpenStatic
POSTA_IN.Open "select * from posta_in where not elaborata_;", G_Sys_Stato.CN_LS
 
Do While Not POSTA_IN.EOF
   P.Allegati = Produce_Stringa_Allegati(POSTA_IN.Fields("kiave_").Value)
   P.Soggetto = POSTA_IN.Fields("mittente_").Value
   P.Oggetto = POSTA_IN.Fields("oggetto_").Value
   P.Corpo = POSTA_IN.Fields("corpo_").Value
   P.Cnc = POSTA_IN.Fields("cc_").Value
   P.Bcc = POSTA_IN.Fields("cc_nascosti_").Value
   P.Anomalie = POSTA_IN.Fields("anomalie_").Value
   P.Esito = ""
 
   If Len(P.Anomalie) Then Invia_Anomalie P: GoTo Skip_Mail
 
   Select Case POSTA_IN.Fields("oggetto_").Value
 
      Case "1.1":   Invia_PBNP_Report P
      Case "1.2":   Invia_PBDS_Report P
      Case "1.3":   Invia_PBOV_Report P
      Case "1.999": Invia_Output_Query P
 
   End Select
 
Skip_Mail:
   POSTA_IN.Fields("elaborata_").Value = True
   POSTA_IN.Update
   POSTA_IN.MoveNext
Loop
 
POSTA_IN.Close:  Set POSTA_IN = Nothing
 
DoEvents
End Sub
Public Function Invia_Mail(P As POSTA) As Boolean
     On Error GoTo ERRORE
' ------------- dichiarazioni variabili tipiche --------------------
     Dim OTLK              As Outlook.Application
     Dim MAPISession       As Outlook.Namespace
     Dim MAPIFolder        As Outlook.MAPIFolder
     Dim MAPIMailItem      As Outlook.MailItem
     Dim y()               As String
     Dim i                 As Long
     Dim A                 As Long
' ------------- routine --------------------------------------------
     Set OTLK = GetObject(, "Outlook.application")
     Set MAPISession = OTLK.Session
'    MAPISession.Logon , , True, False
     Set MAPIFolder = MAPISession.GetDefaultFolder(olFolderOutbox)
     Set MAPIMailItem = MAPIFolder.Items.Add(olMailItem)
 
     If Len(Trim(P.Allegati)) > 0 Then
        y = Split(P.Allegati, ";")
        A = UBound(y)
        For i = 0 To A
            MAPIMailItem.Attachments.Add y(i), olByValue
        Next i
     End If
 
     MAPIMailItem.To = P.Soggetto
     MAPIMailItem.CC = P.Cnc
     MAPIMailItem.Bcc = P.Bcc
     MAPIMailItem.Subject = P.Oggetto
 
     If Len(P.Html_Corpo) > 0 Then
        MAPIMailItem.HTMLBody = P.Html_Corpo
     Else
        MAPIMailItem.Body = P.Corpo
     End If
 
     MAPIMailItem.HTMLBody = P.Html_Corpo
     MAPIMailItem.Send
 
     DoEvents
 
     Set MAPIMailItem = Nothing
     Set MAPIFolder = Nothing
     Esito = "OK"
'60  MAPISession.Logoff
' ------------------------------------------------------------------
     Invia_Mail = True
     Exit Function
ERRORE:
     Esito = Err.Description
End Function
 
Ciao

 l' outlook come un pupazzo :-) 
Detto in endecasillabi:
     Faccio una gran fatica a metter mano
     allo codice mio dopo appena
     due settimane dall'averlo scritto
     che se proprio non preme la bisogna
     in quello altrui manco ci metto il naso.
non mi è venuta la rima...
 
Grazie comunque.
Bruno


Ma come, l' avevi chiesto tu ... Vabbe' :-) 
(ti capisco eh ! Eccome !)
 

 (ti capisco eh ! Eccome !)
 
Sì, però di 30-40 righe! non di 250!
 
Bruno