#vb.net #linq #uipath
Вопрос:
У меня есть база данных с приведенными ниже данными, которую я хочу отформатировать, и у меня есть только данные за последние недели.
ID | Имя | Неделя 1 | Неделя 2 | Неделя 3 | Неделя 4 |
---|---|---|---|---|---|
1 | Конор | 100 | 87 | 3 | 0 |
2 | Откровенный | 35 | 70 | 0 | 0 |
3 | Джефф | 35 | 13 | 0 | 57 |
Я хотел бы сохранить первые 2 столбца, а затем сохранить самый правый столбец, который не равен 0, что дает мне следующее
ID | Имя | Ценность |
---|---|---|
1 | Конор | 3 |
2 | Откровенный | 70 |
3 | Джефф | 57 |
Я совсем новичок в LINQ, поэтому немного не уверен, можно ли это сделать или нет, поэтому буду признателен за любую помощь.
Дополнительная информация: Я забыл упомянуть, что создаю решение в UiPath (инструмент RPA), поэтому, хотя код VB был бы лучше для этого экземпляра, предпочтительнее LINQ.
Комментарии:
1. Как
DataTable
происходит загрузка данных?2. Я заполняю его из электронной таблицы Excel
Ответ №1:
Linq-это круто, но рабочий код еще круче. Linq не обязательно быстрее. Он выполняет внутренние циклы.
Ваш код в GetDataTable
функции будет представлять собой извлечение данных из Excel. Я только что создал таблицу данных, соответствующую вашему примеру.
В событии нажатия кнопки я создал таблицу для хранения результата. Внешний цикл проходит через каждую строку в источнике DataTable
. Внутренний For
цикл начинается с самого правого столбца dtSource
и возвращается к третьему столбцу (индекс 2). Обратите внимание на Step -1
. Это должно работать для любого количества столбцов недели, так как мы используем dtSource.Columns.Count - 1
, как только он находит ненулевое значение, он добавляет запись dtResult
и завершает внутренний For
переход к следующей строке dtSource
.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dtSource = GetDataTable()
Dim dtResult As New DataTable
dtResult.Columns.Add("ID", GetType(Integer))
dtResult.Columns.Add("Name", GetType(String))
dtResult.Columns.Add("Value", GetType(Integer))
For Each row As DataRow In dtSource.Rows
For i = dtSource.Columns.Count - 1 To 2 Step -1
If CInt(row(i)) <> 0 Then
dtResult.Rows.Add({row("ID"), row("Name"), row(i)})
Exit For
End If
Next
Next
DataGridView1.DataSource = dtResult
End Sub
Private Function GetDataTable() As DataTable
Dim dt As New DataTable
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("Week1", GetType(Integer))
dt.Columns.Add("Week2", GetType(Integer))
dt.Columns.Add("Week3", GetType(Integer))
dt.Columns.Add("Week4", GetType(Integer))
dt.Rows.Add({1, "Conor", 100, 87, 3, 0})
dt.Rows.Add({2, "Frank", 35, 70, 0, 0})
dt.Rows.Add({3, "Jeff", 35, 13, 0, 57})
Return dt
End Function
Комментарии:
1. Полностью согласен, и в идеальном мире именно такое решение я бы, вероятно, реализовал. Проблема, с которой я сталкиваюсь, заключается в том, что я внедряю решение в UiPath, и хотя мы можем
Invoke Code
сделать то же самое, что и выше, было бы предпочтительнее, чтобы это можно было сделать с помощью операторов LINQ