2014-05-15 75 views
0

對於我們公司正在使用的合併應用程序,我有點尷尬。我們從進度數據庫創建一個csv文件,這個csv文件有14列和NO頭。csv修改文件

CSV文件包含付款(約173,000行)。大多數這些行的是除了列金額(最後一列)相同

例子:

2014;MONTH;;SC;10110;;;;;;;;EUR;-6500000 
2014;01;;SC;10110;;;;;;;;EUR;-1010665 
2014;01;;LLC;11110;;;;;;;;EUR;-6567000 
2014;01;;SC;10110;;;;;;;;EUR;-1110665 
2014;01;;LLC;11110;;;;;;;;EUR;65670.00 
2014;01;;SC;10110;;;;;;;;EUR;-11146.65 

(約174000行)

正如你可以看到一些這些線是除了相同爲金額列。我需要的是排序所有行,加起來的金額和保存一個獨特的行而不是1100行與不同的金額。

我的編碼技巧無法讓我在特定的時間範圍內完成工作,也許你們中的一個可以讓我朝正確的方向解決這個問題。

實施例代碼

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string input = File.ReadAllText(@"c:\temp\test.txt"); 
      string inputLine = ""; 
      StringReader reader = new StringReader(input); 
      List<List<string>> data = new List<List<string>>(); 
      while ((inputLine = reader.ReadLine()) != null) 
      { 
       if (inputLine.Trim().Length > 0) 
       { 
        string[] inputArray = inputLine.Split(new char[] { ';' }); 
        data.Add(inputArray.ToList()); 
       } 
      } 
      //sort data by every column 
      for (int sortCol = data[0].Count() - 1; sortCol >= 0; sortCol--) 
      { 
       data.OrderBy(x => x[sortCol]); 
      } 
      //delete duplicate rows 
      for (int rowCount = data.Count - 1; rowCount >= 1; rowCount--) 
      { 
       Boolean match = true; 
       for (int colCount = 0; colCount < data[rowCount].Count - 2; colCount++) 
       { 
        if(data[rowCount][colCount] != data[rowCount - 1][colCount]) 
        { 
         match = false; 
         break; 
        } 
       } 
       if (match == true) 
       { 
        decimal previousValue = decimal.Parse(data[rowCount - 1][data[rowCount].Count - 1]); 
        decimal currentValue = decimal.Parse(data[rowCount][data[rowCount].Count - 1]); 
        string newStrValue = (previousValue + currentValue).ToString(); 
        data[rowCount - 1][data[rowCount].Count - 1] = newStrValue; 
        data.RemoveAt(rowCount); 
       } 
      } 

      string output = string.Join("\r\n",data.AsEnumerable() 
       .Select(x => string.Join(";",x.Select(y => y).ToArray())).ToArray()); 
      File.WriteAllText(@"c:\temp\test1.txt",output); 
     } 
    } 
} 
+4

你已經嘗試到目前爲止 –

+0

是輸入文件相當小,使得它可以完全讀入內存? – Codor

+0

如果您從數據庫創建CSV文件,這意味着您可以直接使用數據庫?這在數據庫級上要容易得多。 – Richard

回答

2

閱讀由線CSV文件線,並建立在其中保持的總計(和其它信息您需要)在內存中的字典。由於大多數線路屬於同一個密鑰,因此它可能不會導致內存不足問題。之後,根據字典中的信息生成新的CSV。

0

正如我理解你的問題,你的問題,你所要求的解決方案是如何把你的輸入是在

@"2014;MONTH;;SC;10110;;;;;;;;EUR;-6500000 
2014;01;;SC;10110;;;;;;;;EUR;-1010665 
2014;01;;LLC;11110;;;;;;;;EUR;-6567000 
2014;01;;SC;10110;;;;;;;;EUR;-1110665 
2014;01;;LLC;11110;;;;;;;;EUR;65670.00 
2014;01;;SC;10110;;;;;;;;EUR;-11146.65" 

形式獲取的最後一列,然後總結一下?如果是這樣這其實是很容易像這樣的東西

