ricerca di data e inserimento riga



  • ricerca di data e inserimento riga di Luca.Donati data: 10/01/2017 13:02:50

    Buongiorno e buon anno a tutti.
    Torno su questo forum dopo un bel po' di assenza.
    Sto tentando di fare l'inserimento di righe per un'agenda in un foglio che si chiama "age". Ogni riga, un evento; in col A la data e l'ora (gg/mm/aaaa hh:mm), sulle altre svariati dettagli per lo più in formato testo.
    Vorrei pilotare l'inserimento dei nuovi eventi da un altro foglio (tipo "home") ed ho iniziato la compilazione del codice vba qui sotto.
    La prima cosa che penso di dover fare è individuare la posizione in cui devo inserire la nuova riga e... non ci riesco.
    Bisogna infatti che le righe restino ordinate, per permettere sia a certe formule di ricerca di funzionare facilmente, sia a me di andare poi nel foglio "age" e raccapezzarmici.
    Il codice che vi posto è un po' disordinato perché comprende due strategie diverse che ho provato successivamente: una con Find, l'altra con Vlookup. Il blocco If, Else serviva a usare le due versioni di Vlookup, una con True, l'altra con False.

    In tutti i casi, qualcosa non va: come sta adesso mi dice all'ultima riga che la variabile oggetto o la variabile del blocco whit non è impostata (!). Se invece attivo le righe con Vlookup, mi da un errore run-time 1004 e dice che è impossibile trovare la proprietà Vlooup per la classe WorksheetFunction...
    Tutto questo mi pare assai bizzarro...
    Qualcuno mi saprebbe aiutare?
    Grazie, ciao.
     
    Public giorno As Date, r As Integer, c As Integer, Rig As Integer, dove As Range
    Sub InserAge()
    giorno = Range("ricerca").Value
    If Range("confr") = False Then 'in questa cella: =SE.ERRORE(CERCA.VERT(ricerca;age!InterAge;C$20;FALSO);FALSO)
        'r = WorksheetFunction.VLookup(giorno, Sheets("age").Range("InterAge"), 1, False)
        With Sheets("age").Columns("a:a")
            Set dove = .Cells.Find(What:=giorno, LookIn:=xlValues)
        End With
    Else 'cioè se l'occorrenza ESATTA esiste
        'r = WorksheetFunction.VLookup(giorno, Sheets("age").Range("InterAge"), 1, True)
        With Sheets("age").Columns("a:a")
            Set dove = .Cells.Find(What:=giorno, LookIn:=xlValues)
        End With
    End If
    'MsgBox dove
    dove.Select
    End Sub
    


  • di alfrimpa data: 10/01/2017 15:22:02

    Ciao Luca e bentrovato

    Quando in VBA il VLookup dà quell'errore vuol dire che il CERCA.VERT non va a buon fine e restituisce #ND.

    Fai le verifiche lato foglio con il normale CERCA.VERT inserendo gli stessi parametri che usi nel codice e vedi se questa restituisce il risultato corretto o un #ND.

    Alfredo


  • di Luca73 data: 10/01/2017 15:54:14

    Ciao Secondo me hai invertito il vero/falso di intervallo (vedi sotto)
    CERCA.VERT(valore; matrice_tabella; indice; [intervallo])
    Se intervallo è VERO o è omesso, verrà restituita una corrispondenza esatta o approssimativa. Se non viene trovata alcuna corrispondenza esatta, verrà restituito il successivo valore più grande, inferiore a valore.
    Se intervallo è FALSO, non sarà necessario ordinare i valori della prima colonna di matrice_tabella.

    tu scrivi

    Else 'cioè se l'occorrenza ESATTA esiste
    'r = WorksheetFunction.VLookup(giorno, Sheets("age").Range("InterAge"), 1, True)



  • di Luca.Donati data: 11/01/2017 11:32:12

    Per prima cosa grazie per le vostre risposte.
    Ho fatto i tentativi che avete detto (cioè scambiare True e False, incrociando ciascuno con occorrenze esistenti ed inesistenti), ma ho sempre, in tutti i casi, un errore.
    Invece, in un vecchio file ho ritrovato una vecchia macro, che funziona ancora, e che mi permette proprio di inserire una riga fra due valori ordinati (cioè quello che serve a me). Questa macro usa Match, e funziona in quel file. (La funzione è illustrata alla pagina h t t p s : / / msdn.microsoft.com/en-us/library/office/ff835873.aspx).

    Nel nuovo file con l'agenda, invece, si blocca proprio alla riga con Match e dice che il tipo non corrispnde...
    Mi viene in mente che qui in ufficio ho cambiato recentemente computer. Ma ché, per caso c'è qualche libreria o simili che mi sono scordato di attivare?
    Ho 5 riferimenti spuntati:
    - Visual Basic for Applications
    - Microsoft Excel 14.0 Object Library
    - OLE Automation
    - Microsoft Office 14.0 Object Library
    - Microsoft Forms 2.0 Object Library 
     
    Sub InserAge2()
    Dim giu As Integer, RgDest As Integer
    Dim valo As Date, q 'ho provato anche Dim valo senza specificare il tipo
    valo = Range("ricerca").Value
    giu = Application.Match(valo, Sheets("age").Columns("a:a")) 'SI BLOCCA QUI
    RgDest = Sheets("age").Range("A1").Row + giu ' inutile aggiungere 1 perché giu = spostamento rispetto alla cella "zero"
    MsgBox ("valore: " & valo & " - rango: " & giu & " - riga: " & RgDest)
    'q = Application.CountIf(Range(RgDest - 1 & ":" & RgDest - 1), cell.Value > 0)
    'If Cells(RgDest - 1, 1).Value = valo Then
    'q = Cells(RgDest - 1, 1).Value & "/" & Cells(RgDest - 1, 2).Value & "/" & Cells(RgDest - 1, 3).Value & "/" & Cells(RgDest - 1, 4).Value
    ' If q > "" Then
    '    r = MsgBox(q & Chr(10) & "Inserisco comunque la nuova scheda?", vbYesNo)
    '    If r = vbNo Then Exit Sub
    ' End If
    'End If
    '    Cells(RgDest, 1).EntireRow.Insert
    '    Call TrasfeDatiColRiga(ActiveCell.Column, RgDest)
    End Sub
    


  • di Luca73 data: 11/01/2017 14:06:05

    Allega un file per favore altrimenti diventa impossibile aiutarti al buio...


  • di Luca.Donati data: 12/01/2017 10:28:32

    Grazie dell'interessamento, Luca73.
    File di esempio inserito, alleggerito dai dati sensibili. Considera che non ho avuto il tempo di sgombrare il VBE da tutta la mondezza di macro, comunque le due su cui sto lavorando adesso sono: InserAge e InserAge2.
    Ciao. Luca


  • di Albatros54 data: 12/01/2017 11:20:21

    Prova cosi
     
    Sub InserAge2()
    Dim giu As Integer, RgDest As Integer
    Dim valo As Date, q
    valo = Range("ricerca").Value
    vlA = Sheets("age").Columns("a:a")<<=====Modifica
    giu = Application.Match(valo, vlA)<<=====Modifica
    RgDest = Sheets("age").Range("A1").Row + giu ' inutile aggiungere 1 perché giu = spostamento rispetto alla cella "zero"
    MsgBox ("valore: " & valo & " - rango: " & giu & " - riga: " & RgDest)
    'q = Application.CountIf(Range(RgDest - 1 & ":" & RgDest - 1), cell.Value > 0)
    'If Cells(RgDest - 1, 1).Value = valo Then
    'q = Cells(RgDest - 1, 1).Value & "/" & Cells(RgDest - 1, 2).Value & "/" & Cells(RgDest - 1, 3).Value & "/" & Cells(RgDest - 1, 4).Value
    ' If q > "" Then
    '    r = MsgBox(q & Chr(10) & "Inserisco comunque la nuova scheda?", vbYesNo)
    '    If r = vbNo Then Exit Sub
    ' End If
    'End If
    '    Cells(RgDest, 1).EntireRow.Insert
    '    Call TrasfeDatiColRiga(ActiveCell.Column, RgDest)
    End Sub


  • di Luca73 data: 12/01/2017 13:09:58

    Ciao
    ho provato alcune soluzioni e sono arrivato ad una possibile
    ti do' il consiglio poi prova tu ad implementarlo.
    la funzione match è l'equivalente italiano di =CONFRONTA(ricerca;age!A2:A41;1)
    Vedi L'help per tutti i dettagli
    Nel modo seguente la usi in VBNA per farti dare la posizione. Poi sai che la posizione è relatyiva ad A2 (prima riga delle date) e lì puoi inserire la riga che ti serve.
    Evaluate non l'avevo mai usato prima. ti valuta il valore di una formula senza passare da Worksheets function.


    Fammi sapere se funziona.


     
    Sub Prova
    With Worksheets(1)
       Dim pippo
        pippo = Evaluate("=MATCH(ricerca,age!A2:A41)")
    End With
    End Sub
    


  • di Luca.Donati data: 12/01/2017 15:22:22

    Grazie davvero a tutti e due.

    Luca73, purtroppo Match deve avere qualche particolarità di sintassi che non mi è chiara nel passaggio al VBA e mi restituisce un "errore 2029"; anche modificando quello che potevo intuitivamente (soprattutto come indicare il Range).
    All'occasione, se mi capita bene torno volentieri sullo studio di questa funzione.

    Albatros54, la tua modifica risolve!
    ...ma perché? Cioè, perché Application.Match interpreta bene il contenuto di una variabile e non sa leggere invece l'indicazione diretta di un valore?
    Non so se saprai rispondere a questo mio quesito, ma intanto io nel frattempo vado avanti così, poi torno qui a dare il codice completo.
    Grazie e a molto presto. Luca


  • di Luca.Donati data: 13/01/2017 16:00:47

    Ho cantato vittoria troppo presto.
    Application.Match funziona correttamente nel senso che non si blocca.
    Ma in realtà il risultato che fornisce è completamente anarchico: qualche volta cade dieci righe troppo in alto, qualche volta una mezza dozzina più in basso; mi ha perfino dato lo stesso valore per due date diverse che stanno a qualche riga l'una dall'altra.
    In un primo momento ho pensato che potesse dipendere dal formato di data americano a cui il VBE è tanto affezionato... Però se dopo la riga "valo = Range("ricerca").Value", aggiungo anche "valo = Format(valo, "dd/mm/aaaa hh:mm")", si blocca lì e mi dice che il formato non corrisponde.

    Riallego il codice per semplicità, anche se i cambiamenti sono quasi irrilevanti.
     
    Sub InserAge2()
    Dim giu As Integer, RgDest As Integer
    Dim valo As Date, q, vlA, app
    valo = Range("ricerca").Value
    'valo = Format(valo, "dd/mm/aaaa hh:mm")
    vlA = Sheets("age").Columns("a:a")
    giu = Application.Match(valo, vlA) '- 1 'dovrebbe essere meno uno perché parte da A1 - in realtà risultato anarchico
    RgDest = Sheets("age").Range("A1").Row + giu
    app = Sheets("age").Cells(RgDest, 5).Value
    MsgBox ("valore: " & valo & " - rango: " & giu & " - riga: " & RgDest & Chr(10) & app)
    End Sub