Condividi:        

macro temporizzate

Vuoi potenziare i tuoi documenti Word? Non sai come si fa una macro in Excel? Devi creare una presentazione in PowerPoint?
Oppure sei passato a OpenOffice e non sei sicuro di come lavorare al meglio?

Moderatori: Anthony47, Flash30005

macro temporizzate

Postdi simo73 » 17/09/15 17:50

Salve a tutti, il mio problema consiste in questo. Ho un file excel con due macro temporizzate che lanciano due sub in tempi diversi. La macro A carica ogni due secondi dei valori in un array e dopo 15 minuti mi restituisce il primo valore, l'ultimo caricato il max ed il min. La macro B ogni 15 minuti ed un secondo preleva i dati calcolati dalla macro A e gli utilizza per alcuni calcoli. Tutto dovrebbe funzionare per 8 h. Le due macro provate singolarmente funzionano perfettamente, invece insieme nascono i problemi. In particolare la macro A ogni volta non riesce a terminare il caricamento dei dati, ogni volta si arresta in un punto diverso cioè una volta carica 100 dati un'altra 210 senza mai arrivare ai 450 dati dei primi 15 minuti, cosa che invece fa sempre se la lancio in un file a parte. Sinceramente non capisco da cosa possa dipendere e perchè le due macro vanno in conflitto visto che agiscono in tempi diversi. Ringrazio anticipatamente chi saprà aiutarmi.
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Sponsor
 

Re: macro temporizzate

Postdi Anthony47 » 18/09/15 00:18

Ciao simo73, benvenuto nel forum.
Non puoi pensare di schedulare una macro perche' parta 1 secondo dopo quando dovrebbe finire la prima e dare per scontato che la prima finisce effettivamente 1 secondo prima...
Il mio suggerimento e' che lanci la seconda quando la prima ha finito il suo lavoro, che servano 10 minuti o 20 o quanti ne prendera'; per questo inserirai Call Macro2 in coda alla prima.

Ricorda che se scheduli una macro usando "OnTime" allora dovresti anche prevedere che, se vuoi fermarti, devi "deschedulare" l'evento, altrimenti la macro si attiva a quell' OnTime e magari si rischedula; col risultato che alla fine ti trovi due cicli di schedulazione (se nel frattempo hai riavviato il processo), e poi magari con tre, e poi con ...

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 18/09/15 13:53

Il problema è che non riesco a terminare neanche la prima macro che si pianta prima di aver caricato tutti i valori. E comunque avrei necessità che là macro 1 continuasse comunque il suo lavoro perché altrimenti mi perderei dei dati.Avevo provato a tenere i due file separati e collegare solo le celle che mi interessano, però non so perché ma la cartella dove aggiornavo i dati me la ritrovavo anche nell'altro file. Non è possibile trovare una soluzione in tal senso, scusami se ho detto cavolate.
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 18/09/15 14:45

Ma io ti ho suggerito di avviare Macro2 non "a tempo" ma in coda a Macro1, cioe' quando Macro1 finisce.
Se Macro1, girando da sola, non riesce a finire il suo lavoro allora c'e' qualcosa che riguarda quella macro e il suo ambiente.

Il fatto che ti trovi dei dati nel file (o nel foglio?) sbagliato significa inoltre che il codice della macro non indirizza in modo esplicito il workbook e il worksheet di destinazione, lavorando cosi' su file (o fogli) che sono quelli attivi al momento, cioe' casuale.

Prova a pubblicare il codice di Macro1 e vedremo se ci capiamo qualcosa.

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 18/09/15 23:17

Secondo me hai centrato il problema, domani vedo di pubblicarti il codice. Se riesco a rendere indipendenti le due macro avrei risolto il problema anche perché non posso mandare in esecuzione là macro due di seguito a macro 1 perché come ti dicevo perderei dei dati. Macro 1 uno ogni 14 minuti e 58 sec elabora 450 dati ed individua primo valore,ultimo valore, max e min. Macro due prende questi dati ed elabora delle formule, ma nello stesso tempo dopo due secondi all'inizio del 15 minuto per altri 14:58 sec là macro 1 rielabora 450 dati ecc il tutto per 8 ore.
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 19/09/15 02:11

