Comment importer des fichiers CSV via Excel VBA dans un ensemble, dans des groupes ou dans plusieurs fichiers individuels, plutôt qu'un à la fois?Comment charger plus de 1 fichier CSV à la fois via Excel VBA?
Répondre
Vous pouvez écrire une application console simple pour analyser un lot de fichiers CSV et les enregistrer dans des fichiers Excel.
Ce n'est pas la solution la plus simple, mais cela pourrait être une option.
Cela obtenir un fichier dans une matrice unidimensionnelle rapidement
Open "myfile.csv" For Input As 1
Dim Txt As String
Txt = Input(LOF(1), 1)
Close #1
Dim V As Variant
V = Split(Txt, ",")
Alors V contient tous les éléments dans une seule colonne, NB premier élément est V (0)
Je suis un peu perplexe en ce sens que la plupart des versions d'Excel ouvriront des fichiers .csv sans aucun problème.
strPath = "C:\Docs\"
strFile = Dir(strPath & "*.csv")
Do While strFile <> ""
Workbooks.Open Filename:=strPath & strFile
ActiveWorkbook.SaveAs Filename:=strPath & Mid(strFile, 1, InStr(strFile, ".") - 1) _
& "Conv.xls", FileFormat:=xlNormal
strFile = Dir
Loop
vous pouvez également utiliser workbooks.opentext
L'idée que j'avais à l'origine était la suivante. Compte tenu de ces données
Dog Names,Dog Ages,Collar Size
Woof,3,4
Bowser,2,5
Ruffy,4.5,6
Angel,1,7
Demon,7,8
Dog,9,2
créer trois tableaux globaux, appelé Dog_Names
, Dog_Ages
et Collar_Size
et les remplir avec les données du fichier CSV.
Ce bit de VBScript effectue ce travail et affiche les résultats. Supprimez la marque de commentaire du wscript.echo
dans le sous-programme x
pour voir tout cela se produire.
Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim oStream
Dim sData
Dim aData
Set oStream = fso.OpenTextFile("data.csv")
sData = oStream.ReadAll
aData = Split(sData, vbNewLine)
Dim sLine
sLine = aData(0)
Dim aContent
aContent = Split(sLine, ",")
Dim aNames()
Dim nArrayCount
nArrayCount = UBound(aContent)
ReDim aNames(nArrayCount)
Dim i
For i = 0 To nArrayCount
aNames(i) = Replace(aContent(i), " ", "_")
x "dim " & aNames(i) & "()"
Next
For j = 0 To nArrayCount
x "redim " & aNames(j) & "(" & UBound(aData) - 1 & ")"
Next
Dim j
Dim actual
actual = 0
For i = 1 To UBound(aData)
sLine = aData(i)
If sLine <> vbnullstring Then
actual = actual + 1
aContent = Split(sLine, ",")
For j = 0 To nArrayCount
x aNames(j) & "(" & i - 1 & ")=" & Chr(34) & aContent(j) & Chr(34)
Next
End If
Next
For j = 0 To nArrayCount
x "redim preserve " & aNames(j) & "(" & actual - 1 & ")"
Next
For i = 0 To actual - 1
For j = 0 To nArrayCount
x "wscript.echo aNames(" & j & ")," & aNames(j) & "(" & i & ")"
Next
Next
Sub x(s)
'wscript.echo s
executeglobal s
End Sub
Le résultat ressemble à ceci
>cscript "C:\Documents and Settings\Bruce\Desktop\datathing.vbs"
Dog_Names Woof
Dog_Ages 3
Collar_Size 4
Dog_Names Bowser
Dog_Ages 2
Collar_Size 5
Dog_Names Ruffy
Dog_Ages 4.5
Collar_Size 6
Dog_Names Angel
Dog_Ages 1
Collar_Size 7
Dog_Names Demon
Dog_Ages 7
Collar_Size 8
Dog_Names Dog
Dog_Ages 9
Collar_Size 2
>Exit code: 0 Time: 0.338
boost - si je comprends bien ExecuteGlobal (et Execute) ne sont disponibles que dans VBScript mais pas dans VBA? –
Ceci est une autre façon qui évite le recalcul que vous obtenez lorsque vous ouvrez un fichier csv dans Excel.
Ajouter une feuille blanche à votre classeur et ajoutez le code suivant l'objet de la feuille
Function getCsv(fn)
Dim d, scrup As Boolean
scrup = Application.ScreenUpdating
Application.ScreenUpdating = False
With Me.QueryTables.Add(_
Connection:="TEXT;" & fn, _
Destination:=Me.Range("A1") _
)
.Name = "data"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshStyle = xlOverwriteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = False
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileCommaDelimiter = True
.Refresh BackgroundQuery:=False
End With
d = Me.Names(1).RefersToRange.Value
Me.Names(1).Delete
Me.UsedRange.Rows.Delete
Application.ScreenUpdating = scrup
getCsv = d
End Function
Vous pouvez également cacher la feuille, de sorte que personne n'utilise accidentellement. vous pouvez utiliser comme celui-ci
dim d
d = getCsv("C:\temp\some.csv")
Une chose qui me préoccupe un peu est que le nom s'incrémenté à chaque fois que vous utilisez la fonction (par exemple données_1, données_2, ...), donc il pourrait y avoir un problème de stabilité si ces noms sont sauvés quelque part.
Je pense que vous feriez mieux de fractionner vbNewLine pour diviser le fichier en lignes, puis en divisant chaque ligne par une virgule. De cette façon, vous serez en mesure d'adresser chaque champ comme V (ligne) (colonne). ligne et colonne seraient bien sûr basées sur zéro. – bugmagnet
En outre, cela suppose que les champs ne sont pas délimités par des guillemets ou contiennent des virgules incorporées. – Graham