在csv数据文件中组织像矩阵这样的值

时间:2012-10-16 15:27:08

标签: arrays vbscript formatting string-formatting

其实我正在编写一个文件转换工具。数据值表示120x120矩阵。我的第一个想法是两个嵌套for循环,而第一个内部只是一个新行:Easy。

输入文件的每个fith值都有一个vbNewLine。 我将输入文件解析为字符串strAll

输入

strAll包含10个字符的长值

"  -24.1189"  (two blanks before value)
"    1.2345"  (four blanks before value)

输出

-24.1189;-24.1189; (...total 120 values...)
-24.1234;-24.1189; (...total 120 values...)
(... total 120 rows ...)

使用Mid帽子应该很容易解析:Mid(strAll, 1+i, 10+i),其中i是for循环中的计数器。 Replace(stAll, " ", "")应删除所有3个空格,2个空白和一个空白。

问题:如何将字符串输出到文件中,格式化为矩阵?

Dim intValueLength, maxValue, intValueInRowMax
intValueLength=10
intValueInRowMax=120
maxValues=intValueInRowMax * intValueInRowMax



Sub Strg2Array
  arrAll = array()

  ' convert to array
      For i=1 To maxValues
        ReDim Preserve arrAll(UBound(arrAll) +1)
        arrAll(UBound(arrAll)) = Mid(strAll, 1+(i-1)*intValueLength, i*intValueLength)
      Next
End Sub

Sub SaveAll
      Dim intValueInRow
      intValueInRow=0
  Const ForWriting = 2
  Set objFSOOut = CreateObject("Scripting.FileSystemObject")
  Set objOutput = objFSOOut.OpenTextFile(strFileName, ForWriting, true)
      for each value in arrAll
        objOutput.Write value
        intValueInRow = intValueInRow + 1  'Argh, there is no "++" operator?
        If (intValueInRow = intValueInRowMax) Then
          objOutput.Write vbNewLine
          intValueInRow=0
        End If
      next
objOutput.Close
Set objFSOOutput = Nothing
End Sub

2 个答案:

答案 0 :(得分:1)

对于你的程序中似乎有一个拼写错误Strg2Array()

arrAlles(UBound(arrAll)) = ...

可能应该是

arrAll(UBound(arrAll)) = ...

话虽如此,我可以提出一个不同的方法吗?因为您似乎有这样的输入文件:

"  -24.1189";"    1.2345";"  124.5290";"   -5.3951";"    2.1062"
"    2.6702";"  -23.1502";"   -1.5028";"   -2.6223";"  -24.3573"
...

并且似乎想要仅使用数字(没有双引号和空格)来创建以分号分隔的输出,如下所示:

-24.1189;1.2345;124.5290;-5.3951;2.1062;...(115 more)...
...

我会使用更像这样的东西:

Set fso = CreateObject("Scripting.FileSystemObject")

strAll = fso.OpenTextFile(WScript.Arguments.Unnamed(0), 1).ReadAll

Set re = New RegExp
re.Pattern = "\s+"

strAll = Replace(strAll, vbNewLine, ";")
strAll = Replace(strAll, """", "")
strAll = re.Replace(strAll, "")

arrAll = Split(strAll, ";")

For i = 0 To UBound(arrAll)
  WScript.StdOut.Write arrAll(i)
  If i Mod 120 = 119 Then
    WScript.StdOut.WriteLine
  Else
    WScript.StdOut.Write ";"
  End If
Next

这将读取作为脚本的第一个参数给出的文件的输入,删除双引号和空格,然后将字段写入StdOut(每行120个字段)。将输出重定向到新文件,您就完成了。

如果你需要用空字段填充最后一行,请添加如下内容:

If (i Mod 120) <> 0 Then
  For n = i Mod 120 To 118   ' max. index - 1
    WScript.StdOut.Write ";"
  Next
End If

您可以像这样调用脚本:

cscript.exe input.csv > output.csv

答案 1 :(得分:1)

(几乎)和Ansgar一样的想法,不同的实现:

  Const cnRows = 4    ' to keep the demo simple
  Const cnCols = 3
  Const csFSep = ";"
' Const csRSep = vbLf
  Dim   csRSep : csRSep = vbLf

  Dim aInps : aInps = Array( _
      Join(Array("A1  B1 C1 A2", vbLf, "B2,C2", "comment", vbCrLf, "A3 B3 C3", vbTab, "A4-B4-C4")) _
    , "1 2 3 4 5 6 7 8 9 10 11 12" _
    , Join(Array("1.1 -2.2 3.3 4", vbLf, "0.5 -6.6", "comment", vbCrLf, "7 8.0 -9.99", vbTab, "10.10*11.11***-12.12")) _
  )
  ' no need to care for the input format, as long as the valid data can be
  ' specified by a RegExp pattern (and the file contains 'enough' info)
  Dim reCut : Set reCut = New RegExp
  reCut.Global  = True
  reCut.Pattern = "([A-Z-])?\d+(\.\d+)?"

  Dim sInp
  For Each sInp In aInps
      WScript.Echo Join(Array("----", vbCrLf, sInp, vbCrLf, "----"), "")
      Dim oMTS : Set oMTS = reCut.Execute(sInp)
      If oMTS.Count <> cnRows * cnCols Then
         WScript.Echo "Bingo:", oMTS.Count, "<>", (cnRows * cnCols)
      Else
         Dim m
         For m = 0 To oMTS.Count - 1
             WScript.Stdout.Write oMTS(m).Value
             If 0 = (m + 1) Mod cnCols Then WScript.Stdout.Write csRSep Else WScript.Stdout.Write csFSep
         Next
      End If
  Next

输出:

----
A1  B1 C1 A2
 B2,C2 comment
 A3 B3 C3        A4-B4-C4
----
A1;B1;C1
A2;B2;C2
A3;B3;C3
A4;B4;C4
----
1 2 3 4 5 6 7 8 9 10 11 12
----
1;2;3
4;5;6
7;8;9
10;11;12
----
1.1 -2.2 3.3 4
 0.5 -6.6 comment
 7 8.0 -9.99     10.10*11.11***-12.12
----
1.1;-2.2;3.3
4;0.5;-6.6
7;8.0;-9.99
10.10;11.11;-12.12

我的模式尝试识别有效数据并避免(可能代价高昂)字符串操作。