public static void Main() 
    { 
     string input = @"2014;MONTH;;SC;10110;;;;;;;;EUR;-6500000 
2014;01;;SC;10110;;;;;;;;EUR;-1010665 
2014;01;;LLC;11110;;;;;;;;EUR;-6567000 
2014;01;;SC;10110;;;;;;;;EUR;-1110665 
2014;01;;LLC;11110;;;;;;;;EUR;65670.00 
2014;01;;SC;10110;;;;;;;;EUR;-11146.65"; 

     var rows = input.Split('\n'); 

     decimal totalValue = 0m; 

     foreach(var row in rows) 
     {   
      var transaction = row.Substring(row.LastIndexOf(';') +1); 

      decimal val = 0m; 

      if(decimal.TryParse(transaction, out val)) 
       totalValue += val; 
     } 

     Console.WriteLine(totalValue); 
    } 

做不過也許我誤解你問什麼?

0

對不起回答我的帖子這麼晚了,但是這是我的最終解決方案

更換所有「字和寫的輸出流作家。(從25MB去一個15MB的文件)。不是複製我的CSV文件我的新文件只有+/- 700KB!

Filldata()方法正在填充SQL Server,因此我可以批量插入。插入後,我只是查詢表和讀/寫結果集到一個新的文件。在我的應用程序datagridview,以便您可以查看結果,而不是在Excel中打開該文件。

我是新的與C#,我目前wri直接或在內存中查詢csv文件並將其寫回新文件的新解決方案。

方法一:

   string line; 

       StreamWriter sw = new StreamWriter(insertFile); 

       using (StreamReader sr = new StreamReader(sourcePath)) 
       { 
        while ((line = sr.ReadLine()) != null) 
        { 
         sw.WriteLine(line.Replace("\"", "")); 
        } 

        sr.Close(); 
        sw.Close(); 
        sr.Dispose(); 
        sw.Dispose(); 

        File.Copy(insertFile, @"\\SQLSERVER\C$\insert.csv"); 

       } 

方法2:

var destinationFile = @"c:\insert.csv"; 

       var querieImportCSV = "BULK INSERT dbo.TABLE FROM '" + destinationFile + "' WITH (FIELDTERMINATOR = ';', ROWTERMINATOR = '\n', FIRSTROW = 1)"; 
       var truncate = @"TRUNCATE TABLE dbo.TABLE"; 

       string queryResult = 
     @"SELECT [Year] 
       ,[Month] 
       ,[Week] 
       ,[Entity] 
       ,[Account] 
       ,[C11] 
       ,[C12] 
       ,[C21] 
       ,[C22] 
       ,[C3] 
       ,[C4] 
       ,[CTP] 
       ,[VALUTA] 
       ,SUM(AMOUNT) as AMOUNT 
       ,[CURRENCY_ORIG] 
       ,[AMOUNTEXCH] 
       ,[AGENTCODE] 
      FROM dbo.TABLE 
      GROUP BY YEAR, MONTH, WEEK, Entity, Account, C11, C12, C21, C22, C3, C4, CTP, VALUTA, CURRENCY_ORIG, AMOUNTEXCH, AGENTCODE 
      ORDER BY Account"; 

       var conn = new SqlConnection(connectionString); 

       conn.Open(); 
       SqlCommand commandTruncate = new SqlCommand(truncate, conn); 
       commandTruncate.ExecuteNonQuery(); 

       SqlCommand commandInsert = new SqlCommand(querieImportCSV, conn); 
       SqlDataReader readerInsert = commandInsert.ExecuteReader(); 
       readerInsert.Close(); 

       FillData(); 

       SqlCommand commandResult = new SqlCommand(queryResult, conn); 
       SqlDataReader readerResult = commandResult.ExecuteReader(); 

       StringBuilder sb = new StringBuilder(); 

       while (readerResult.Read()) 
       { 
         sb.Append(readerResult["Year"] + ";" + readerResult["Month"] + ";" + readerResult["Week"] + ";" + readerResult["Entity"] + ";" + readerResult["Account"] + ";" + 
         readerResult["C11"] + ";" + readerResult["C12"] + ";" + readerResult["C21"] + ";" + readerResult["C22"] + ";" + readerResult["C3"] + ";" + readerResult["C4"] + ";" + 
         readerResult["CTP"] + ";" + readerResult["Valuta"] + ";" + readerResult["Amount"] + ";" + readerResult["CURRENCY_ORIG"] + ";" + readerResult["AMOUNTEXCH"] + ";" + readerResult["AGENTCODE"]); 
       } 
       sb.Replace("\"",""); 

       StreamWriter sw = new StreamWriter(homedrive); 
       sw.WriteLine(sb); 

       readerResult.Close(); 
       conn.Close(); 
       sw.Close(); 
       sw.Dispose();