大量のランプログラムを読み込み機能で処理する方法大量のコンマ区切りデータをコンソールに出力する外部アプリケーションを実行しようとしています。 出力は基本的に、.NET アプリケーションからの大きなデータテーブルです。 「行」はコンマで区切られ、各行の後に改行文字が続きます。 最初の行はヘッダーであり、これらでデータテーブルを更新する必要があります。 コンソールを読み取るサンプルコードに従いましたが、一部の行が部分的に完全になっている(改行で区切られていない)という問題が発生しています。 次に、部分的な行を削除して次の行の先頭に追加しようとしていますが、まだ数行が不足しています (4338 のうち 35 まで)。 プログラムが終了したらテキスト変数に書き込んで処理すると、動作しますが、はるかに遅くなります(おそらく、文字列が非常に長く、外部アプリケーションと並行していないためですが、それは私の推測です)。
一度に完全な行をキャプチャできるように、読み取り関数が呼び出されるタイミングを制御する方法はありますか? これを処理する既知の方法はありますか (データは 4000 行 x 200 列で、おそらくセルの約 50% が塗りつぶされており、セルごとに 10 文字の文字列に関するデータが含まれています)。
私は .NET ソース コードにアクセスでき、必要に応じて出力を変更して JSL 対応にすることができます。
機密性の高い列名を「IDx」に置き換えて、コードを貼り付けています。 前もって感謝します!
results = Run Program(
Executable(myExecutable),
Options(options),
Read Function(Function({this},
fullValue = this << Read;
lines = Words( fullValue,"\!n" );
lineIndex = 1;
totalLines = totalLines + N Items(lines);
callCount++;
words = Words(lines[1], ",");
if (N Items(words) > 1,
if (extraContent != "", lines[1] = appendExtraContent(lines[1],extraContent),);
newExtraContent = getExtraContent(fullValue);
if (N Items(lines) == 1,
extraContent = extraContent || newExtraContent,
extraContent = newExtraContent
);
if (extraContent != "",
print(lines[NItems(lines)]);
Remove From(lines, N Items(lines));
extraLines++;,
);
if (N Items(lines) >= 1,
if (first == 1,
headers = Words(lines[1],",");
For (i = 14, i <= N Items(headers), i++,
dt << New Column(headers[i], Character);
);
headerCount++;
first = 0;
lineIndex++;
cols = dt << Get Column Names();,);
For( i = lineIndex, i <= N Items(lines), i++,
//print(lines[i]);
count++;
word = break_string_by_sep(lines[i], ",");
if ( N Items(word) > maxHeaders, maxHeaders = N Items(word),);
if (N Items(word) >= 14,
dt << Add Row({
:ID1 = word[1];
:ID2 = word[2];
:ID3 = Num(word[3]);
:ID4 = Num(word[4]);
:ID5 = word[5];
:ID6 = Num(word[6]);
:ID7 = word[7];
:ID8 = Num(word[8]);
:ID9 = word[9];
:ID10 = word[10];
:ID11 = Num(word[11]);
:ID12 = Num(word[12]);
:ID13 = Num(word[13]);
For (k = 14, k <= N Items(cols) , k++,
if (N Items(word) >= k,
AsColumn(dt,cols[k]) = word[k],
);
);
}),
);
);
,);
,);
);
)
);
While (!(results << Is Read EOF), Wait(1));
dt << ShowWindow(1);
);
appendExtraContent = Function({partialValue, extra}, {default local},
fullLine = extra || partialValue;
fullLine;
);
getExtraContent = Function({allLines}, {default local},
lines = Words(allLines, "\!n");
lastValue = N Items(lines);
startValue = Contains(allLines, lines[lastValue]);
last7 = Substr(allLines, -1);
if (last7 == "\!n",
extra = "",
extra = Substr(allLines, startValue);
);
extra;
);
Re: 読み込み機能でランプログラムを大量に処理する方法次のようなことを試してください (外部データ ソースをシミュレートするために Windows .bat ファイル用に記述されています):
dt = New Table( "fetched", New Column( "a" ), New Column( "b" ), New Column( "c" ), New Column( "d" ), New Column( "bufsize" ) );
// https://stackoverflow.com/questions/2591758/batch-script-loop
bat = Save Text File( "$temp/data.bat", "@echo off\!nfor /l %%x in (1, 1, 100000) do echo %%x, 444, 555, 666" );
buffer = "";
runprog = RunProgram(
executable( "CMD.EXE" ),
options( {"/C", bat} ),
readfunction(
Function( {this},
{data},
While( this << canread,
buffer = buffer || (this << read);
While( Pat Match( buffer, Pat Break( "\!n" ) >> data + "\!n", "" ),
dt << addrow( 1 );
{dt:a, dt:b, dt:c, dt:d} = Words( data, "," );
dt:bufsize = Length( buffer );
If( Mod( N Rows( dt ), 1000 ) == 0,
Wait( 0 )
); // show the updates
);
)
)
)
);
100,000 行は、テーブルの更新に時間がかかります (おそらく 15 秒)。 この方法では、はるかに高速 (~4 秒) に実行されます。
dt = New Table( "fetched", New Column( "a" ), New Column( "b" ), New Column( "c" ), New Column( "d" ), New Column( "bufsize" ) );
// https://stackoverflow.com/questions/2591758/batch-script-loop
bat = Save Text File( "$temp/data.bat", "@echo off\!nfor /l %%x in (1, 1, 100000) do echo %%x, 444, 555, 666" );
buffer = "";
dt << begin Data Update;
runprog = RunProgram(
executable( "CMD.EXE" ),
options( {"/C", bat} ),
readfunction(
Function( {this},
{data},
While( this << canread,
buffer = buffer || (this << read);
While( Pat Match( buffer, Pat Break( "\!n" ) >> data + "\!n", "" ),
dt << addrow( 1 );
{dt:a, dt:b, dt:c, dt:d} = Words( data, "," );
dt:bufsize = Length( buffer );
);
)
)
)
);
Write( "\!nWaiting\!n" );
While( !(runprog << isreadeof), Wait( .01 ) );
dt << end Data Update;
Write( "\!nDone" );
<