0

1日の終わりに作成される2つのレポートがあります。月末に分析できるようにしたいと思います。

各ファイルの中には、1000行ほどの長いASCII文字列があります。これは正常にコーディングされていますが、一度に1つのファイルを抽出して分析を実行するためだけです。

以下のコードの関連する構造を試してみます。これで、何をする必要があるかを理解するのに十分だと思います。そうでない場合は、すべてを投稿させていただきます。

using (StreamReader reader = new StreamReader("YYYYMMDD----1234D.dat"))
{
while loop //this goes through all the lines in the file. 
{if //if meets certain criteria then store into a list, otherwise ignore

}
foreach // this part does the analysis of all the values in the list, totals, etc

最初のレポートは上記の形式であり、もう1つは1234Dの代わりに異なる番号を持っています(引数のために、5678D、つまりyyyymmdd ---- 5678D)。これらの数値は両方とも全体を通して一定です。

すべてのファイルからすべてのデータをリストに保存し、毎日の内訳ではなく、月全体で分析を実行できるようにしたいので、各ファイルがループするようになります。ファイルの終わりに、名前を1日ずつインクリメントし、それをループします(または、月がXのすべてのファイルを検索します-どちらか良い方)。これによりリストにデータが入力され、foreachが分析と出力を実行します。必要なすべてのファイルを、プログラムで現在使用されているものと同じフォルダーに入れることが期待されています。

現在のコード:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

class Program 
{
    public class EntryLine
    {
        public int I { get; set; }
        public string LineStart { get; set; }
        public string Letters { get; set; }
        public int TVolume { get; set; }
        public long TPrice { get; set; }
        public double MVolume { get; set; }
        public string Currency { get; set; }
        public string DateTime {get; set; }

    }

    static void Main(string[] args)
    {
        List<EntryLine> myList = new List<EntryLine>();
        int i = 1;
        using (StreamReader reader = new StreamReader("20121203----1234D.dat"))
        {
            string line;
            var locations = new Dictionary<string, int[]>() {
            {"210", new [] {405, 4, 128, 12, 141, 12, 247, 15, 121, 3}}, 
            {"310", new [] {321, 4, 112, 12, 125, 12, 230, 15, 105, 3}}, 
            {"410", new [] {477, 4, 112, 12, 125, 12, 360, 15, 105, 3}} 
        };

            while ((line = reader.ReadLine()) != null)
            {
                var lineStart = line.Substring(0, 3);

                if (lineStart == "210" || lineStart == "310" || lineStart == "410")
                {
                    var currentLocations = locations[lineStart];
                    var letters = line.Substring(currentLocations[0], currentLocations[1]);

                    var tvolume =
                        int.Parse(line.Substring(currentLocations[2], currentLocations[3])) +
                        int.Parse(line.Substring(currentLocations[4], currentLocations[5]));

                    var tprice = long.Parse(line.Substring(currentLocations[6], currentLocations[7]));
                    var mvolume = tprice * tvolume * 0.01 * 0.0000001;
                    var currency = line.Substring(currentLocations[8], currentLocations[9]);

                    myList.Add(new EntryLine()
                    {
                        I = i,
                        LineStart = lineStart,
                        Letters = letters,
                        TVolume = tvolume,
                        TPrice = tprice,
                        MVolume = mvolume,
                        Currency = currency
                    });
                    i = i + 1;
                }
            }

            var x = myList.GroupBy(g => new { g.Letters, g.Currency })
                .Select(a => new { a.Key.Letters, a.Key.Currency, TSum = a.Sum(s => s.TVolume), MSum = a.Sum(s => s.MVolume) });

            foreach (var item in x)
            {
                Console.WriteLine("{0} currency: {1} tvolume: {2} mVolume: {3}", item.Letters, item.Currency, item.TSum, item.MSum);
            }
        } Console.ReadLine();
    }

}
4

3 に答える 3

1

これを行うにはいくつかの方法があります。1つのオプションがあります。まず、コードのメンテナンスを容易にするために、プロシージャをいくつかの関数に分割します。次に、1つの関数を使用してすべてのファイルをループし、情報のリストを作成し、別の関数を使用してその情報を分析します。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ReportAnalysis {
static class Program {
    static void Main() {
        //lets run the analysis for Nov, 2012

        //First, read in all report files, and store relevant lines
        var reportInfo = ReportAnalyzer.ReadFiles(2012, 11);

        //Now analyze all files at once
        ReportAnalyzer.RunAnalysis(reportInfo);
    }
}
class ReportAnalyzer {
    struct ReportFile {
        public string Path;
        public DateTime Date;
        public List<string> Lines;
    }

    public static IList<ReportFile> ReadFiles(int year, int month) {
        //Put names of files here.
        string[] fileNames = new string[] { "{0:YYYYMMDD}----1234D.dat", "{0:YYYYMMDD}----5678D.dat" };

        DateTime dateStart = new DateTime(year, month, 1); //start of month
        DateTime dateEnd = dateStart.AddMonths(1); //start of NEXT month (i.e. 1 day past end of this month)

        var reportList = new List<ReportFile>();

        DateTime date = dateStart;
        while (date < dateEnd) {  //we don't actually get to dateEnd, just the day before it.
            foreach (var fileTemplate in fileNames) {
                //insert the date in YYYYMMDD format
                var file = string.Format(fileTemplate, date);
                if (File.Exists(file)) {
                    var report = new ReportFile() {
                        Date = date,
                        Path = file,
                        Lines = GetReportLines(file)
                    };
                    reportList.Add(report);
                }
            }
            //now jump to next day
            date = date.AddDays(1);
        }
        return reportList;
    }

    private static List<string> GetReportLines(string file) {
        var lines = new List<string>();
        try {
            using (StreamReader reader = new StreamReader(file)) {
                while (!reader.EndOfStream) {
                    var line = reader.ReadLine();
                    if (true /* insert criteria */)
                        lines.Add(line);
                }
            }
        } catch (Exception ex) {
            //log the error however you see fit
            lines.Add(string.Format("ERROR Could not open report file {0}: {1}", file, ex.Message));
        }
        return lines;
    }

    public static void RunAnalysis(IList<ReportFile> reports) {
        foreach (var r in reports) {
            //Do whatever analysis you need
            Console.WriteLine(r.Date);
            Console.WriteLine(r.Path);
            foreach (var line in r.Lines)
                Console.WriteLine(line);
        }
    }
}
}

ここに、重要な部分だけに取り掛かる「short-n-sweet」バージョンがあります。

void ProcessReports {
    string[] fileNames = new string[] { "{0:YYYYMMDD}----1234D.dat", "{0:YYYYMMDD}----5678D.dat" };
    DateTime dateStart = new DateTime(year, month, 1); //start of month
    DateTime dateEnd = dateStart.AddMonths(1); //start of NEXT month (i.e. 1 day past end of this month)
    List<string> lines = new List<string>();
    DateTime date = dateStart;
    while (date < dateEnd) {  //we don't actually get to dateEnd, just the day before it.
        foreach (var fileTemplate in fileNames) {
            //insert the date in YYYYMMDD format
            var file = string.Format(fileTemplate, date);
            if (File.Exists(file)) {
                using (StreamReader reader = new StreamReader(file)) {
                    while (!reader.EndOfStream) {
                        var line = reader.ReadLine();
                        if (true /* insert criteria */)
                            lines.Add(line);
                    }
                }
            }
        }
        //now jump to next day
        date = date.AddDays(1);
    }   
    //Now we have all the lines. Let's process them;
    foreach (var line in lines) {
        //do something with the report lines
    }
}
于 2012-12-04T10:34:05.027 に答える
0

foreachブロックから移動するだけの場合は、2番目のファイル名でブロックをusing複製したり、ファイル名を渡す独自のループ内にブロックを配置したりすることを妨げるものは何もありません。usingusing

string[] filenames = new string[] {
    "20121203 ----1234D.dat",
    "20121204 ----1234D.dat",
    "20121205 ----1234D.dat" };
List<Whatever> yourListOfMatchingItems = new List<Whatever>();

foreach (string filename in filenames)
{
    using (StreamReader reader = new StreamReader(filename))
    {
        while (/* whatever you had before */)
        {
            if (/* whatever you had before */)
            {
            }
        }
    }
}
foreach (/* item in your list */)
{
}
于 2012-12-04T09:57:28.810 に答える
0

ファイルをハードコーディングするのではなく、動的にファイルの名前を作成する必要があります。次に、すべてのファイルをループして値のリストを生成し、それらを処理できます。

いくつかの方法に分けてみませんか?何かのようなもの:

public void Process()
{
    // logic to get string[] of filenames here. You could loop through each
    // day you need a list for and generate a filename for the given day
    var values = new List<T>();
    foreach (var filename in filenames)
    {
        var valuesFromFile = GetValuesFrom(filename);
        values.AddRange(valuesFromFile);
    }
    ProcessValues(values);
}

private List<T> GetValuesFrom(string filename)
{
    var values = new List<T>();
    while loop //this goes through all the lines in the file. 
    {if //if meets certain criteria then store into a list, otherwise ignore
    }
    return values;
}

private void ProcessValues(List<T> values)
{
    foreach // this part does the analysis of all the values in the list, totals, etc
}

Tはもちろんあなたの価値観のタイプです

于 2012-12-04T10:20:40.970 に答える