2009-03-27 6 views
1

J'ai besoin de lire un fichier CSV, et la seule langue que je peux utiliser est VBScript.Est-ce que VBscript a des modules? J'ai besoin de gérer CSV

Je suis en train d'ouvrir le fichier et de le séparer en virgules, et cela fonctionne correctement car il n'y a pas de virgules entre guillemets dans les champs. Mais je suis conscient que c'est une solution incroyablement fragile.

Alors, est-ce que je peux utiliser un module VBScript? Quelque part pour obtenir une expression régulière éprouvée qui ne se diviserait que par des virgules entre guillemets?

Toute suggestion reçue avec gratitude.

+0

Merci pour les réponses, tout le monde. Je vais les tester quand je serai de retour au travail lundi. – AmbroseChapel

Répondre

7

VBScript ne possède pas de système de module comparable à Perl. Cependant, vous pouvez ouvrir les fichiers CSV avec ADO et y accéder comme une table de base de données. Le code serait quelque chose comme ceci:

(Les commentaires drôles sont uniquement pour corriger la syntaxe VB est si brisée en surbrillance)

Dim conn ''// As ADODB.Connection 
Dim rs  ''// As ADODB.RecordSet 
Dim connStr ''// As String 
Dim dataDir ''// As String 

dataDir = "C:\"       '" 
connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dataDir & ";Extended Properties=""text""" 

Set conn = CreateObject("ADODB.Connection") 
conn.Open(connStr) 
Set rs = conn.Execute("SELECT * FROM [data.txt]") 

''// do something with the recordset 
WScript.Echo rs.Fields.Count & " columns found." 
WScript.Echo "---" 

WScript.Echo rs.Fields("Col1Name").Value 
If Not rs.EOF Then 
    rs.MoveNext 
    WScript.Echo rs.Fields("Col3Name").Value 
End If 

''// explicitly closing stuff is somewhat optional 
''// in this script, but consider it a good habit 
rs.Close 
conn.Close 

Set rs = Nothing 
Set conn = Nothing 

Création d'un fichier schema.ini qui décrit exactement votre entrée est optimale. Si vous ne le faites pas, vous forcez le pilote de texte à deviner, et tous les paris sont désactivés s'il devine la mauvaise chose. Le schema.ini doit résider dans le même répertoire que vos données.

mine ressemblait à ceci:

[data.txt] 
Format=Delimited(;) 
DecimalSymbol=. 
ColNameHeader=True 
MaxScanRows=0 
Col1=Col1Name Long 
Col2=Col2Name Long 
Col3=Col3Name Text 
Col4=Col4Name Text 

et avec ce data.txt:

a;b;c;d 
1;2;"foo bar";"yadayada" 
1;2;"sample data";"blah" 

je reçois cette sortie:

C:\>cscript -nologo data.vbs 
4 columns found. 
--- 
1 
sample data 

C:\> 

Vaut lire à cet égard: Much ADO About Text Files au large de la MSDN.

+0

J'essaie d'exécuter le script comme indiqué et il se plaint qu'il n'y a pas d'objet Wscript. Qu'est-ce que je rate? – AmbroseChapel

+0

Vous n'essayez pas de l'exécuter depuis un environnement VB, n'est-ce pas? C'est VBScript, pas VB. – Tomalak

0

Vous pouvez essayer de créer une source de données ODBC Excel au format CSV (appelé DSN Je pense que dans Panneau de configuration -.> Outils d'administration -.> Sources de données ODBC Ensuite, vous pouvez interroger à l'aide de SQL

.

Je suis toujours pas sûr si vous pouvez obtenir ce que vous voulez que je veux dire l'insertion d'une chaîne avec des virgules en elle comme une valeur pour une cellule particulière

0

a regexp:..

'Credits go to http://www.codeguru.com/cpp/cpp/algorithms/strings/article.php/c8153/ 
r.Pattern = ",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))" 

il trouvera toutes les virgules que ne sont pas à l'intérieur tes.

Vous pouvez également utiliser cette fonction que je viens d'adapter pour vbs.

call test 


Function ParseCSV(StringToParse, Quotes) 
    Dim i, r(), QuotedItemStart, prevpos 

    ReDim r(0) 
    prevpos = 1 

    For i = 1 To Len(StringToParse) 
    If Mid(StringToParse, i, 1) = "," Then 
     If QuotedItemStart = 0 Then 
     r(UBound(r)) = Trim(Mid(StringToParse, prevpos, i - prevpos)) 
     ReDim Preserve r(UBound(r) + 1) 
     prevpos = i + 1 
     End If 
    Else 
     If InStr(1, Quotes, Mid(StringToParse, i, 1)) Then 
     If QuotedItemStart Then 
      r(UBound(r)) = Trim(Mid(StringToParse, QuotedItemStart, i - QuotedItemStart)) 
      ReDim Preserve r(UBound(r) + 1) 
      QuotedItemStart = 0 
      prevpos = i + 2 
      i = i + 1 
     Else 
      QuotedItemStart = i + 1 
     End If 
     End If 
    End If 
    Next 

    If prevpos < Len(StringToParse) Then r(UBound(r)) = Trim(Mid(StringToParse, prevpos)) 
    ParseCSV = r 
End Function 


Sub Test() 
    Dim i, s 

    s = ParseCSV("""This is, some text!"",25,""Holy holes!"", 286", """") 

    For i = LBound(s) To UBound(s) 
    msgbox s(i) 
    Next 

    msgbox "Items: " & CStr(UBound(s) - LBound(s) + 1) 
End Sub 
0

Pour répondre à l'autre moitié de votre question, je me souviens vaguement que vous pouvez utiliser Windows Script Host réparti sur plusieurs fichiers WSF. Je ne l'ai jamais fait moi-même, link to MSDN. VBS non pur, mais il devrait fonctionner dans des fenêtres «justes», si c'était la vraie contrainte.

Plus de liens:

Questions connexes