2012-02-16 48 views
5

Ho una formula in C2, ad esempio =A2+B2. Ogni volta che C2 cambia valore (valore effettivo, non formula), voglio che la data e l'ora attuali siano aggiornate in D2.Aggiornamento automatico della data in una cella quando il valore di un'altra cella cambia (come calcolato da una formula)

Ho provato un sacco di codici e trucchi VBA e nessuno di loro funziona se una formula viene inserita in C2. MA se digito manualmente un valore in C2, la data e l'ora vengono aggiornate secondo necessità. Questo è ovviamente perché un valore reale è inserito/cambia - dove la formula rimane la stessa, per così dire.

Domanda: E 'possibile creare un codice VBA (o qualcos'altro) che aggiorna D2, quando il risultato della formula nei cambiamenti C2?

Se possibile, ho bisogno di questo per essere attivo per le celle C2: C30 (+ D2: D30 per la data + tempo)

Utilizzo di Excel 2010.

+1

"Ho provato un sacco di codici VBA" Cura di mostrarci [cosa hai provato?] (Http://mattgemmell.com/2008/12/08/what-have-y-tried/) –

risposta

10

Si potrebbe riempire la cella dependend (D2) da una funzione definita dall'utente (funzione macro VBA) che prende il valore della cella C2 come parametro di input, restituendo la data corrente come uscita.

Avere C2 come parametro di input per l'UDF in D2 indica a Excel che è necessario rivalutare D2 ogni volta che cambia C2 (ovvero se il calcolo automatico delle formule è attivato per la cartella di lavoro).

EDIT:

Ecco il codice:

Per l'UDF:

Public Function UDF_Date(ByVal data) As Date 

     UDF_Date = Now() 

    End Function 

Come Formula in D2:

=UDF_Date(C2) 

Si dovrà dare la D2-Cell un formato data-ora, o mostrerà un rappresentante numerico la data del valore di data.

Ed è possibile espandere la formula nell'intervallo desiderato trascinandola se si mantiene il riferimento C2 nella formula relativa D2.

Nota: Questo ancora potrebbe non essere la soluzione ideale, perché ogni volta che Excel ricalcola la cartella di lavoro la data in D2 sarà ripristinato al valore corrente. Per fare in modo che D2 rifletta solo l'ultima volta in cui C2 è stato modificato, ci dovrebbe essere una sorta di tracciamento dei valori passati di C2. Ciò potrebbe ad esempio essere implementato nell'UDF fornendo anche l'indirizzo al di là del valore del parametro di input, memorizzando i parametri di input in un foglio nascosto e confrontandoli con i valori precedenti ogni volta che viene richiamato l'UDF.

Addendum:

Ecco un esempio di implementazione di un UDF che tiene traccia delle modifiche dei valori delle celle e restituisce la data-tempo in cui è stato rilevato gli ultimi cambiamenti. Se lo si usa, si prega di essere consapevole del fatto che:

  • L'uso del UDF è la stessa come descritto sopra.

  • L'UDF funziona solo per intervalli di input a cella singola.

  • La cella valori sono tracciati memorizzando l'ultimo valore della cella e la data-tempo in cui la modifica è stata rilevata nelle proprietà del documento della lavoro. Se la formula viene utilizzata su set di dati di grandi dimensioni, la dimensione del file potrebbe aumentare notevolmente come per ogni cella monitorata da la formula aumenta i requisiti di archiviazione (ultimo valore della cella + data dell'ultima modifica.) Inoltre, forse Excel è non in grado di gestire quantità di proprietà del documento pari a e il codice potrebbe frenare a un determinato punto.

  • Se il nome di un foglio di lavoro viene modificato, tutte le informazioni di rilevamento delle celle contenute sono andate perse.

  • Il codice potrebbe frenare per valori di cella per i quali la conversione in stringa non è deterministica.

  • Il codice riportato di seguito è non testato e deve essere considerato solo come prova del concetto . Usalo a tuo rischio e pericolo.

    Public Function UDF_Date(ByVal inData As Range) As Date 
    
        Dim wb As Workbook 
        Dim dProps As DocumentProperties 
        Dim pValue As DocumentProperty 
        Dim pDate As DocumentProperty 
        Dim sName As String 
        Dim sNameDate As String 
    
        Dim bDate As Boolean 
        Dim bValue As Boolean 
        Dim bChanged As Boolean 
    
        bDate = True 
        bValue = True 
    
        bChanged = False 
    
    
        Dim sVal As String 
        Dim dDate As Date 
    
        sName = inData.Address & "_" & inData.Worksheet.Name 
        sNameDate = sName & "_dat" 
    
        sVal = CStr(inData.Value) 
        dDate = Now() 
    
        Set wb = inData.Worksheet.Parent 
    
        Set dProps = wb.CustomDocumentProperties 
    
    On Error Resume Next 
    
        Set pValue = dProps.Item(sName) 
    
        If Err.Number <> 0 Then 
         bValue = False 
         Err.Clear 
        End If 
    
    On Error GoTo 0 
    
        If Not bValue Then 
         bChanged = True 
         Set pValue = dProps.Add(sName, False, msoPropertyTypeString, sVal) 
        Else 
         bChanged = pValue.Value <> sVal 
         If bChanged Then 
          pValue.Value = sVal 
         End If 
        End If 
    
    On Error Resume Next 
    
        Set pDate = dProps.Item(sNameDate) 
    
        If Err.Number <> 0 Then 
         bDate = False 
         Err.Clear 
        End If 
    
    On Error GoTo 0 
    
        If Not bDate Then 
         Set pDate = dProps.Add(sNameDate, False, msoPropertyTypeDate, dDate) 
        End If 
    
        If bChanged Then 
         pDate.Value = dDate 
        Else 
         dDate = pDate.Value 
        End If 
    
    
        UDF_Date = dDate 
    End Function 
    
