PDA

View Full Version : [VBA] Excel, programmino per il lavoro


Rejde
23-09-2008, 15:45
Ciao, premetto che sono totalmente a digiuno di visual basic, mi sono dilettato nella programmazione alle superiori frequentando il corso di elettronica ma poi mi sono "spostato" su ing meccanica.
Cmq in questi giorni mi è venuto lo schizzo di realizzare un piccolo programmino in visual basic per excel per importare alcuni file dati al lavoro e convertirli per una maschera in excel.
Diciamo che leggendo qua e là me la sto cavando, mi sono bloccato nell'analisi di una matrice ricavata dalla funzione GetOpenFileName...mi spiego: vorrei dare la possibilità di selezionare più file dati, ottengo perciò una matrice riportante riga per riga il percorso dei file che si vogliono modificare, bene, ora voglio analizzare tali file ma non riesco a trovare la funzione che riporti il numero di righe di tale matrice e senza questa informazione non posso impostare un ciclo "for", mi sapreste dare qualche consiglio?
Utilizzerò questo thread per eventuali altri consigli...se mai ne avrò ancora bisogno.

yorkeiser
23-09-2008, 15:52
Se non conosci la dimensione esatta dell'array, ti conviene usare un ciclo while.
Come condizione di uscita dal ciclo, potresti ad esempio l'informazione sul fatto che il nome del file deve contenere qualcosa, se è nullo vuol dire che hai terminato l'elaborazione (è un'ipotesi, non conosco la tua applicazione). Una cosa del tipo:

dim file_processato as integer
file_processato = 0

while array_dei_nomi(file_processato) <> ""
[... processa array_dei_nomi(file_processato)...]
file_processato = file_processato + 1
wend

Rejde
24-09-2008, 10:57
Grazie per la risposta, non credo però di essermi spiegato bene.
Utilizzando la funzione GetOpenFileName vorrei dare l'opportunità di aprire più file dati contemporaneamente, ottengo in uscita dalla funzione perciò una stringa riportante il percorso per esteso in cui è collocato ciascun file selezionato, da ciò che mi pare di avere intuito analizzando la variabile ciascun percorso è su una riga diversa dalla matrice stringa, vorrei riuscire a ricavare da ciascun percorso il nome nel file ripulendolo dal percorso. Se devo fare l'operazione su una matrice di cui non conosco la dimensione, non sapendo quanti file l'utente potrà andare a selezionare come posso agire? Premetto che su una stringa monodimensionale l'operazione mi riesce bene, il mio problema in poche parole, è risalire al numero di righe della matrice per impostare un ciclo for che vada ad analizzare ciscuna riga

yorkeiser
24-09-2008, 11:58
Non ho capito granchè, andiamo per esempi: com'è la matrice ?
Ad esempio, se l'utente/programma apre 3 files, la matrice sarà del tipo
matrice(0)="c:\windows\....\file1"
matrice(1)="c:\windows\....\file2"
matrice(2)="c:\windows\....\file3"

o no ?

Rejde
24-09-2008, 12:12
Non ho capito granchè, andiamo per esempi: com'è la matrice ?
Ad esempio, se l'utente/programma apre 3 files, la matrice sarà del tipo
matrice(0)="c:\windows\....\file1"
matrice(1)="c:\windows\....\file2"
matrice(2)="c:\windows\....\file3"

o no ?

Proprio così!

yorkeiser
24-09-2008, 13:31
Ok, allora il codice che ti ho postato precedentemente dovrebbe funzionare nel tuo caso, devi solo aggiungere l'istruzione che "ripulisce" il nome del file dal percorso.

dim file_processato as integer
dim nome_ripulito as string
file_processato = 0

while array(file_processato) <> "" and file_processato<=ubound(array())

nome_ripulito = mid(array(file_processato), InstrRev(array(file_processato),"/")+1)

file_processato = file_processato + 1
wend

supponendo che "/" sia il carattere di nesting delle directory sul tuo sistema operativo.

Rejde
24-09-2008, 14:14
Non capisco, ci deve essere un problema di tipologia di variabile che causa l'errore perchè passando riga per riga il codice con F8 nel momento in cui tento di fare una qualsiasi operazione sulla stringa restituita da GetOpenFilename risulta un errore. Analizzando nella finestra espressioni di controllo la variabile su cui vengono memorizzati i percorsi dei file è di tipo Variant/String, può essere questo?
Per capirci riporto alcune righe di codice
fileDATToOpen = Application.GetOpenFilename("Dati origine DAT (*.dat), *.dat", , , , True)

a questo punto volendo ad esempio riportare i percorsi dei file con una listbox farei in un ciclo for each
lstDAT.additem fileDATToOpen(i)
ma ottengo un errore di incompatibilità di tipi
se provo a scrivere una riga del tipo

dim prova as string
prova = fileDATToOpen(0)

ottengo un errore di "indice non incluso nell'intervallo", insomma non riesco ad lavorare su sta cavolo di stringa fileDATToOpen, sicuramente credo di sbagliare nell'assegnazione del tipo di variabili :confused:

Rejde
25-09-2008, 12:06
Nessuno saprebbe come aiutarmi? Ho provato a fare una conversione da variant a string ma non ne scappooo cmq! Se è utile posso postare il listato del codice...

a2000.1
25-09-2008, 16:43
questo va. ;)



Sub aaa()
Dim v As Variant

