View Full Version : [Excel Vb] Controllo valori
Ciao a tutti, premetto che di excel ci ho sempre capito poco, ma mi è stata rifilata una magagna che devo risolvere, e non ho il tempo materiale di documentarmi per imparare le tonnellate di cose che non conosco:(
In pratica mi è stato consegnato un file excel con dentro varie macro, che svolgono diverse funzioni relative all'apertura e controllo di vari fogli contenuti in diversi file.
Devo scrivere una sub che viene attivata in caso di errore nel check di alcuni valori (in pratica se nelle celle di determinate colonne è contenuto un valore stringa invece di un reale).
Questa sub deve trovare le celle contenenti delle stringhe, ed il contenuto deve diventare il commento della cella in questione (esempio, se la cella a3 contiene il valore xyz4 questo deve diventare il suo commento, lasciandola vuota).
Considerato che nel momento in questa sub viene attivata io stò già lavorando nel foglio contenente l'errore devo trovare un modo per controllare quali celle di varie colonne presentano l'errore, e successivamente fare quanto scritto sopra) :(
Spero che qualcuno mi possa aiutare perchè sono davvero alla frutta.
Se vi serve saperlo uso office 2003
john_revelator
25-02-2008, 23:00
Premesso che non sono una cima di vba, una sub del genere dovrebbe andare bene.
Sub stringhe()
For Each cella In Selection.Cells
If Not IsNumeric(cella.Value) Then
cella.AddComment
cella.Comment.Visible = False
cella.Comment.Text Text:=cella.Value
cella.Value = ""
End If
Next
End Sub
Selezioni le celle che vuoi verificare e richiami la sub. Magari provala su una copia del tuo file. :D
E' possibile applicare il comando
For each cells in (colonna) ??
questo risolverebbe il problema completamente! ^^ grazie mille per la risposta!
john_revelator
26-02-2008, 12:18
Per una sola colonna
For Each cella In ActiveSheet.Range("A:A")
Questa invece esegue la macro sulle colonne A e B :)
For Each cella In ActiveSheet.Range("A:B")
Chiarissimo!!!
Ora, io sò che la prima riga utilizzata è la 4, e l'ultima viene determinata da un'altra routine chiamata tab_valori(3)
Quindi, per fare il controllo sulla colonna dalla riga che mi interessa fino a quella dovrei scrivere così?
For Each cells in ActiveSheet.Range("A4: Atab_valori(3)") ?
john_revelator
26-02-2008, 13:42
Dovrebbe essere così
For Each cells in ActiveSheet.Range("A4:A" & tab_valori(3))
In effetti sembra funzionare!!! grazie mille per l'aiuto che mi hai dato!!
Uff mi hanno rifilato una seconda routine da fare -_- provo a farla da solo! nel caso posso chiederti nuovamente qualche suggerimento per favore?
Ora scappo che vado a cercarmi un libro decente su excel
john_revelator
26-02-2008, 17:32
Se potrò esserti utile volentieri, altrimenti c'è gente molto più preparata di me che sicuramente ti darà una mano. :)
La seconda (ed utilma spero) routine che mi hanno rifilato è ancora più infida della prima -_-
In pratica deve prendere dei valori contenuti in certe celle di certe colonne e copiarli in un foglio contenuto in un altro file, salvandolo e rinominandolo col nome del foglio da cui ha preso i dati delle celle.
Inoltre poi deve chiudere il file da cui sono stati presi i dati senza salvarlo...
john_revelator
26-02-2008, 18:06
La seconda (ed utilma spero) routine che mi hanno rifilato è ancora più infida della prima -_-
In pratica deve prendere dei valori contenuti in certe celle di certe colonne e copiarli in un foglio contenuto in un altro file, salvandolo e rinominandolo col nome del foglio da cui ha preso i dati delle celle.
Inoltre poi deve chiudere il file da cui sono stati presi i dati senza salvarlo...
Questi valori vanno presi da degli intervalli di celle specifici oppure devono essere recuperati in base a qualche criterio?
Questi valori vanno presi da degli intervalli di celle specifici oppure devono essere recuperati in base a qualche criterio?
Nessuno criterio, intervalli di celle specifico
Da A:4 a A & tab_valori(3)
Idem con patate per le colonne D E G H J
e poi vanno ricopiati nel medesimo posto in un file diverso, che deve essere rinominato (e salvato) come il file da cui vengono presi i valori , che deve essere a sua volta chiuso senza essere salvato...
... non ho la minima idea di come codificarlo :((
Questi valori vanno presi da degli intervalli di celle specifici oppure devono essere recuperati in base a qualche criterio?
Allora, ho scritto una cavolata nel mio ultimo reply :) correggo
Devo copiare TUTTE le celle, a partire dalla riga 4 fino alla riga Tab_valori(3) di tutte le colonne comprese tra A e AVV
Facendo attenzione a non copiare eventuali formule ma solo i numeri.
Considerato che ogni file che apre ha più fogli da copiare.. come cavolo faccio a fare in modo che questa funzione copi tutto mettendolo al posto giusto?
-In pratica deve aprire un file excel
-Copiare il contenuto delle celle che ho elencato sopra nella stessa posizione in cui si trovano ma in un file diverso (esempio.xls)
-Salvare esempio.xls cambiandogli nome e mettendolo in uan certa directory ma lasciando il vecchio esempio.xls libero per essere riutilizzato
-Chiudere il file da cui sono stati copiati i valori senza salvare
Sono in panico, ho provato a studiarmi un pò di funzioni excel, credo che per la prima parte (e cioè copiare le celle) serva un metodo copy applicato ad un range.. ma non ho idea di come dirgli di andare a pescare esempio.xls e poi copiare tutti i fogli con lo stesso nome ecc ecc :(
Devo copiare TUTTE le celle, a partire dalla riga 4 fino alla riga Tab_valori(3) di tutte le colonne comprese tra A e AVV
Facendo attenzione a non copiare eventuali formule ma solo i numeri.
Considerato che ogni file che apre ha più fogli da copiare.. come cavolo faccio a fare in modo che questa funzione copi tutto mettendolo al posto giusto?
-In pratica deve aprire un file excel
-Copiare il contenuto delle celle che ho elencato sopra nella stessa posizione in cui si trovano ma in un file diverso (esempio.xls)
-Salvare esempio.xls cambiandogli nome e mettendolo in uan certa directory ma lasciando il vecchio esempio.xls libero per essere riutilizzato
-Chiudere il file da cui sono stati copiati i valori senza salvare
Mah... Si potrebbe semplificare un po' con una bella Macro che salva il file origine nel percorso specificato ( in questo modo risparmi un po' di passaggi inutili, apri di qua, copia/incolla, salva di là... ) dopo aver eliminato le celle che non interessano... Al salvataggio del file con nuovo nome/percorso, quello precedentemente aperto ( ossia il file origine ) viene chiuso in automatico senza salvataggio... ;)
Mah... Si potrebbe semplificare un po' con una bella Macro che salva il file origine nel percorso specificato ( in questo modo risparmi un po' di passaggi inutili, apri di qua, copia/incolla, salva di là... ) dopo aver eliminato le celle che non interessano... Al salvataggio del file con nuovo nome/percorso, quello precedentemente aperto ( ossia il file origine ) viene chiuso in automatico senza salvataggio... ;)
Il concetto l'ho capito, ma non ho idea di come scriverlo però :(
Cmq appena risolta questa magagna mi verrà dato del tempo per studiare excel, è assurdo lavorare in queste condizioni con delle scadenze così vicine.
in attesa di john il salvatore :mc:
Nessuno nessuno saprebbe darmi una manina? :(
Ok. Seguimi. Ti faccio un esempio utile.
Crea un file Excel... Nel mio esempio ho 3 Fogli, con tre tabelle dati ciascuno, che contengono sia numeri che formule.
La tabella dati su ogni foglio va da A4 a D6 [ A4 : D6 ].
Il file si chiama "sorgente.xls". Lo useremo per creare "esempio.xls".
Ora, devi inserire un CommandButton su Foglio1. Il codice che andrà ad eseguire il Click di CommandButton1 è questo :
Private Sub CommandButton1_Click()
If ThisWorkbook.Name <> "sorgente.xls" Then
Exit Sub
End If
SALVATAGGIO
End Sub
A questo punto, nell'editor VBA, crea un Modulo di codice, e mettici questo :
Public Sub SALVATAGGIO()
Dim percorso As String
percorso = ThisWorkbook.Path & "\"
Dim Foglio As Worksheet
For Each Foglio In ThisWorkbook.Sheets
Foglio.Select
Dim Cella As Range
For Each Cella In Foglio.Range("A4:" & "D6")
If Left(Cella.Formula, 1) = "=" Then
Cella.FormulaR1C1 = Cella.Text
End If
Next
Next
ThisWorkbook.SaveAs (percorso & "esempio.xls")
End Sub
Questo, con le opportune modifiche, risolve già gran parte di ciò che devi fare... Intanto prova... ;)
Ciao Marco, prima di tutto ti ringrazio per la risposta chiara ed esauriente chep roverò il prima possibile :)
Oggi mi sono finalmente comprato un libro su excel 2003 ("Le macro di Excel 2003")
Un pizzone da 500 pagine, però sembra chiaro e quindi mi servirà solo un pò di tempo per studiarlo.
Oggi al lavoro hanno criticato la routine per la quale ho aperto il thread, la prima, e cioè quella per il controllo degli errori in certe colonne -_-
Ti posto il codice intero, così che risulti più chiaro quanto stò per dire (fai conto che non l'ho scritto io, mi ci sono messo sopra solo dopo :( )
Public nomefo(1 To 10) As String, numscono As Integer, tab_range(1 To 7, 1 To 2) As String, tab_valori(1 To 5), tab_mesi(1 To 12) As String
Public tab_nomi(1 To 50, 1 To 2) As String, tab_bb(1 To 60, 1 To 2), tab_righe(1 To 4) As Integer
Public papero As range
Public erroritrovati(1 To 9) As String
Public i As Integer
Sub ricerca()
'
nomefo(1) = ActiveWorkbook.Path & "\"
nomefo(2) = ActiveWorkbook.Name
nomefo(3) = "C:\Lavori\Clienti\" 'Path Source
nomefo(4) = "C:\Lavori\ClientiNew" 'Path Destination
nomefo(5) = "ESEMPIO.XLS" 'Archivio Esempio (struttura)
nomefo(6) = Empty 'Nome Archivio Corrente
nomefo(7) = Empty 'Nome Foglio corrente
nomefo(8) = Empty
nomefo(9) = Empty
nomefo(10) = Empty
'range (rettangolo selezionato)
tab_range(1, 1) = "$A$4:$N$"
tab_range(2, 1) = "$Q$4:$Q$"
tab_range(3, 1) = "$S$4:$T$"
tab_range(4, 1) = "$AA$4:$AC$"
tab_range(5, 1) = "$AG$4:$AH$"
tab_range(6, 1) = "$AQ$4:$AQ$"
tab_range(7, 1) = "$AW$4:$AZ$"
'
tab_range(1, 2) = "$A$4"
tab_range(2, 2) = "$Q$4"
tab_range(3, 2) = "$S$4"
tab_range(4, 2) = "$AA$4"
tab_range(5, 2) = "$AG$4"
tab_range(6, 2) = "$AQ$4"
tab_range(7, 2) = "$AW$4"
'
tab_mesi(1) = "Gen"
tab_mesi(2) = "Feb"
tab_mesi(3) = "Mar"
tab_mesi(4) = "Apr"
tab_mesi(5) = "Mag"
tab_mesi(6) = "Giu"
tab_mesi(7) = "Lug"
tab_mesi(8) = "Ago"
tab_mesi(9) = "Set"
tab_mesi(10) = "Ott"
tab_mesi(11) = "Nov"
tab_mesi(12) = "Dic"
'
' Imposta il Ricalcolo Manuale
With Application
.Calculation = xlManual
.MaxChange = 0.001
End With
nrigacorr = 1
iswc = 0
papero1 = ""
papero2 = "ESEMPIO.xls"
MYPATH = nomefo(3) ' Imposta il percorso.
nomefo(6) = Dir(MYPATH & "*.XLS", vbNormal) ' Recupera la prima voce.
Do While nomefo(6) <> "" ' Avvia il ciclo.
tt = 0
Select Case nomefo(6)
Case papero1
iswc = 1
tt = 1
Case papero2
tt = 0
Case Else
If iswc = 0 Then
tt = 1
Else
tt = 1
End If
End Select
If tt = 1 Then
numscono = 0
Workbooks.Open Filename:=nomefo(3) & nomefo(5), UpdateLinks:=0 'Apre Esempio
'
Workbooks.Open Filename:=nomefo(3) & nomefo(6), UpdateLinks:=0 'Apre clientexx.XLS (old Format)
Windows(nomefo(6)).Activate
Calculate
n1 = Sheets.Count 'determina numero di fogli presenti
i = 1
Do While i <= n1
Windows(nomefo(6)).Activate
Sheets(i).Select
Call foglio
i = i + 1
Loop
'
Application.DisplayAlerts = False
Windows(nomefo(6)).Close savechanges:=False 'Chiude clientexxx.xls (old format)
Call ordinafo
Windows(nomefo(5)).Close savechanges:=True, Filename:=nomefo(4) & "\" & nomefo(6)
Application.DisplayAlerts = True
End If
nomefo(6) = Dir ' Legge la voce successiva.
Loop
'
Calculate
With Application
.Calculation = xlAutomatic
.MaxChange = 0.001
End With
End Sub
Sub foglio()
'
nomefo(7) = Trim(ActiveSheet.Name)
Select Case nomefo(7)
Case Is = "Ord.", "ord.", "ord", "Ord", "Parametri"
' scarta il foglio
Case Else
maxblk = 20
numblk = 0
tab_valori(3) = 4 'Riga Corrente nel foglio Source
tab_righe(1) = 0 'Prima riga Usata nel foglio source
tab_righe(2) = 0 'ultima riga usata nel foglio source
nofine = True
Do While nofine
If Cells(tab_valori(3), 3).Borders(xlEdgeBottom).LineStyle = xlContinuous And Cells(tab_valori(3), 3).Borders(xlEdgeBottom).Weight = xlThick Then
nofine = False
End If
If Len(Cells(tab_valori(3), 3)) < 3 And Len(Cells(tab_valori(3), 6)) < 4 Then
numblk = numblk + 1
If numblk > maxblk Then
nofine = False
End If
Else
If tab_righe(1) = 0 Then
tab_righe(1) = tab_valori(3)
End If
tab_righe(2) = tab_valori(3)
numblk = 0
End If
tab_valori(3) = tab_valori(3) + 1
Loop
'
tab_valori(1) = Empty 'Data Foglio
tab_valori(2) = Trim(Cells(1, 3)) 'Ragione Sociale
tab_valori(4) = 0 'Indicatore di errore
tab_valori(5) = Empty 'Nome foglio
If IsDate(Cells(1, 17)) Then
tab_valori(1) = CDate(Cells(1, 17))
End If
'
errore = 0
aa = "$A$4:$AZ$" & tab_valori(3)
On Error GoTo pippo
papero = range(aa).SpecialCells(xlCellTypeFormulas, 16).Select
On Error GoTo 0
If errore = 0 Then
Call modisource
End If
'
If nomefo(7) = "Vari" Then
J = 1
Do While J < 8
zonadati = tab_range(J, 1) & tab_valori(3)
Call copiazona(zonadati, tab_range(J, 2))
J = J + 1
Loop
Rows(tab_valori(3) + 1 & ":500").Delete
Call completa_VARI
Else
If Not IsEmpty(tab_valori(1)) And IsDate(tab_valori(1)) Then
b1 = Month(tab_valori(1))
b2 = Year(tab_valori(1))
tab_valori(5) = tab_mesi(b1) & Right(Format(b2, "0000"), 2)
Else
numscono = numscono + 1
tab_valori(5) = "TMP" & Format(numscono, "000")
End If
Call creafoglio
zonadati = "$A$4:$AZ$" & tab_valori(3)
Call copiazona(zonadati, "$A$4")
End If
End Select
Exit Sub
'
pippo:
errore = 1
Resume Next
End Sub
Sub copiazona(a1, a2)
'
Windows(nomefo(6)).Activate 'Archivio Source
Sheets(nomefo(7)).Select 'Foglio source
range(a1).Select
Selection.Copy
'
Windows(nomefo(5)).Activate 'Archivio Destination
If nomefo(7) = "Vari" Then
Sheets("Vari").Select 'Foglio Destination
Else
Sheets(tab_valori(5)).Select
End If
range(a2).Select
On Error GoTo pippo
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
On Error GoTo 0
If Not nomefo(7) = "Vari" Then
Sheets("Vari").range("$A$1:$AZ$3").Copy
range("$A$1").PasteSpecial
Cells(1, 17) = tab_valori(1)
End If
Exit Sub
'
pippo:
Windows(nomefo(2)).Activate
Sheets("Parametri").Cells(nrigacorr, 1) = nomefo(6)
Windows(nomefo(2)).Activate
Sheets("Parametri").Cells(nrigacorr, 2) = nomefo(7)
nrigacorr = nrigacorr + 1
Windows(nomefo(5)).Activate 'Archivio Destination
If nomefo(7) = "Vari" Then
Sheets("Vari").Select 'Foglio Destination
Else
Sheets(tab_valori(5)).Select
End If
Resume Next
End Sub
Sub creafoglio()
'
Windows(nomefo(5)).Activate 'Archivio Destination
On Error GoTo creafo
tab_valori(4) = 10
Sheets(tab_valori(5)).Select
On Error GoTo 0
Exit Sub
'
creafo:
If Err.Number = 9 Then 'Errore=9 ==> foglio inesistente
Sheets.Add after:=Worksheets(Worksheets.Count)
Sheets(Sheets.Count).Name = tab_valori(5)
Sheets(tab_valori(5)).Move after:=Sheets("Vari")
tab_valori(4) = 0
Resume
End If
End Sub
Sub ordinafo()
' questa sub ordina i fogli con NOME=DATA in ordine decrescente
Windows(nomefo(5)).Activate
k = 0
n1 = Sheets.Count
i = 1
Do While i <= n1
nomefo(7) = Trim(Sheets(i).Name)
aa = "01-" & Left(nomefo(7), 3) & "-" & Right(nomefo(7), 2)
If IsDate(aa) Then
k = k + 1
tab_nomi(k, 1) = nomefo(7)
tab_nomi(k, 2) = Format(CDate(aa), "DD-MM-YYYY")
End If
i = i + 1
Loop
'
Windows(nomefo(2)).Activate
Sheets("Appoggio").Select 'Vuota il foglio appoggio
range("$A$2:$Z$2000").Select
Selection.ClearContents
J = 2
Do While J <= k + 1
Cells(J, 1) = tab_nomi(J - 1, 1)
Cells(J, 2) = tab_nomi(J - 1, 2)
J = J + 1
Loop
bb = "$A$1:$B$" & k + 1
range(bb).Select
Selection.Sort key1:=range("B1"), order1:=xlDescending, header:=xlYes
J = 2
Do While J <= k + 1
tab_nomi(J - 1, 1) = Cells(J, 1)
J = J + 1
Loop
Windows(nomefo(5)).Activate
J = 1
Do While J <= k
If J = 1 Then
bb = "Vari"
Else
bb = tab_nomi(J - 1, 1)
End If
Sheets(tab_nomi(J, 1)).Move after:=Sheets(bb)
J = J + 1
Loop
'
End Sub
Sub completa_VARI()
'
' tab_valori(1)= data presente nel foglio
' tab_valori(2)= Ragione sociale presente
' tab_valori(3)= numero assoluto dell'ultima riga
'
Cells(1, 3) = tab_valori(2) 'Ragione Sociale
If Not IsEmpty(tab_valori(1)) Then
Cells(1, 17) = tab_valori(1)
End If
zonaN = "$A$4:$AZ$" & tab_valori(3)
range(zonaN).Select
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThick
.ColorIndex = xlAutomatic
End With
'
tab_nomi(1, 1) = "$AS$4"
tab_nomi(1, 2) = "$AU$4"
Windows(nomefo(6)).Activate 'archivio originale
Sheets("Vari").Select
jj = 1
Do While jj < 3
k = 4
jk = 0
n1 = range(tab_nomi(1, jj)).Column
n2 = range("$AZ$1").Column
Do While k <= tab_valori(3)
If IsNumeric(Cells(k, n1)) Then
If Not Cells(k, n1) = 0 Then
If Not Cells(k, n1).HasFormula Then
jk = jk + 1
tab_bb(jk, 1) = Cells(k, n1)
tab_bb(jk, 2) = k
End If
End If
Else
If Len(Cells(k, n1)) > 0 Then
jk = jk + 1
tab_bb(jk, 1) = Cells(k, n1)
tab_bb(jk, 2) = k
End If
End If
k = k + 1
Loop
If jk > 0 Then
Windows(nomefo(5)).Activate
Sheets("Vari").Select
kzkz = 1
Do While kzkz <= jk
If IsNumeric(tab_bb(kzkz, 1)) Then
Cells(tab_bb(kzkz, 2), n1) = tab_bb(kzkz, 1)
Else
Cells(tab_bb(kzkz, 2), n2) = tab_bb(kzkz, 1)
End If
kzkz = kzkz + 1
Loop
Windows(nomefo(6)).Activate 'Archivio nuovo
Sheets("Vari").Select
End If
jj = jj + 1
Loop
End Sub
Sub modisource(ccc As range)
Dim c As range
For Each c In ccc
If Not IsNumeric(Cell.Value) Then
Cells.AddComment
Cells.Comment.Visible = False
Cells.Comment.Text Text:=Cell.Value
Cell.Value = Null
Next
End Sub
A me è stato chiesto di sviluppare la sub modisource, in modo che il programma sia il più funzionale possibile (e cioè che cicli meno volte possibile per correggere gli eventuali errori).
Noterai che la sub che chiama modisource contiene un metodo speciale che cerca solo le celle contenenti formule che vanno in errore (almeno, la spiegazione che excel mi dà è questa -_-), io pensavo che il modo più "rapido" per correggerle fosse il seguente.
Partendo dalla cella con formula in errore io ciclo le celle contenute in certe colonne di quella riga, così che vengano corrette... mi sembra intelligente no?
E cmq ho codificato un pezzo, ma poi non sò come recuperare la riga, infatti se lo faccio partire così mi corregge solo le celle con le formule, che io non voglio toccare.
Spero di essere stato chiaro!
Oggi al lavoro hanno criticato la routine per la quale ho aperto il thread, la prima, e cioè quella per il controllo degli errori in certe colonne -_-
Sub modisource(ccc As range)
Dim c As range
For Each c In ccc
If Not IsNumeric(Cell.Value) Then
Cells.AddComment
Cells.Comment.Visible = False
Cells.Comment.Text Text:=Cell.Value
Cell.Value = Null
Next
End Sub
A me è stato chiesto di sviluppare la sub modisource, in modo che il programma sia il più funzionale possibile (e cioè che cicli meno volte possibile per correggere gli eventuali errori).
...
Allora, cominciamo col dire che ho dato una rapida occhiata al programma, e perdona la franchezza, ma è tutto fuorchè chiaro e leggibile. Alla faccia della portabilità del codice ! :D
Se un cliente mi chiedesse di verificargli una cosa simile e correggerla, assolutamente non lo farei gratis !
Detto questo, non ho capito perchè nella tua routine "modisource" dichiari un oggetto c per poi non usarlo mai...
Prova intanto a sostituirla con questa :
Sub modisource(ccc As Range)
Dim c As Range
For Each c In ccc
If Not IsNumeric(c.Value) Then
c.AddComment
c.Comment.Visible = False
c.Comment.Text Text:=c.Value
c.Value = Null
End If
Next
End Sub
Infine, la critica che ti è stata mossa sul fatto che la routine in questione NON sia efficiente, ossia utilizzi più cicli del necessario, è ingiusta : per definizione un costrutto For Each assicura proprio che ogni elemento di una Collection ( in questo caso un Range ), venga preso in esame una sola volta !
Fammi sapere... ;)
PRovo entro il pomeriggio :) e ti faccio sapere!
Se fossi un privato ti darei assolutamente ragione, è un extra che mi hanno "chiesto" al lavoro, e dato che stò cercando una promozione diciamo che non ho troppa scelta :(
Che non è chiaro e leggibile purtroppo lo sò :( ma non l'ho scritto io, ma il mio capo... e quindi mi tocca lavorarci sopra... situazione del cavolo!
Sulla storia dei cicli io ho fatto un certo tipo di ragionamento.
Io ho studiato la programmazione orientata ad oggetti, quindi per me l'ideale è creare un programma formato da sottoalgoritmi da riutilizzare via via, che sono più comodi da scrivere, più facili da consultare, e snelliscono la codifica del programma finale.
Ho ragionato sul fatto che io controllerei le varie colonne d'interesse in modo da evitare l'eventuale formazione di errori, e non dopo.
Il mio capo invece preferisce che partendo dalla cella contenente una formula in errore si correggano le celle della colonna della riga in questione..
Il mio capo invece preferisce che partendo dalla cella contenente una formula in errore si correggano le celle della colonna della riga in questione..
E così facendo si finisce col riesaminare celle già corrette in precedenza, perchè comunque, almeno una volta, le dovrai pur esaminare una per una per vedere se contengono errori... Questo sì che sarebbe poco efficiente.
Comunque nel codice scritto dal tuo capo vedo parecchi "Range.Select", "Foglio.Select", "Cella.Select" ecc... , il che non è certo una gran cosa in termini di prestazioni. Molti pensano che un programma Excel-VBA si lento... In realtà usano tonnellate di ".Select", per fare ogni minima cosa, come leggere o scrivere in una cella, e questo forza Excel ad aggiornare a video ogni passaggio intermedio. Su una Macro da 1000 linee di codice, con Range massicci in lettura e scrittura, l'effetto è devastante.
Non è assolutamente necessario selezionare fogli, range, celle ecc... per operazioni elementari. Si può fare tutto elegantemente in una sola riga di codice, ad esempio, per scrivere "abc" nel Range("A1") del "Foglio3", molti fanno :
Sheets("Foglio3").Select
Range("A1").Select
Selection.Formula = "abc"
Mentre per Excel è molto più veloce fare :
Sheets("Foglio3").Range("A1").Formula = "abc" ;)
Ok, ho fatto qualche prova.
in questa parte
aa = "$A$4:$AZ$" & tab_valori(3)
papero = range(aa).SpecialCells(xlCellTypeFormulas, 16).Select
On Error GoTo 0
If errore = 0 Then
Call modisource
Se non ho capito male il programma cerca le celle con formule che vanno in errore, e nel caso chiama modisource.
Sub modisource(ccc As range)
Dim c As range
For Each c In ccc
If Not IsNumeric(c.Value) Then
c.AddComment
c.Comment.Visible = False
c.Comment.Text Text:=c.Value
c.Value = Null
End If
Next
Il punto è che così com'è modisource non corregge le celle delle righe delle colonne che interessano la formula in errore, ma la cella della formula stessa!
Stò cercando un metodo per inserire in un eventuale vettore le coordinate delle celle in errore, per creare un sistema che funzioni così (o almeno, che il mio capo apprezza :stordita: ).
-Il programma cerca celle con formule in errore
-Salva gli indirizzi di tali celle in un vettore
-Il vettore guarda la riga in cui si trova la cella e cicla con il controllo le celle delle colonne d'interesse per correggerle
In questo modo non viene fuori un programma snello?
Che ne pensi?
aa = "$A$4:$AZ$" & tab_valori(3)
papero = range(aa).SpecialCells(xlCellTypeFormulas, 16).Select
On Error GoTo 0
If errore = 0 Then
Call modisource
Sub modisource(ccc As range)
Dim c As range
For Each c In ccc
If Not IsNumeric(c.Value) Then
c.AddComment
c.Comment.Visible = False
c.Comment.Text Text:=c.Value
c.Value = Null
End If
Next
Eh, no ! Non ha senso...
Scusa, definisci una Sub "modisource" che accetta un parametro non opzionale ( il Range ccc ), e poi quando la usi non glielo passi ? E allora a che servono gli oggetti ccc e c ?
Stai facendo un po' di casino... :)
Intanto usa correttamente il codice che già hai a disposizione, e vedi se può risolvere, sennò non ne esci vivo...
Comunque, se vuoi un parere, io farei così ( la vostra routine che decide se una cella contenga o meno una formula in errore, non l'ho capita... ), dato che in Excel se una cella da errore, il suo ".Text" inizia sempre per "#" :
1. Verifico che una cella ( esempio "A1" ) contiene una formula con errore :
If Left(Range("A1").Formula, 1) = "=" And Left(Range("A1").Text, 1) = "#" Then
'Azione in caso di errore...
End If
2. Dato un range di controllo ( il nostro ccc), applico quanto sopra ad ogni cella che contiene l'errore, ossia faccio fare tutto alla modisource, una volta sola !
Sennò a che serve 'sta modisource ?! :)
1. Verifico che una cella ( esempio "A1" ) contiene una formula con errore :
If Left(Range("A1").Formula, 1) = "=" And Left(Range("A1").Text, 1) = "#" Then
'Azione in caso di errore...
End If
O anche ( molto meglio ) :
If IsError(Range("A1")) Then
'Azione in caso di errore...
End If
;)
Oddio hai ragione.. sono in confusione più totale, mi sono perso :(
ccc è il range con formule da controllare oppure è il range con i valori che devo cambiare in caso d'errore? :(
Ecco a cosa porta una cattiva analisi... :rolleyes:
Secondo me fai prima a riscrivere il programma da zero. Qualcosa mi dice che verrà molto meglio di come l'ha fatto il tuo capo... :asd:
Ecco a cosa porta una cattiva analisi... :rolleyes:
Secondo me fai prima a riscrivere il programma da zero. Qualcosa mi dice che verrà molto meglio di come l'ha fatto il tuo capo... :asd:
Ci avevo pensato seriamente... ma ci sono dei fattori che giocano contro
- 1, non conosco l'ambiente di excel, e devo consegnare questo "lavoro" entro l'unedì prossimo, avessi molto tempo per studiare potrei pure provarci
- 2 indipendentemente che funzioni o meno se cancello il lavoro di un mio superiore e spaccio per migliore il mio (vero o falso che sia) mi tiro una zappata sui piedi.
Cmq chiedo scusa marco se ti ho disturbato così tanto per questo programma, spero di non averti annoiato/impegnato eccessivamente! sei stato molto gentile con me!
- 2 indipendentemente che funzioni o meno se cancello il lavoro di un mio superiore e spaccio per migliore il mio (vero o falso che sia) mi tiro una zappata sui piedi.
Cmq chiedo scusa marco se ti ho disturbato così tanto per questo programma, spero di non averti annoiato/impegnato eccessivamente! sei stato molto gentile con me!
Ma figurati, nessun disturbo. Se dai un'occhiata ai miei thread noterai che spesso vengo colto da attacchi... di altruismo... :D
Questo programma, comunque mi ha incuriosito. Se ti interessa e riesci a farmi un'analisi completa ( ossia spiegare molto precisamente e brevemente il "flusso di cose" che deve fare il programma, dall'inizio alla fine ) posso provare a riscriverlo, quando ho tempo, chiaramente... ;)
Ma figurati, nessun disturbo. Se dai un'occhiata ai miei thread noterai che spesso vengo colto da attacchi... di altruismo... :D
Questo programma, comunque mi ha incuriosito. Se ti interessa e riesci a farmi un'analisi completa ( ossia spiegare molto precisamente e brevemente il "flusso di cose" che deve fare il programma, dall'inizio alla fine ) posso provare a riscriverlo, quando ho tempo, chiaramente... ;)
Allora, vediamo se riesco a spiegarlo in poche parole :)
C'è una directory (chiamata clienti) che contiene dei file excel, che a loro volta hanno più fogli (in riferimento agli ordini di vari mesi).
Questi file sono organizzati tutti alla stessa maniera (quindi i fogli in essi contenuti hanno gli stessi nomi e le formule sono messe sempre nelle stesse celle).
Ora, io sò che la prima riga utilizzata in ogni file excel è la 4, mentre l'ultima deve essere determinata (NB: non tutte le celle contengono dati per forza) usando una linea più spessa di separazione che indica la fine del foglio.
Ora, il nostro programma dovrebbe aprire uno alla volta i files excel contenuti nella directory clienti, determinare il numero di fogli in essi contenuti, e fare la copia del file in un altro file excel chiamato Esempio (se per caso il nome del file o di un foglio sono scorretti, perchè contengono uno spazio all'inizio o alla fine, questo và tolto con la funzione trim).
Una volta che i fogli del file sono stati ricopiati dentro ESEMPIO, questo file si deve rinominare da solo col nome del file "sorgente" e poi salvarsi in una directory nuova, mentre il file originario và chiuso senza essere salvato.
Il controllo dell'errore (che è stato affidato parzialmente a me) serve ad assicurarsi che alcune celle (che cominciano sempre dalla riga 4 fino all'ultima riga utilizzata dal foglio) contengano solo numeri, se invece contengono stringhe queste devono diventare il commento alla cella stessa, e successivamente pulirla, così che la formula che fà riferimento a questa non vada in errore.
Le colonne d'interesse sono A D E G H J
Spero di essere stato chiaro, nel caso chiedi pure... se vuoi provo a passarti un paio di file (cambio i nomi dei clienti per privacy) di clienti così vedi come sono strutturati.
Ci sto. :)
Passami qualche file...
Vediamo un po'. La tua analisi è questa :
1. Aprire uno alla volta i files excel contenuti nella directory clienti.
2. Determinare il numero di fogli in essi contenuti,
3. Fare la copia del file in un altro file excel chiamato Esempio
(se per caso il nome del file o di un foglio sono scorretti, perchè contengono uno spazio all'inizio o alla fine,
questo và tolto con la funzione trim).
4. Una volta che i fogli del file sono stati ricopiati dentro ESEMPIO,
questo file si deve rinominare da solo col nome del file "sorgente"
e poi salvarsi in una directory nuova,
mentre il file originario và chiuso senza essere salvato.
5. Il controllo dell'errore serve ad assicurarsi che alcune celle
(che cominciano sempre dalla riga 4 fino all'ultima riga utilizzata dal foglio) contengano solo numeri,
se invece contengono stringhe queste devono diventare il commento alla cella stessa,
e successivamente pulirla, così che la formula che fà riferimento a questa non vada in errore.
Le colonne d'interesse sono A D E G H J.
_______________________________________
Punti 1. e 2. Ok.
Punti 3. e 4. rivisti & corretti :
Da ciò che dici il file Esempio altro non è che un passaggio intermedio, dal mio punto di vista inutile.
La funzione Trim sui nomi dei fogli/files ecc... durante l'esecuzione in automatico di codice VBA non mi piace per niente.
Consiglio : risolvere il problema alla radice, ossia evitare gli spazi ( come regola generale io non uso MAI spazi nei nomi di cartelle, fogli, documenti, campi o nomi di tabelle Access... insomma MAI, in nessun progetto VBA. Gli spazi nei nomi fanno solo casino, e possono essere tranquillamente rimpiazzati all'origine con altri caratteri, "-", "_", ecc... ).
Ti assicuro che ho validi motivi per dire queste cose, ma qui cerco di essere stringato.
Cmq vedo dai tuoi files che non esistono nomi di fogli o cartelle di lavoro che contengono spazi. :)
Punto 5. Ok.
E' quanto andremo a fare per primo.
Innanzitutto l'organizzazione di files e directory :
- Ho una cartella "Main" ( o il nome che vuoi ), che contiene tutto.
- Nella dir Main, per ora, metto 2 cartelle :
- cartella "clienti", che contiene i files cliente originari (.xls).
- cartella "Saved", che conterrà i files cliente, una volta corretti.
Ogni nuovo file cliente, immagino, viene creato da voi su un modello iniziale, ossia file-cliente-tipo già esistente, perciò quanto farei io ha un impatto minimo in termini di modifica.
Per iniziare quindi, prendi un file cliente dei tuoi, aggiungi un modulo di codice al suo interno, e inserisci questa Sub :
Public Sub CORREZIONI()
Dim Foglio As Worksheet
Dim indiceCellaLibera As Long
For Each Foglio In ThisWorkbook.Sheets
Dim Cella As Range
Dim indiciColonne As String
indiciColonne = "ADEGHJ"
Dim indiceColonna As String
Dim i As Long
For i = 1 To Len(indiciColonne)
indiceColonna = Mid(indiciColonne, i, 1)
indiceCellaLibera = Foglio.Range(indiceColonna & "65536").End(xlUp).Row + 1
For Each Cella In Foglio.Range(indiceColonna & "4:" & indiceColonna & indiceCellaLibera)
If Not Cella.Text = "" Then
If Not IsNumeric(Cella.Text) Then
Cella.AddComment (Cella.Text)
Cella.Comment.Visible = False
Cella.FormulaR1C1 = 0
End If
End If
Next
Next i
Next
End Sub
Puoi lanciarla ad esempio da un pulsante sul primo foglio "Parametri" di ogni book cliente.
Intanto vedi se è tutto come da analisi.
Vedremo poi come correggere a cascata, da un programma esterno, tutti i books clienti e salvare le versioni corrette nella dir "Saved". ;)
Prima di tutto ti ringrazio nuovamente per la tua consulenza/assistenza (ti dovrò pagare alla fine? :) )
Immagino che la tua scelta di inserire una sub per correggere direttamente nel foglio clienti sia dovuta ad una questione di ordine, esatto?
E poi, devo metterla a mano per ogni cliente giusto? (non è un problema questo, per sapere ^^)
Prima di tutto ti ringrazio nuovamente per la tua consulenza/assistenza (ti dovrò pagare alla fine? :) )
Ogni libera donazione è ben accetta... ;) :D
Immagino che la tua scelta di inserire una sub per correggere direttamente nel foglio clienti sia dovuta ad una questione di ordine, esatto?
E poi, devo metterla a mano per ogni cliente giusto? (non è un problema questo, per sapere ^^)
Una questione di ordine, ma soprattutto un modo per ridurre la quantità di codice inutile ed ingombrante...
Sì, la devi mettere in ogni foglio cliente. Chiaramente, una volta messa nel foglio-base, ossia il modello di partenza per ogni nuovo foglio-cliente, il gioco sarà fatto. ;)
Quando sarai sicuro che fa tutto come richiesto, passeremo alla fase 2.
Hai pm :)
Cmq negli ultimi 5 min è saltato fuori un cambiamento -_-
In pratica il capo desidera che il foglio originario rimanga con le formule errate mentre quello nuovo che è stato creato venga corretto.
Immagino sia una cosa positiva, così cambia mettere il debug direttamente nel foglio esempio,no?
In pratica il capo desidera che il foglio originario rimanga con le formule errate mentre quello nuovo che è stato creato venga corretto.
Immagino sia una cosa positiva, così cambia mettere il debug direttamente nel foglio esempio,no?
Temo di non aver capito io stavolta... :(
Cosa cambia rispetto a prima ? Era già così nelle specifiche che avevi postato tu...
Comunque ti ricordo che nella mia versione del programma non c'è nessun file "esempio"...
Temo di non aver capito io stavolta... :(
Cosa cambia rispetto a prima ? Era già così nelle specifiche che avevi postato tu...
Comunque ti ricordo che nella mia versione del programma non c'è nessun file "esempio"...
In pratica, se il foglio clienti presenta un errore nelle colonne d'interesse (con relativa formula in errore) deve rimanere così.
Il file copia invece deve essere corretto (e quindi le celle con stringhe devono diventare il commento della cella stessa, come già detto).
Mi son spiegato meglio?
In pratica, se il foglio clienti presenta un errore nelle colonne d'interesse (con relativa formula in errore) deve rimanere così.
Il file copia invece deve essere corretto (e quindi le celle con stringhe devono diventare il commento della cella stessa, come già detto).
Mi son spiegato meglio?
Perfetto. E' già tutto incluso nel mio codice al post #32. ;)
Provalo...
Fatto, ho creato un nuovo modulo per ogni cliente che contiene la sub CORREZIONI :D
Fatto, ho creato un nuovo modulo per ogni cliente che contiene la sub CORREZIONI :D
Ok. Allora, prima di procedere fai un test, come ti avevo già detto, per verificare che la Sub CORREZIONI esegua come tu vuoi le modifiche sul Workbook cliente in cui è inserita.
Per fare ciò, puoi creare un CommandButton sul foglio "Parametri" e associare al Click l'esecuzione della Sub CORREZIONI... Così :
Private Sub CommandButton1_Click()
CORREZIONI
End Sub
Fallo ovviamente su un solo Workbook cliente di prova... ;)
Fammi sapere se il risultato è ok.
Poi procediamo.
Ok funziona! :)
Bene.
Adesso viene il bello. :)
1. Verifica che la struttura delle directory sia esattamente questa :
- Una cartella principale, chiamiamola "Main", in cui devono esserci altre 2 cartelle :
-- cartella "clienti" > contiene tutti i Workbook clienti da correggere.
-- cartella "Saved" > vuota.
2. Posizionati nella cartella "Main" e crea un nuovo Workbook Excel vuoto, che chiameremo "PROGRAMMA.xls".
3. Apri PROGRAMMA.xls, entra nell'editor VBA e aggiungi un solo modulo di codice. Questo modulo deve contenere le 2 seguenti Sub :
Public Sub GENERA_TUTTI()
Dim percorsoGet As String
percorsoGet = ThisWorkbook.Path & "\clienti\"
Dim percorsoSave As String
percorsoSave = ThisWorkbook.Path & "\Saved\"
Dim nomeFile As String
nomeFile = Dir(percorsoGet & "*.xls")
Dim cnt As Long
cnt = 1
Application.ScreenUpdating = False
Do While nomeFile <> ""
MsgBox "Sto generando : " & nomeFile, vbInformation, "In Progress..."
Call GENERA(nomeFile, percorsoGet, percorsoSave)
cnt = cnt + 1
nomeFile = Dir
Loop
Application.ScreenUpdating = True
MsgBox "Files Cliente Generati.", vbInformation, "Ok."
End Sub
Public Sub GENERA(nomeWorkbook As String, pathGet As String, pathSave As String)
Dim workbookTarget As Workbook
Dim CloseIt As Boolean
Dim nomeRoutine As String
nomeRoutine = "CORREZIONI"
Application.ScreenUpdating = False
On Error Resume Next
Set workbookTarget = Workbooks(nomeWorkbook)
If Err.Number <> 0 Then
Err.Clear
Set workbookTarget = Workbooks.Open(pathGet & nomeWorkbook)
CloseIt = True
End If
If Err.Number = 1004 Then
MsgBox "File specificato : " & nomeWorkbook & " inesistente."
Exit Sub
End If
On Error GoTo 0
Application.Run (workbookTarget.Name & "!" & nomeRoutine)
If CloseIt = True Then
workbookTarget.SaveAs (pathSave & nomeWorkbook)
workbookTarget.Close savechanges:=False
Else
ThisWorkbook.Activate
End If
Application.ScreenUpdating = True
End Sub
clienti e Saved sono i nomi delle cartelle, perciò se li modifichi, li dovrai modificare anche nel codice.
4. Portati sul Foglio1 di PROGRAMMA.xls e mettici un CommandButton, il cui Click lancerà la Sub GENERA_TUTTI, perciò... :
Private Sub CommandButton1_Click()
GENERA_TUTTI
End Sub
A questo punto siamo a cavallo. ;)
Basterà aprire PROGRAMMA.xls, un Click sul pulsante, e tutti i books nella cartella "clienti" verranno corretti / copiati in "Saved", mentre in "clienti" rimarranno le rispettive versioni originarie. ;)
Davvero niente male... :cool: . Prova...
Davvero sbalorditivo!!!!
Il programma funziona, a parte un paio di cose.
I file vengono corretti e copiati correttamente (pare) ma durante l'operazione appare prima una textbox con scritto : " stò copiando XXX" e bisogna premere ok, e poi appare questo
http://img398.imageshack.us/img398/4646/erroreexceljg8.jpg (http://imageshack.us)
Secondo te è possibile fare in modo che la textbox non richieda la pressione del bottone ok e che non appaia questo fastidioso messaggio ?? così sarebbe tutto automatico.
Secondo te è possibile fare in modo che la textbox non richieda la pressione del bottone ok e che non appaia questo fastidioso messaggio ?? così sarebbe tutto automatico.
Per quanto riguarda il primo messaggio, è opera mia. ;)
E' un messaggio informativo che ho inserito a scopo di debug, e che segnala l'inizio di ogni singola operazione.
Se non vuoi che compaia più, elimina ( o commenta ) la riga di codice rossa nella Sub "GENERA_TUTTI" :
Public Sub GENERA_TUTTI()
Dim percorsoGet As String
percorsoGet = ThisWorkbook.Path & "\clienti\"
Dim percorsoSave As String
percorsoSave = ThisWorkbook.Path & "\Saved\"
Dim nomeFile As String
nomeFile = Dir(percorsoGet & "*.xls")
Dim cnt As Long
cnt = 1
Application.ScreenUpdating = False
Do While nomeFile <> ""
MsgBox "Sto generando : " & nomeFile, vbInformation, "In Progress..."
Call GENERA(nomeFile, percorsoGet, percorsoSave)
cnt = cnt + 1
nomeFile = Dir
Loop
Application.ScreenUpdating = True
MsgBox "Files Cliente Generati.", vbInformation, "Ok."
End Sub
La finestra dei "collegamenti ad altre origini dati" invece è opera del tuo capo. :(
Esce sempre anche a me quando apro uno dei files cliente che mi hai mandato.
Evidentemente è stato impostato un collegamento a origini dati esterne. Ma questo dovreste saperlo voi meglio di me. In ogni caso il mio codice non va assolutamente in conflitto con altre Macro, o collegamenti dati eventualmente già presenti, e non richiede alcuna origine dati esterna. :)
La finestra dei "collegamenti ad altre origini dati" invece è opera del tuo capo. :(
Esce sempre anche a me quando apro uno dei files cliente che mi hai mandato.
Evidentemente è stato impostato un collegamento a origini dati esterne. Ma questo dovreste saperlo voi meglio di me. In ogni caso il mio codice non va assolutamente in conflitto con altre Macro, o collegamenti dati eventualmente già presenti, e non richiede alcuna origine dati esterna. :)
Immagino, vorrei disabilitare questa finestra, o fare in modo che venga selezionato in automatico la voce "non aggiornare"
:( però non ci riesco, stò cercando nell'help online di excel ma non lo trovo.
Inutile dire che il mio capo non lo vedo/sento prima di lunedì :p
E poi mi dà un errore con un file clienti, mi dice che non trova la macro CORREZIONI, eppure dentro c'è :confused: ..questa non l'ho capita proprio..
Che sciocco che sono, non ho messo la riga che và in errore con quel cliente
Application.Run (workbookTarget.Name & "!" & nomeRoutine)
Immagino, vorrei disabilitare questa finestra, o fare in modo che venga selezionato in automatico la voce "non aggiornare"
:( però non ci riesco, stò cercando nell'help online di excel ma non lo trovo.
Fossi in te non lo farei.
A quanto pare ogni file cliente prende dati importanti mediante uno o più collegamenti ad altri files Excel esterni.
Se tenti di aggiornare, Excel ti dirà che non può farlo, perchè tali files probabilmente si trovano solo sul Pc del boss.
Sulla finestra che ti informa dell'impossibilità di aggiornare i collegamenti esterni, troverai il pulsante "Modifica collegamenti", cliccando il quale vedrai una finestra come questa :
http://www.freeimagehosting.net/uploads/th.43c5419e64.jpg (http://www.freeimagehosting.net/image.php?43c5419e64.jpg)
Noterai che ci sono alcuni files Excel esterni da cui prende i dati, e inoltre che i percorsi sono assoluti.
Perciò poco male. :)
Se tu avessi quei file che sono richiesti, non vedresti nessuna finestra che ti chiede di aggiornare...
E poi mi dà un errore con un file clienti, mi dice che non trova la macro CORREZIONI, eppure dentro c'è :confused: ..questa non l'ho capita proprio..
Assicurati che il nome del file non contenga spazi.
Se non riesci a capire il motivo, mandamelo.
Assicurati che il nome del file non contenga spazi.
Se non riesci a capire il motivo, mandamelo.
In effetti contiene uno spazio, e ci sono altri file clienti così (con uno spazio nel nome) o che contengono caratteri speciali (ad esempio "&" )
In effetti contiene uno spazio, e ci sono altri file clienti così (con uno spazio nel nome) o che contengono caratteri speciali (ad esempio "&" )
Ti avevo già messo in guardia sui nomi che contengono spazi...
Consiglio : risolvere il problema alla radice, ossia evitare gli spazi ( come regola generale io non uso MAI spazi nei nomi di cartelle, fogli, documenti, campi o nomi di tabelle Access... insomma MAI, in nessun progetto VBA. Gli spazi nei nomi fanno solo casino, e possono essere tranquillamente rimpiazzati all'origine con altri caratteri, "-", "_", ecc... ).
Ti assicuro che ho validi motivi per dire queste cose, ma qui cerco di essere stringato.
Se proprio non puoi evitarlo, vai in PROGRAMMA.xls, entra nella Sub
GENERA(nomeWorkbook As String, pathGet As String, pathSave As String)
>> Sostituisci la riga di codice che inizia con Application.Run, con questa :
Application.Run ("'" & workbookTarget.Name & "'" & "!" & nomeRoutine)
Questo ti permette di gestire nomi files che contengono spazi. ;)
Il carattere "&", invece non crea nessun problema.
Scusa Marco, da vero cretino avevo capito che ti riferissi ai nomi dei fogli contenuti nel file excel, non al nome del file stesso... :/
Grazie mille, ti faccio sapere ;)
Non mi ero accorto che mi era arrivata una mail dall'ufficio con delle stupende novità :doh:
Anticipo che se ti sei stufato di aiutarmi puoi smettere assolutamente quando vuoi, hai già fatto talmente tanto che non ho parole per ringraziarti!
In pratica non mi era stato detto un pezzo del lavoro che il programma deve fare -.-
Presente CORREZIONI?
Ok, il programma deve aprire i vari fogli excel e, a questo punto deve fare le seguenti cose.
-Il primo foglio, parametri, deve essere copiato così com'è, senza correzione alcuna
-il foglio Vari deve essere copiato con la correzione.
-Gli altri fogli devono essere ricopiati anche loro così come sono
Presente CORREZIONI?
Ok, il programma deve aprire i vari fogli excel e, a questo punto deve fare le seguenti cose.
-Il primo foglio, parametri, deve essere copiato così com'è, senza correzione alcuna
-il foglio Vari deve essere copiato con la correzione.
-Gli altri fogli devono essere ricopiati anche loro così come sono
Beh, in tal caso, dato che CORREZIONI funziona solo sul foglio "Vari", andrà leggermente modificata :
Public Sub CORREZIONI()
Dim indiceCellaLibera As Long
Dim Cella As Range
Dim indiciColonne As String
indiciColonne = "ADEGHJ"
Dim indiceColonna As String
Dim i As Long
For i = 1 To Len(indiciColonne)
indiceColonna = Mid(indiciColonne, i, 1)
indiceCellaLibera = Sheets("Vari").Range(indiceColonna & "65536").End(xlUp).Row + 1
For Each Cella In Sheets("Vari").Range(indiceColonna & "4:" & indiceColonna & indiceCellaLibera)
If Not Cella.Text = "" Then
If Not IsNumeric(Cella.Text) Then
Cella.AddComment (Cella.Text)
Cella.Comment.Visible = False
Cella.FormulaR1C1 = 0
End If
End If
Next
Next i
End Sub
;)
quindi se io volessi, per esempio, fare in modo che le correzioni vadano solo su alcuni fogli (vari, esempio1, esempio2) il comando sarebbe questo?
indiceCellaLibera = Sheets("Vari", "Esempio1", "esempio2").Range(indiceColonna & "65536").End(xlUp).Row + 1
No. Non funzionerebbe.
In quel caso dovresti riprendere la Sub CORREZIONI originaria e condizionare il ciclo For Each sui fogli, facendo un controllo sul nome-foglio...
Stamane mi è stato chiesto di guardare il lavoro da me (te) svolto.
Inutile dire che il mio superiore non era felice di vedere che avessimo cambiato tutto, e quindi (secondo me) si è incattivito APPOSTA per cercare errori.
Non serve che te lo dico Marco, ma se davvero ti annoi/rompi/non hai più tempo/ti fà incazzare dover cambiare via via le cose non farti problemi a scaricare tutto :) non mi offendo, anzi non potrò mai ringraziarti abbastanza per il tuo prezioso aiuto.
La consegna è fissata per dopodomani (ovviamente non fissata da me), inutile dire che con le nuove modifiche temo sia impossibile approntare il programma, ad ogni modo ti scrivo le news...
- Aggiunte alle colonne d'interesse per la correzione la L e la M
- Bisogna testare e correggere i fogli "Vari" e con i vari mesi (per esempio "marzo04", "febbraio07" ecc ecc) mentre i fogli "Parametri" ,"Ord.", "ord.", "ord", "Ord" vanno lasciati così come sono.
- La prima riga è stata cambiata, dalla 4 è diventata la 3; PER TUTTI I FOGLI
- Infine, nei fogli testati (e potenzialmente corretti) bisogna anche copiare dalla colonna AW alla BA in quanto potrebbero esserci devi commenti/valori in più.
Mi sembrano tantissime cose... temo sia impossibile entro dopodomani... che rabbia.. :(
- Aggiunte alle colonne d'interesse per la correzione la L e la M
- Bisogna testare e correggere i fogli "Vari" e con i vari mesi (per esempio "marzo04", "febbraio07" ecc ecc) mentre i fogli "Parametri" ,"Ord.", "ord.", "ord", "Ord" vanno lasciati così come sono.
- La prima riga è stata cambiata, dalla 4 è diventata la 3; PER TUTTI I FOGLI
- Infine, nei fogli testati (e potenzialmente corretti) bisogna anche copiare dalla colonna AW alla BA in quanto potrebbero esserci devi commenti/valori in più.
Mi sembrano tantissime cose... temo sia impossibile entro dopodomani... che rabbia.. :(
In realtà no. E' molto semplice modificare / aggiornare il MIO codice. :)
Riguardo il tuo capo, consentimi una personale considerazione : dovrebbe semplicemente accettare il fatto che, se quello che ha scritto lui ( magari sbagliando pure ) si può fare con meno del 30% in quantità di codice, evidentemente in questo campo gli converrebbe ( E MOLTO ! ) saper accettare un consiglio, quando gli viene dato.
Entro domani avrai la soluzione. ;)
In realtà no. E' molto semplice modificare / aggiornare il MIO codice. :)
Riguardo il tuo capo, consentimi una personale considerazione : dovrebbe semplicemente accettare il fatto che, se quello che ha scritto lui ( magari sbagliando pure ) si può fare con meno del 30% in quantità di codice, evidentemente in questo campo gli converrebbe ( E MOLTO ! ) saper accettare un consiglio, quando gli viene dato.
Entro domani avrai la soluzione. ;)
Hai ragione nel dire il TUO codice, anche se magari non sembra da dietro uno schermo sono una persona molto umile e non cercherei mai di prendermi il merito di un lavoro altrui :)
La mia (nostra) è la tipica situazione di un ufficio DOMINATO da un vecchio signore circondato da ragazzi diplomati/neodiplomati/neolaureati, convinto che tutto/i siano meno intelligenti/capaci/arguti eccecc.
Forse è stato ancora più semplice del previsto...
Devi sostituire alla Sub CORREZIONI questa nuova :
Public Sub CORREZIONI()
Dim Foglio As Worksheet
Dim indiceCellaLibera As Long
For Each Foglio In ThisWorkbook.Sheets
If Foglio.Name = "Vari" Or IsNumeric(Right(Foglio.Name, 1)) Then
Dim Cella As Range
Dim indiciColonne As String
indiciColonne = "ADEGHJLM"
Dim indiceColonna As String
Dim i As Long
For i = 1 To Len(indiciColonne)
indiceColonna = Mid(indiciColonne, i, 1)
indiceCellaLibera = Foglio.Range(indiceColonna & "65536").End(xlUp).Row + 1
For Each Cella In Foglio.Range(indiceColonna & "3:" & indiceColonna & indiceCellaLibera)
If Not Cella.Text = "" Then
If Not IsNumeric(Cella.Text) Then
Cella.AddComment (Cella.Text)
Cella.Comment.Visible = False
Cella.FormulaR1C1 = 0
End If
End If
Next
Next i
End If
Next
End Sub
Fammi sapere... ;)
Ok provato, sembra funzioni, a parte una cosa.
In pratica nei fogli da controllare c'è da fare una piccola distinzione sulla riga.
La prima riga da controllare rimane la 4, mentre la 3 è unicamente da copiare senza controllo (contiene i nomi dei vari campi).
La prima riga da controllare rimane la 4, mentre la 3 è unicamente da copiare senza controllo (contiene i nomi dei vari campi).
Allora sostituisci nell'ultima versione della Sub CORREZIONI questa riga :
For Each Cella In Foglio.Range(indiceColonna & "4:" & indiceColonna & indiceCellaLibera)
4 al posto di 3.
Ok, ora fà proprio quello che deve fare, anche il capo mi è sembrato tutto sommato soddisfatto (è cmq di umore nero)!!
Mi ha chiesto, come ultimissima cosa, se è possibile nei fogli contenenti i nomi dei mesi (giugno06, aprile04 ecc ecc) fare in modo che (dopo aver effettuato i soliti controlli nelle colonne d'interesse) vengano ricopiate le celle con la funzione incolla valori&formati , così che nel nuovo file creato non ci siano formule (in questi fogli) ma numeri puri (mentre negli altri dovrebbero essere eventualmente ricopiate).
E infine, domanda di informatica generale... ma secondo te non è un sistema davvero del cazzo dire i problemi "a step" ?
Rileggendo i miei appunti (ed il thread) mi son reso conto che mi ha detto le cose da fare a pezzi, cambiandole un sacco di volte ed aggiungendo viavia un sacco di roba... penso che se avessi saputo TUTTO il da farsi sarebbe stato più semplice stilare un'analisi corretta. (per la codifica taccio, non avrei MAI saputo fare il lavoro che tu hai svolto in modo così encomiabile).
Mi ha chiesto, come ultimissima cosa, se è possibile nei fogli contenenti i nomi dei mesi (giugno06, aprile04 ecc ecc) fare in modo che (dopo aver effettuato i soliti controlli nelle colonne d'interesse) vengano ricopiate le celle con la funzione incolla valori&formati , così che nel nuovo file creato non ci siano formule (in questi fogli) ma numeri puri (mentre negli altri dovrebbero essere eventualmente ricopiate).
Vediamo se ho capito... :
Vuoi che SOLO nei fogli "tipo-mese" del file cliente generato ( cioè quello che sta nella cartella "Saved", per intenderci ) alle Celle che contengono una formula venga sostituito il relativo risultato... Giusto ?
E infine, domanda di informatica generale... ma secondo te non è un sistema davvero del cazzo dire i problemi "a step" ?
Rileggendo i miei appunti (ed il thread) mi son reso conto che mi ha detto le cose da fare a pezzi, cambiandole un sacco di volte ed aggiungendo viavia un sacco di roba... penso che se avessi saputo TUTTO il da farsi sarebbe stato più semplice stilare un'analisi corretta. (per la codifica taccio, non avrei MAI saputo fare il lavoro che tu hai svolto in modo così encomiabile).
Si tratta del problema Numero 1 di ogni sviluppo. Il cliente non sa mai cosa vuole. E quando comincia a capire ciò che realmente vuole... metà del lavoro è da buttare e da rifare. :rolleyes:
E' un classico.
Un buon programma è possibile solo se basato su una buona analisi, e qui ti sei fatto un idea di come una persona inesperta finisca con scrivere fiumi di codice superfluo e incomprensibile.
Finchè l'analisi è in corso non andrebbe scritta nemmeno una riga di codice.
Ma spesso la realtà non funziona così, e il povero sviluppatore... :ncomment: :D
Vediamo se ho capito... :
Vuoi che SOLO nei fogli "tipo-mese" del file cliente generato ( cioè quello che sta nella cartella "Saved", per intenderci ) alle Celle che contengono una formula venga sostituito il relativo risultato... Giusto ?
Si esattamente. faccio un esempio
Nel solito file cliente AAA.xls ci son dentro i soliti 3 fogli "parametri", "vari" e "luglio03"
I fogli "vari" e "lug lio03" vanno testati e corretti entrambi, come già fatto; ma al foglio "luglio03" vanno tolte le formule.
Quindi se nella cella az c'è un =A4+B4 dovrà apparire solo il risultato puro (esempio =24)
Immagino inoltre che domani mi sarà chiesto (diciamo che ne sono sicuro al 100%, l'ho sentito dire stasera mentre uscivo dall'ufficio -.-), come ultimo step che conclude definitivamente il programma la seguente cosa...
Nei fogli dei MESI e VARI capita che la prima riga utilizzata (la 4) sia vuota poi ci siano varie righe scritte ed infine delle righe vuote prima della linea spessa che indica la fine del foglio utilizzato.
Le righe vuote all'inizio ed alla fine devono essere tolte e la linea spessa messa alla fine.
Provo a fare un esempio, non riesco a spiegarmi bene anche se è un concetto semplice ;(
Riga 4 libera
Riga 5 libera
Riga 6 libera
Riga 8 libera
Riga 10 occupata
Riga 11 libera
Riga 12 occupata
Riga 13 ....X libera (per X intendo fine del foglio utilizzato).
Nel momento in cui vengono ricopiati le righe libere all'inizio ed alla fine vengono eliminate (ma quelle in mezzo rimangono come sono!), risultando così.
Vecchia riga Riga Ricopiata
Riga 6 Riga 4
Riga 8 Riga 5
Riga 9 Riga 6
Riga 10 Riga 7
Riga 11 Riga 8
Riga 12 Riga 9
FINE DEL FOGLIO UTILE (caratterizzato da una linea spessa, come quella nei file che ti ho passato)
Si esattamente. faccio un esempio
Nel solito file cliente AAA.xls ci son dentro i soliti 3 fogli "parametri", "vari" e "luglio03"
I fogli "vari" e "lug lio03" vanno testati e corretti entrambi, come già fatto; ma al foglio "luglio03" vanno tolte le formule.
Quindi se nella cella az c'è un =A4+B4 dovrà apparire solo il risultato puro (esempio =24)
Cella AZ ? Quindi questa ulteriore correzione non prende in esame solo le colonne A D E G H J L M, ma TUTTE le colonne dei fogli mese ?
Cella AZ ? Quindi questa ulteriore correzione non prende in esame solo le colonne A D E G H J L M, ma TUTTE le colonne dei fogli mese ?
Tutte le colonne con formule (scusa il ritardo ma stamattina il mio capo aveva una riunione ho potuto chiedere conferma solo ora) contenute nei fogli MESI.
Tutte le colonne con formule (scusa il ritardo ma stamattina il mio capo aveva una riunione ho potuto chiedere conferma solo ora) contenute nei fogli MESI.
Allora :
1. Sostituisci ancora la Sub CORREZIONI con questa nuova :
Public Sub CORREZIONI()
Dim Foglio As Worksheet
Dim Cella As Range
Dim indiceCellaLibera As Long
Dim indiceColonna As String
Dim rangeDati As Range
For Each Foglio In ThisWorkbook.Sheets
If Foglio.Name = "Vari" Or IsNumeric(Right(Foglio.Name, 1)) Then
Dim indiciColonne As String
indiciColonne = "ADEGHJLM"
Dim i As Long
For i = 1 To Len(indiciColonne)
indiceColonna = Mid(indiciColonne, i, 1)
indiceCellaLibera = Foglio.Range(indiceColonna & "65536").End(xlUp).Row + 1
For Each Cella In Foglio.Range(indiceColonna & "3:" & indiceColonna & indiceCellaLibera)
If Not Cella.Text = "" Then
If Not IsNumeric(Cella.Text) Then
Cella.AddComment (Cella.Text)
Cella.Comment.Visible = False
Cella.FormulaR1C1 = 0
End If
End If
Next
Next i
End If
If IsNumeric(Right(Foglio.Name, 1)) Then
Foglio.Select
DETERMINA_RANGEDATI rangeDati
For Each Cella In rangeDati
If Left(Cella.Formula, 1) = "=" And Not IsError(Cella) Then
Cella.FormulaR1C1 = Cella.Text
End If
Next
End If
Next
End Sub
2. Aggiungi alla Sub CORREZIONI ( in ogni file cliente, quindi ) questa nuova Sub :
Public Sub DETERMINA_RANGEDATI(ByRef rangeDati As Range)
Dim primaRow As Integer
Dim primaCol As Integer
Dim ultimaRow As Integer
Dim ultimaCol As Integer
primaRow = Cells.Find(What:="*", _
SearchDirection:=xlNext, _
SearchOrder:=xlByRows).Row
primaCol = Cells.Find(What:="*", _
SearchDirection:=xlNext, _
SearchOrder:=xlByColumns).Column
ultimaRow = Cells.Find(What:="*", _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByRows).Row
ultimaCol = Cells.Find(What:="*", _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByColumns).Column
Set rangeDati = Range(Cells(primaRow, primaCol), Cells(ultimaRow, ultimaCol))
End Sub
Fammi sapere...
Provato adesso, non và proprio :(
I fogli Ord e parametri sono ok
Per vari e Mesi no :( in quanto la riga 3 viene corretta (invece dovrebbe copiarla e basta, mentre dalla 4 in poi deve correggere e copiare).
Le celle con le formule si sono sballate del tutto e sono piene di errori o #####
Se vuoi ti passo qualche file + il programma e vedi tu stesso, cmq gli errori son questi :(
niente, scritto cavolata.
niente, scritto cavolata.
Ah ecco, mi pareva. Quindi funziona tutto ?
Ah ecco, mi pareva. Quindi funziona tutto ?
No, non funziona. Avevo provato a scrivere una soluzione alternativa, ma non funziona per un cavolo :( per questo ho editato e scritto che era una cavolata!
Hai visto il pm?
:doh: .
Ti ho postato la CORREZIONI sbagliata. :fagiano:
Metti questa :
Public Sub CORREZIONI()
Dim Foglio As Worksheet
Dim Cella As Range
Dim indiceCellaLibera As Long
Dim indiceColonna As String
Dim rangeDati As Range
For Each Foglio In ThisWorkbook.Sheets
If Foglio.Name = "Vari" Or IsNumeric(Right(Foglio.Name, 1)) Then
Dim indiciColonne As String
indiciColonne = "ADEGHJLM"
Dim i As Long
For i = 1 To Len(indiciColonne)
indiceColonna = Mid(indiciColonne, i, 1)
indiceCellaLibera = Foglio.Range(indiceColonna & "65536").End(xlUp).Row + 1
For Each Cella In Foglio.Range(indiceColonna & "4:" & indiceColonna & indiceCellaLibera)
If Not Cella.Text = "" Then
If Not IsNumeric(Cella.Text) Then
Cella.AddComment (Cella.Text)
Cella.Comment.Visible = False
Cella.FormulaR1C1 = 0
End If
End If
Next
Next i
End If
If IsNumeric(Right(Foglio.Name, 1)) Then
Foglio.Select
DETERMINA_RANGEDATI rangeDati
For Each Cella In rangeDati
If Left(Cella.Formula, 1) = "=" And Not IsError(Cella) Then
Cella.FormulaR1C1 = Cella.Text
End If
Next
End If
Next
End Sub
Non è cambiato molto! :(
Il foglio vari viene ricopiato correttamente ma i mesi danno problemi.
Quasi tutte le formule sono state eliminate correttamente però a posto del risultato puro appaiono #####
Invece in una sola colonna le formule sono rimaste così com'erano e danno un errore #valore
Non è cambiato molto! :(
Il foglio vari viene ricopiato correttamente ma i mesi danno problemi.
Quasi tutte le formule sono state eliminate correttamente però a posto del risultato puro appaiono #####
Invece in una sola colonna le formule sono rimaste così com'erano e danno un errore #valore
Per forza. A continuare ad aggiungere roba sul progetto iniziale prima o poi si fa casino. Il fatto è che prima bisognava ( cito tue testuali parole ) pulire le celle che rispondevano ad alcuni requisiti sulle colonne A D E G H J L M. Per "pulire" io ho interpretato come "inserire uno zero", e fin lì andava bene... Ora bisogna rimodificare e chiaramente le funzioni che pescano dalle celle nelle colonne A D E G H J L M è possibile che vadano in errore...
Ripeto, il mio codice funziona al 100%, nel senso che fa quanto richiesto dalla tua analisi. Se l'analisi è sbagliata non ci posso fare molto...
In ogni caso appena ho tempo do un'occhiata ai files che mi hai mandato e ti faccio sapere. :)
Per forza. A continuare ad aggiungere roba sul progetto iniziale prima o poi si fa casino. Il fatto è che prima bisognava ( cito tue testuali parole ) pulire le celle che rispondevano ad alcuni requisiti sulle colonne A D E G H J L M. Per "pulire" io ho interpretato come "inserire uno zero", e fin lì andava bene... Ora bisogna rimodificare e chiaramente le funzioni che pescano dalle celle nelle colonne A D E G H J L M è possibile che vadano in errore...
Ripeto, il mio codice funziona al 100%, nel senso che fa quanto richiesto dalla tua analisi. Se l'analisi è sbagliata non ci posso fare molto...
In ogni caso appena ho tempo do un'occhiata ai files che mi hai mandato e ti faccio sapere. :)
Hai ragione ad essere contrariato, ti assicuro cmq che se mi avessero detto tutto subito avrei evitato come un demente di aggingere cose su cose :(
Edito: mi hanno appena ricordato che la consegna è fissata per domattina.. mi sà tanto che è andata... :(
Per fare una prova, vorrei avere una copia in Pvt di uno di quei files che vengono caricati dal file cliente.
Ad esempio, vedo che il file 3S ha collegamenti con altri 2 files ( "lastra166930" e "QCC-OCL" ). Se puoi, mandameli.
In ogni caso dubito molto che chiunque abbia scritto la versione originale di questo applicativo sarà poi in grado di modificarlo o di finirselo da solo. ;)
Se invece deciderete di intraprendere la saggia via di una nuova ed esaustiva analisi e successiva completa riscrittura del codice... Fammi sapere.
Per fare una prova, vorrei avere una copia in Pvt di uno di quei files che vengono caricati dal file cliente.
Ad esempio, vedo che il file 3S ha collegamenti con altri 2 files ( "lastra166930" e "QCC-OCL" ). Se puoi, mandameli.
In ogni caso dubito molto che chiunque abbia scritto la versione originale di questo applicativo sarà poi in grado di modificarlo o di finirselo da solo. ;)
Se invece deciderete di intraprendere la saggia via di una nuova ed esaustiva analisi e successiva completa riscrittura del codice... Fammi sapere.
Ne ho parlato...
Prima di tutto i files in questione non li ho, e non mi sono stati dati in quanto : "non necessari al completamento del lavoro assegnatomi"
Mi sono permesso di consigliare una consuleza con te per la risoluzione definitiva del problema in questione e mi è stato risposto che :"non servono consulenti esterni per la risoluzione di un problema che io (il capo) ho già risolto per 3/4"
Per il resto, e cioè il discorso di cui avevo accennato in pm, direi che ci mettiamo d'accordo per vie private; alla fine mi hai aiutato (e perso una valanga di tempo per me) lo stesso.. anche se domani non potrò consegnare il programma funzionante :(
Insomma abbiamo a che fare con un vero "nazista" aziendale ! :D :D :D
Insomma abbiamo a che fare con un vero "nazista" aziendale ! :D :D :D
Semplicemente una persona che crede di aver visto/sapere tutto e che non ha voglia di imparare da nulla e nessuno.. non ti dico la strigliata che mi son preso perchè ti metteresti a ridere ;)
Speriamo che non legga mai questo thread... :D :D :D
Speriamo che non legga mai questo thread... :D :D :D
Difficile che il "Portatore di Luce" legga un forum ;)
Cmq.. Ho fatto i salti mortali per sapere tutto, ma dovrei aver fatto l'analisi finale totale del programma.
Il punto di partenza è un file excel cliente contenente vari fogli.
I fogli sicuramente presenti sono "Vari" e "Parametri", nel caso ci possono essere altri fogli chiamati "Ord.", "Ord", "ord.", "ord" e mese+numero ("giugno07", "aprile06" eccecc).
Questi fogli vanno controllati e copiati in un nuovo file, che avrà lo stesso nome e sarà messo in una directory diversa.
Per prima cosa: i fogli parametri, ord, ord., Ord., Ord si lasciano così come sono, e saranno copiati con formule e tutto.
Nei fogli Vari e mesi bisogna per prima cosa determinare la prima riga utilizzata e l'ultima secondo un certo criterio.
POTENZIALMENTE la prima riga in cui si possono scrivere i dati di un cliente è la 4, l'ultima non si sà.
Per determinare una riga vuota si guardano le celle delle colonne C F, se ENTRAMBE contengono una stringa il cui num di caratteri è < 4 allora quella riga è da considerarsi come vuota.
Per determinare l'ultima riga si fà così:
Data una riga, se le 20 righe successive risultano vuote (secondo il parametro appena spiegato) allora quella è l'ultima.
A questo punto si fà un controllo su certe colonne, che sono rispettivamente.
A D E G H J L M
Se contengono un valore non numerico (stringa) allora il contenuto delle celle diventeranno il commento della cella stessa.
-------------------------
A questo punto dovremmo sapere per i fogli vari e mesi quali sono le prime e le ulime righe utilizzate, e i valori che ci interessano corretti; possiamo cominciare a copiare, seguendo questo criterio.
La riga 1 non và copiata per intero, servono solo 2 valori, che sono la ragione sociale in (C;1) e il valore che è presente in (Q:1) ; questo valore dovrebbe essere una data, nel caso in cui non lo sia non và ricopiato nel foglio nuovo (quindi se è stata scritta in modo tale che non sia riconoscibile come data).
Righe 2 e 3 vanno ricopiate normalmente (anche perchè non vengono testate).
Ora bisogna fare un distinguo tra VARI e MESI.
Nei fogli vari si copia così.
partendo dalla prima riga utilizzata fino all'ultima
Per le celle delle colonne
Da A a N
Q
Da S a T
Da AA a AC
Da AG a AH
AQ
da AW a AZ
si copiano con la tecnica valori e formati, così che nel nuovo foglio appariranno solo i valori risultanti dalle formule, e non le formule stesse (devono diventare numeri pui, e non risultati di formule).
Per i fogli MESI
Dopo aver determinato prima ed ultima riga utilizzate si copia TUTTO (a parte la riga 1, 2 e 3 che sono già state trattate come ho spiegato sopra) con la funzione valori e formati, perchè nel foglio copiato non devono più apparire formule in questi mesi, ma solo numeri puri.
Infine bisogna che nel foglio copiato i fogli dei mesi (se presenti) siano ordinati in ordine decrescente.
A questo punto il foglio origine viene chiuso senza essere salvato, e quello nuovo avrà lo stesso nome e verrà salvato in una directory diversa.
Questa dovrebbe essere l'analisi TOTALE ed esaustiva del programma, è scritta chiaramente?
Mamma mia... :doh: :D
Sai, più che un gestionale sembra tanto l'esercizio universitario di un prof. pazzo.
Comunque ho alcune osservazioni : non esiste più alcun riferimento alle formule che vanno in errore, nè a quelle celle "da pulire" che erano presenti nelle scorse puntate... Sicuro che poi tutta 'sta roba non cambierà di nuovo ? :rolleyes:
Mamma mia... :doh: :D
Sai, più che un gestionale sembra tanto l'esercizio universitario di un prof. pazzo.
Comunque ho alcune osservazioni : non esiste più alcun riferimento alle formule che vanno in errore, nè a quelle celle "da pulire" che erano presenti nelle scorse puntate... Sicuro che poi tutta 'sta roba non cambierà di nuovo ? :rolleyes:
Ma infatti non ho idea di come sarà utilizzato, ne soprattutto IL MOTIVO per il quale serve...
Allora, le storie delle celle in errore e formule da pulire erano rispettivamente
- un modo secondo il quale venivano trovate le stringhe nelle colonne da testare e correggere, ma sono riuscito a fargli capire che cmq il risultato è lo stesso (incredibile ma vero).
- Per lui "pulire" non significa cancellare ma solo correggere le celle contenenti stringhe con il solito metodo (mettere il commento) e lasciare il contenuto della cella a 0.
Cmq stavolta ho rotto le palle per quasi 2 ore con domande e richieste di chiarimento.
Sono SICURO che questa analisi è praticamente perfetta, nel senso che racchiude tutto ciò che il programma deve fare e come và fatto.
Ti sembra chiara oppure riscrivo tutto pezzo per pezzo?
Ok. Sembra abbastanza chiara così.
Ho deciso di suddividere ulteriormente le operazioni, in modo tale da rendere il tutto più leggibile e modificabile.
Certo, un tantino in velocità di esecuzione verrà perso, ma credo che non ci saranno problemi.
Mi rifaccio vivo per ulteriori chiarimenti durante la scrittura... Stay tuned... ;)
Ultima cosa prima di cominciare : dovresti riuscire a farmi avere un file cliente-tipo valido con i valori già aggiornati. Voglio dire, senza che abbia bisogno di aggiornare i valori con i collegamenti esterni. Potrebbe essermi utile. ( uno come 3S sarebbe ok, ha tutti i fogli che servono, e non è troppo pesante per i test... )
Un modo sarebbe aprire quel file in presenza degli altri fogli di cui ha bisogno, e poi salvarne una copia. Ce la fai ?
Mi chiedi una cosa che non posso fare in quanto mi è stato impedito l'accesso ai file correlati a quelli dei clienti.
Intendo i file che vengono richiamati dalla macro di quel file (come tutti, del resto).
Cmq i file NON e ripeto NON vanno aggiornati, rimangono così come sono (questo ovviamente in fase di apertura, quando viene chiesto o meno l'aggiornamento, le operazioni successive sono una storia a se stante).
Ok. Proviamo questa soluzione :
1. Anzitutto :
- La gerarchia delle directory ( Cartella Programma / clienti / Saved ) è rimasta identica a prima.
- Il file PROGRAMMA.xls è identico al precedente.
2. Per cominciare vedremo solo la modifica del Foglio "Vari". Se questa funziona al 100%, passeremo ai fogli Mese.
3. Prendi un file cliente di test, ed ELIMINA TUTTE le precedenti Routine che ti avevo passato. Su un unico modulo di codice adesso devi avere QUESTE nuove routines :
Public Sub CORREZIONI()
CORREZIONE_VARI
End Sub
Public Sub CORREZIONE_VARI()
Dim Cella As Range
Dim indiceColonna As String
Dim indiceUltimaRiga As Long
'RIGA 1 :
For Each Cella In Sheets("Vari").Range("A1:IV1")
If Cella.Text <> Sheets("Vari").Range("C1").Text And Cella.Text <> Sheets("Vari").Range("Q1").Text Then
Cella.FormulaR1C1 = ""
Cella.Interior.ColorIndex = xlNone
End If
Next
If Not IsDate(Sheets("Vari").Range("Q1")) Then
Sheets("Vari").Range("Q1").FormulaR1C1 = ""
Sheets("Vari").Range("Q1").Interior.ColorIndex = xlNone
End If
'[RIGA 4 > RIGA N]x[ADEGHJLM] :
Dim indiciColonne As String
indiciColonne = "ADEGHJLM"
Dim i As Integer
For i = 1 To Len(indiciColonne)
indiceColonna = Mid(indiciColonne, i, 1)
indiceUltimaRiga = ULTIMA_RIGA("Vari", indiceColonna)
'Sheets("Vari").Range(indiceColonna & indiceUltimaRiga).Interior.ColorIndex = 3
For Each Cella In Sheets("Vari").Range(indiceColonna & "4:" & indiceColonna & indiceUltimaRiga)
If Cella.Text <> "" Then
If Not IsNumeric(Cella.Text) Then
Cella.AddComment (Cella.Text)
Cella.Comment.Visible = False
Cella.FormulaR1C1 = 0
End If
End If
Next
Next i
'[RIGA 4 > RIGA N]x[ABCDEFGHIJKLMNQST] :
Dim indiciColonne1 As String
indiciColonne1 = "ABCDEFGHIJKLMNQST"
Dim j As Integer
For j = 1 To Len(indiciColonne1)
indiceColonna = Mid(indiciColonne1, j, 1)
indiceUltimaRiga = ULTIMA_RIGA("Vari", indiceColonna)
For Each Cella In Sheets("Vari").Range(indiceColonna & "4:" & indiceColonna & indiceUltimaRiga)
If Cella.Text <> "" Then
If Left(Cella.Formula, 1) = "=" Then
Cella.FormulaR1C1 = Cella.Text
End If
End If
Next
Next j
'[RIGA 4 > RIGA N]x[AAABACAGAHAQAWAXAYAZ] :
Dim indiciColonne2 As String
indiciColonne2 = "AAABACAGAHAQAWAXAYAZ"
Dim start As Integer
Dim k As Integer
For k = 1 To (Len(indiciColonne2) / 2)
start = k * 2 - 1
indiceColonna = Mid(indiciColonne2, start, 2)
indiceUltimaRiga = ULTIMA_RIGA("Vari", indiceColonna)
For Each Cella In Sheets("Vari").Range(indiceColonna & "4:" & indiceColonna & indiceUltimaRiga)
If Cella.Text <> "" Then
If Left(Cella.Formula, 1) = "=" Then
Cella.FormulaR1C1 = Cella.Text
End If
End If
Next
Next k
End Sub
Public Function ULTIMA_RIGA(nomeFoglio As String, indiceCol As String) As Long
ULTIMA_RIGA = Sheets(nomeFoglio).Range(indiceCol & "65536").End(xlUp).Row + 1
End Function
Questo per testare, per ora, SOLO il Foglio Vari.
Prova...
Scusa il ritardo con il quale scrivo, giornata delirante in ufficio...
Ho provato adesso e non funziona completamente.
Allora la parte da ricopiare senza formule è ok.
La storia della prima riga no, mi viene riportato tutto così com'è nel foglio originale, invece dovrebbe togliere tutte le righe vuote utilizzate PRIMA della prima linea utile (con la condizione scritta addietro ,ovvero che in C ed in F siano presenti stringhe con un tot di lettere > di 4)
e tutte quelle DOPO l'ultima.
Ho provato adesso e non funziona completamente.
Allora la parte da ricopiare senza formule è ok.
La storia della prima riga no, mi viene riportato tutto così com'è nel foglio originale, invece dovrebbe togliere tutte le righe vuote utilizzate PRIMA della prima linea utile (con la condizione scritta addietro ,ovvero che in C ed in F siano presenti stringhe con un tot di lettere > di 4)
e tutte quelle DOPO l'ultima.
Allora devi cercare di essere parecchio più preciso, perchè te lo dico sinceramente, mi sa che non ci sto più capendo una mazza. :muro:
Tu avevi chiesto che nel Foglio Vari le righe 2 e 3 vanno messe sul file generato pari-pari...
La riga 1, cito tue testuali parole :
"La riga 1 non và copiata per intero, servono solo 2 valori, che sono la ragione sociale in (C;1) e il valore che è presente in (Q:1) ;
questo valore dovrebbe essere una data, nel caso in cui non lo sia non và ricopiato nel foglio nuovo
(quindi se è stata scritta in modo tale che non sia riconoscibile come data)."
E il mio codice fa esattamente questo.
:confused:
Mia imprecisione di scrittura, chiedo venia.
La prima riga, con i suoi 2 valori vengono copiati correttamente.
Intendevo la prima riga a partire dalla 4, il programma non riconosce correttamente se la riga è utilizzata o meno, o se lo riconosce cmq non la toglie nella copia.
Scusa, ho scritto di fretta.
Intendevo la prima riga a partire dalla 4, il programma non riconosce correttamente se la riga è utilizzata o meno, o se lo riconosce cmq non la toglie nella copia.
Scusa, ho scritto di fretta.
Allora, vediamo se è corretto :
Rimaniamo sempre su Foglio Vari, per ora :
1. Manca il controllo sulle righe vuote ( dalla riga 4 in poi... ).
2. Le celle da controllare per determinare se la riga è da considerarsi VUOTA, e quindi eliminabile, sono le due celle sulle colonne C e F.
>> Se ENTRAMBE le celle sono VUOTE ( ossia non contengono neanche lo "0" ) >> Riga VUOTA ed ELIMINABILE.
>> Se ENTRAMBE le celle contengono una STRINGA, e se questa STRINGA ha lunghezza strettamente < 4 ( non minore-uguale ) >> Riga VUOTA ed ELIMINABILE.
3. Sono tutte qui le condizioni ? E' corretto come ho scritto ?
4. Una volta che una riga è data per ELIMINABILE, cosa bisogna farne ? Viene eliminata e la riga subito sotto ( a patto che non sia essa stessa VUOTA ) ne prende il posto ? Ossia bisogna "shiftare" le righe verso l'alto in modo che non esistano più righe VUOTE nel file generato ?
Fammi sapere...
Esattamente, la riga sotto dev SHIFTARE sopra.
NB: questo discorso vale solo per le righe vuote PRIMA della prima utilizzata e DOPO l'ultima utilizzata.
Quindi nel foglio copiato alla riga 4 apparirà subito la prima riga utilizzata nel foglio originale (anche se magari era la 20esima perchè quelle prima erano vuote), poi ci saranno altre righe utilizzate (magari con qualche riga vuota in mezzo, ma sempre meno di 20, come scritto nell'analisi) ed il tutto finirà dopo l'ultima riga utilizzata.
Elimina tutte le mie precedenti routines dal foglio cliente di test,
e nel nostro "modulo aggiuntivo" copia tutte quelle nuove che trovi in questo file allegato :
60155
Prova e fammi sapere esattamente cosa eventualmente va aggiunto/corretto.
Provato.
Le righe inutili presenti tra la riga 4 e la prima utilizzata vengono eliminate correttamente e correttamente la riga utile viene shiftata in alto.
Le righe vuote presenti tra una riga utilizzata e l'altra rimangono presenti correttamente.
Unico problema sono le righe vuote DOPO l'ultima utilizzata, che dovrebbero essere eliminate ed invece restano.
Potremmo provare, per dare un senso di ordine a shiftare la riga spessa che indica la fine delle righe utilizzate in un foglio sotto l'ultima riga utilizzata, così da creare un rettangolo ordinato e preciso.
In questo modo
Faccio esempio
------------------------------------- (riga spessa nera presente tra la riga 3 e 4)
PRIMA
Vuota
Vuote
Utile
Vuota
Utile
Utile
ULTIMA RIGA UTILE
-------------------------------------- (riga spessa nera)
Provato.
Le righe inutili presenti tra la riga 4 e la prima utilizzata vengono eliminate correttamente e correttamente la riga utile viene shiftata in alto.
Le righe vuote presenti tra una riga utilizzata e l'altra rimangono presenti correttamente.
Unico problema sono le righe vuote DOPO l'ultima utilizzata, che dovrebbero essere eliminate ed invece restano.
Perfetto. Come mi aspettavo. L'unica cosa che non va è in effetti quella che devo ancora aggiungere. :)
Manca ancora poco. Una volta risolto al 100% il Foglio "Vari", con i Fogli Mese sarà tutto più veloce. Siamo quasi alla fine, se Dio vuole... :D
Al solito, elimina tutte le mie precedenti routines dal foglio cliente di test, e copia tutte quelle nuove che trovi in questo file allegato :
60178
Righette a parte, fammi sapere se è ok adesso. ;)
Adesso dà un errore.
Quando faccio partire programma appare una msgbox che dice:
"errore di compilazione. Sub o Function non definita"
Quando premo ok indica
'Cancella righe vuote prima della prima valida :
Dim i As Long
For i = 4 To ultimaRiga
If SE_RIGA_VALIDA("Vari", indiceRiga) = False Then
Range("C" & indiceRiga).EntireRow.Delete Shift:=xlUp
End If
Next i
Contenuta in Public Sub ELIMINA_VUOTE(nomeFoglio As String)
Provato e riprovato : da me funziona perfettamente.
Forse hai sbagliato a copiare... :(
Ripeto : devi sostituire TUTTO il precedente codice per il foglio cliente con quello che ti mando nel file .txt.
Quando ti mando un nuovo file MODULO txt, quello sostituisce tutti i precedenti, e così via.
Non cercare di importare il file txt direttamente nel progetto vba, ma aprilo, poi Seleziona tutto, Copia, Incolla nel Modulo VBA del file cliente, facendo attenzione di non mischiare parti del codice vecchio con quello nuovo !
Controlla bene che nel file cliente di test ci sia questa Function, scritta esattamente così :
Public Function SE_RIGA_VALIDA(nomeFoglio As String, indiceRiga As Long) As Boolean
Dim cond1 As Boolean
cond1 = True
Dim cond2 As Boolean
cond2 = True
'cond1 :
If Sheets(nomeFoglio).Range("C" & indiceRiga).Text = "" And Sheets(nomeFoglio).Range("F" & indiceRiga).Text = "" Then
cond1 = False
End If
'cond2 :
If Not IsNumeric(Sheets(nomeFoglio).Range("C" & indiceRiga).Text) And Not IsNumeric(Sheets(nomeFoglio).Range("F" & indiceRiga).Text) Then
If Len(Sheets(nomeFoglio).Range("C" & indiceRiga).Text) < 4 And Len(Sheets(nomeFoglio).Range("F" & indiceRiga).Text) < 4 Then
cond2 = False
End If
End If
If cond1 = True And cond2 = True Then
SE_RIGA_VALIDA = True
Else
SE_RIGA_VALIDA = False
End If
End Function
Credo di essere stato chiaro, che più chiaro non si può. :D
P.s.: Già che ci siamo, per la storia delle righe orizzontali, dimmi esattamente da che colonna a che colonna la riga deve essere disegnata : ad esempio vedo che nel file "3S" la riga spessa orizzontale va dalla colonna A alla colonna AP...
Per la riga: dalla colonna A alla AP và bene.
Ho riprovato cancellando il modulo e ricreandolo ed effettivamente parte :)
Per quanto riguarda la riga vuota "sopra" (cioè quella prima della prima riga utilizzata) funziona bene, come l'altro tentativo.
Per la riga sotto funziona parzialmente, ti spiego.
Nel foglio 3s che usiamo per i test la prima riga utilizzata (nel foglio originale) è la 5 e l'ultima è la 19.
Quindi nel foglio copiato dovrebbero essere rispettivamente la 4 e la 18, sotto la 18 non ci dovrebbe essere nulla, solo la linea spessa che indica la fine del foglio utilizzato.
Invece ora come ora, la prima riga è giusta, l'ultima è giusta ma sotto rimangono 12 righe da considerarsi vuote che andrebbero tolte.
Cmq il programma funziona parzialmente in quanto nel foglio originale le righe vuote sotto l'ultima utilizzata sono 14; quindi 2 sono state eliminate correttamente (una è la prima che fà shiftare tutto verso l'alto, ma l'altra deve essere stata tolta da sotto, in quanto le righe vuote tra quelle utilizzate sono state tenute correttamente).
Eliminare tutto e sostituire... :
60188
Prova. :)
Funziona perfettamente!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
Funziona perfettamente!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
OTTIMO. :)
Ora, prima di procedere con la correzione dei Fogli Mese, ho assolutamente bisogno di avere alcune risposte, riguardo il metodo ( pessimo :( ) con cui il tuo caro boss ha deciso di nominare i fogli.
1. I fogli Vari e Parametri, vanno benone, a patto che siano nominati esattamente così in tutti i files.
2. Il foglio Ord., non può, essere nominato in 4 modi diversi ( ord, Ord, ord., Ord., ... ), a seconda del file ! Ripeto per l'ennesima volta : eliminare i problemi e le inutili complicazioni in fase di analisi !
Perciò questo benedetto foglio si chiamerà SEMPRE Ord.. Esattamente come l'ho scritto, pena il mancato ordinamento decrescente dei fogli alla fine del processo.
3. Fogli mese : qui soprattutto è stato scelto un metodo pessimo, in particolare se poi si pianifica di usare i nomi all'interno di procedure automatiche ! Bisogna semplificarsela la vita, non complicarsela inutilmente, e qui abbiamo l'ennesimo saggio della scarsa lungimiranza di chi ha fatto l'analisi originaria del progetto.
Scusa se "sparo a zero", ma la realtà è purtroppo questa. :(
Perciò ti dico subito che ho già qui tutto il codice pronto, che esegue il 100% della tua analisi, ma urge rinominare i fogli mese !
Quello che consiglio caldamente io :
anzichè dicembre07 >> 2007_12
anzichè gennaio08 >> 2008_01
anzichè febbraio08 >> 2008_02
...
e così via.
Secondo me una persona intelligente accetterebbe.
Se invece viene posto un veto irremovibile alla rinomina dei fogli mese, ti dico subito che dovrete rinunciare all'ultima operazione di ordinamento decrescente dei fogli. :rolleyes:
Se tutto questo può essere fatto >> ti consegno già il programma finito. :)
Mi sembra una soluzione molto intelligente!! domattina chiedo!!
Mi sembra una soluzione molto intelligente!! domattina chiedo!!
Allora hai chiesto ? Fumata bianca o nera ? :)
Allora hai chiesto ? Fumata bianca o nera ? :)
Fumata nera! I mesi restano così come sono... piuttosto non si riordina...
... mah...
Fumata nera! I mesi restano così come sono... piuttosto non si riordina...
... mah...
Me l'aspettavo.
Comunque ti informo che questo non avrebbe "stravolto" nulla, perchè alla rinomina di un foglio, Excel provvede automaticamente ad aggiornare eventuali collegamenti o riferimenti... :rolleyes:
Si trattava solo di avere un pizzico di elasticità.
Allora ti invio il codice modulo, versione senza riordino, che va a sostituire il precedente :
60248
Fammi sapere.
Beh, come va ? Sparito ?
Vedo che spesso sei online, e non spieghi perchè hai cessato di interessarti alla soluzione di un problema
che fino a pochi giorni fa era per te di vitale importanza...
E in ogni caso, non ti sembra il tuo un comportamento, a dir poco, scorretto e ineducato ?
Due giorni dopo il mio ultimo post ( 19 / 03 / 2008 ) sei online e discuti della tua nuova Lumix, correggimi se sbaglio...
Ma quanto tempo ti ci vuole per scrivere "Scusa, non ho ancora provato. Non ho avuto tempo..."oppure "Scusa ma il mio capo è quello che è... Grazie tante, ma abbiamo fatto marcia indietro e non se ne fa più nulla..."
o ancora, che so io, "Problema risolto, ma ti ho fatto un'offerta che non ero in grado di mantenere..."
Frasi semplici no ? 10 secondi, forse... O per te è già troppo ?
Casomai ripassassi di qui, ti chiarisco definitivamente la situazione :
- Anzitutto, dei tuoi regalucci / soldi non ho alcun bisogno.
Già te lo avevo fatto capire in pvt, mi pare...
- Hai chiesto aiuto tu, e sei stato aiutato ben oltre le tue aspettative.
- Hai offerto tu di pagare. Nessuno qui ti ha mai chiesto un cent,
e comunque non dovresti fare offerte che non sei in grado di onorare.
Scappare non serve a nulla, solo a farti fare una figuraccia... :rolleyes:
- Mia Personale Opinione : hai dimostrato di saper usare molto male questo Forum.
Se ora hai deciso di abbandonare la discussione, è un problema tuo,
ma potevi almeno cercare di farlo nel modo giusto, magari spendendo due parole per spiegarne il motivo
e ringraziando pubblicamente chi invece ti ha puntualmente risposto e trattato con il dovuto rispetto.
Credo non sia chiedere troppo, a fronte di tutta l'attenzione che hai ricevuto.
Forse queste non saranno esplicite regole del Forum
in base alle quali tu possa essere sanzionato ( mi piacerebbe molto che lo fossero ).
Sicuramente, almeno a casa mia, il rispondere a tono a chi ti
tende generosamente una mano è più che altro una regola di vita.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.