Excel ricerca dati particolari
Hai un problema con Excel? 
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 |
Vuoi Approfondire?