v = Application.GetOpenFilename(, , , , True)
For i = 1 To UBound(v)
v(i) = Mid$(v(i), InStrRev(v(i), "\") + 1)
Next i

End Sub

MarcoGG
29-09-2008, 10:38
Per capirci riporto alcune righe di codice
fileDATToOpen = Application.GetOpenFilename("Dati origine DAT (*.dat), *.dat", , , , True)

a questo punto volendo ad esempio riportare i percorsi dei file con una listbox farei in un ciclo for each
lstDAT.additem fileDATToOpen(i)
ma ottengo un errore di incompatibilità di tipi
se provo a scrivere una riga del tipo

dim prova as string
prova = fileDATToOpen(0)

ottengo un errore di "indice non incluso nell'intervallo", insomma non riesco ad lavorare su sta cavolo di stringa fileDATToOpen, sicuramente credo di sbagliare nell'assegnazione del tipo di variabili :confused:


Se vuoi usare GetOpenFilename, la funzione presume che l'utente selezioni almeno un file. Ovvio che se, sulla finestra di selezione, dai "annulla", la routine produce un errore di incompatibilità del tipo...
Tornando al tuo tentativo, il codice VBA corretto per popolare la tua listbox con i percorsi completi dei files selezionati dall'utente è questo :

lstFiles.Clear
Dim arrayNomi() As Variant
ChDir ThisWorkbook.Path & "\Test"
On Error Resume Next
arrayNomi = Application.GetOpenFilename("Files DAT (*.DAT), *.DAT", , "Selezionare i files :", , True)

Dim i As Integer
i = 0
For i = 1 To UBound(arrayNomi)
lstFiles.AddItem (arrayNomi(i))
Next i
Ove lstFiles è il controllo ListBox, mentre On Error Resume Next in quella posizione previene dall'errore di runtime nel caso in cui l'utente esca dalla funzione senza selezionare alcun file.
Infine ChDir ThisWorkbook.Path & "\Test" in questo caso permette di aprire la dialogBox in una directory desiderata ( la cartella "Test" che sta nella stessa dir del Workbook corrente ). ;)

Rejde
08-10-2008, 09:26
Grazie mille a tutti per l'aiuto...scusate il ritardo ma ho avuto un pò da fare in questo periodo. La parte finale di codice che ho utilizzato è la seguente:
For i = 0 To UBound(fileDATToOpen)
If i = 0 Then
nDAT = 0
ElencoDAT = fileDATToOpen
lstDAT.Clear
temp = CStr(fileDATToOpen(i + 1))
RevPos = InStrRev(temp, "\")
nomeFile(i) = Mid$(temp, RevPos + 1)
lstDAT.AddItem nomeFile(i)
Else
temp = CStr(fileDATToOpen(i + 1))
RevPos = InStrRev(temp, "\")
nomeFile(i) = Mid$(temp, RevPos + 1)
lstDAT.AddItem nomeFile(i)
nDAT = nDAT + 1
End If
Next i
Pare non dare alcun problema.
Ora sto testando un pò il programmino, alcuni problemi ci sono ancora...nel caso non risolva mi rivolgerò nuovamente a voi, in questo thread :D
In verità avrei già un quesito, mi sapreste consigliare qualche riga di codice per individuare l'inizio di una serie di dati numerici? Mi spiego meglio, il file dati che viene generato dalla macchina riporta un'intestazione che può occupare diverse righe e colonne, con codici numerici o parole, dopodichè, ad una certa riga, partendo dall'alto, (supponiamo la riga 9) iniziano i dati, che possono occupare più colonne ma comunque dalla riga 9 in poi si avranno solo numeri. Vorrei individuare la riga in cui iniziano questi dati numerici; ricordo che tutte le celle di questo foglio hanno formato generico e tale foglio è ottenuto utilizzando la funzione Workbooks.OpenText mediante la quale importo il appunti il file dati generato dalla macchina.

MarcoGG
08-10-2008, 09:44
In verità avrei già un quesito, mi sapreste consigliare qualche riga di codice per individuare l'inizio di una serie di dati numerici? Mi spiego meglio, il file dati che viene generato dalla macchina riporta un'intestazione che può occupare diverse righe e colonne, con codici numerici o parole, dopodichè, ad una certa riga, partendo dall'alto, (supponiamo la riga 9) iniziano i dati, che possono occupare più colonne ma comunque dalla riga 9 in poi si avranno solo numeri. Vorrei individuare la riga in cui iniziano questi dati numerici; ricordo che tutte le celle di questo foglio hanno formato generico e tale foglio è ottenuto utilizzando la funzione Workbooks.OpenText mediante la quale importo il appunti il file dati generato dalla macchina.


Pigliati una colonna di riferimento, poi scorri le righe dall'alto in basso ( For i = 1 to n ) e con IsNumeric() controlli se il contenuto della cella è numerico. Se sì, il valore i del ciclo For sarà l'indice di riga in cui iniziano i dati...

Rejde
10-10-2008, 14:13
Grazie mille ragazzi! Con l'utilizzo del programma mi vengono in mente idee per cercare di automatizzare sempre più operazioni.
Vorrei porvi questo problema: solitamente nei fogli XLS in cui vengono importati i dati è presente un grafico che utilizza valori presenti in 2 colonne (del foglio in cui ho importato i dati) che a priori non posso conoscere, ci sarebbe un modo per poter individuare il grafico presente nel foglio, le colonne di dati che utilizza e fare in modo che di volta in volta venga settato il range di righe occupate da valori numerici (il numero di righe sarà lo stesso per tutte e due le colonne ovviamente) e quindi da utilizzare per il grafico?

Rejde
17-10-2008, 15:55
Nessuna idea? :stordita: