problema funzione evaluate in ciclo for



  • problema funzione evaluate in ciclo for
    di Luca (utente non iscritto) data: 06/11/2013 17:03:09

    Salve,
    sto sviluppando una macro che deve fare le seguenti cose:

    1)copiare sul foglio2 il risultato della moltiplicazione delle colonne L e M del foglio1

    2)il secondo passo è sistemare le date nella colonna H del foglio 1 e copiarle nel foglio 2, tramite ciclo for

    3)ordinare la tabella così ottenuta, dalla data più vicina alla data più lontana.

    Sono fermo al passo2 per un errore che temo sia banale ma non riesco a risolvere. Il passo 3 lo farò dopo che ho fatto il passo 2, ma ho già idee su come fare.

    l'errore lo da sulla riga con nuovadata = Evaluate etc etc, e dice: errore di compilazione previsto separatore di elenco oppure ).
    La formula però è scritta giusta, provata fuori dalla macro fa proprio quello che deve fare! Non capisco.

    Come si può risolvere?

    Grazie mille in anticipo.
     
    Sub prova_ordinamento2()
    'il primo passo è copiare sul foglio2 il risultato della moltiplicazione delle colonne L e M del foglio1
     
    Set sh1 = Workbooks("esempio.xlsm").Worksheets("foglio1")
    Set sh2 = Workbooks("esempio.xlsm").Worksheets("foglio2")
    Set SourceRange = sh2.Range("C3")
     
    Sheets("Foglio2").Activate
    sh2.Range("C3").Select
    ActiveCell.FormulaR1C1 = "=Foglio1!R[6]C[9]*Foglio1!R[6]C[10]"
    SourceRange.AutoFill Destination:=sh2.Range("C3:C5"), Type:=xlFillDefault
     
    'il secondo passo è sistemare le date nella colonna H del foglio 1 e copiarle nel foglio 2, tramite ciclo for
     
     Dim oneRange As Range
     Dim aCell As Range
     
     Set oneRange = Range("H9:H11")
     Set aCell = Range("H9")
     
     'seleziono la cella da cui deve iniziare a copiare il ciclo
     sh2.Range("B3").Select
     
     For Each aCell In oneRange
     nuovadata = Evaluate("=SOSTITUISCI(TESTO(aCell;"gg/mm/aaaa");ANNO(aCell);(SE(MESE(aCell)>MESE(H3);2013;2014)))")
     ActiveCell.Value = nuovadata
     ActiveCell.Offset(1, 0).Select
     Next
      
    'il terzo passo è ordinare la tabella così creata
    'lo farò dopo che ho tutti i dati corretti
     
    End Sub
    
    



  • di gaetanopr data: 06/11/2013 18:03:29

    Ciao Luca, ho dato un'occhiata veloce, la formula in evaluate deve essere in inglese e non in italiano



  • di Vecchio Frac data: 07/11/2013 09:38:38

    cit. "la formula in evaluate deve essere in inglese"
    ---> Esatto come dice gaetano.
    Come fare per la traduzione? è piuttosto semplice: scrivi la formula in italiano in una cella qualsiasi (la stringa tra virgolette dopo Evaluate, per capirci; e non importa se avrai un valore errato), conferma con Invio e rimani posizionato su questa cella, poi apri l'editor di codice (Alt-F11), accedi alla finestra Immediata (Ctrl-G), scrivi queste parole magiche:
    ?activecell.Formula
    conferma con Invio ed eccoti la traduzione; copia incolla questa stringa dentro le virgolette di Evaluate e dovresti essere a posto.






  • di Luca (utente non iscritto) data: 07/11/2013 11:43:05

    Grazie per le risposte.

    Ho fatto come consigliavate, ora la formula è questa:

    nuovadata = Evaluate("=SUBSTITUTE(TEXT(aCell,"gg/mm/aaaa");YEAR(aCell);(IF(MONTH(aCell)>MONTH(H3);2013;2014)))")

    Mi da lo stesso identico errore.

    Ho notato invece che se metto i doppi apici attorno a gg/mm/aaaa (ovvero ""gg/mm/aaaa""), non da più errore, però sulle celle compare #VALORE.

    Il formato delle celle è data, ma anche con generale non cambia niente.
    Da cosa dipende?
    Grazie ancora!



  • di Grograman (utente non iscritto) data: 07/11/2013 11:50:49

    I doppi apici proprio non piacciono all'editor VBA.

    Meglio abituarsi (e io non ci sono ancora arrivato) ad usare il chr(34).
    Molto a naso non avendo il file di prova:
     
    nuovadata = Evaluate("=SUBSTITUTE(TEXT(" & aCell & Chr(34) & "," & Chr(34) & "gg/mm/aaaa" & Chr(34) & ");YEAR(" & aCell & ");(IF(MONTH(" & aCell & ")>MONTH(H3);2013;2014)))")



  • di Luca (utente non iscritto) data: 07/11/2013 12:45:29

    Purtroppo da sempre lo stesso errore :(

    Ho trovato questo link, sembra sia proprio un problema di evaluate

    edit: non mi fa inserire il link..



  • di Grograman (utente non iscritto) data: 07/11/2013 12:54:40

    Scusa dimenticavo, va indicato l'indirizzo della cella:

    Ma ribadisco che senza file di esempio è abbastanza inutile ^_^
     
    aCell.address



  • di gaetanopr data: 07/11/2013 13:09:32

    Ciao a tutti, cambia i punto e virgola con la virgola



  • di Vecchio Frac data: 07/11/2013 14:26:48

    Forse vi ho portati fuori strada io, perchè ho dato per scontato che le virgolette dentro una stringa vanno raddoppiate oppure si usa Chr(34).
    E poichè la formula usa la notazione inglese, devono essere usate le virgole invece dei punti e virgola (purtroppo le localizzazioni hanno sortito brutti effetti. Ce ne sono altri).





  • di Luca (utente non iscritto) data: 07/11/2013 15:13:59

    Grazie mille per gli interventi.

    aCell viene impostato nel ciclo.

    L'unica differenza la ho nel caso di doppi apici e virgole, in quel caso mi da errore #NOME.

    Comunque ora allego il file.



  • di Grograman (utente non iscritto) data: 07/11/2013 16:00:54

    Non so se è il risultato che vuoi ottenere, ma così non da errori "logici":
     
    nuovadata = Evaluate("=SUBSTITUTE(TEXT(" & aCell.Address & "," & Chr(34) & "gg/mm/aaaa" & Chr(34) & "),YEAR(" & aCell.Address & "),(IF(MONTH(" & aCell.Address & ")>MONTH(H3),2013,2014)))")



  • di gaetanopr data: 07/11/2013 16:22:23

    ciao ragazzi, io non posso fare prove ma ho notato un'altra cosa gg/mm/aaaa dovrebbe essere dd/mm/yyyy



  • di Grograman (utente non iscritto) data: 07/11/2013 16:48:12

    Giusta osservazione!
     
    nuovadata = Evaluate("=SUBSTITUTE(TEXT(" & aCell.Address & "," & Chr(34) & "dd/mm/yyyy" & Chr(34) & "),YEAR(" & aCell.Address & "),(IF(MONTH(" & aCell.Address & ")>MONTH(H3),2013,2014)))")



  • di Luca (utente non iscritto) data: 07/11/2013 17:19:59

    E' vero, così non da errori.

    Però fornisce solo l'anno corretto, giorno e mese vengono persi. Si ha qualcosa come 00/01/2014.

    A me serve che giorno e mese non vengano toccati, come accade nella formula originaria.

    Se la provate fuori dalla macro, potete vedere come dovrebbe funzionare..

    Grazie in ogni caso :D



  • di isy data: 07/11/2013 18:51:48

    Ciao

    Forse in questo modo...

    Sostituisci il codice con:
     
    Sub prova_ordinamento2()
    'il primo passo è copiare sul foglio2 il risultato della moltiplicazione delle colonne L e M del foglio1
    
    Set sh1 = Workbooks("esempio.xlsm").Worksheets("foglio1")
    Set sh2 = Workbooks("esempio.xlsm").Worksheets("foglio2")
    Set SourceRange = sh2.Range("C3")
    
    Sheets("Foglio2").Activate
    sh2.Range("C3").Select
    ActiveCell.FormulaR1C1 = "=Foglio1!R[6]C[9]*Foglio1!R[6]C[10]"
    SourceRange.AutoFill Destination:=sh2.Range("C3:C5"), Type:=xlFillDefault
    
    'il secondo passo è sistemare le date nella colonna H del foglio 1 e copiarle nel foglio 2, tramite ciclo for
    
     Dim oneRange As Range
     Dim aCell As Range
    
     Set oneRange = sh1.Range("H9:H11")
     Set aCell = sh1.Range("H9")
    
     'seleziono la cella da cui deve iniziare a copiare il ciclo
     sh2.Range("B3").Select
    
     For Each aCell In oneRange
      x = CDbl(aCell)
      If Month(x) > Month(sh1.[H3].Value) Then
        nuovadata = DateSerial(2013, Month(x), Day(x))
      Else
        nuovadata = DateSerial(2014, Month(x), Day(x))
      End If
     ActiveCell.Value = nuovadata
     ActiveCell.Offset(1, 0).Select
     Next
     
    'il terzo passo è ordinare la tabella così creata
    'lo farò dopo che ho tutti i dati corretti
    UltimaRiga = Range("A65536").End(xlUp).Row
    sh2.Sort.SortFields.Add Key:=Range("B3:B" & UltimaRiga) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    
    End Sub



  • di Luca (utente non iscritto) data: 08/11/2013 12:19:34

    Ti ringrazio per la risposta, purtroppo ancora non ci siamo.

    Non ho provato la parte di ordinamento, ma la parte di "trasformazione" delle date, non funziona come dovrebbe.

    Per qualche motivo, trasforma tutte le date in 30/12/2013. Da cosa può dipendere?

    Le date passate sono:
    24/03/2045
    22/10/2018
    14/09/2022

    e dovrebbe essere:
    24/03/2014
    22/10/2014
    14/09/2014.

    Non capisco...qualche problema di formato?



  • di gaetanopr data: 08/11/2013 19:39:42

    Salve a tutti, il problema sta nel fatto che una volta attivato il secondo foglio, aCell.Address non fà piuù riferimento alla cella H9 del primo foglio ma alla cella H9 del secondo foglio, quindi nell'istruzione evaluate bisogna indicare anche il nome nel foglio, nello stesso modo in cui faresti scrivendo una formula nel secondo foglio ma riferendoti a celle nel primo
    Facendo alcune prove ho cambiata completamente l'istruzione
     
    nuovadata = Evaluate("=DATE(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!" & aCell.Address & "),2013,2014 ),MONTH(Foglio1!" & aCell.Address & "),Day(Foglio1!" & aCell.Address & "))")



  • di gaetanopr data: 08/11/2013 19:49:46

    Ho sbagliato riposto macro
     
    nuovadata = Evaluate("=DATE(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!H3),2013,2014 ),MONTH(Foglio1!" & aCell.Address & "),Day(Foglio1!" & aCell.Address & "))")
     
    oppure
    
    nuovadata = Evaluate("=SUBSTITUTE(TEXT(Foglio1!" & aCell.Address & "," & Chr(34) & "dd/mm/yyyy" & Chr(34) & "),YEAR(Foglio1!" & aCell.Address & "),(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!H3),2013,2014)))")



  • di gaetanopr (utente non iscritto) data: 08/11/2013 20:13:32

    Ho apportato alcune modifiche alla macro, più tardi allego il file funzionante



  • di Luca (utente non iscritto) data: 09/11/2013 14:04:45

    Grande! ho provato con l'ultima funzione che hai postato, e funziona!!

    Ora non mi resta che studiarmela un minimo e poi applicare l'ordinamento!

    Grazie :D



  • di Luca (utente non iscritto) data: 09/11/2013 15:41:51

    Sto provando a ordinare i dati della tabella creata.

    Purtroppo il codice postato da isy non da errore ma non ordina :(

    Facendo delle prove penso che questo possa essere risolto facendo qualche rapida modifica, ma ho delle dfficoltà.

    Per esempio penso che vada sostituito DataOption:=xlSortNormal con DataOption:=xlSortTextAsNumbers, ma questo non è sufficiente. Ho provato ad aggiungere altri campi, ma mi da errore. L'errore è: Errore di runtime 448 Impossibile trovare argomento predefinito.

    Il codice è il seguente:

     
    'il terzo passo è ordinare la tabella così creata
    'lo farò dopo che ho tutti i dati corretti
    UltimaRiga = Range("A65536").End(xlUp).Row
    sh2.Sort.SortFields.Add Key:=Range("B3:B" & UltimaRiga) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers _
            , Orientation:=xlTopToBottom 'SortMethod:=xlPinYin
    
    



  • di gaetanopr (utente non iscritto) data: 09/11/2013 19:22:12

    Ciao Luca, ti consiglio di usare la prima soluzione di evaluate in quanto restituisce una data e non un testo come la seconda, quindi il formato giusto anche per effettuare l'ordinamento
    Per la macro non posso fare prove al momento però puoi semplicemente registrare una macro e vedi come và

    Saluti



  • di Luca (utente non iscritto) data: 10/11/2013 14:23:31

    Intendi questa formula?

    Uhm...non ordina neanche così. Sia se uso DataOption:=xlSortNormal o DataOption:=xlSortTextAsNumber.

    L'idea di registrare una macro è buona, e ci ho provato. Quello che viene è postato di sotto. Potrei anche usarlo, però mi piace capire quello che sto facendo è la usa il comando With che non ho proprio capito.

    Quello che non capisco è perchè non posso aggiungere al codice che mi ha postato isy, quei 2 o 3 comandi che per me sistemerebbero tutto. Perchè se per esempio aggiungo, Orientation:=xlTopToBottom o SortMethod:=xlPinYin come descrivo nel post precedente, mi quell'errore?
     
    nuovadata = Evaluate("=DATE(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!H3),2013,2014 ),MONTH(Foglio1!" & aCell.Address & "),Day(Foglio1!" & aCell.Address & "))")
    
    
    'MACRO registrata
    Sub ordinamento_finale()
    '
    ' ordinamento_finale Macro
    '
    
    '
        Range("B3:C5").Select
        ActiveWorkbook.Worksheets("Foglio2").Sort.SortFields.Clear
        ActiveWorkbook.Worksheets("Foglio2").Sort.SortFields.Add Key:=Range("B3:B5") _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
            xlSortTextAsNumbers
        With ActiveWorkbook.Worksheets("Foglio2").Sort
            .SetRange Range("B3:C5")
            .Header = xlGuess
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
    End Sub
    
    



  • di Vecchio Frac data: 10/11/2013 14:35:53

    cit. "nuovadata = Evaluate("=DATE(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!H3),2013,2014 ),MONTH(Foglio1!" & aCell.Address & "),Day(Foglio1!" & aCell.Address & "))")"
    ---> Considerazione parallela.
    E se (invece di passare da Evaluate) scrivessi le corrispondenti istruzioni VBA, visto che sei in VBA e le hai a disposizione?

    anno = iif (month(acell) > month([h3]), 2013, 2014)
    nuovadata = dateserial(anno, month(acell), day(acell))

    o simile, con gli aggiustamenti del caso.

    Per il secondo problema, tu e isy avete versioni di Excel diverse?





  • di Luca (utente non iscritto) data: 10/11/2013 15:32:07

    Grazie, anche il tuo suggerimento funziona bene :D

    Il problema dell'ordinamento rimane. Perchè pensi possa essere dovuto a versioni diverse? Io, in ogni caso, ho excel 2010.

    Non capisco proprio perchè non posso aggiungere un sortmethod o altro a quelle due righe là. Bisogna per forza usare il With???



  • di Vecchio Frac data: 10/11/2013 18:56:56

    With non è niente di particolare, è un gestore di contesto, un modo per semplificare la scrittura del codice.
    Se tu hai XL2010 non è un problema di versioni.






  • di Luca (utente non iscritto) data: 10/11/2013 21:28:23

    Allora il messaggio di errore se aggiungo anche solo "SortMethod:=xlPinYin" da cosa può dipendere?



  • di Vecchio Frac data: 11/11/2013 10:13:01

    Dalla Guida:
    SortMethod Argomento facoltativo di tipo XlSortMethod. Specifica il tipo di ordinamento. Alcune di queste costanti sono disponibili in base al supporto linguistico selezionato o installato.

    XlSortMethod può essere rappresentato da una delle seguenti costanti XlSortMethod.
    xlStroke Ordina in base alla quantità di battute per ciascun carattere.
    xlPinYin predefinito. Tipo di ordinamento fonetico dei caratteri cinesi.


    Hai provato semplicemente a omettere il parametro SortMethod?
    ActiveWorkbook.Worksheets("Foglio2").[B3:B5].Sort Key1:=[B3], Order1:=xlAscending, Header:=xlGuess






  • di Luca (utente non iscritto) data: 11/11/2013 11:28:39

    Ho fatto un po' di prove, partendo da queste due istruzioni:

    UltimaRiga = Range("B65536").End(xlUp).Row
    sh2.Sort.SortFields.Add Key:=Range("B3:B" & UltimaRiga) _

    Ora, se metto solo:
    , Order1:=xlAscending, Header:=xlGuess
    mi da il solito Errore di runtime 448 Impossibile trovare argomento predefinito.

    L'unico modo in cui NON mi da quell'errore è quello scritto da isy:
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal (o con DataOption:=xlSortTextAsNumbers)
    Ma non ordina.

    Sulla base della macro che ho registrato con excel (che ho postato prima), servirebbe aggiungere Orientation = xlTopToBottom , SortMethod = xlPinYin e forse anche altro, affinchè funzioni l'ordinamento.

    Ma qualsiasi cosa aggiungo (anche solo Header:=xlGuess) mi da quel maledetto errore. Quello che mi chiedo è, se effettivamente With è utilizzato per semplificare la scrittura del codice, ci deve essere anche un modo per NON usarlo. Qual è??

    P.S: grazie comunque per il supporto.








  • di gaetanopr (utente non iscritto) data: 11/11/2013 13:52:42

    Ciao Luca io non riscontro nessun problema, uso excel 2007 e l'ordinamento funziona perfettamente almeno utilizzando il file che avevi allegato sul forum
    Il tuo file originale è lo stesso di quello postato? bisognerebbe che allegassi il file con la macro che restituisce gli errori da te descritti, perché così è difficile aiutarti non riscontrando le stesse tue anomalie.



  • di Luca (utente non iscritto) data: 11/11/2013 17:16:06

    Ciao,
    che codice hai usato per l'ordinamento? quello che ha postato isy?

    Ho allegato il file esempio2. La macro di riferimento è prova_ordinamento_old. Sono presenti entrambe le formule che hai postato in precedenza, una è ovviamente commentata.
    Nell'ordinamento sono presenti anche i comandi aggiuntivi, che mi danno il famoso errore 448. Se li tolgo, e lascio solo il codice postato da isy, ottengo questo:

    24/03/2014 30
    22/10/2014 80
    14/09/2014 60

    Non sono ordinate. Le ultime 2 colonne vanno invertite.



  • di gaetanopr data: 11/11/2013 18:49:33

    Ti allego file con la macro che ho usato io



  • di Luca (utente non iscritto) data: 12/11/2013 12:31:38

    Ti ringrazio molto. In effetti così funziona.

    Se non sbaglio è analogo al codice che restituisce excel quando registro macro.

    E' comunque un ottima soluzione, solo che, non conoscendolo, avrei preferito non usare with.
    Mi sfugge il perchè non posso usare quei comandi fuori da with, non capisco perchè non riesco a mettere questi: , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
    xlSortTextAsNumbers

    dentro il With..

    Bho...la cosa mi intristisce. :(



  • di gaetanopr (utente non iscritto) data: 12/11/2013 12:43:20

    Ciao Luca il costrutto With serve ad effettuare più operazioni sullo stesso oggetto, quindi semplifica la scrittura del codice ma soprattutto velocizza l'esecuzione dello stesso, quindi non ha neanche a che vedere con il mancato funzionamento della macro, anzi dovresti acquisirne il funzionamento e utilizzarlo per ottimizzare il codice.



  • di Luca (utente non iscritto) data: 13/11/2013 16:12:52

    Ok, è un ottimo consiglio.

    Solamente sembra che la macro senza WITH non funzioni. Su questo siamo d'accordo?



  • di Vecchio Frac data: 13/11/2013 17:14:50

    Non ha molto senso.
    With è solo un gestore di contesto.
    Usarlo o non usarlo: dipende da quanto si vuole smanettare con il copia e incolla degli oggetti padre.
    Per il resto non influisce sul codice.





  • di Luca (utente non iscritto) data: 14/11/2013 16:39:00

    Perfetto: allora perchè non riusciamo a far funzionare la macro senza with?? :(

    E' solo per capire..



  • di gaetanopr (utente non iscritto) data: 14/11/2013 20:06:06

    Ecco un esempio senza With

    Uriga = sh2.Cells(Rows.Count, 2).End(xlUp).Row
    sh2.Range("B3:C" & Uriga).Sort Key1:=Range("B3:B" & Uriga), Order1:=xlAscending, DataOption1:=xlSortNormal



  • di Luca (utente non iscritto) data: 15/11/2013 13:12:04

    Sei un genio!! Grande! Grandissimo!!

    Ora, perchè questo:
    UltimaRiga = Range("B65536").End(xlUp).Row
    sh2.Sort.SortFields.Add Key:=Range("B3:B" & UltimaRiga) _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

    in tutte le sue varianti non ordina oppure da errore come riportato nei post precedenti e il tuo codice no?

    La cosa che mi salta all'occhio è che il campo SortFields non è specificato. Insomma, non mi sembra sia scritto da nessuna parte quale è il range della tabella che deve ordinare...è possibile che sia questo il problema?

    Grazie ancora di tutto!!



  • di Vecchio Frac data: 15/11/2013 16:58:22

    cit. "Ecco un esempio senza With"
    ---> E' come l'avevo proposto io qualche giorno fa :) solo che Gaetano si piglia tutto il merito ^_^





  • di Luca (utente non iscritto) data: 15/11/2013 17:04:55

    Ti chiedo scusa.

    Ti riferisci per caso al post del 11/11/2013 10:13:01?

    Questo codice, quindi-->ActiveWorkbook.Worksheets("Foglio2").[B3:B5].Sort Key1:=[B3], Order1:=xlAscending, Header:=xlGuess

    Ero sicuro di averlo provato e che non funzionava...:mumble:

    Sorry.



  • di Vecchio Frac data: 15/11/2013 18:12:48

    Niente di cui scusarsi ti prego... era una battuta, notate le faccine ^_^





  • di Luca (utente non iscritto) data: 28/11/2013 14:28:23

    Salve,
    scusate se ritiro su questo thread, ma sto apportando delle modifiche al codice, e purtroppo sono di nuovo in difficoltà.
    In pratica, questa volta, il codice, oltre a restituire la variabile nuovadata che è stata calcolata in precendenza, anche una variabile primo_flusso pari a nuovadata con 6 mesi in meno.
    Per fare ciò sto utilizzando la funzione DATA.MESE (ovviamente in inglese) e sto inoltre utilizzando una versione super semplificata del codice: le altre cose potranno essere aggiunte dopo.

    Ho fatto vari tentativi, ma tutti terminano con le celle con #VALORE.

    La cosa "strana" è che se copio nelle celle "nuovadata" e poi da excel, quindi non dalla macro, applico la formula, questa funziona senza problemi. Quello che mi viene in mente è che la variabile nuovadata passata a primo_flusso non gli piaccia, ma non ho capito perchè.

    Qualcuno può aiutarmi?

    Grazie mille!
     
    Sub prova_ordinamento_multianno()
    
    Set sh1 = Workbooks("copia di esempio.xlsm").Worksheets("foglio1")
    Set sh2 = Workbooks("copia di esempio.xlsm").Worksheets("foglio2")
    Set SourceRange = sh2.Range("C3")
    
     Dim oneRange As Range
     Dim aCell As Range
    
     UltimaRigafoglio1 = sh1.Range("H65536").End(xlUp).Row
     Set oneRange = sh1.Range("H9:H" & UltimaRigafoglio1)
     Set aCell = sh1.Range("H9")
      
     'seleziono la prima cella in cui deve copiare delle date
     
     Mese = Month(sh1.Range("H3"))
     
     Sheets("Foglio2").Activate 
     sh2.Range("B3").Select
      
     For Each aCell In oneRange
       
      'non funzionano 
      'nuovadata = Evaluate("=DATE(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!H3),2013,2014 ),MONTH(Foglio1!" & aCell.Address & "),Day(Foglio1!" & aCell.Address & "))")
      'nuovadata = Evaluate("=DATE(IF(MONTH(Foglio1!" & aCell.Address & ")>MONTH(Foglio1!H3),2013,2014 ),MONTH(Foglio1!" & aCell.Address & "),Day(Foglio1!" & aCell.Address & "))")
      
      'non funziona neanche così
      anno = IIf(Month(aCell) > Mese, 2013, 2014)
      nuovadata = DateSerial(anno, Month(aCell), Day(aCell))
      
      primo_flusso = Evaluate("=EDATE(nuovadata;-6)")
      ActiveCell.Value = primo_flusso
      ActiveCell.Offset(1, 0).Select
    
     Next
    
    End Sub



  • di Luca (utente non iscritto) data: 28/11/2013 14:36:14

    Scusate, ho risolto facendo in questo modo:

    Sembra funzionare...
     
      nuovo_mese = Month(aCell) - 6
      primo_flusso = DateSerial(anno, nuovo_mese, Day(aCell))
    



  • di Luca (utente non iscritto) data: 28/11/2013 15:43:56

    Scusatemi, sto facendo un po' di prove con le date e veramente ne sto uscendo pazzo. Ovviamente sono cose che mi servono per la macro che sto sviluppando.

    Ipotizziamo semplicemente che io debba scrivere in una variabile il valore di una data e poi copiarlo in una cella. Per una serie di lunghi motivi devo per forza usare una variabile, quindi niente Range.formula..

    Ho fatto i seguenti tentativi:

    Possibile che funziona solo il caso 2?? perchè il 3 non va?? che differenza c'è tra l'istruzione "g = Day(sh1.Range("H3"))" e "oggi = Today(sh1.Range("H3"))"??

    Grazie a tutti!
     
    '1)
    oggi = Evaluate("=today(sh1.Range(""H3""))")
    Range("N10").Value = oggi
    
    'restituisce il solito #valore
    
    '2)
    g = Day(sh1.Range("H3"))
    m = Month(sh1.Range("H3"))
    a = Year(sh1.Range("H3"))
    oggi = DateSerial(a, m, g)
    Range("N10").Value = oggi
    
    'funziona.
    
    '3)
    oggi = Today(sh1.Range("H3"))
    Range("N10").Value = oggi
    
    'da errore-->sub o function non definita!
    



  • di scossa data: 28/11/2013 15:53:57

    @luca:
    1) la funzione today() non esiste.

    3) la funzione today() non esiste.




  • di Luca (utente non iscritto) data: 28/11/2013 16:23:11

    Uhm...sicuro? su office.microsoft.com mi dice di si. Purtroppo non posso postare link :(

    In ogni caso, anche sostituendola con =oggi() non cambia niente...



  • di scossa data: 28/11/2013 16:34:34

    cit luca "...Uhm...sicuro? su office.microsoft.com mi dice di si. Purtroppo non posso postare link :( "

    stiamo parlando di VBA, ed in VBA la funzione today() non esiste, esiste Date e Now, la prima restituisce la data corrente, la seconda restituisce data e orario.



  • di Mister_x (utente non iscritto) data: 28/11/2013 16:40:11

    ciao

    TODAY() in inglese
    OGGI() Italiano
    HEUTE() Tedesco
    AUJOURDHUI() Francese
    HOY() Spagnolo
    СЕГОДНЯ() Russo

    vedi help di excel per la funzione OGGI()

    ciao





  • di scossa data: 28/11/2013 16:43:38

    @Mister_X: stiamo parlando di VBA!



  • di Mister_x (utente non iscritto) data: 28/11/2013 17:11:47

    ciao Scossa
    mi riferivo a Luca che nella sua sub() di VBA a inserito la funzione TODAY() e parla di un link che spiega come utilizzarla
    questa funzione lo so che in VBA non e' contemplata ma esiste solamente in excel inglese, dato che in VBA abbiamo due metodi per ricercare la data di oggi

    oggi = Date
    oggi = CDate(Format(Now, "dd/mm/yyyy"))

    ciao Mister_x





  • di Vecchio Frac data: 28/11/2013 21:23:35

    cit. " in VBA abbiamo due metodi per ricercare la data di oggi "
    ---> Di più... ^_^
    ...e scoprite le differenze :P
     
    In VBA:
    oggi = [NOW] restituisce "28/11/2013 21:20:28"
    oggi = [NOW()] restituisce " 41606,8895671296"
    oggi = [TODAY] restituisce "Errore 2029"
    oggi = [TODAY()] restituisce "41606"






  • di scossa data: 28/11/2013 23:01:09

    Non capisco perché complicarsi la vita, visto che in VBA abbiamo già Date(), Now() e Time() per gestire date/orari .....

    comunque, premesso che il tuo esempio indica che oggi è dichiarata come Single (o Double), direi che, a parte il comportamento anomalo di [Now],

    oggi = [NOW()] restituisce " 41606,8895671296"
    oggi = [TODAY] restituisce "Errore 2029"
    oggi = [TODAY()] restituisce "41606"

    sono la forma abbreviata di:
    oggi = evaluate("NOW()") restituisce " 41606,8895671296"
    oggi = evaluate("TODAY") restituisce "Errore 2029"
    oggi = evaluate("TODAY()") restituisce "41606"

    quindi vengono valutate "lato celle", il che non mi pare efficiente.

    Da notare che, lato celle, né Today() (e l'equivalente italiano Oggi()) né Now() (e l'equivalente italiano Adesso()) sono disponibili in Application.WorksheetFunction esistendo le sopracitate equivalenti funzioni VBA native.



  • di Vecchio Frac data: 29/11/2013 09:33:52

    @scossa
    Considerazioni importanti, e ti ringrazio, forse ti manca da parte mia la precisazione che in questo forum si fa (anche) formazione/informazione e non soltanto risoluzione di problemi. Anzi direi che non essendo un forum di consulenze, essenzialmente si tende a insegnare a pescare piuttosto che a fornire il pesce già pescato :)
    La ricerca dell'efficienza va benissimo (io stesso tendo a ottenere il massimo col minimo sforzo).
    Spesso però come sai ci sono soluzioni multiple allo stesso problema o se vogliamo approcci diversi per la risoluzione. Mostrare agli utenti più possibilità per vedere lati diversi della stessa medaglia non è male, a volte anche a scapito dell'efficienza.
    Quindi lungi dal "complicarsi la vita", lo stimolo a scoprire la possibilità di richiamare nel codice le funzioni native può essere utile per qualcuno per figurarsi il necessario completamento delle funzioni Excel con VBA. Ecco il senso del mio invito a "scoprire le differenze"... questo non è un codicificio ma un luogo di scambio.
    IMHO.





  • di Luca (utente non iscritto) data: 29/11/2013 11:12:05

    Grandissimi, davvero!

    Post utili, interessanti e pieni di spunti. Ora va.

    Grazie ancora!



  • di scossa data: 29/11/2013 12:39:59

    @Vecchio Frac: "...forse ti manca da parte mia la precisazione che in questo forum si fa (anche) formazione/informazione e non soltanto risoluzione di problemi. Anzi direi che non essendo un forum di consulenze, essenzialmente si tende a insegnare a pescare piuttosto che a fornire il pesce già pescato :) "

    Condivido pienamente; pensa che la massima nella mia firma (in altri forum) è:
    "Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)"



  • di Luca (utente non iscritto) data: 29/11/2013 15:54:20

    Nuovi problemi.. :(

    Ora ho questa necessità, sempre per la macro che sto realizzando, per sostituire l'autofill che non va più bene per quello che ora mi serve.

    Non so quanto riuscirò a spiegarmi bene a parole, quindi allegherò un file. In pratica, se vi ricordate, ho un ciclo for che, appunto, cicla delle date memorizzate nella variabile aCell, le modifica e le copia su un altro foglio.

    Per ogni data aCell ciclata la macro deve anche calcolare il prodotto di due valori presenti sulla stessa riga in colonne attigue.

    La mia idea era quindi usare queste istruzioni
    1)mi memorizzo in due variabili a e b il valore delle celle presenti 4 e 5 colonne spostate a dx
    a = Selection(aCell).Cells(0, 4).Value
    b = Selection(aCell).Cells(0, 5).Value

    2)copio il prodotto di a e b nella cella desiderata
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Formula = a * b

    ActiveCell è stato impostato correttamente in precedenza.

    Quello che succede è che mi scrive 0.
    Allora ho provato a fare le seguenti cose:
    1)magari ho contato male le colonne ed ho provato a fare con 3,4 e 5,6, ma niente.
    2)ho provato ad usare Offset, ma niente.
    3)ho provato a scrivere il valore di a o b o a*b con Range("cella").Value, ma niente.

    La cosa strana è che se invece di scrivere la formula, ma solo a o solo b, non scrive niente. Quindi per me il problema è proprio al passo 1).
    Possibile?

    Riposto sotto il codice completo:
     
    Sub macro()
    
    Set sh1 = Workbooks("allegato_date.xlsm").Worksheets("foglio1")
    Set sh2 = Workbooks("allegato_date.xlsm").Worksheets("foglio2")
    Set SourceRange = sh2.Range("C3")
    
     Dim oneRange As Range
     Dim aCell As Range
     
     'definisco il range delle date
     UltimaRigafoglio1 = sh1.Range("H65536").End(xlUp).Row
     Set oneRange = sh1.Range("H9:H" & UltimaRigafoglio1)
     Set aCell = sh1.Range("H9")
    
     Mese = Month(sh1.Range("H3"))
    
     'seleziono la prima cella in cui deve copiare delle date
     Sheets("Foglio2").Activate
     sh2.Range("B3").Select
    
      For Each aCell In oneRange
      
      anno = IIf(Month(aCell) > Mese, 2013, 2014)
      nuovadata = DateSerial(anno, Month(aCell), Day(aCell))
      
      oggi = Date
      nuovo_mese = Month(aCell) - 6
      altro_flusso = DateSerial(anno, nuovo_mese, Day(aCell))
         
         If (altro_flusso < oggi) Then
         nuovo_mese = Month(aCell) + 6
         altro_flusso = DateSerial(anno, nuovo_mese, Day(aCell))
         End If
      
      ActiveCell.Value = nuovadata
      
        a = Selection(aCell).Cells(0, 3).Value
        b = Selection(aCell).Cells(0, 4).Value
    
      'mi sposto a destra
      ActiveCell.Offset(0, 1).Select
      'ora devo inserire il risultato del prodotto relativo alla data di interesse
      ActiveCell.Formula = a * b
      
      'mi sposto sotto e a sx
      ActiveCell.Offset(1, -1).Select
      'copio la data differita di 6 mesi
      ActiveCell.Value = altro_flusso
      ActiveCell.Offset(1, 0).Select
     
     Next
    
    
    End Sub
    



  • di Luca (utente non iscritto) data: 29/11/2013 15:55:45

    Ho allegato il file-->allegato_date



  • di scossa data: 29/11/2013 16:16:43

    Sono di corsa quindi mi limito ad un suggerimento:
    evita tutti quegli inutili Select ed ActiveCell.



  • di scossa data: 29/11/2013 17:46:50

    Partiamo dall'inizio.

    Puoi spiegare *cosa* vuoi fare (anziché *come* vuoi farlo) in modo preciso e chiaro?
    Cosa rappresentano le date nel Foglio1?
    Cosa rappresentano le date nel Foglio2?
    Le colonne G ed I, che nel file di esempio sono vuote, sono realmente vuote o nel file originale contengono dati?
    ......




  • di Raffaele_53 (utente non iscritto) data: 29/11/2013 22:17:45

    Per quello che ho capito, l'avrei scritta così.

    Ciao scossa,
    almeno cosi mi controlli se l'ho scritta corretta
     
    Option Explicit
    Sub Calcola()
    Dim sh1 As Worksheet
    Dim sh2 As Worksheet
    Dim oneRange As Range, aCell As Range
    Dim A As Double, B As Double, UltimaRiga As Long, Riga As Long
    Dim mese As Integer, nuovo_mese As Integer, anno As Integer, nuovadata As Date, altro_flusso As Date, oggi As Date
    Set sh1 = Workbooks("allegato_date.xlsm").Worksheets("foglio1")
    Set sh2 = Workbooks("allegato_date.xlsm").Worksheets("foglio2")
    
     'UltimaRiga = sh2.Range("B" & Rows.Count).End(xlUp).Row
     'sh2.Range("B3:C" & UltimaRiga).ClearContents
     UltimaRiga = sh1.Range("H" & Rows.Count).End(xlUp).Row
     Set oneRange = sh1.Range("H9:H" & UltimaRiga)
     mese = Month(Date)
     Riga = 3
      For Each aCell In oneRange
        anno = IIf(Month(aCell) > mese, 2013, 2014)
        nuovadata = DateSerial(anno, Month(aCell), Day(aCell))
        oggi = Date
        nuovo_mese = Month(aCell) - 6
        altro_flusso = DateSerial(anno, nuovo_mese, Day(aCell))
            If (altro_flusso < oggi) Then
                nuovo_mese = Month(aCell) + 6
                altro_flusso = DateSerial(anno, nuovo_mese, Day(aCell))
             End If
        sh2.Cells(Riga, 2) = nuovadata
        A = aCell.Offset(0, 4).Value
        B = aCell.Offset(0, 5).Value
        sh2.Cells(Riga, 3) = A * B
        sh2.Cells(Riga + 1, 2) = altro_flusso
        Riga = Riga + 2
     Next
    Set sh1 = Nothing
    Set sh2 = Nothing
    Set oneRange = Nothing
    End Sub



  • di Luca (utente non iscritto) data: 30/11/2013 15:47:47

    @scossa:

    Allora, nel foglio finale le colonne G e I saranno piene.

    Le date nel foglio 1 rappresentano scadenze di bond. Le altre due colonne sono invece l'importo e il rendimento.
    Le date nel foglio 2 invece rappresentano le date dei prossimi stacco cedola con associato il relativo importo. Ovviamente se un bond è semestrale o trimestrale ci saranno 2 o 4 date di stacco cedola con relativi flussi.

    L'obiettivo finale prevede che la macro, semplicemente partendo dai dati presenti sul foglio 1 (più il numero di cedole che però starà scritto in un commento delle celle della colonna h) , restituisca i prossimi flussi di cassa ordinati per data.

    Fintanto che i flussi di cassa erano unici per bond (quindi per data presente sul foglio 1), quanto abbiamo ottenuto in precedenza, andava bene.

    Ora però, dato che la prima data può avere una singola data associata nel foglio 2, oppure più di una, l'autofill non può più essere utilizzato. Bisogna "lavorare" ogni data/bond singolarmente.

    Per ora sto studiando il caso per 2 flussi (da qua la variabile altro_flusso spostata di 6 mesi), poi penso che estenderlo per flussi = n sia fattibile. Ci metterò un po', ma l'obiettivo è questo :D

    Non so se ora è più chiaro... :)




  • di Luca (utente non iscritto) data: 30/11/2013 15:53:40

    @Raffaele_53

    Grazie per la risposta.

    Purtroppo ora non ho excel disponibile e non la posso provare. Leggendo noto che:

    1)hai salvato la riga in una variabile
    2)grazie a questo puoi usare l'istruzione Cells per copiare il risultato della formula, e inoltre non hai bisogno di tutti quegli ActiveCell e offset che usavo io.

    Però comunque mi chiedo, il tuo è uno dei modi, oppure usare "ActiveCell.Formula = a * b" può funzionare in qualche modo?



  • di scossa data: 30/11/2013 17:52:43

    cit. patel: "Ciao scossa, almeno cosi mi controlli se l'ho scritta corretta"

    Ottima.
    Semplificherei solo in un punto (vedi codice).
     
    Sub Calcola()
      Dim sh1 As Worksheet
      Dim sh2 As Worksheet
      Dim oneRange As Range, aCell As Range
      Dim A As Double, B As Double, UltimaRiga As Long, Riga As Long
      Dim mese As Integer, anno As Integer, nuovadata As Date, altro_flusso As Date, oggi As Date
      Set sh1 = ThisWorkbook.Worksheets("foglio1")
      Set sh2 = ThisWorkbook.Worksheets("foglio2")
      
      'UltimaRiga = sh2.Range("B" & Rows.Count).End(xlUp).Row
      'sh2.Range("B3:C" & UltimaRiga).ClearContents
      UltimaRiga = sh1.Range("H" & Rows.Count).End(xlUp).Row
      Set oneRange = sh1.Range("H9:H" & UltimaRiga)
      mese = Month(Date)
      Riga = 3
      For Each aCell In oneRange
        anno = IIf(Month(aCell) > mese, 2013, 2014)
        nuovadata = DateSerial(anno, Month(aCell), Day(aCell))
        oggi = Date
        
        '--- modifica -----
        altro_flusso = DateAdd("m", -6, nuovadata)
        If (altro_flusso < oggi) Then altro_flusso = DateAdd("m", 6, nuovadata)
        '--- fine modifica -----
        
        sh2.Cells(Riga, 2) = nuovadata
        A = aCell.Offset(0, 4).Value
        B = aCell.Offset(0, 5).Value
        sh2.Cells(Riga, 3) = A * B
        sh2.Cells(Riga + 1, 2) = altro_flusso
        Riga = Riga + 2
      Next
      Set sh1 = Nothing
      Set sh2 = Nothing
      Set oneRange = Nothing
    End Sub



  • di Raffaele_53 (utente non iscritto) data: 30/11/2013 19:58:42

    Grrr, L'unico pezzo che non ho voluto toccare

    Il tuo problema erano queste variabili non dichiarate correttamente
    Dim A As Double, B As Double

    Vada per la A (per sicurezza l'ho messo pure a lei), mà B con percentuale o virgola va dichiarata Double



  • di Scossa (utente non iscritto) data: 30/11/2013 20:09:47

    Errata:
    cit. patel: "Ciao scossa, almeno cosi mi controlli se l'ho scritta corretta"

    Corrige:
    cit. Raffaele: "Ciao scossa,....."



  • di Luca (utente non iscritto) data: 02/12/2013 15:46:23

    Grazie ancora per le risposte.

    Ho fatto un po' di prove e in realtà penso che il mio problema sia un altro. Sicuramente, come fai notare, è buona norma dichiarare le variabili come double, ma dato che il risultato è sempre un intero, anche senza funziona uguale.

    Invece, a quanto ho notato, il problema è proprio nell'istruzione:
    a = Selection(aCell).Cells(0, 4).Value
    b = Selection(aCell).Cells(0, 5.Value

    sostituendole, come hai scritto tu, con:
    A = aCell.Offset(0, 4).Value
    B = aCell.Offset(0, 5).Value

    funziona tutto a meraviglia.

    Non so perchè...



  • di scossa data: 02/12/2013 17:15:08

    cit. Luca:
    ".... il problema è proprio nell'istruzione:
    a = Selection(aCell).Cells(0, 4).Value
    b = Selection(aCell).Cells(0, 5).Value

    Non so perchè... "

    Perché Selection(aCell).Cells(0, 4).Value è priva di senso.



  • di Luca (utente non iscritto) data: 02/12/2013 17:33:17

    ah, ok, ti ringrazio.

    Non mi ricordo dove l'ho presa, penso di averla trovata da qualche parte su google..