+0

+ 1 questo è un buon modo per farlo, non puoi davvero usare una formula poiché tutte le funzioni relative al tempo sono volatili e ricalcoli alla caduta di un cappello –

+0

Ciao e grazie per la risposta rapida. Ho provato quello che hai pubblicato, ma ho ottenuto un # NOME? anche se la cella è stata formattata per mostrare una data. – AlienHand

+0

#Nome? probabilmente significa che Excel non trova l'UDF. Dove hai memorizzato la funzione VBA, è dichiarato Pubblico e il nome corrisponde a ciò che hai scritto in D2? – Roman

0
Private Sub Worksheet_Change(ByVal Target As Range) 

    If Target.Address = "$C$2" Then 

     ActiveSheet.Range("D2").Value = Now() 

    End If 

End Sub 
4

Fai l'inserimento della data di condizione che la gamma.

Questo ha il vantaggio di non cambiare le date a meno che il contenuto della cella viene modificata, ed è nell'intervallo C2: C2, anche se il foglio è chiuso e salvato, non ricalcola meno che la cella adiacente i cambiamenti.

adattato da this tip e @ Paolo S risposta

Private Sub Worksheet_Change(ByVal Target As Range) 
Dim R1 As Range 
Dim R2 As Range 
Dim InRange As Boolean 
    Set R1 = Range(Target.Address) 
    Set R2 = Range("C2:C20") 
    Set InterSectRange = Application.Intersect(R1, R2) 

    InRange = Not InterSectRange Is Nothing 
    Set InterSectRange = Nothing 
    If InRange = True Then 
    R1.Offset(0, 1).Value = Now() 
    End If 
    Set R1 = Nothing 
    Set R2 = Nothing 
End Sub 
+0

Questo sembra molto elegante. Proveremo. Grazie! ; o) – AlienHand

+0

Test di questo ... – AlienHand

+0

Questo funziona solo se si modificano manualmente i dati all'interno dell'intervallo (ed è perfetto per quello). Ma se hai una formula nella cella (come faccio io) non aggiornerà/cambierà la data in cui vengono apportate modifiche. Ergo, non posso usarlo. Scusate. – AlienHand

-1

Il modo più semplice è quello di aggiungere =IF(B3="","Not Allocated",Now()) e cambiare il formato della colonna per la data e l'ora formato richiesto. Ma qui se la colonna B viene modificata, la data e l'ora della rispettiva colonna che ha bisogno dell'aggiornamento si aggiornerà automaticamente per tutte le colonne poiché non controlla il vecchio valore. Ma se va bene per ottenere l'ora corrente, questo può essere facilmente utilizzato.

Problemi correlati