Se riesco a rendere indipendenti le due macro avrei risolto il problema anche perché non posso mandare in esecuzione là macro due di seguito a macro 1 perché come ti dicevo perderei dei dati
Adesso mi stai confondendo... Se Macro2 (che non hai detto quanto dura) non puo' andare in esecuzione quando ha finito Macro1 allora quando la fai partire?
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 19/09/15 13:19

Allora cerco di spiegarmi meglio: la macro 1 termina dopo 14:58 secondi e restituisce il primo,l'ultimo valore,max e min di una serie di dati caricati che preleva da una cella DDE. La macro 2 parte al 15:00 minuto e dura circa 2 secondi e dovrebbe prelevare i dati rilevati dalla macro 1 e utilizzarli per aggiornare delle formule e dei grafici. Quindi succede che le due macro per un piccolo lasso di tempo lavorano contemporaneamente (perchè nel frattempo la macro 1 è ripartita per ricaricare i dati dei successivi 15 minuti) ed è per questo che la soluzione ideale sarebbe riuscire a mantenere i due file distinti e collegare semplicemente le celle in cui la macro 2 va a prelevare i dati, sarebbe funzionale al massimo.

La macro 1 è la seguente tieni presente che il primo ciclo per esigenze mie fa un primo ciclo solo di 14 minuti per cui dovrebbe caricare solo 420 dati nei cicli successivi (cicli da 15 mniuti) invece dovrebbe caricare 450 dati.
Codice: Seleziona tutto
Public Sub DDE()

    timeDDE = [L20]
    interDDE = [M20]
    contDDE = 0
   
    ncicliDDEFINE = [L18]
    [J17] = "prima rilevazione " & timeDDE
   
    primarilevazione = [O18]
   
   
    Application.OnTime timeDDE, "caricoDDE"
   
   
   
End Sub



Public Sub caricoDDE()

   
    contDDE = contDDE + 1
    [J20] = contDDE
    datiDDE(contDDE) = [J18]
    timeDDE = timeDDE + interDDE
     
   
    If primarilevazione = 0 And contDDE = 420 Then
                openDDE = datiDDE(1)
                closeDDE = datiDDE(30)
                maxDDE = 0
                minDDE = 100000
   
                For icont = 1 To 420
                    If datiDDE(icont) > maxDDE Then maxDDE = datiDDE(icont)
                    If datiDDE(icont) < minDDE Then minDDE = datiDDE(icont)
                Next icont
   
            [N20] = openDDE
            [Q20] = closeDDE
            [P20] = minDDE
            [O20] = maxDDE
           
            For icont = 1 To 420
                datiDDE(icont) = 0
            Next icont
           
           
            contDDE = 0
           
            primarilevazione = 1
            [Q18] = primarilevazione
            ncicli = ncicli + 1
            [I20] = ncicli
            [K20] = Now
           
     End If
     
   If primarilevazione = 1 And contDDE = 450 Then
                openDDE = datiDDE(1)
                closeDDE = datiDDE(60)
                maxDDE = 0
                minDDE = 100000
   
                For icont = 1 To 450
                    If datiDDE(icont) > maxDDE Then maxDDE = datiDDE(icont)
                    If datiDDE(icont) < minDDE Then minDDE = datiDDE(icont)
                Next icont
   
            [N20] = openDDE
            [Q20] = closeDDE
            [P20] = minDDE
            [M20] = maxDDE
   
            For icont = 1 To 450
                datiDDE(icont) = 0
            Next icont
   
            contDDE = 0
           
            primarilevazione = 1
            [Q18] = primarilevazione
            ncicli = ncicli + 1
            [I20] = ncicli
            [K20] = Now
           
     End If
   
   
   
If ncicli = ncicliDDEFINE Then Exit Sub

Application.OnTime timeDDE, "caricoDDE"

End Sub



