Excel ricerca dati particolari



  • Excel, ricerca dati particolari
    di beppexile (utente non iscritto) data: 27/05/2015 16:52:29

    Salve a tutti, recentemente sto lavorando a un piccolo database, dove per ogni prodotto inserito, viene creato un lotto univoco, ricavato da anno, giorno e progressivo di inserimento.
    Mi spiego meglio.
    Se oggi 27-05-2015, viene caricato un prodotto nel database, viene creato il seguente lotto:
    1514701D, dove le prime 2 cifre (15) stanno per l'anno di inserimento, le successive 3 cifre (147) indicano il giorno contando dall'inizio dell'anno, e le finali (01D) indicano il primo prodotto caricato oggi.
    Ovviamente il secondo prodotto caricato oggi avrà il lotto 1514702D, e così via.
    Il mio problema è proprio nella creazione dei successivi lotti dopo il primo.
    Il lotto, viene creato automaticamente dalla data di inserimento.
    Quindi, a rigor di logica, ho impostato il codice nel seguente modo:
    scrivo la data e il codice mi genera automaticamente
    1- il numero dell'anno
    2- il numero del giorno
    3- il numero 01D (per il primo lotto)
    4- unisco i 3 codici precedentemente creati e li scrivo su una cella solo se non sia già presente lo 01D riferito a quella data, in tal caso, incremento di 1 portando il progressivo a 02D e rieseguo il passo 4
    e così via.
    Bene, fino al punto 3, nessun problema.... ma con i cicli for each sto impazzendo.
    Io non conosco bene il linguaggio VBA, sono un autodidatta, e mi chiedevo se qualche anima pia mi può spiegare come fare a risolvere questo problema.
    La data viene inserita tramite un DTPicker rinominato DataLotto, e all'evento Change viene scritto il lotto sul Range("PARK_DATA") collegato a una TextBox.
    Il codice che ho sviluppato finora è il seguente:
     
        '------------------------------------------------------------------------
        'INSERISCO LA DATA SU DATABASE(B2) --------------------------------------
        '------------------------------------------------------------------------
            'evitiamo i saltellamenti a schermo
                Application.ScreenUpdating = False
            'memorizzo la data impostata in DataLotto sulla variabile "d"
            'per poi scriverla sulla cella B2 del foglio DATABASE
                d = DataLotto.Value
                Sheets("DATABASE").Range("PARK_DATA") = d
        '------------------------------------------------------------------------
        'COSTRUISCO IL LOTTO ----------------------------------------------------
        '------------------------------------------------------------------------
            'PRIMA PARTE: ANNO
                'seleziono la cella con la data del lotto
                    Sheets("DATABASE").Select
                    Range("PARK_DATA").Select
                'assegno il valore della cella ad una variabile, che chiamo d1
                    d1 = Selection.Value
                'mi sposto sul foglio GEN_LOTTO per la ricerca sul Range("B1:K368")
                'della prima parte del lotto: il numero riferito all'anno
                    Sheets("GEN_LOTTO").Select
                'dichiariamo una variabile di tipo Object
                    Dim AL As Object
                'inizio il ciclo di ricerca: per ogni cella (AL) nel range B1:K368
                    For Each AL In Sheets("GEN_LOTTO").Range("B1:K368")
                'se il valore della cella (AL) è uguale al valore di d1
                    If AL.Value = d1 Then
                        'seleziono la cella (AL)
                            AL.Select
                        'mi sposto a inizio colonna e seleziono la cella inizio colonna
                            With ActiveCell
                            Cells(1, ActiveCell.Column).Select
                            End With
                        'assegno il valore di questa cella alla variabile anno
                            anno = Selection.Value
                            Range("PARK_ANNO") = anno
                    End If
                'fine ciclo di ricerca anno
                    Next
            'SECONDA PARTE: GIORNO
                'seleziono la cella con la data del lotto
                    Sheets("DATABASE").Select
                    Range("PARK_DATA").Select
                'assegno il valore della cella ad una variabile, che chiamo d2
                    d2 = Selection.Value
                'mi sposto sul foglio GEN_LOTTO per la ricerca sul Range("B1:K368")
                'della seconda parte del lotto: il numero riferito al giorno
                    Sheets("GEN_LOTTO").Select
                'dichiariamo una variabile di tipo Object
                    Dim GL As Object
                'inizio il ciclo di ricerca: per ogni cella (GL) nel range B1:K368
                    For Each GL In Sheets("GEN_LOTTO").Range("B1:K368")
                'se il valore della cella (GL) è uguale al valore di d2
                    If GL.Value = d2 Then
                        'seleziono la cella (GL)
                            GL.Select
                        'mi sposto a inizio riga e seleziono la cella inizio riga
                            With ActiveCell
                            Cells(ActiveCell.Row, 1).Select
                            End With
                        'assegno il valore di questa cella alla variabile giorno
                            giorno = Selection.Value
                            Range("PARK_GIORNO") = giorno
                    End If
                'fine ciclo di ricerca giorno
                    Next
            'TERZA PARTE: CONTATORE
                contatore = "01"
                Range("PARK_CONTATORE") = contatore
            'QUARTA PARTE: LETTERA FISSA
                lettera = "D"
            'a questo punto, se concateno le varie parti ho già il lotto, ma:
            '1)devo creare un contatore vero e proprio
            '2)devo verificare che non vi siano doppioni
        '------------------------------------------------------------------------
        'VERIFICO SE IL LOTTO E' UNICO E CREO IL CONTATORE ----------------------
        '------------------------------------------------------------------------
        
    'il mio problema è proprio qui, come fare???
    
        '------------------------------------------------------------------------
        'SCRIVO IL LOTTO SU DATABASE (PARK_LOTTO) -------------------------------
        '------------------------------------------------------------------------
            'seleziono la cella dove scrivere il lotto e lo assemblo
                Sheets("DATABASE").Select
                Range("PARK_LOTTO") = "" & anno & "" & giorno & "" & contatore & "" & lettera & ""
    



  • di Marius44 data: 27/05/2015 21:18:56

    E' sempre preferibile allegare file/files di ciò che si è già fatto per agevolare il lavoro di chi è disposto ad aiutarti.
    Ciò premesso, se ho capito bene il tuo problema sta nel contatore. Dal tuo listato apprendo che la data la assumi da DATALOTTO e poi la trascrivi in DATABASE Range PARK_DATA per le successive elaborazioni.
    Ecco.
    Perchè non inserisci il contatore in una cella vicina a PARK_DATA? Potresti assumerlo da qui, incrementarlo e costruire il lotto. Dopo aver completato salvi il lavoro (ed il contatore). Quando riapri per un nuovo carico hai il tuo contatore bello e pronto (da incrementare).
    Si può fare?
    Fammi sapere.



  • di beppexile (utente non iscritto) data: 28/05/2015 07:50:42

    Ho allegato il file.
    Il problema principale è che lavoro con circa 5000 lotti l'anno, e la tua idea sarebbe molto valida, solo che ogni nuovo giorno inizio a contare da 01D.
    Il file lo avevo sviluppato già anni fa con le formule inserite nelle celle di excel, ma dopo un anno circa è diventato talmente pesante che per aprirlo, nel frattempo potevi prendere caffè e brioches al bar.
    Pensavo che, facendogli fare i vari compiti in vba, solo quando sono richiesti e non tutti i calcoli all'apertura, avrei snellito la cosa.
    Di contro non conosco bene vba, e mi sto cimentando con varie guide trovate sul web, in particolare, credo di aver capito che mi serve un ciclo For each next nidificato in un ciclo for..... o al contrario... comunque, se dai un'occhiata al file, ho aggiunto tre colonne prima del lotto, dove in ognuna ho scomposto il lotto nelle varie parti; da li volevo fare la seguente cosa:
    inserisco la data su DataLotto, quindi con l'evento change genero il lotto con 01D finale per quella data e cerco, aiutandomi con le tre colonne le varie parti del lotto, per vedere che non ci siano doppioni, così facendo, se avessi trovato 01D finale, avrei voluto incrementare il valore di 1 e scrivere un lotto con 02D nella cella PARK_LOTTO. Ovviamente prima della scrittura definitiva, avrei ricercato nuovamente se esiste lo 02D è così via.................. ma forse ho complicato troppo le cose!!
    Ho allegato anche un'altro esempio di partenza da cui stavo partendo per fargli fare la ricerca incrociata che volevo ma... qualcosa non va!
     
    Sub prova()
    
        Sheets("DATABASE").Select
        Dim x As Boolean
        a = Range("PARK_ANNO").Value
        For Each AN In Range("A4:A5000")
            If AN = a Then
                x = True
            End If
        Next
        Dim y As Boolean
        g = Range("PARK_GIORNO").Value
        For Each GI In Range("B4:B5000")
            If GI = g Then
                y = True
            End If
        Next
        Dim z As Boolean
        c = Range("PARK_CONTATORE").Value
        For Each CO In Range("C4:C5000")
            If CO = c Then
            z = True
            End If
        Next
        If x = True Then
            If y = True Then
                If z = True Then
                    MsgBox (c + 1)
                Else
                    MsgBox (c)
                End If
            End If
        End If
    
    
    End Sub
    



  • di Marius44 data: 28/05/2015 13:47:36

    Purtroppo non ho Excel2010 ed non posso "lavorare" sul tuo file.
    Ti allego, però, il file Contatore.xls (Excel 2007) che potrebbe esserti d'aiuto.
    In altri termini il codice viene "costruito" dalle formule inserite nel foglio.
    Due accortezze:
    1a) devi prevedere nel tuo file a far registrare la data ed il cont_carico del carico che vai ad effettuare;
    2a) all'apertura del file (PRIMA DELLA REGISTRAZIONE DEL PRIMO CARICO) la cella cont_carico deve essere azzerata MANUALMENTE.
    Fammi sapere.
    Ciao



  • di Albatros54 data: 28/05/2015 14:48:26

    Idea: se nel foglio DATABSE nella colonna Parcheggio data , i dati sono messi in ordine crescente, potresti selezionare l'utima data inserita, spostarti anella colonna a SX, recuperare il codice Parcheggio lotto, dalla stringa recuperare l'utimo valore numerico e incrementarlo. Ti posto due righe di codice, che potrebbero essere un punto di partenza.
    Ciao
    gioacchino
     
     'TERZA PARTE: CONTATORE
             Sheets("DATABASE").Select
              Cells(2, 5).Activate
               
            If ActiveCell = d2 Then
            'Cells("PARK_data").Activate
            numero = ActiveCell.Offset(0, -1)
            contatore = Val(numero)
            contatore0 = 1
            contatore0 = Right(contatore, 1) + 1
            End If
                'contatore0 = 1
                'Range("PARK_CONTATORE") = contatore0
            'QUARTA PARTE: LETTERA FISSA






  • di beppexile (utente non iscritto) data: 28/05/2015 15:45:38

    Grazie per l'idea Albatros54, potrebbe essere una soluzione valida.

    Tuttavia stamani mi sono svegliato con una idea: applicare CONTA.SE al vba ---> CountIF
    è ho risolto nel seguente modo.

    Ovviamente devo provare tutti i vari casi che si possono creare, ma per i principali funziona alla grande.

    Grazie infinite a tutti per gli spunti.

    P.S.: mi rivolgo agli amministratori, come recupero i miei dati di registrazione del forum?
     
    Private Sub DataLotto_Change()
        '------------------------------------------------------------------------
        'INSERISCO LA DATA SU DATABASE(B2) --------------------------------------
        '------------------------------------------------------------------------
            'evitiamo i saltellamenti a schermo
                Application.ScreenUpdating = False
            'memorizzo la data impostata in DataLotto sulla variabile "d"
            'per poi scriverla sulla cella B2 del foglio DATABASE
                d = DataLotto.Value
                Sheets("DATABASE").Range("PARK_DATA") = d
        '------------------------------------------------------------------------
        'COSTRUISCO IL LOTTO ----------------------------------------------------
        '------------------------------------------------------------------------
            'PRIMA PARTE: ANNO
                'seleziono la cella con la data del lotto
                    Sheets("DATABASE").Select
                    Range("PARK_DATA").Select
                'assegno il valore della cella ad una variabile, che chiamo d1
                    d1 = Selection.Value
                'mi sposto sul foglio GEN_LOTTO per la ricerca sul Range("B1:K368")
                'della prima parte del lotto: il numero riferito all'anno
                    Sheets("GEN_LOTTO").Select
                'dichiariamo una variabile di tipo Object
                    Dim AL As Object
                'inizio il ciclo di ricerca: per ogni cella (AL) nel range B1:K368
                    For Each AL In Sheets("GEN_LOTTO").Range("B1:K368")
                'se il valore della cella (AL) è uguale al valore di d1
                    If AL.Value = d1 Then
                        'seleziono la cella (AL)
                            AL.Select
                        'mi sposto a inizio colonna e seleziono la cella inizio colonna
                            With ActiveCell
                            Cells(1, ActiveCell.Column).Select
                            End With
                        'assegno il valore di questa cella alla variabile anno
                            anno = Selection.Value
                            Range("PARK_ANNO") = anno
                    End If
                'fine ciclo di ricerca
                    Next
            'SECONDA PARTE: GIORNO
                'seleziono la cella con la data del lotto
                    Sheets("DATABASE").Select
                    Range("PARK_DATA").Select
                'assegno il valore della cella ad una variabile, che chiamo d2
                    d2 = Selection.Value
                'mi sposto sul foglio GEN_LOTTO per la ricerca sul Range("B1:K368")
                'della seconda parte del lotto: il numero riferito al giorno
                    Sheets("GEN_LOTTO").Select
                'dichiariamo una variabile di tipo Object
                    Dim GL As Object
                'inizio il ciclo di ricerca: per ogni cella (GL) nel range B1:K368
                    For Each GL In Sheets("GEN_LOTTO").Range("B1:K368")
                'se il valore della cella (GL) è uguale al valore di d2
                    If GL.Value = d2 Then
                        'seleziono la cella (GL)
                            GL.Select
                        'mi sposto a inizio riga e seleziono la cella inizio riga
                            With ActiveCell
                            Cells(ActiveCell.Row, 1).Select
                            End With
                        'assegno il valore di questa cella alla variabile giorno
                            giorno = Selection.Value
                            Range("PARK_GIORNO") = giorno
                    End If
                'fine ciclo di ricerca
                    Next
            'TERZA PARTE: CONTATORE
                Dim contA As Variant
                Dim contB As Variant
                Dim contatore As Variant
                'contatore = 1
                contA = 1
                contB = WorksheetFunction.CountIf(Sheets("DATABASE").Range("E4:E1000"), Range("PARK_DATA"))
                If contB = contA Then
                contatore = contA
                contatore = Format(contatore, "##00")
                ElseIf contB > contA Then
                contatore = contB + 1
                contatore = Format(contatore, "##00")
                Else
                contatore = contA
                contatore = Format(contatore, "##00")
                End If
                'Range("PARK_CONTATORE") = contatore
            'QUARTA PARTE: LETTERA FISSA
                lettera = "D"
        '------------------------------------------------------------------------
        'SCRIVO IL LOTTO SU DATABASE (PARK_LOTTO) -------------------------------
        '-----------------------------------------------------------------------
            'seleziono la cella dove scrivere il lotto e lo assemblo
                Sheets("DATABASE").Select
                Range("PARK_LOTTO") = "" & anno & "" & giorno & "" & contatore & "" & lettera & ""
    End Sub