VBscript 有模塊嗎?我需要處理 CSV (Does VBscript have modules? I need to handle CSV)


問題描述

VBscript 有模塊嗎?我需要處理 CSV (Does VBscript have modules? I need to handle CSV)

I have a need to read a CSV file, and the only language I can use is VBscript.

I'm currently just opening the file and splitting on commas, and it's working OK because there aren't any quoted commas in fields. But I'm aware this is an incredibly fragile solution.

So, is there such a thing as a VBscript module I can use? Somewhere to get a tried-and-tested regular expression that would only split on commas not in quotes?

Any suggestions gratefully received.


參考解法

方法 1:

VBScript does not have a module system comparable to Perl. However you can open CSV files with ADO and access them like a database table. The code would go something like this:

(The funny comments are solely to fix SO's broken VB syntax highlighting)

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

Creating a schema.ini file that exactly describes your input is optimal. If you don't, you force the text driver to guess, and all bets are off if it guesses the wrong thing. The schema.ini must reside in the same directory where your data is.

Mine looked like this:

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

and with this data.txt:

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

I get this output:

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

C:\>

Worth a read in this regard: Much ADO About Text Files off the MSDN.

方法 2:

You can try creating an Excel ODBC Data Source to CSV (Called DSN I think. Its in Control Panel -> Administrative Tools -> ODBC Data Sources. Then on, you can query it using SQL.

I am still unsure if you can get what you want. I mean inserting a string with commas in it as a value for a particular cell.

方法 3:

A regexp:

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

It will find all commas that are not inside quotes.

Alternatively, you can use this function which I just adapted for 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

方法 4:

To answer the other half of your question, I have a vague recollection that you can use Windows Script Host spread across several WSF files. I have never done it myself, link to MSDN. Not pure VBS, but it should work in 'just' windows, if that was the real constraint.

More links:

  • Scripting Guys 
  • Wikipedia
  • 'Tutorial'

(by AmbroseChapelTomalakdaanish.rumaniGSergBenjol)

參考文件

  1. Does VBscript have modules? I need to handle CSV (CC BY-SA 3.0/4.0)

#split #module #vbscript #CSV #RegEx






相關問題

將 xml 元素內容拆分為固定行數 (Split xml element content into fix number of lines)

是否有任何標准說明“aba”.split(/a/) 是否應該返回 1,2 或 3 個元素? (Is there any standard which says if "aba".split(/a/) should return 1,2, or 3 elements?)

Cố gắng gọi các phương thức trong phương thức main với biến được khởi tạo trong các phương thức khác (Trying to call methods in main method with variable initialized in other methods)

使用 Java-Regex 與 Regex 成對拆分多行文本 (Split text with Java-Regex in pairs with Regex over several lines)

如何分割字節數組 (How to split a byte array)

String componentsSeparatedByString 做一次 (String componentsSeparatedByString do one time)

從一行文本中獲取特定數據 (Get specific data from a line of text)

(Python)拆分字符串多個分隔符更有效?1) 使用多重替換方法然後使用拆分 2) 使用正則表達式 ((Python) which is more efficient to split a string multiple separators? 1) Using multiple replace method then using split 2) using regular Expressions)

ValueError:發現樣本數量不一致的輸入變量:[2935848、2935849] (ValueError: Found input variables with inconsistent numbers of samples: [2935848, 2935849])

在 Powershell 中拆分和添加字符串 (Splitting and Adding String in Powershell)

在 python 函數中檢查月份的有效性時出錯 (Error in checking validity of month in python function)

如何將 .obj 文件拆分為其他兩個文件(python、open3d)? (How to split a .obj file into two other files (python, open3d)?)







留言討論