Per la macro 2 ti metto solo una parte relativa al caricamento dati, le celle M3,N3,O3,P3 in teoria dovrebbero essere colegate alle celle della macro 1 in cui ritorovo i valori max, min ecc.

omissis
Codice: Seleziona tutto
 Sheets("Dati").Select
   
    R = [I6].Value + 1
    [I6] = R
    R = R + 2
    Cells(R, 6) = [M3]
 Cells(R, 7) = [N3]
 Cells(R, 8) = [O3]
 Cells(R, 9) = [P3]
    Cells(R, 1) = Now
    Cells(R, 2) = timeset
   
    timeset = timeset + INTERVALLO
   
   
    [I9] = "Prossima rilevazione: " & timeset
    [K13] = Cells(R, 6)
    [I13] = Cells(R, 1)
    [J13] = Cells(R, 2)
omissis
    Sheets("Dati").Select
    Application.OnTime TimeValue(FINE), "StopOnTime"
    If INTERVALLO > 0 Then Application.OnTime timeset, "RoutineOnTime"


EDIT Flash: Per una migliore lettura è opportuno usare il Tag Code quando vengono pubblicate righe codice di macro e/o formule
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 20/09/15 20:33

Il codice pubblicato e' di impossibile interpretazione, visto che molti parametri sono su celle del foglio di lavoro o su variabili probabilmente dichiarate pubbliche e compilate su altri moduli.
Pero' posso dire che e' lacunosa tutta la fase di identificazione di quali celle devono essere "lavorate": notazioni quali [J20] = contDDE indicano che il contenuto della cella J20 del foglio attivo e del file attivo in quel momento verra' compilato col valore di contDDE.
Trattandosi di macro che dovrebbe girare per 8 ore mi sembra difficile che al momento dell'esecuzione delle varie macro temporizzate il file attivo e il foglio attivo siano ancora quello che la macro si aspetta.
Devi cioe' rendere esplicito il nome del workbook e il nome del file; il workbook puo' essere indicato come "ThisWorkbook", se e' il file che contiene la macro in esecuzione; per il foglio userai la notazione Sheets("NomeFoglio"), oppure (meglio) invece del NomeFoglio (che puo' essere modificato) puoi usare il "CodeName", che e' impostato in fase di progettazione della macro e non modificabile dall'utente.
Quindi invece di [J20] = contDDE
Codice: Seleziona tutto
ThisWorkbook.Sheets("DDE in lettura").Range("J20) = contDDE


Puoi usare tecniche tipo With /End With oppure Set, per semplificare la scrittura; es
Codice: Seleziona tutto
Set myDest = ThisWorkbook.Sheets("DDE in lettura")

e poi (con riferimento al codice precedente)
Codice: Seleziona tutto
myDest.Range("J20) = contDDE


Ovviamente questo lavoro dovra' essere fatto su tutte le righe interessate e su tutte le macro temporizzate.

Se Macro1 e Macro2 si possono dar fastidio non ho elementi per capirlo; tuttavia se anche Macro2 e' temporizzata valgono per essa le stesse considerazioni sull'identificazione esplicita di workbook e sheet di riferimento, e trovo pericoloso che faccia un "Sheets("Dati").Select" perche' potrebbe mandare in errore la macro se sul pc e' attivo un altro workbook nel momento in cui si esegue la macro.

Ciao.
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 20/09/15 22:08

Bene proverò a fare queste modifiche, quindi mi suggerisci di esplicitare dove là macro deve leggere i vari dati e dove agire. . Un ultima cosa se posso chiedere, io avrei bisogno di un comando che sostituisce msgbox. Ho notato che msgbox mi blocca l'esecuzione dei comandi successivi fino a quando non viene chiuso il messaggio. Inoltre vorrei che fosse sempre in primo piano sullo schermo anche quando ho altre applicazioni aperte.Leggendo in giro su internet ho visto che bisognerebbe usare un form con una textbox (spero di non dire cavolate) ma alla fine anche questa soluzione mi blocca l'eventuale svolgimento delle operazioni successive e non sono comunque riuscito a portare la textbox in primo piano.
GRAZIE DI NUOVO, poi ti farò sapere se tutto funziona.
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi simo73 » 20/09/15 22:14

Scusami di nuovo, quindi anche se mi devo spostare semplicemente in un altro foglio dove fare altre operazioni devo utilizzare la funzione thisworkbook.sheets("dati").select
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 20/09/15 22:27

In una macro temporizzata non dovresti mai mettere la selezione di un foglio; cosa capita se io sto lavorando sul Pc e la macro mi seleziona un altro ambiente di lavoro? Quindi la macro deve indirizzare in modo esplicito file e foglio, ma senza selezionarli.
Cioe' non devi mettere genericamente Range("A1"), ma chiarire di quale file e di quale foglio quel Range("A1") fa parte, perche' quando la macro va in esecuzione non puoi sapere quale file e quale foglio saranno attivi.
Non ti sto a dire che anche quando non lavori in modo temporizzato il ".Select" si puo' /in genere e' meglio evitare, perche' in quel caso si genera solo una macro un po' piu' lenta da eseguire (cosa con cui spesso si puo' convivere) e che fa storcere il naso ai programmatori puri (cosa di cui in genere non ci preoccupiamo).

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi Anthony47 » 20/09/15 22:43

Per mettere un messaggio non vincolante puoi usare una userform contenente una label; poi mostri la userform con l'istruzione
Codice: Seleziona tutto
UserForm1.Show vbModeless

Mentre il contenuto della label (il messaggio) lo imposti con
Codice: Seleziona tutto
UserForm1.Label1.Caption = "Testo del messaggio"

Qando vuoi che scompaia:
Codice: Seleziona tutto
Unload UserForm1


Quale finestra tenere in primo piano lo decide Windows; quindi se vuoi forzare una finestra in primo piano devi usare le api di Windows, in particolare la Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Ma su questo non ti posso aiutare perche' non sono un esperto.

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 23/09/15 22:43

Grazie Anthony47 per quanto riguarda il messaggio ci siamo ed ho risolto seguendo le tue indicazioni, invece ancora mi trovo in difficoltà con la gestione delle macro. Un consiglio, le due macro conviene tenerle sullo stesso file, magari in due moduli diversi oppure no? Inoltre il comando thisworkbook ecc lo devo utilizzare per tutte le celle che in qualche modo entrano nella routine, giusto?
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 24/09/15 00:23

Se le due macro lavorano all'interno dello stesso file, come ho capito, e' logico caricarle su Moduli (standard) dello stesso file.
ThisWorkbook tra l'altro fa riferimento a "il file che contiene la macro in esecuzione", quindi se per assurdo la macro fosse su un altro file allora l'uso di ThisWorkbook sarebbe sbagliato, e bisognerebbe ripiegare su Workbooks("NomeDelWorkbook").

Qualsiasi accesso a dati contenuti nel file, sia in lettura che in scrittura, dovra' contenere "l' indirizzo" completo della cella, cioe' File + Foglio + Cella. Es:
ThisWorkbook.Sheets("QuelFoglio").Range("A1")

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 24/09/15 13:12

Bene ho fatto una piccola macro di prova e penso di aver trovato la soluzione. Ultima domanda e poi prometto di non 'distrurbare' più, nellla mia macro ho un codice che ogni volta che viene lanciata la macro2 (15') mi copia nel foglio di nome "calcolo" l'ultima riga dove all'interno delle celle sono contenute delle formule e incolla tutto nella riga successiva ripetendo anche le formule. Riesco a ripetere questa operazione senza spostarmi nel foglio, ovvero utilizzando la funzione thisworbook.sheets("calcolo").....
Di seguito il codice che fa questa operazione, grazie in anticipo.

Codice: Seleziona tutto
 ActiveCell.Select
    Sheets("Calcolo").Select
    Range("A4").Select
    Selection.End(xlDown).Select
    ActiveCell.Range("A1:BX1").Select
    Selection.AutoFill Destination:=ActiveCell.Range("A1:BX2"), Type:= _
        xlFillDefault
    ActiveCell.Range("A1:BX2").Select
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi simo73 » 24/09/15 18:33

Ci sono riuscito così ma non sono certo che si il modo migliore

Codice: Seleziona tutto
Sub Macro2()
'
contriga = 15
contcolonna = 6

valore = ThisWorkbook.Sheets("calcolo").Range("F8")
ThisWorkbook.Sheets("foglio3").Range("A1") = valore

ThisWorkbook.Sheets("calcolo").Cells(contriga, contcolonna).Copy

ThisWorkbook.Sheets("calcolo").Cells(contriga + 1, contcolonna).PasteSpecial
 
End Sub
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 26/09/15 00:29

Sapendo che l'ottimo e' nemico del bene, io direi che se funziona va bene cosi'.
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: macro temporizzate

Postdi simo73 » 26/09/15 14:52

In realtà non fa proprio quello che chiedevo, mi copia solo una cella e la sua formula , se volessi copiare più celle contemporaneamente pensavo di utilizzare questo codice ma mi da errore

Codice: Seleziona tutto
Sub Macro2()
'
contriga = 16
contcolonna = 6

'
valore = ThisWorkbook.Sheets("calcolo").Range("F8")

ThisWorkbook.Sheets("foglio3").Range("A1") = valore


ThisWorkbook.Sheets("calcolo").Range(Cells(16, 6), Cells(16, 7)).Copy

ThisWorkbook.Sheets("calcolo").Range(Cells(contriga + 1, 6), Cells(contriga + 1, 7)).PasteSpecial

'ThisWorkbook.Sheets("calcolo").Range(Cells(contriga + 1, 6), Cells(contriga + 1, 7)).Copy

'ThisWorkbook.Sheets("calcolo").Range(Cells(1, 6), Cells(1, 7)).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Taspose:=False
   
   
End Sub
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi simo73 » 26/09/15 15:38

Codice: Seleziona tutto
ThisWorkbook.Sheets("calcolo").Range(Cells(16, 6), Cells(16, 7)).Copy


Non capisco dove sta l'errore, utilizzo cells per selezionare due celle consecutive, chiaramente potevo usare semplicemente range("F16:G16") però questa soluzione in un secondo passaggio mi permette di individuare riga e colonna con delle variabili :evil: :evil: :evil:
simo73
Utente Junior
 
Post: 38
Iscritto il: 19/05/15 10:01

Re: macro temporizzate

Postdi Anthony47 » 26/09/15 22:40

Cells e' una proprieta' di un Range o di un Worksheet; nel tuo utilizzo il "padre" della proprieta' e' omesso, quindi (come dice l'help on line) "[Se si utilizza questa proprietà senza un qualificatore di oggetto,] verrà restituito un oggetto Range che rappresenta tutte le celle del foglio di lavoro attivo".
Quindi le tue Cells(16, 6) e Cells(16, 7) indicano F16 e G16 del foglio di lavoro attivo; il suo uso all'interno di ThisWorkbook.Sheets("calcolo") e' quindi errato, salvo che il foglio attivo non sia proprio lo stesso ThisWorkbook.Sheets("calcolo"); cosa poco probabile visto che si tratta di una macro "on time" che quel che trova attivo non si sa.
In sostanza, anche "Cells" deve essere riferita a ThisWorkbook.Sheets("calcolo"), cosa che viene semplificata usando le istruzioni With ThisWorkbook.Sheets("calcolo") /End With; tipo:
Codice: Seleziona tutto
With ThisWorkbook.Sheets("Foglio1")
    .Range(.Cells(16, 6), .Cells(16, 7)).Copy
    .Cells(contriga + 1, 6).PasteSpecial     ' VEDI NOTA*
    'altre istruzioni
    '
End With

Nota*: come vedi ti ho eliminato la definizione di un intervallo piu' ampio di copia, perche' e' sufficiente indicare la cella 1,1 su cui incollare.

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Prossimo

Torna a Applicazioni Office Windows


Topic correlati a "macro temporizzate":


Chi c’è in linea

Visitano il forum: Nessuno e 31 ospiti