2012-10-16 3 views
1

사실 파일 변환기 도구를 쓰고 있습니다. 데이터 값은 120x120 행렬을 나타냅니다. 내 첫 번째 생각은 두 개의 중첩 된 루프와 첫 번째 내부의 새로운 라인이었습니다. 쉽습니다.CSV 데이터 파일의 매트릭스와 같은 값 구성

입력 파일에는 각 값에 대해 vbNewLine이 있습니다. 입력 파일을 문자열 strAll으로 구문 분석했습니다.

입력 strAll 포함

10 문자 길이 값

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

쉬워야 Mid 모자를 사용

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

파싱 출력 : Mid(strAll, 1+i, 10+i), i 카운터 인 안에 for 루프. Replace(stAll, " ", "")은 3 개의 공백, 2 개의 공백 및 1 개의 공백을 모두 제거해야합니다.

질문 : 문자열을 파일로 출력하는 방법은 매트릭스 형식입니까?

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 

답변

1

프로 시저에 오타가있는 것 같습니다. Strg2Array().

arrAlles(UBound(arrAll)) = ... 

은 아마 내가 다른 접근 방식을 제안 할 수 있습니다, 말했다와

arrAll(UBound(arrAll)) = ... 

있어야하는데? 이 같은 입력 파일을 갖고있는 것 같다 이후 :

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

I :

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

및 것 같은 (따옴표와 공백없이) 그냥 숫자 세미콜론으로 구분 된 출력을 생성 할 수 있습니다 필드를 작성 후,

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 필드). 출력을 새 파일로 리디렉션하면 작업이 완료됩니다.

당신은 빈 필드의 마지막 줄을 채우기 같은 것을 추가해야하는 경우 :

cscript.exe input.csv > output.csv 
+2

표준 텍스트 파일 (후행 EOL)의 경우 "분할"전략은 결과 배열에 빈/가짜 마지막 요소를 만듭니다. –

+0

네가 맞다. 이것은 오타이다. 내 독일어 함수 이름을 번역해야했다. 모듈러스 작업에 감사드립니다. 좋은 오래된 C++ % -Modulo처럼 들립니다. –

+0

@ Ekkehard.Horner 예, 언급 했어야합니다. 결정된. –

1

(거의) 같은 :이 같은 스크립트를 호출 할 것

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

을 안스 같은 생각, 다른 구현 :

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 

내 패턴은 유효한 데이터를 식별하고 (아마도 값이 비싼) 문자열 조작을 피합니다.

+0

간략한 예. RegExp는 shure에 대해 유연합니다. 계산 성능이 좋을수록 strAll이 더 큽니까? –

+1

@StefanBischof 귀하는 항상 RegExps의 추가 기능에 대해 비용을 지불합니다. 그래서 당신은 문자열 연산 (예 : Replace (s, "", ""))뿐만 아니라 할 수있는 작업에 그들을 사용해서는 안됩니다. 그러나 원하는만큼 정확하게 전달하는 하나의 RegExp를 사용하지 않으면 많은 개별 사용자 정의/특수 문자열 연산 (각 문자열 전체를 스캔)을 적용하는 것이 아니라 RegExps가 더 오래 걸리더라도 더 저렴합니다. –

관련 문제