Обновление значений в файле .csv зависит от значений во втором .csv - PullRequest
0 голосов
/ 10 ноября 2019

У меня есть два файла CSV, которые содержат некоторые данные. Один из них выглядит следующим образом:

drid;aid;1date;2date;res;
2121;12;"01.11.2019 06:49";"01.11.2019 19:05";50;
9;10;"01.11.2019 10:47";"01.11.2019 11:33";0;
72;33;"01.11.2019 09:29";"01.11.2019 14:19";0;
777;31;"03.11.2019 04:34";"03.11.2019 20:38";167,35;

Второй SCV выглядит следующим образом

datetime;res;drid
"2019-11-01 09:02:00";14,59;2121
"2019-11-03 12:59:00";25,00;777

Моя цель для сравнения дня даты также "слива", и если они совпадают в обоих файлахзатем получите сумму "res" и замените значения "res" в первом csv. Результат должен выглядеть следующим образом:

2121;12;"01.11.2019 06:49";"01.11.2019 19:05";64,59;
9;10;"01.11.2019 10:47";"01.11.2019 11:33";0;
72;33;"01.11.2019 09:29";"01.11.2019 14:19";0;
777;31;"03.11.2019 04:34";"03.11.2019 20:38";192,35;

Что мне нужно сделать, чтобы получить такие результаты в vb.net? Я пытался использовать LINQ Query, но безрезультатно, потому что я новичок и не нашел способа объявить переменные в двух файлах, а затем сравнить их. Хорошо, с помощью .bat я сделал объединение обоих csv в одном big.csv и попытался получить результаты из одного файла, но снова безуспешно. Последний код:

Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click
       Dim Raplines As String() = IO.File.ReadAllLines("C:\Users\big.csv")
       Dim strList As New List(Of String)
       Dim readFirst As Boolean
       For Each line In Raplines
           If readFirst Then
               Dim strValues As String() = line.Split(";")
               Dim kn1 As String = strValues(0)
               Dim kn2 As String = strValues(59)
               Dim pvm1 As Date = strValues(2)
               Dim pvm1Changed = pvm1.ToString("dd")
               Dim pvm2 As Date = strValues(3)
               Dim pvm2Changed = pvm2.ToString("dd")
               Dim pvm3 As Date = strValues(60)
               Dim pvm3Changed = pvm3.ToString("dd")
               Dim Las1 As Decimal = strValues(9)
               Dim Las2 As Decimal = strValues(61)
               Dim sum As Decimal = Las1 - Las2
               If kn1 = kn2 And pvm3Changed = pvm1Changed Or pvm3Changed = pvm2Changed Then
                   strValues(9) = sum
                   strList.Add(String.Join(";", strValues))
               End If
           End If
           readFirst = True
       Next
       IO.File.WriteAllLines("C:\Users\big_new.csv", strList.ToArray())
   End Sub

Ответы [ 2 ]

0 голосов
/ 10 ноября 2019

Вместо изменения существующего файла я написал новый. Я использовал StringBuilder, чтобы среда выполнения не создавала и не выбрасывала столько строк. StringBuilder изменчив в отличие от Strings. Я проанализировал различные форматы дат и использовал .Date, чтобы игнорировать Times.

Private Sub ChangeCVSFile()
    Dim lines1 = File.ReadAllLines("C:\Users\someone\Desktop\CSV1.cvs")
    Dim lines2 = File.ReadAllLines("C:\Users\someone\Desktop\CSV2.cvs")
    Dim sb As New StringBuilder
    For Each line1 In lines1
        Dim Fields1 = line1.Split(";"c) 'drid;aid;1date;2date;res
        For Each line2 In lines2
            Dim Fields2 = line2.Split(";"c) 'datetime;res;drid
            '                                  
            '                        Trim the exta double quotes   "01.11.2019 06:49"
            Dim d1 = DateTime.ParseExact(Fields1(2).Trim(Chr(34)), "dd.MM.yyyy hh:mm", CultureInfo.InvariantCulture).Date
            '                                                      "2019-11-01 09:02:00"
            Dim d2 = DateTime.ParseExact(Fields2(0).Trim(Chr(34)), "yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture).Date
            If Fields1(0) = Fields2(2) AndAlso d1 = d2 Then
                Dim sum = CDec(Fields1(4)) + CDec(Fields2(1))
                Fields1(4) = sum.ToString
            End If
        Next
        sb.AppendLine(String.Join(";", Fields1))
    Next
    File.WriteAllText("C:\Users\someone\Desktop\CSV3.cvs", sb.ToString)
End Sub
0 голосов
/ 10 ноября 2019

Это должно решить проблему:


Option Strict Off 'To allow late binding.

Dim file1 As String = "c:\users\file1.csv"
Dim file2 As String = "c:\users\file2.csv"
Dim lst1 As New List(Of Object)
'Read all lines but the first one. Skipping -> drid;aid;1date;2date;res;
Dim file1Lines() As String = IO.File.ReadAllLines(file1).Skip(1).ToArray
'Read all lines of the second file but the first line. Skipping -> datetime;res;drid
Dim file2Lines() As String = IO.File.ReadAllLines(file2).Skip(1).ToArray

For Each line As String In file1Lines.Where(Function(a) Not String.IsNullOrEmpty(a))
    Dim arrLine() As String = line.Split({";"}, StringSplitOptions.RemoveEmptyEntries)
    'Create a temporary anonymous object for each entry of the main file.
    Dim item As New With {
        .drid = Convert.ToInt32(arrLine(0)),
        .aid = Convert.ToInt32(arrLine(1)),
        .date1 = DateTime.ParseExact(arrLine(2).Replace("""", ""), "dd.MM.yyyy HH:mm", Globalization.CultureInfo.InvariantCulture),
        .date2 = DateTime.ParseExact(arrLine(3).Replace("""", ""), "dd.MM.yyyy HH:mm", Globalization.CultureInfo.InvariantCulture),
        .res = Decimal.Parse(arrLine(4).Replace(",", "."), Globalization.NumberStyles.Float)
    }
    lst1.Add(item)
Next

'The second file.
For Each line As String In file2Lines.Where(Function(a) Not String.IsNullOrEmpty(a))
    Dim arrLine() As String = line.Split({";"}, StringSplitOptions.RemoveEmptyEntries)
    Dim newItem As New With {
        .DateTime = DateTime.ParseExact(arrLine(0).Replace("""", ""), "yyyy-MM-dd HH:mm:ss", Globalization.CultureInfo.InvariantCulture),
        .res = Decimal.Parse(arrLine(1).Replace(",", "."), Globalization.NumberStyles.Float),
        .drid = Convert.ToInt32(arrLine(2))
    }

    'Search for matches in the second file.
    Dim item = (From a In lst1 Where a.drid.Equals(newItem.drid) AndAlso a.date1.Date.Equals(newItem.DateTime.Date)).FirstOrDefault

    'If any, do the sum.
    If item IsNot Nothing Then
        item.res += newItem.res
    End If
Next

'Overwrite the first file.
Using sw As New IO.StreamWriter(file1)
    For Each item In lst1
        Dim dt1 As String = Convert.ToDateTime(item.date1).ToString("dd.MM.yyyy HH:mm")
        Dim dt2 As String = Convert.ToDateTime(item.date2).ToString("dd.MM.yyyy HH:mm")

        'Maintaining the same order and format of the entries.
        sw.WriteLine($"{item.drid};{item.aid};""{dt1}"";""{dt2}"";{item.res};")
    Next
End Using

Вывод:

2121; 12; "01.11.2019 06:49"; "01.11.2019 19:05"; 64,59;
9; 10;" 01.11.2019 10:47 ";" 01.11.2019 11:33 "; 0;
72; 33;" 01.11.2019 09:29 ";" 01.11. 2019 14:19 "; 0;
777; 31;" 03.11.2019 04:34 ";" 03.11.2019 20:38 "; 192.35;

Однако, если я могу предложить,локальная база данных или сериализуемые объекты сделают ваш день намного лучше.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...